/[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 678 by ph10, Sun Aug 28 15:23:03 2011 UTC revision 915 by zherczeg, Tue Feb 14 13:05:39 2012 UTC
# Line 6  Line 6 
6  and semantics are as close as possible to those of the Perl 5 language.  and semantics are as close as possible to those of the Perl 5 language.
7    
8                         Written by Philip Hazel                         Written by Philip Hazel
9             Copyright (c) 1997-2008 University of Cambridge             Copyright (c) 1997-2012 University of Cambridge
10    
11    The machine code generator part (this module) was written by Zoltan Herczeg    The machine code generator part (this module) was written by Zoltan Herczeg
12                        Copyright (c) 2010-2011                        Copyright (c) 2010-2012
13    
14  -----------------------------------------------------------------------------  -----------------------------------------------------------------------------
15  Redistribution and use in source and binary forms, with or without  Redistribution and use in source and binary forms, with or without
# Line 52  POSSIBILITY OF SUCH DAMAGE. Line 52  POSSIBILITY OF SUCH DAMAGE.
52  we just include it. This way we don't need to touch the build  we just include it. This way we don't need to touch the build
53  system files. */  system files. */
54    
55    #define SLJIT_MALLOC(size) (PUBL(malloc))(size)
56    #define SLJIT_FREE(ptr) (PUBL(free))(ptr)
57  #define SLJIT_CONFIG_AUTO 1  #define SLJIT_CONFIG_AUTO 1
58    #define SLJIT_CONFIG_STATIC 1
59  #define SLJIT_VERBOSE 0  #define SLJIT_VERBOSE 0
60  #define SLJIT_DEBUG 0  #define SLJIT_DEBUG 0
61    
62  #include "sljit/sljitLir.c"  #include "sljit/sljitLir.c"
63    
64  #if defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED  #if defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED
65  #error "Unsupported architecture"  #error Unsupported architecture
66  #endif  #endif
67    
68  /* Allocate memory on the stack. Fast, but limited size. */  /* Allocate memory on the stack. Fast, but limited size. */
# Line 119  The generated code will be the following Line 122  The generated code will be the following
122   jump to D hot path   jump to D hot path
123   C fallback path   C fallback path
124   A fallback path   A fallback path
125    
126   Notice, that the order of fallback code paths are the opposite of the fast   Notice, that the order of fallback code paths are the opposite of the fast
127   code paths. In this way the topmost value on the stack is always belong   code paths. In this way the topmost value on the stack is always belong
128   to the current fallback code path. The fallback code path must check   to the current fallback code path. The fallback code path must check
# Line 145  Thus we can restore the locals to a part Line 148  Thus we can restore the locals to a part
148  typedef struct jit_arguments {  typedef struct jit_arguments {
149    /* Pointers first. */    /* Pointers first. */
150    struct sljit_stack *stack;    struct sljit_stack *stack;
151    PCRE_SPTR str;    const pcre_uchar *str;
152    PCRE_SPTR begin;    const pcre_uchar *begin;
153    PCRE_SPTR end;    const pcre_uchar *end;
154    int *offsets;    int *offsets;
155    uschar *ptr;    pcre_uchar *ptr;
156    /* Everything else after. */    /* Everything else after. */
157    int offsetcount;    int offsetcount;
158    int calllimit;    int calllimit;
159    uschar notbol;    pcre_uint8 notbol;
160    uschar noteol;    pcre_uint8 noteol;
161    uschar notempty;    pcre_uint8 notempty;
162    uschar notempty_atstart;    pcre_uint8 notempty_atstart;
163  } jit_arguments;  } jit_arguments;
164    
165  typedef struct executable_function {  typedef struct executable_functions {
166    void *executable_func;    void *executable_funcs[JIT_NUMBER_OF_COMPILE_MODES];
167    pcre_jit_callback callback;    PUBL(jit_callback) callback;
168    void *userdata;    void *userdata;
169  } executable_function;    sljit_uw executable_sizes[JIT_NUMBER_OF_COMPILE_MODES];
170    } executable_functions;
171    
172  typedef struct jump_list {  typedef struct jump_list {
173    struct sljit_jump *jump;    struct sljit_jump *jump;
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 mode;
279    int nltype;    int nltype;
280    int newline;    int newline;
281    int bsr_nltype;    int bsr_nltype;
282    int endonly;    int endonly;
283    sljit_w ctypes;    sljit_w ctypes;
284      sljit_uw name_table;
285      sljit_w name_count;
286      sljit_w name_entry_size;
287      struct sljit_label *partialmatchlabel;
288    struct sljit_label *acceptlabel;    struct sljit_label *acceptlabel;
289    stub_list *stubs;    stub_list *stubs;
290    recurse_entry *entries;    recurse_entry *entries;
291    recurse_entry *currententry;    recurse_entry *currententry;
292      jump_list *partialmatch;
293    jump_list *accept;    jump_list *accept;
294    jump_list *calllimit;    jump_list *calllimit;
295    jump_list *stackalloc;    jump_list *stackalloc;
# Line 291  typedef struct compiler_common { Line 301  typedef struct compiler_common {
301    jump_list *casefulcmp;    jump_list *casefulcmp;
302    jump_list *caselesscmp;    jump_list *caselesscmp;
303    BOOL jscript_compat;    BOOL jscript_compat;
304  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
305    BOOL utf8;    BOOL utf;
306  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
307    BOOL useucp;    BOOL use_ucp;
308  #endif  #endif
309    jump_list *utf8readchar;    jump_list *utfreadchar;
310    jump_list *utf8readtype8;  #ifdef COMPILE_PCRE8
311      jump_list *utfreadtype8;
312  #endif  #endif
313    #endif /* SUPPORT_UTF */
314  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
315    jump_list *getucd;    jump_list *getucd;
316  #endif  #endif
# Line 310  typedef struct compare_context { Line 322  typedef struct compare_context {
322    int length;    int length;
323    int sourcereg;    int sourcereg;
324  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
325    int byteptr;    int ucharptr;
326    union {    union {
327      int asint;      sljit_i asint;
328      short asshort;      sljit_uh asushort;
329    #ifdef COMPILE_PCRE8
330      sljit_ub asbyte;      sljit_ub asbyte;
331      sljit_ub asbytes[4];      sljit_ub asuchars[4];
332    #else
333    #ifdef COMPILE_PCRE16
334        sljit_uh asuchars[2];
335    #endif
336    #endif
337    } c;    } c;
338    union {    union {
339      int asint;      sljit_i asint;
340      short asshort;      sljit_uh asushort;
341    #ifdef COMPILE_PCRE8
342      sljit_ub asbyte;      sljit_ub asbyte;
343      sljit_ub asbytes[4];      sljit_ub asuchars[4];
344    #else
345    #ifdef COMPILE_PCRE16
346        sljit_uh asuchars[2];
347    #endif
348    #endif
349    } oc;    } oc;
350  #endif  #endif
351  } compare_context;  } compare_context;
352    
353  enum {  enum {
354    frame_end = 0,    frame_end = 0,
355    frame_setmaxindex = -1,    frame_setstrbegin = -1
   frame_setstrbegin = -2  
356  };  };
357    
358    /* Undefine sljit macros. */
359    #undef CMP
360    
361  /* Used for accessing the elements of the stack. */  /* Used for accessing the elements of the stack. */
362  #define STACK(i)      ((-(i) - 1) * (int)sizeof(sljit_w))  #define STACK(i)      ((-(i) - 1) * (int)sizeof(sljit_w))
363    
364  #define TMP1          SLJIT_TEMPORARY_REG1  #define TMP1          SLJIT_TEMPORARY_REG1
365  #define TMP2          SLJIT_TEMPORARY_REG3  #define TMP2          SLJIT_TEMPORARY_REG3
366  #define TMP3          SLJIT_TEMPORARY_EREG2  #define TMP3          SLJIT_TEMPORARY_EREG2
367  #define STR_PTR       SLJIT_GENERAL_REG1  #define STR_PTR       SLJIT_SAVED_REG1
368  #define STR_END       SLJIT_GENERAL_REG2  #define STR_END       SLJIT_SAVED_REG2
369  #define STACK_TOP     SLJIT_TEMPORARY_REG2  #define STACK_TOP     SLJIT_TEMPORARY_REG2
370  #define STACK_LIMIT   SLJIT_GENERAL_REG3  #define STACK_LIMIT   SLJIT_SAVED_REG3
371  #define ARGUMENTS     SLJIT_GENERAL_EREG1  #define ARGUMENTS     SLJIT_SAVED_EREG1
372  #define MAX_INDEX     SLJIT_GENERAL_EREG2  #define CALL_COUNT    SLJIT_SAVED_EREG2
373  #define RETURN_ADDR   SLJIT_TEMPORARY_EREG1  #define RETURN_ADDR   SLJIT_TEMPORARY_EREG1
374    
375  /* Locals layout. */  /* Locals layout. */
# Line 353  enum { Line 379  enum {
379  /* Two local variables for possessive quantifiers (char1 cannot use them). */  /* Two local variables for possessive quantifiers (char1 cannot use them). */
380  #define POSSESSIVE0      (2 * sizeof(sljit_w))  #define POSSESSIVE0      (2 * sizeof(sljit_w))
381  #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))  
382  /* Head of the last recursion. */  /* Head of the last recursion. */
383  #define RECURSIVE_HEAD   (5 * sizeof(sljit_w))  #define RECURSIVE_HEAD   (4 * sizeof(sljit_w))
 /* Number of recursions. */  
 #define CALL_COUNT       (6 * sizeof(sljit_w))  
384  /* Max limit of recursions. */  /* Max limit of recursions. */
385  #define CALL_LIMIT       (7 * sizeof(sljit_w))  #define CALL_LIMIT       (5 * sizeof(sljit_w))
386  /* Last known position of the requested byte. */  /* Last known position of the requested byte.
387  #define REQ_BYTE_PTR     (8 * sizeof(sljit_w))  Same as START_USED_PTR. (Partial matching and req_char are exclusive) */
388    #define REQ_CHAR_PTR     (6 * sizeof(sljit_w))
389    /* First inspected character for partial matching.
390    Same as REQ_CHAR_PTR. (Partial matching and req_char are exclusive) */
391    #define START_USED_PTR   (6 * sizeof(sljit_w))
392    /* Starting pointer for partial soft matches. */
393    #define HIT_START        (8 * sizeof(sljit_w))
394  /* End pointer of the first line. */  /* End pointer of the first line. */
395  #define FIRSTLINE_END    (9 * sizeof(sljit_w))  #define FIRSTLINE_END    (9 * sizeof(sljit_w))
396  /* The output vector is stored on the stack, and contains pointers  /* The output vector is stored on the stack, and contains pointers
# Line 372  the start pointers when the end of the c Line 400  the start pointers when the end of the c
400  #define OVECTOR_START    (10 * sizeof(sljit_w))  #define OVECTOR_START    (10 * sizeof(sljit_w))
401  #define OVECTOR(i)       (OVECTOR_START + (i) * sizeof(sljit_w))  #define OVECTOR(i)       (OVECTOR_START + (i) * sizeof(sljit_w))
402  #define OVECTOR_PRIV(i)  (common->cbraptr + (i) * sizeof(sljit_w))  #define OVECTOR_PRIV(i)  (common->cbraptr + (i) * sizeof(sljit_w))
403  #define PRIV(cc)         (common->localptrs[(cc) - common->start])  #define PRIV_DATA(cc)    (common->localptrs[(cc) - common->start])
404    
405    #ifdef COMPILE_PCRE8
406    #define MOV_UCHAR  SLJIT_MOV_UB
407    #define MOVU_UCHAR SLJIT_MOVU_UB
408    #else
409    #ifdef COMPILE_PCRE16
410    #define MOV_UCHAR  SLJIT_MOV_UH
411    #define MOVU_UCHAR SLJIT_MOVU_UH
412    #else
413    #error Unsupported compiling mode
414    #endif
415    #endif
416    
417  /* Shortcuts. */  /* Shortcuts. */
418  #define DEFINE_COMPILER \  #define DEFINE_COMPILER \
# Line 396  the start pointers when the end of the c Line 436  the start pointers when the end of the c
436  #define COND_VALUE(op, dst, dstw, type) \  #define COND_VALUE(op, dst, dstw, type) \
437    sljit_emit_cond_value(compiler, (op), (dst), (dstw), (type))    sljit_emit_cond_value(compiler, (op), (dst), (dstw), (type))
438    
439  static uschar* bracketend(uschar* cc)  static pcre_uchar* bracketend(pcre_uchar* cc)
440  {  {
441  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));
442  do cc += GET(cc, 1); while (*cc == OP_ALT);  do cc += GET(cc, 1); while (*cc == OP_ALT);
# Line 405  cc += 1 + LINK_SIZE; Line 445  cc += 1 + LINK_SIZE;
445  return cc;  return cc;
446  }  }
447    
448  /* Functions whose might need modification for all new supported opcodes:  /* Functions whose might need modification for all new supported opcodes:
449   next_opcode   next_opcode
450   get_localspace   get_localspace
451   set_localptrs   set_localptrs
# Line 417  return cc; Line 457  return cc;
457   compile_fallbackpath   compile_fallbackpath
458  */  */
459    
460  static uschar *next_opcode(compiler_common *common, uschar *cc)  static pcre_uchar *next_opcode(compiler_common *common, pcre_uchar *cc)
461  {  {
462  SLJIT_UNUSED_ARG(common);  SLJIT_UNUSED_ARG(common);
463  switch(*cc)  switch(*cc)
# Line 472  switch(*cc) Line 512  switch(*cc)
512    case OP_SKIPZERO:    case OP_SKIPZERO:
513    return cc + 1;    return cc + 1;
514    
515      case OP_ANYBYTE:
516    #ifdef SUPPORT_UTF
517      if (common->utf) return NULL;
518    #endif
519      return cc + 1;
520    
521    case OP_CHAR:    case OP_CHAR:
522    case OP_CHARI:    case OP_CHARI:
523    case OP_NOT:    case OP_NOT:
524    case OP_NOTI:    case OP_NOTI:
   
525    case OP_STAR:    case OP_STAR:
526    case OP_MINSTAR:    case OP_MINSTAR:
527    case OP_PLUS:    case OP_PLUS:
# Line 514  switch(*cc) Line 559  switch(*cc)
559    case OP_NOTPOSPLUSI:    case OP_NOTPOSPLUSI:
560    case OP_NOTPOSQUERYI:    case OP_NOTPOSQUERYI:
561    cc += 2;    cc += 2;
562  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
563    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]);
564  #endif  #endif
565    return cc;    return cc;
566    
# Line 535  switch(*cc) Line 580  switch(*cc)
580    case OP_NOTMINUPTOI:    case OP_NOTMINUPTOI:
581    case OP_NOTEXACTI:    case OP_NOTEXACTI:
582    case OP_NOTPOSUPTOI:    case OP_NOTPOSUPTOI:
583    cc += 4;    cc += 2 + IMM2_SIZE;
584  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
585    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]);
586  #endif  #endif
587    return cc;    return cc;
588    
589    case OP_NOTPROP:    case OP_NOTPROP:
590    case OP_PROP:    case OP_PROP:
591      return cc + 1 + 2;
592    
593    case OP_TYPEUPTO:    case OP_TYPEUPTO:
594    case OP_TYPEMINUPTO:    case OP_TYPEMINUPTO:
595    case OP_TYPEEXACT:    case OP_TYPEEXACT:
# Line 550  switch(*cc) Line 597  switch(*cc)
597    case OP_REF:    case OP_REF:
598    case OP_REFI:    case OP_REFI:
599    case OP_CREF:    case OP_CREF:
600      case OP_NCREF:
601      case OP_RREF:
602      case OP_NRREF:
603    case OP_CLOSE:    case OP_CLOSE:
604    cc += 3;    cc += 1 + IMM2_SIZE;
605    return cc;    return cc;
606    
607    case OP_CRRANGE:    case OP_CRRANGE:
608    case OP_CRMINRANGE:    case OP_CRMINRANGE:
609    return cc + 5;    return cc + 1 + 2 * IMM2_SIZE;
610    
611    case OP_CLASS:    case OP_CLASS:
612    case OP_NCLASS:    case OP_NCLASS:
613    return cc + 33;    return cc + 1 + 32 / sizeof(pcre_uchar);
614    
615  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
616    case OP_XCLASS:    case OP_XCLASS:
617    return cc + GET(cc, 1);    return cc + GET(cc, 1);
618  #endif  #endif
# Line 574  switch(*cc) Line 624  switch(*cc)
624    case OP_ASSERTBACK_NOT:    case OP_ASSERTBACK_NOT:
625    case OP_REVERSE:    case OP_REVERSE:
626    case OP_ONCE:    case OP_ONCE:
627      case OP_ONCE_NC:
628    case OP_BRA:    case OP_BRA:
629    case OP_BRAPOS:    case OP_BRAPOS:
630    case OP_COND:    case OP_COND:
# Line 591  switch(*cc) Line 642  switch(*cc)
642    case OP_CBRAPOS:    case OP_CBRAPOS:
643    case OP_SCBRA:    case OP_SCBRA:
644    case OP_SCBRAPOS:    case OP_SCBRAPOS:
645    return cc + 1 + LINK_SIZE + 2;    return cc + 1 + LINK_SIZE + IMM2_SIZE;
646    
647    default:    default:
648    return NULL;    return NULL;
649    }    }
650  }  }
651    
652  static int get_localspace(compiler_common *common, uschar *cc, uschar *ccend)  static int get_localspace(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend)
653  {  {
654  int localspace = 0;  int localspace = 0;
655  uschar *alternative;  pcre_uchar *alternative;
656  /* 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. */
657  while (cc < ccend)  while (cc < ccend)
658    {    {
# Line 612  while (cc < ccend) Line 663  while (cc < ccend)
663      case OP_ASSERTBACK:      case OP_ASSERTBACK:
664      case OP_ASSERTBACK_NOT:      case OP_ASSERTBACK_NOT:
665      case OP_ONCE:      case OP_ONCE:
666        case OP_ONCE_NC:
667      case OP_BRAPOS:      case OP_BRAPOS:
668      case OP_SBRA:      case OP_SBRA:
669      case OP_SBRAPOS:      case OP_SBRAPOS:
# Line 623  while (cc < ccend) Line 675  while (cc < ccend)
675      case OP_CBRAPOS:      case OP_CBRAPOS:
676      case OP_SCBRAPOS:      case OP_SCBRAPOS:
677      localspace += sizeof(sljit_w);      localspace += sizeof(sljit_w);
678      cc += 1 + LINK_SIZE + 2;      cc += 1 + LINK_SIZE + IMM2_SIZE;
679      break;      break;
680    
681      case OP_COND:      case OP_COND:
# Line 644  while (cc < ccend) Line 696  while (cc < ccend)
696  return localspace;  return localspace;
697  }  }
698    
699  static void set_localptrs(compiler_common *common, int localptr, uschar *ccend)  static void set_localptrs(compiler_common *common, int localptr, pcre_uchar *ccend)
700  {  {
701  uschar *cc = common->start;  pcre_uchar *cc = common->start;
702  uschar *alternative;  pcre_uchar *alternative;
703  while (cc < ccend)  while (cc < ccend)
704    {    {
705    switch(*cc)    switch(*cc)
# Line 657  while (cc < ccend) Line 709  while (cc < ccend)
709      case OP_ASSERTBACK:      case OP_ASSERTBACK:
710      case OP_ASSERTBACK_NOT:      case OP_ASSERTBACK_NOT:
711      case OP_ONCE:      case OP_ONCE:
712        case OP_ONCE_NC:
713      case OP_BRAPOS:      case OP_BRAPOS:
714      case OP_SBRA:      case OP_SBRA:
715      case OP_SBRAPOS:      case OP_SBRAPOS:
# Line 670  while (cc < ccend) Line 723  while (cc < ccend)
723      case OP_SCBRAPOS:      case OP_SCBRAPOS:
724      common->localptrs[cc - common->start] = localptr;      common->localptrs[cc - common->start] = localptr;
725      localptr += sizeof(sljit_w);      localptr += sizeof(sljit_w);
726      cc += 1 + LINK_SIZE + 2;      cc += 1 + LINK_SIZE + IMM2_SIZE;
727      break;      break;
728    
729      case OP_COND:      case OP_COND:
# Line 693  while (cc < ccend) Line 746  while (cc < ccend)
746  }  }
747    
748  /* Returns with -1 if no need for frame. */  /* Returns with -1 if no need for frame. */
749  static int get_framesize(compiler_common *common, uschar *cc, BOOL recursive)  static int get_framesize(compiler_common *common, pcre_uchar *cc, BOOL recursive)
750  {  {
751  uschar *ccend = bracketend(cc);  pcre_uchar *ccend = bracketend(cc);
 uschar *end;  
752  int length = 0;  int length = 0;
753  BOOL possessive = FALSE;  BOOL possessive = FALSE;
 BOOL needs_frame = FALSE;  
 BOOL needs_maxindex = FALSE;  
754  BOOL setsom_found = FALSE;  BOOL setsom_found = FALSE;
755    
756  if (!recursive && (*cc == OP_CBRAPOS || *cc == OP_SCBRAPOS))  if (!recursive && (*cc == OP_CBRAPOS || *cc == OP_SCBRAPOS))
757    {    {
758    length = 3 + 2;    length = 3;
   needs_maxindex = TRUE;  
759    possessive = TRUE;    possessive = TRUE;
760    }    }
761    
# Line 725  while (cc < ccend) Line 774  while (cc < ccend)
774      cc += (*cc == OP_SET_SOM) ? 1 : 1 + LINK_SIZE;      cc += (*cc == OP_SET_SOM) ? 1 : 1 + LINK_SIZE;
775      break;      break;
776    
     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;  
   
777      case OP_CBRA:      case OP_CBRA:
778      case OP_CBRAPOS:      case OP_CBRAPOS:
779      case OP_SCBRA:      case OP_SCBRA:
780      case OP_SCBRAPOS:      case OP_SCBRAPOS:
     if (!needs_maxindex)  
       {  
       needs_maxindex = TRUE;  
       length += 2;  
       }  
781      length += 3;      length += 3;
782      cc += 1 + LINK_SIZE + 2;      cc += 1 + LINK_SIZE + IMM2_SIZE;
783      break;      break;
784    
785      default:      default:
# Line 767  while (cc < ccend) Line 789  while (cc < ccend)
789      }      }
790    
791  /* Possessive quantifiers can use a special case. */  /* Possessive quantifiers can use a special case. */
792  if (SLJIT_UNLIKELY(possessive) && !needs_frame && length == 3 + 2)  if (SLJIT_UNLIKELY(possessive) && length == 3)
793    return -1;    return -1;
794    
795  if (length > 0)  if (length > 0)
796    return length + 2;    return length + 1;
797  return needs_frame ? 0 : -1;  return -1;
798  }  }
799    
800  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)
801  {  {
 /* TMP2 must contain STACK_TOP - (-STACK(stackpos)) */  
802  DEFINE_COMPILER;  DEFINE_COMPILER;
803  uschar *ccend = bracketend(cc);  pcre_uchar *ccend = bracketend(cc);
 BOOL needs_maxindex = FALSE;  
804  BOOL setsom_found = FALSE;  BOOL setsom_found = FALSE;
805  int offset;  int offset;
806    
807  if (stackpos < stacktop)  /* >= 1 + shortest item size (2) */
808    {  SLJIT_UNUSED_ARG(stacktop);
809    SLJIT_ASSERT(stackpos + 1 == stacktop);  SLJIT_ASSERT(stackpos >= stacktop + 2);
   return;  
   }  
810    
811  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);  
   
812  if (recursive || (*cc != OP_CBRAPOS && *cc != OP_SCBRAPOS))  if (recursive || (*cc != OP_CBRAPOS && *cc != OP_SCBRAPOS))
813    cc = next_opcode(common, cc);    cc = next_opcode(common, cc);
814  SLJIT_ASSERT(cc != NULL);  SLJIT_ASSERT(cc != NULL);
# Line 815  while (cc < ccend) Line 829  while (cc < ccend)
829      cc += (*cc == OP_SET_SOM) ? 1 : 1 + LINK_SIZE;      cc += (*cc == OP_SET_SOM) ? 1 : 1 + LINK_SIZE;
830      break;      break;
831    
     case OP_ASSERT:  
     case OP_ASSERT_NOT:  
     case OP_ASSERTBACK:  
     case OP_ASSERTBACK_NOT:  
     case OP_ONCE:  
     cc = bracketend(cc);  
     break;  
   
832      case OP_CBRA:      case OP_CBRA:
833      case OP_CBRAPOS:      case OP_CBRAPOS:
834      case OP_SCBRA:      case OP_SCBRA:
835      case OP_SCBRAPOS:      case OP_SCBRAPOS:
     if (!needs_maxindex)  
       {  
       OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, frame_setmaxindex);  
       stackpos += (int)sizeof(sljit_w);  
       OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, MAX_INDEX, 0);  
       stackpos += (int)sizeof(sljit_w);  
       needs_maxindex = TRUE;  
       }  
836      offset = (GET2(cc, 1 + LINK_SIZE)) << 1;      offset = (GET2(cc, 1 + LINK_SIZE)) << 1;
837      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, OVECTOR(offset));      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, OVECTOR(offset));
838      stackpos += (int)sizeof(sljit_w);      stackpos += (int)sizeof(sljit_w);
# Line 845  while (cc < ccend) Line 843  while (cc < ccend)
843      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP2, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP2, 0);
844      stackpos += (int)sizeof(sljit_w);      stackpos += (int)sizeof(sljit_w);
845    
846      cc += 1 + LINK_SIZE + 2;      cc += 1 + LINK_SIZE + IMM2_SIZE;
847      break;      break;
848    
849      default:      default:
# Line 855  while (cc < ccend) Line 853  while (cc < ccend)
853      }      }
854    
855  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, frame_end);  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, frame_end);
856  SLJIT_ASSERT(stackpos == STACK(stacktop + 1));  SLJIT_ASSERT(stackpos == STACK(stacktop));
857  }  }
858    
859  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)
860  {  {
861  int localsize = 2;  int localsize = 2;
862  uschar *alternative;  pcre_uchar *alternative;
863  /* Calculate the sum of the local variables. */  /* Calculate the sum of the local variables. */
864  while (cc < ccend)  while (cc < ccend)
865    {    {
# Line 872  while (cc < ccend) Line 870  while (cc < ccend)
870      case OP_ASSERTBACK:      case OP_ASSERTBACK:
871      case OP_ASSERTBACK_NOT:      case OP_ASSERTBACK_NOT:
872      case OP_ONCE:      case OP_ONCE:
873        case OP_ONCE_NC:
874      case OP_BRAPOS:      case OP_BRAPOS:
875      case OP_SBRA:      case OP_SBRA:
876      case OP_SBRAPOS:      case OP_SBRAPOS:
# Line 883  while (cc < ccend) Line 882  while (cc < ccend)
882      case OP_CBRA:      case OP_CBRA:
883      case OP_SCBRA:      case OP_SCBRA:
884      localsize++;      localsize++;
885      cc += 1 + LINK_SIZE + 2;      cc += 1 + LINK_SIZE + IMM2_SIZE;
886      break;      break;
887    
888      case OP_CBRAPOS:      case OP_CBRAPOS:
889      case OP_SCBRAPOS:      case OP_SCBRAPOS:
890      localsize += 2;      localsize += 2;
891      cc += 1 + LINK_SIZE + 2;      cc += 1 + LINK_SIZE + IMM2_SIZE;
892      break;      break;
893    
894      case OP_COND:      case OP_COND:
# Line 910  SLJIT_ASSERT(cc == ccend); Line 909  SLJIT_ASSERT(cc == ccend);
909  return localsize;  return localsize;
910  }  }
911    
912  static void copy_locals(compiler_common *common, uschar *cc, uschar *ccend,  static void copy_locals(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend,
913    BOOL save, int stackptr, int stacktop)    BOOL save, int stackptr, int stacktop)
914  {  {
915  DEFINE_COMPILER;  DEFINE_COMPILER;
# Line 919  int count; Line 918  int count;
918  BOOL tmp1next = TRUE;  BOOL tmp1next = TRUE;
919  BOOL tmp1empty = TRUE;  BOOL tmp1empty = TRUE;
920  BOOL tmp2empty = TRUE;  BOOL tmp2empty = TRUE;
921  uschar *alternative;  pcre_uchar *alternative;
922  enum {  enum {
923    start,    start,
924    loop,    loop,
# Line 974  while (status != end) Line 973  while (status != end)
973        case OP_ASSERTBACK:        case OP_ASSERTBACK:
974        case OP_ASSERTBACK_NOT:        case OP_ASSERTBACK_NOT:
975        case OP_ONCE:        case OP_ONCE:
976          case OP_ONCE_NC:
977        case OP_BRAPOS:        case OP_BRAPOS:
978        case OP_SBRA:        case OP_SBRA:
979        case OP_SBRAPOS:        case OP_SBRAPOS:
980        case OP_SCOND:        case OP_SCOND:
981        count = 1;        count = 1;
982        srcw[0] = PRIV(cc);        srcw[0] = PRIV_DATA(cc);
983        SLJIT_ASSERT(srcw[0] != 0);        SLJIT_ASSERT(srcw[0] != 0);
984        cc += 1 + LINK_SIZE;        cc += 1 + LINK_SIZE;
985        break;        break;
# Line 988  while (status != end) Line 988  while (status != end)
988        case OP_SCBRA:        case OP_SCBRA:
989        count = 1;        count = 1;
990        srcw[0] = OVECTOR_PRIV(GET2(cc, 1 + LINK_SIZE));        srcw[0] = OVECTOR_PRIV(GET2(cc, 1 + LINK_SIZE));
991        cc += 1 + LINK_SIZE + 2;        cc += 1 + LINK_SIZE + IMM2_SIZE;
992        break;        break;
993    
994        case OP_CBRAPOS:        case OP_CBRAPOS:
995        case OP_SCBRAPOS:        case OP_SCBRAPOS:
996        count = 2;        count = 2;
997        srcw[1] = OVECTOR_PRIV(GET2(cc, 1 + LINK_SIZE));        srcw[1] = OVECTOR_PRIV(GET2(cc, 1 + LINK_SIZE));
998        srcw[0] = PRIV(cc);        srcw[0] = PRIV_DATA(cc);
999        SLJIT_ASSERT(srcw[0] != 0);        SLJIT_ASSERT(srcw[0] != 0);
1000        cc += 1 + LINK_SIZE + 2;        cc += 1 + LINK_SIZE + IMM2_SIZE;
1001        break;        break;
1002    
1003        case OP_COND:        case OP_COND:
# Line 1006  while (status != end) Line 1006  while (status != end)
1006        if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)        if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)
1007          {          {
1008          count = 1;          count = 1;
1009          srcw[0] = PRIV(cc);          srcw[0] = PRIV_DATA(cc);
1010          SLJIT_ASSERT(srcw[0] != 0);          SLJIT_ASSERT(srcw[0] != 0);
1011          }          }
1012        cc += 1 + LINK_SIZE;        cc += 1 + LINK_SIZE;
# Line 1170  while (list_item) Line 1170  while (list_item)
1170      case stack_alloc:      case stack_alloc:
1171      add_jump(compiler, &common->stackalloc, JUMP(SLJIT_FAST_CALL));      add_jump(compiler, &common->stackalloc, JUMP(SLJIT_FAST_CALL));
1172      break;      break;
   
     case max_index:  
     OP1(SLJIT_MOV, MAX_INDEX, 0, SLJIT_IMM, list_item->data);  
     break;  
1173      }      }
1174    JUMPTO(SLJIT_JUMP, list_item->leave);    JUMPTO(SLJIT_JUMP, list_item->leave);
1175    list_item = list_item->next;    list_item = list_item->next;
# Line 1185  static SLJIT_INLINE void decrease_call_c Line 1181  static SLJIT_INLINE void decrease_call_c
1181  {  {
1182  DEFINE_COMPILER;  DEFINE_COMPILER;
1183    
1184  OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_MEM1(SLJIT_LOCALS_REG), CALL_COUNT, SLJIT_MEM1(SLJIT_LOCALS_REG), CALL_COUNT, SLJIT_IMM, 1);  OP2(SLJIT_SUB | SLJIT_SET_E, CALL_COUNT, 0, CALL_COUNT, 0, SLJIT_IMM, 1);
1185  add_jump(compiler, &common->calllimit, JUMP(SLJIT_C_ZERO));  add_jump(compiler, &common->calllimit, JUMP(SLJIT_C_ZERO));
1186  }  }
1187    
# Line 1218  struct sljit_label *loop; Line 1214  struct sljit_label *loop;
1214  int i;  int i;
1215  /* At this point we can freely use all temporary registers. */  /* At this point we can freely use all temporary registers. */
1216  /* TMP1 returns with begin - 1. */  /* TMP1 returns with begin - 1. */
1217  OP1(SLJIT_MOV, MAX_INDEX, 0, 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);  
1218  if (length < 8)  if (length < 8)
1219    {    {
1220    for (i = 0; i < length; i++)    for (i = 0; i < length; i++)
# Line 1236  else Line 1231  else
1231    }    }
1232  }  }
1233    
1234  static SLJIT_INLINE void copy_ovector(compiler_common *common)  static SLJIT_INLINE void copy_ovector(compiler_common *common, int topbracket)
1235  {  {
1236  DEFINE_COMPILER;  DEFINE_COMPILER;
1237  struct sljit_label *loop;  struct sljit_label *loop;
1238  struct sljit_jump *earlyexit;  struct sljit_jump *earlyexit;
1239    
1240  /* At this point we can freely use all registers. */  /* At this point we can freely use all registers. */
1241    OP1(SLJIT_MOV, SLJIT_SAVED_REG3, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1));
1242    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1), STR_PTR, 0);
1243    
1244  OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG1, 0, ARGUMENTS, 0);  OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG1, 0, ARGUMENTS, 0);
1245  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));
1246  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));
1247  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));
1248  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);
1249  /* Unlikely, but possible */  /* Unlikely, but possible */
1250  earlyexit = CMP(SLJIT_C_EQUAL, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, 0);  earlyexit = CMP(SLJIT_C_EQUAL, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, 0);
1251  loop = LABEL();  loop = LABEL();
1252  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);
1253  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));
1254  /* Copy the integer value to the output buffer */  /* Copy the integer value to the output buffer */
1255  OP1(SLJIT_MOVU_SI, SLJIT_MEM1(SLJIT_TEMPORARY_REG3), sizeof(int), SLJIT_GENERAL_REG2, 0);  #ifdef COMPILE_PCRE16
1256    OP2(SLJIT_ASHR, SLJIT_SAVED_REG2, 0, SLJIT_SAVED_REG2, 0, SLJIT_IMM, 1);
1257    #endif
1258    OP1(SLJIT_MOVU_SI, SLJIT_MEM1(SLJIT_TEMPORARY_REG3), sizeof(int), SLJIT_SAVED_REG2, 0);
1259  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);
1260  JUMPTO(SLJIT_C_NOT_ZERO, loop);  JUMPTO(SLJIT_C_NOT_ZERO, loop);
1261  JUMPHERE(earlyexit);  JUMPHERE(earlyexit);
1262    
1263    /* Calculate the return value, which is the maximum ovector value. */
1264    if (topbracket > 1)
1265      {
1266      OP2(SLJIT_ADD, SLJIT_TEMPORARY_REG1, 0, SLJIT_LOCALS_REG, 0, SLJIT_IMM, OVECTOR_START + topbracket * 2 * sizeof(sljit_w));
1267      OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, topbracket + 1);
1268    
1269      /* OVECTOR(0) is never equal to SLJIT_SAVED_REG3. */
1270      loop = LABEL();
1271      OP1(SLJIT_MOVU, SLJIT_TEMPORARY_REG3, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG1), -(2 * (sljit_w)sizeof(sljit_w)));
1272      OP2(SLJIT_SUB, SLJIT_TEMPORARY_REG2, 0, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, 1);
1273      CMPTO(SLJIT_C_EQUAL, SLJIT_TEMPORARY_REG3, 0, SLJIT_SAVED_REG3, 0, loop);
1274      OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_TEMPORARY_REG2, 0);
1275      }
1276    else
1277      OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, 1);
1278    }
1279    
1280    static SLJIT_INLINE void return_with_partial_match(compiler_common *common, struct sljit_label *leave)
1281    {
1282    DEFINE_COMPILER;
1283    
1284    SLJIT_COMPILE_ASSERT(STR_END == SLJIT_SAVED_REG2, str_end_must_be_saved_reg2);
1285    
1286    OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, ARGUMENTS, 0);
1287    OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_PARTIAL);
1288    OP1(SLJIT_MOV_SI, SLJIT_TEMPORARY_REG3, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), SLJIT_OFFSETOF(jit_arguments, offsetcount));
1289    CMPTO(SLJIT_C_LESS, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, 2, leave);
1290    
1291    /* Store match begin and end. */
1292    OP1(SLJIT_MOV, SLJIT_SAVED_REG1, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), SLJIT_OFFSETOF(jit_arguments, begin));
1293    OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), SLJIT_OFFSETOF(jit_arguments, offsets));
1294    OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG3, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mode == JIT_PARTIAL_HARD_COMPILE ? START_USED_PTR : HIT_START);
1295    OP2(SLJIT_SUB, SLJIT_SAVED_REG2, 0, STR_END, 0, SLJIT_SAVED_REG1, 0);
1296    #ifdef COMPILE_PCRE16
1297    OP2(SLJIT_ASHR, SLJIT_SAVED_REG2, 0, SLJIT_SAVED_REG2, 0, SLJIT_IMM, 1);
1298    #endif
1299    OP1(SLJIT_MOV_SI, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), sizeof(int), SLJIT_SAVED_REG2, 0);
1300    
1301    OP2(SLJIT_SUB, SLJIT_TEMPORARY_REG3, 0, SLJIT_TEMPORARY_REG3, 0, SLJIT_SAVED_REG1, 0);
1302    #ifdef COMPILE_PCRE16
1303    OP2(SLJIT_ASHR, SLJIT_TEMPORARY_REG3, 0, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, 1);
1304    #endif
1305    OP1(SLJIT_MOV_SI, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), 0, SLJIT_TEMPORARY_REG3, 0);
1306    
1307    JUMPTO(SLJIT_JUMP, leave);
1308  }  }
1309    
1310  static SLJIT_INLINE BOOL char_has_othercase(compiler_common *common, uschar* cc)  static SLJIT_INLINE void check_start_used_ptr(compiler_common *common)
1311    {
1312    /* May destroy TMP1. */
1313    DEFINE_COMPILER;
1314    struct sljit_jump *jump;
1315    
1316    if (common->mode == JIT_PARTIAL_SOFT_COMPILE)
1317      {
1318      /* The value of -1 must be kept for START_USED_PTR! */
1319      OP2(SLJIT_ADD, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), START_USED_PTR, SLJIT_IMM, 1);
1320      /* Jumps if START_USED_PTR < STR_PTR, or START_USED_PTR == -1. Although overwriting
1321      is not necessary if START_USED_PTR == STR_PTR, it does not hurt as well. */
1322      jump = CMP(SLJIT_C_LESS_EQUAL, TMP1, 0, STR_PTR, 0);
1323      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), START_USED_PTR, STR_PTR, 0);
1324      JUMPHERE(jump);
1325      }
1326    else if (common->mode == JIT_PARTIAL_HARD_COMPILE)
1327      {
1328      jump = CMP(SLJIT_C_LESS_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), START_USED_PTR, STR_PTR, 0);
1329      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), START_USED_PTR, STR_PTR, 0);
1330      JUMPHERE(jump);
1331      }
1332    }
1333    
1334    static SLJIT_INLINE BOOL char_has_othercase(compiler_common *common, pcre_uchar* cc)
1335  {  {
1336  /* Detects if the character has an othercase. */  /* Detects if the character has an othercase. */
1337  unsigned int c;  unsigned int c;
1338    
1339  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
1340  if (common->utf8)  if (common->utf)
1341    {    {
1342    GETCHAR(c, cc);    GETCHAR(c, cc);
1343    if (c > 127)    if (c > 127)
# Line 1277  if (common->utf8) Line 1348  if (common->utf8)
1348      return FALSE;      return FALSE;
1349  #endif  #endif
1350      }      }
1351    #ifndef COMPILE_PCRE8
1352      return common->fcc[c] != c;
1353    #endif
1354    }    }
1355  else  else
1356  #endif  #endif
1357    c = *cc;    c = *cc;
1358  return common->fcc[c] != c;  return MAX_255(c) ? common->fcc[c] != c : FALSE;
1359  }  }
1360    
1361  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)
1362  {  {
1363  /* Returns with the othercase. */  /* Returns with the othercase. */
1364  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
1365  if (common->utf8 && c > 127)  if (common->utf && c > 127)
1366    {    {
1367  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
1368    return UCD_OTHERCASE(c);    return UCD_OTHERCASE(c);
# Line 1297  if (common->utf8 && c > 127) Line 1371  if (common->utf8 && c > 127)
1371  #endif  #endif
1372    }    }
1373  #endif  #endif
1374  return common->fcc[c];  return TABLE_GET(c, common->fcc, c);
1375  }  }
1376    
1377  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)
1378  {  {
1379  /* Detects if the character and its othercase has only 1 bit difference. */  /* Detects if the character and its othercase has only 1 bit difference. */
1380  unsigned int c, oc, bit;  unsigned int c, oc, bit;
1381  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF && defined COMPILE_PCRE8
1382  int n;  int n;
1383  #endif  #endif
1384    
1385  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
1386  if (common->utf8)  if (common->utf)
1387    {    {
1388    GETCHAR(c, cc);    GETCHAR(c, cc);
1389    if (c <= 127)    if (c <= 127)
# Line 1326  if (common->utf8) Line 1400  if (common->utf8)
1400  else  else
1401    {    {
1402    c = *cc;    c = *cc;
1403    oc = common->fcc[c];    oc = TABLE_GET(c, common->fcc, c);
1404    }    }
1405  #else  #else
1406  c = *cc;  c = *cc;
1407  oc = common->fcc[c];  oc = TABLE_GET(c, common->fcc, c);
1408  #endif  #endif
1409    
1410  SLJIT_ASSERT(c != oc);  SLJIT_ASSERT(c != oc);
# Line 1344  if (c <= 127 && bit == 0x20) Line 1418  if (c <= 127 && bit == 0x20)
1418  if (!ispowerof2(bit))  if (!ispowerof2(bit))
1419    return 0;    return 0;
1420    
1421  #ifdef SUPPORT_UTF8  #ifdef COMPILE_PCRE8
1422  if (common->utf8 && c > 127)  
1423    #ifdef SUPPORT_UTF
1424    if (common->utf && c > 127)
1425    {    {
1426    n = _pcre_utf8_table4[*cc & 0x3f];    n = GET_EXTRALEN(*cc);
1427    while ((bit & 0x3f) == 0)    while ((bit & 0x3f) == 0)
1428      {      {
1429      n--;      n--;
# Line 1355  if (common->utf8 && c > 127) Line 1431  if (common->utf8 && c > 127)
1431      }      }
1432    return (n << 8) | bit;    return (n << 8) | bit;
1433    }    }
1434  #endif  #endif /* SUPPORT_UTF */
1435  return (0 << 8) | bit;  return (0 << 8) | bit;
1436    
1437    #else /* COMPILE_PCRE8 */
1438    
1439    #ifdef COMPILE_PCRE16
1440    #ifdef SUPPORT_UTF
1441    if (common->utf && c > 65535)
1442      {
1443      if (bit >= (1 << 10))
1444        bit >>= 10;
1445      else
1446        return (bit < 256) ? ((2 << 8) | bit) : ((3 << 8) | (bit >> 8));
1447      }
1448    #endif /* SUPPORT_UTF */
1449    return (bit < 256) ? ((0 << 8) | bit) : ((1 << 8) | (bit >> 8));
1450    #endif /* COMPILE_PCRE16 */
1451    
1452    #endif /* COMPILE_PCRE8 */
1453    }
1454    
1455    static void check_partial(compiler_common *common)
1456    {
1457    DEFINE_COMPILER;
1458    struct sljit_jump *jump;
1459    
1460    if (common->mode == JIT_COMPILE)
1461      return;
1462    
1463    jump = CMP(SLJIT_C_GREATER_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), START_USED_PTR, STR_PTR, 0);
1464    if (common->mode == JIT_PARTIAL_SOFT_COMPILE)
1465      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), HIT_START, SLJIT_IMM, -1);
1466    else
1467      {
1468      if (common->partialmatchlabel != NULL)
1469        JUMPTO(SLJIT_JUMP, common->partialmatchlabel);
1470      else
1471        add_jump(compiler, &common->partialmatch, JUMP(SLJIT_JUMP));
1472      }
1473    JUMPHERE(jump);
1474    }
1475    
1476    static struct sljit_jump *check_str_end(compiler_common *common)
1477    {
1478    /* Does not affect registers. Usually used in a tight spot. */
1479    DEFINE_COMPILER;
1480    struct sljit_jump *jump;
1481    struct sljit_jump *nohit;
1482    struct sljit_jump *return_value;
1483    
1484    if (common->mode == JIT_COMPILE)
1485      return CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
1486    
1487    jump = CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0);
1488    if (common->mode == JIT_PARTIAL_SOFT_COMPILE)
1489      {
1490      nohit = CMP(SLJIT_C_GREATER_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), START_USED_PTR, STR_PTR, 0);
1491      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), HIT_START, SLJIT_IMM, -1);
1492      JUMPHERE(nohit);
1493      return_value = JUMP(SLJIT_JUMP);
1494      }
1495    else
1496      {
1497      return_value = CMP(SLJIT_C_GREATER_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), START_USED_PTR, STR_PTR, 0);
1498      if (common->partialmatchlabel != NULL)
1499        JUMPTO(SLJIT_JUMP, common->partialmatchlabel);
1500      else
1501        add_jump(compiler, &common->partialmatch, JUMP(SLJIT_JUMP));
1502      }
1503    JUMPHERE(jump);
1504    return return_value;
1505  }  }
1506    
1507  static SLJIT_INLINE void check_input_end(compiler_common *common, jump_list **fallbacks)  static void fallback_at_str_end(compiler_common *common, jump_list **fallbacks)
1508  {  {
1509  DEFINE_COMPILER;  DEFINE_COMPILER;
1510  add_jump(compiler, fallbacks, CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0));  struct sljit_jump *jump;
1511    
1512    if (common->mode == JIT_COMPILE)
1513      {
1514      add_jump(compiler, fallbacks, CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0));
1515      return;
1516      }
1517    
1518    /* Partial matching mode. */
1519    jump = CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0);
1520    add_jump(compiler, fallbacks, CMP(SLJIT_C_GREATER_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), START_USED_PTR, STR_PTR, 0));
1521    if (common->mode == JIT_PARTIAL_SOFT_COMPILE)
1522      {
1523      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), HIT_START, SLJIT_IMM, -1);
1524      add_jump(compiler, fallbacks, JUMP(SLJIT_JUMP));
1525      }
1526    else
1527      {
1528      if (common->partialmatchlabel != NULL)
1529        JUMPTO(SLJIT_JUMP, common->partialmatchlabel);
1530      else
1531        add_jump(compiler, &common->partialmatch, JUMP(SLJIT_JUMP));
1532      }
1533    JUMPHERE(jump);
1534  }  }
1535    
1536  static void read_char(compiler_common *common)  static void read_char(compiler_common *common)
# Line 1370  static void read_char(compiler_common *c Line 1538  static void read_char(compiler_common *c
1538  /* Reads the character into TMP1, updates STR_PTR.  /* Reads the character into TMP1, updates STR_PTR.
1539  Does not check STR_END. TMP2 Destroyed. */  Does not check STR_END. TMP2 Destroyed. */
1540  DEFINE_COMPILER;  DEFINE_COMPILER;
1541  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
1542  struct sljit_jump *jump;  struct sljit_jump *jump;
1543  #endif  #endif
1544    
1545  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
1546  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
1547  if (common->utf8)  if (common->utf)
1548    {    {
1549    /* Should not found a value between 128 and 192 here. */  #ifdef COMPILE_PCRE8
1550    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 192);    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);
1551    add_jump(compiler, &common->utf8readchar, JUMP(SLJIT_FAST_CALL));  #else
1552    #ifdef COMPILE_PCRE16
1553      jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800);
1554    #endif
1555    #endif /* COMPILE_PCRE8 */
1556      add_jump(compiler, &common->utfreadchar, JUMP(SLJIT_FAST_CALL));
1557    JUMPHERE(jump);    JUMPHERE(jump);
1558    }    }
1559  #endif  #endif
1560  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));
1561  }  }
1562    
1563  static void peek_char(compiler_common *common)  static void peek_char(compiler_common *common)
# Line 1392  static void peek_char(compiler_common *c Line 1565  static void peek_char(compiler_common *c
1565  /* Reads the character into TMP1, keeps STR_PTR.  /* Reads the character into TMP1, keeps STR_PTR.
1566  Does not check STR_END. TMP2 Destroyed. */  Does not check STR_END. TMP2 Destroyed. */
1567  DEFINE_COMPILER;  DEFINE_COMPILER;
1568  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
1569  struct sljit_jump *jump;  struct sljit_jump *jump;
1570  #endif  #endif
1571    
1572  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
1573  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
1574  if (common->utf8)  if (common->utf)
1575    {    {
1576    /* Should not found a value between 128 and 192 here. */  #ifdef COMPILE_PCRE8
1577    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 192);    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);
1578    add_jump(compiler, &common->utf8readchar, JUMP(SLJIT_FAST_CALL));  #else
1579    #ifdef COMPILE_PCRE16
1580      jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800);
1581    #endif
1582    #endif /* COMPILE_PCRE8 */
1583      add_jump(compiler, &common->utfreadchar, JUMP(SLJIT_FAST_CALL));
1584    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
1585    JUMPHERE(jump);    JUMPHERE(jump);
1586    }    }
# Line 1413  static void read_char8_type(compiler_com Line 1591  static void read_char8_type(compiler_com
1591  {  {
1592  /* 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. */
1593  DEFINE_COMPILER;  DEFINE_COMPILER;
1594  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF || defined COMPILE_PCRE16
1595  struct sljit_jump *jump;  struct sljit_jump *jump;
1596  #endif  #endif
1597    
1598  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
1599  if (common->utf8)  if (common->utf)
1600    {    {
1601    OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), 0);    OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), 0);
1602    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));
1603    #ifdef COMPILE_PCRE8
1604    /* This can be an extra read in some situations, but hopefully    /* This can be an extra read in some situations, but hopefully
1605    it is a clever early read in most cases. */    it is needed in most cases. */
1606    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);
1607    /* Should not found a value between 128 and 192 here. */    jump = CMP(SLJIT_C_LESS, TMP2, 0, SLJIT_IMM, 0xc0);
1608    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));  
1609    JUMPHERE(jump);    JUMPHERE(jump);
1610    #else
1611    #ifdef COMPILE_PCRE16
1612      OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);
1613      jump = CMP(SLJIT_C_GREATER, TMP2, 0, SLJIT_IMM, 255);
1614      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);
1615      JUMPHERE(jump);
1616      /* Skip low surrogate if necessary. */
1617      OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0xfc00);
1618      OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, 0xd800);
1619      COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);
1620      OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 1);
1621      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
1622    #endif
1623    #endif /* COMPILE_PCRE8 */
1624    return;    return;
1625    }    }
1626  #endif  #endif
1627  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);  OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), 0);
1628  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 1);  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
1629  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), common->ctypes);  #ifdef COMPILE_PCRE16
1630    /* The ctypes array contains only 256 values. */
1631    OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);
1632    jump = CMP(SLJIT_C_GREATER, TMP2, 0, SLJIT_IMM, 255);
1633    #endif
1634    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);
1635    #ifdef COMPILE_PCRE16
1636    JUMPHERE(jump);
1637    #endif
1638  }  }
1639    
1640  static void skip_char_back(compiler_common *common)  static void skip_char_back(compiler_common *common)
1641  {  {
1642  /* 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. */
1643  DEFINE_COMPILER;  DEFINE_COMPILER;
1644  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF && defined COMPILE_PCRE8
1645  struct sljit_label *label;  struct sljit_label *label;
1646    
1647  if (common->utf8)  if (common->utf)
1648    {    {
1649    label = LABEL();    label = LABEL();
1650    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 1);    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), -IN_UCHARS(1));
1651    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));
1652    OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xc0);    OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xc0);
1653    CMPTO(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, 0x80, label);    CMPTO(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, 0x80, label);
1654    return;    return;
1655    }    }
1656  #endif  #endif
1657  OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 1);  #if defined SUPPORT_UTF && defined COMPILE_PCRE16
1658    if (common->utf)
1659      {
1660      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), -IN_UCHARS(1));
1661      OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
1662      /* Skip low surrogate if necessary. */
1663      OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);
1664      OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xdc00);
1665      COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);
1666      OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
1667      OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
1668      return;
1669      }
1670    #endif
1671    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
1672  }  }
1673    
1674  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 1477  else if (nltype == NLTYPE_ANYCRLF) Line 1691  else if (nltype == NLTYPE_ANYCRLF)
1691    }    }
1692  else  else
1693    {    {
1694    SLJIT_ASSERT(nltype == NLTYPE_FIXED && common->newline <= 255);    SLJIT_ASSERT(nltype == NLTYPE_FIXED && common->newline < 256);
1695    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));
1696    }    }
1697  }  }
1698    
1699  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
1700  static void do_utf8readchar(compiler_common *common)  
1701    #ifdef COMPILE_PCRE8
1702    static void do_utfreadchar(compiler_common *common)
1703  {  {
1704  /* Fast decoding an utf8 character. TMP1 contains the first byte  /* Fast decoding a UTF-8 character. TMP1 contains the first byte
1705  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. */
1706  DEFINE_COMPILER;  DEFINE_COMPILER;
1707  struct sljit_jump *jump;  struct sljit_jump *jump;
1708    
# Line 1494  sljit_emit_fast_enter(compiler, RETURN_A Line 1710  sljit_emit_fast_enter(compiler, RETURN_A
1710  /* Searching for the first zero. */  /* Searching for the first zero. */
1711  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);
1712  jump = JUMP(SLJIT_C_NOT_ZERO);  jump = JUMP(SLJIT_C_NOT_ZERO);
1713  /* 2 byte sequence */  /* Two byte sequence. */
1714  OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), 1);  OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
1715  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));
1716  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x1f);  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x1f);
1717  OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 6);  OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 6);
1718  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
1719  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
1720  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 1);  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, IN_UCHARS(1));
1721  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
1722  JUMPHERE(jump);  JUMPHERE(jump);
1723    
1724  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);
1725  jump = JUMP(SLJIT_C_NOT_ZERO);  jump = JUMP(SLJIT_C_NOT_ZERO);
1726  /* 3 byte sequence */  /* Three byte sequence. */
1727  OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), 1);  OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
1728  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x0f);  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x0f);
1729  OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 12);  OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 12);
1730  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
1731  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6);  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6);
1732  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
1733  OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), 2);  OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(2));
1734  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));
1735  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
1736  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
1737  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 2);  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, IN_UCHARS(2));
1738  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
1739  JUMPHERE(jump);  JUMPHERE(jump);
1740    
1741  OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x08);  /* Four byte sequence. */
1742  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);  
1743  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x07);  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x07);
1744  OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 18);  OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 18);
1745  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
1746  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 12);  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 12);
1747  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
1748  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);  
1749  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
1750  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6);  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6);
1751  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
1752  OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), 4);  OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(3));
1753  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));
1754  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
1755  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
1756  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 4);  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, IN_UCHARS(3));
1757  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
1758  }  }
1759    
1760  static void do_utf8readtype8(compiler_common *common)  static void do_utfreadtype8(compiler_common *common)
1761  {  {
1762  /* Fast decoding an utf8 character type. TMP2 contains the first byte  /* Fast decoding a UTF-8 character type. TMP2 contains the first byte
1763  of the character (>= 192) and TMP1 is destroyed. Return value in TMP1. */  of the character (>= 0xc0). Return value in TMP1. */
1764  DEFINE_COMPILER;  DEFINE_COMPILER;
1765  struct sljit_jump *jump;  struct sljit_jump *jump;
1766  struct sljit_jump *compare;  struct sljit_jump *compare;
# Line 1578  sljit_emit_fast_enter(compiler, RETURN_A Line 1769  sljit_emit_fast_enter(compiler, RETURN_A
1769    
1770  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);
1771  jump = JUMP(SLJIT_C_NOT_ZERO);  jump = JUMP(SLJIT_C_NOT_ZERO);
1772  /* 2 byte sequence */  /* Two byte sequence. */
1773  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
1774  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));
1775  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x1f);  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x1f);
1776  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6);  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6);
1777  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x3f);  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x3f);
# Line 1595  sljit_emit_fast_return(compiler, RETURN_ Line 1786  sljit_emit_fast_return(compiler, RETURN_
1786  JUMPHERE(jump);  JUMPHERE(jump);
1787    
1788  /* We only have types for characters less than 256. */  /* We only have types for characters less than 256. */
1789  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);  
1790  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
1791  OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);  OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);
1792  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
1793  }  }
1794    
1795  #endif  #else /* COMPILE_PCRE8 */
1796    
1797    #ifdef COMPILE_PCRE16
1798    static void do_utfreadchar(compiler_common *common)
1799    {
1800    /* Fast decoding a UTF-16 character. TMP1 contains the first 16 bit char
1801    of the character (>= 0xd800). Return char value in TMP1, length - 1 in TMP2. */
1802    DEFINE_COMPILER;
1803    struct sljit_jump *jump;
1804    
1805    sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize);
1806    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xdc00);
1807    /* Do nothing, only return. */
1808    sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
1809    
1810    JUMPHERE(jump);
1811    /* Combine two 16 bit characters. */
1812    OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
1813    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
1814    OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x3ff);
1815    OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 10);
1816    OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3ff);
1817    OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
1818    OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, IN_UCHARS(1));
1819    OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x10000);
1820    sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
1821    }
1822    #endif /* COMPILE_PCRE16 */
1823    
1824    #endif /* COMPILE_PCRE8 */
1825    
1826    #endif /* SUPPORT_UTF */
1827    
1828  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
1829    
# Line 1620  SLJIT_ASSERT(UCD_BLOCK_SIZE == 128 && si Line 1841  SLJIT_ASSERT(UCD_BLOCK_SIZE == 128 && si
1841    
1842  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);
1843  OP2(SLJIT_LSHR, TMP2, 0, TMP1, 0, SLJIT_IMM, UCD_BLOCK_SHIFT);  OP2(SLJIT_LSHR, TMP2, 0, TMP1, 0, SLJIT_IMM, UCD_BLOCK_SHIFT);
1844  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));
1845  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, UCD_BLOCK_MASK);  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, UCD_BLOCK_MASK);
1846  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, UCD_BLOCK_SHIFT);  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, UCD_BLOCK_SHIFT);
1847  OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, TMP2, 0);  OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, TMP2, 0);
1848  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, (sljit_w)_pcre_ucd_stage2);  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, (sljit_w)PRIV(ucd_stage2));
1849  OP1(SLJIT_MOV_UH, TMP2, 0, SLJIT_MEM2(TMP2, TMP1), 1);  OP1(SLJIT_MOV_UH, TMP2, 0, SLJIT_MEM2(TMP2, TMP1), 1);
1850  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));
1851  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM2(TMP1, TMP2), 3);  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM2(TMP1, TMP2), 3);
1852  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
1853  }  }
# Line 1640  struct sljit_label *newlinelabel = NULL; Line 1861  struct sljit_label *newlinelabel = NULL;
1861  struct sljit_jump *start;  struct sljit_jump *start;
1862  struct sljit_jump *end = NULL;  struct sljit_jump *end = NULL;
1863  struct sljit_jump *nl = NULL;  struct sljit_jump *nl = NULL;
1864    #ifdef SUPPORT_UTF
1865    struct sljit_jump *singlechar;
1866    #endif
1867  jump_list *newline = NULL;  jump_list *newline = NULL;
1868  BOOL newlinecheck = FALSE;  BOOL newlinecheck = FALSE;
1869  BOOL readbyte = FALSE;  BOOL readuchar = FALSE;
1870    
1871  if (!(hascrorlf || firstline) && (common->nltype == NLTYPE_ANY ||  if (!(hascrorlf || firstline) && (common->nltype == NLTYPE_ANY ||
1872      common->nltype == NLTYPE_ANYCRLF || common->newline > 255))      common->nltype == NLTYPE_ANYCRLF || common->newline > 255))
# Line 1657  if (firstline) Line 1881  if (firstline)
1881    if (common->nltype == NLTYPE_FIXED && common->newline > 255)    if (common->nltype == NLTYPE_FIXED && common->newline > 255)
1882      {      {
1883      mainloop = LABEL();      mainloop = LABEL();
1884      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));
1885      end = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);      end = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
1886      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), -1);      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-1));
1887      OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), 0);      OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
1888      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);
1889      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);
1890      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));
1891      }      }
1892    else    else
1893      {      {
# Line 1687  start = JUMP(SLJIT_JUMP); Line 1911  start = JUMP(SLJIT_JUMP);
1911  if (newlinecheck)  if (newlinecheck)
1912    {    {
1913    newlinelabel = LABEL();    newlinelabel = LABEL();
1914    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));
1915    end = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);    end = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
1916    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
1917    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);
1918    COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);    COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);
1919    #ifdef COMPILE_PCRE16
1920      OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
1921    #endif
1922    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
1923    nl = JUMP(SLJIT_JUMP);    nl = JUMP(SLJIT_JUMP);
1924    }    }
# Line 1699  if (newlinecheck) Line 1926  if (newlinecheck)
1926  mainloop = LABEL();  mainloop = LABEL();
1927    
1928  /* 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. */
1929  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
1930  if (common->utf8) readbyte = TRUE;  if (common->utf) readuchar = TRUE;
1931  #endif  #endif
1932  if (newlinecheck) readbyte = TRUE;  if (newlinecheck) readuchar = TRUE;
1933    
1934  if (readbyte)  if (readuchar)
1935    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
1936    
1937  if (newlinecheck)  if (newlinecheck)
1938    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);
1939    
1940  #ifdef SUPPORT_UTF8  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
1941  if (common->utf8)  #if defined SUPPORT_UTF && defined COMPILE_PCRE8
1942    if (common->utf)
1943    {    {
1944    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);
1945      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)PRIV(utf8_table4) - 0xc0);
1946    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
1947      JUMPHERE(singlechar);
1948      }
1949    #endif
1950    #if defined SUPPORT_UTF && defined COMPILE_PCRE16
1951    if (common->utf)
1952      {
1953      singlechar = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800);
1954      OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);
1955      OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xd800);
1956      COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);
1957      OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
1958      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
1959      JUMPHERE(singlechar);
1960    }    }
 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);  
1961  #endif  #endif
1962  JUMPHERE(start);  JUMPHERE(start);
1963    
# Line 1732  if (newlinecheck) Line 1970  if (newlinecheck)
1970  return mainloop;  return mainloop;
1971  }  }
1972    
1973  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)
1974  {  {
1975  DEFINE_COMPILER;  DEFINE_COMPILER;
1976  struct sljit_label *start;  struct sljit_label *start;
1977  struct sljit_jump *leave;  struct sljit_jump *leave;
1978  struct sljit_jump *found;  struct sljit_jump *found;
1979  pcre_uint16 oc, bit;  pcre_uchar oc, bit;
1980    
1981  if (firstline)  if (firstline)
1982    {    {
# Line 1748  if (firstline) Line 1986  if (firstline)
1986    
1987  start = LABEL();  start = LABEL();
1988  leave = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);  leave = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
1989  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
1990    
1991  if ((firstbyte & REQ_CASELESS) == 0)  oc = first_char;
1992    found = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, firstbyte & 0xff);  if (caseless)
1993      {
1994      oc = TABLE_GET(first_char, common->fcc, first_char);
1995    #if defined SUPPORT_UCP && !(defined COMPILE_PCRE8)
1996      if (first_char > 127 && common->utf)
1997        oc = UCD_OTHERCASE(first_char);
1998    #endif
1999      }
2000    if (first_char == oc)
2001      found = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, first_char);
2002  else  else
2003    {    {
2004    firstbyte &= 0xff;    bit = first_char ^ oc;
   oc = common->fcc[firstbyte];  
   bit = firstbyte ^ oc;  
2005    if (ispowerof2(bit))    if (ispowerof2(bit))
2006      {      {
2007      OP2(SLJIT_OR, TMP2, 0, TMP1, 0, SLJIT_IMM, bit);      OP2(SLJIT_OR, TMP2, 0, TMP1, 0, SLJIT_IMM, bit);
2008      found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, firstbyte | bit);      found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, first_char | bit);
2009      }      }
2010    else    else
2011      {      {
2012      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);
2013      COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);      COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);
2014      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);
2015      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 1772  else Line 2017  else
2017      }      }
2018    }    }
2019    
2020  #ifdef SUPPORT_UTF8  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2021  if (common->utf8)  #if defined SUPPORT_UTF && defined COMPILE_PCRE8
2022    if (common->utf)
2023    {    {
2024    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);
2025      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)PRIV(utf8_table4) - 0xc0);
2026      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2027      }
2028    #endif
2029    #if defined SUPPORT_UTF && defined COMPILE_PCRE16
2030    if (common->utf)
2031      {
2032      CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800, start);
2033      OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);
2034      OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xd800);
2035      COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);
2036      OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
2037    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2038    }    }
 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);  
2039  #endif  #endif
2040  JUMPTO(SLJIT_JUMP, start);  JUMPTO(SLJIT_JUMP, start);
2041  JUMPHERE(found);  JUMPHERE(found);
# Line 1816  if (common->nltype == NLTYPE_FIXED && co Line 2070  if (common->nltype == NLTYPE_FIXED && co
2070    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));
2071    firstchar = CMP(SLJIT_C_LESS_EQUAL, STR_PTR, 0, TMP2, 0);    firstchar = CMP(SLJIT_C_LESS_EQUAL, STR_PTR, 0, TMP2, 0);
2072    
2073    OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 2);    OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(2));
2074    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);
2075    COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_GREATER_EQUAL);    COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_GREATER_EQUAL);
2076    #ifdef COMPILE_PCRE16
2077      OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 1);
2078    #endif
2079    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
2080    
2081    loop = LABEL();    loop = LABEL();
2082    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));
2083    leave = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);    leave = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
2084    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), -2);    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-2));
2085    OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), -1);    OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-1));
2086    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);
2087    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);
2088    
# Line 1856  if (common->nltype == NLTYPE_ANY || comm Line 2113  if (common->nltype == NLTYPE_ANY || comm
2113    leave = JUMP(SLJIT_JUMP);    leave = JUMP(SLJIT_JUMP);
2114    JUMPHERE(foundcr);    JUMPHERE(foundcr);
2115    notfoundnl = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);    notfoundnl = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
2116    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
2117    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);
2118    COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);    COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);
2119    #ifdef COMPILE_PCRE16
2120      OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
2121    #endif
2122    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2123    JUMPHERE(notfoundnl);    JUMPHERE(notfoundnl);
2124    JUMPHERE(leave);    JUMPHERE(leave);
# Line 1876  DEFINE_COMPILER; Line 2136  DEFINE_COMPILER;
2136  struct sljit_label *start;  struct sljit_label *start;
2137  struct sljit_jump *leave;  struct sljit_jump *leave;
2138  struct sljit_jump *found;  struct sljit_jump *found;
2139    #ifndef COMPILE_PCRE8
2140    struct sljit_jump *jump;
2141    #endif
2142    
2143  if (firstline)  if (firstline)
2144    {    {
# Line 1885  if (firstline) Line 2148  if (firstline)
2148    
2149  start = LABEL();  start = LABEL();
2150  leave = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);  leave = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
2151  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
2152  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
2153  if (common->utf8)  if (common->utf)
2154    OP1(SLJIT_MOV_UB, TMP3, 0, SLJIT_MEM1(TMP1), (sljit_w)_pcre_utf8_char_sizes);    OP1(SLJIT_MOV, TMP3, 0, TMP1, 0);
2155    #endif
2156    #ifndef COMPILE_PCRE8
2157    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 255);
2158    OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 255);
2159    JUMPHERE(jump);
2160  #endif  #endif
2161  OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);  OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);
2162  OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);  OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);
# Line 1897  OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TM Line 2165  OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TM
2165  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);
2166  found = JUMP(SLJIT_C_NOT_ZERO);  found = JUMP(SLJIT_C_NOT_ZERO);
2167    
2168  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
2169  if (common->utf8)  if (common->utf)
2170    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP3, 0);    OP1(SLJIT_MOV, TMP1, 0, TMP3, 0);
2171  else  #endif
2172    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));
2173  #else  #if defined SUPPORT_UTF && defined COMPILE_PCRE8
2174  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 1);  if (common->utf)
2175      {
2176      CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0, start);
2177      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)PRIV(utf8_table4) - 0xc0);
2178      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2179      }
2180    #endif
2181    #if defined SUPPORT_UTF && defined COMPILE_PCRE16
2182    if (common->utf)
2183      {
2184      CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800, start);
2185      OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);
2186      OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xd800);
2187      COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);
2188      OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
2189      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2190      }
2191  #endif  #endif
2192  JUMPTO(SLJIT_JUMP, start);  JUMPTO(SLJIT_JUMP, start);
2193  JUMPHERE(found);  JUMPHERE(found);
# Line 1913  if (firstline) Line 2197  if (firstline)
2197    OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0);    OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0);
2198  }  }
2199    
2200  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)
2201  {  {
2202  DEFINE_COMPILER;  DEFINE_COMPILER;
2203  struct sljit_label *loop;  struct sljit_label *loop;
# Line 1922  struct sljit_jump *alreadyfound; Line 2206  struct sljit_jump *alreadyfound;
2206  struct sljit_jump *found;  struct sljit_jump *found;
2207  struct sljit_jump *foundoc = NULL;  struct sljit_jump *foundoc = NULL;
2208  struct sljit_jump *notfound;  struct sljit_jump *notfound;
2209  pcre_uint16 oc, bit;  pcre_uchar oc, bit;
2210    
2211  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);
2212  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);
2213  toolong = CMP(SLJIT_C_LESS, TMP1, 0, STR_END, 0);  toolong = CMP(SLJIT_C_LESS, TMP1, 0, STR_END, 0);
2214  alreadyfound = CMP(SLJIT_C_LESS, STR_PTR, 0, TMP2, 0);  alreadyfound = CMP(SLJIT_C_LESS, STR_PTR, 0, TMP2, 0);
2215    
2216  if (has_firstbyte)  if (has_firstchar)
2217    OP2(SLJIT_ADD, TMP1, 0, STR_PTR, 0, SLJIT_IMM, 1);    OP2(SLJIT_ADD, TMP1, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2218  else  else
2219    OP1(SLJIT_MOV, TMP1, 0, STR_PTR, 0);    OP1(SLJIT_MOV, TMP1, 0, STR_PTR, 0);
2220    
2221  loop = LABEL();  loop = LABEL();
2222  notfound = CMP(SLJIT_C_GREATER_EQUAL, TMP1, 0, STR_END, 0);  notfound = CMP(SLJIT_C_GREATER_EQUAL, TMP1, 0, STR_END, 0);
2223    
2224  OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP1), 0);  OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(TMP1), 0);
2225  if ((reqbyte & REQ_CASELESS) == 0)  oc = req_char;
2226    found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, reqbyte & 0xff);  if (caseless)
2227      {
2228      oc = TABLE_GET(req_char, common->fcc, req_char);
2229    #if defined SUPPORT_UCP && !(defined COMPILE_PCRE8)
2230      if (req_char > 127 && common->utf)
2231        oc = UCD_OTHERCASE(req_char);
2232    #endif
2233      }
2234    if (req_char == oc)
2235      found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, req_char);
2236  else  else
2237    {    {
2238    reqbyte &= 0xff;    bit = req_char ^ oc;
   oc = common->fcc[reqbyte];  
   bit = reqbyte ^ oc;  
2239    if (ispowerof2(bit))    if (ispowerof2(bit))
2240      {      {
2241      OP2(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_IMM, bit);      OP2(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_IMM, bit);
2242      found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, reqbyte | bit);      found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, req_char | bit);
2243      }      }
2244    else    else
2245      {      {
2246      found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, reqbyte);      found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, req_char);
2247      foundoc = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, oc);      foundoc = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, oc);
2248      }      }
2249    }    }
2250  OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);  OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(1));
2251  JUMPTO(SLJIT_JUMP, loop);  JUMPTO(SLJIT_JUMP, loop);
2252    
2253  JUMPHERE(found);  JUMPHERE(found);
2254  if (foundoc)  if (foundoc)
2255    JUMPHERE(foundoc);    JUMPHERE(foundoc);
2256  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);
2257  JUMPHERE(alreadyfound);  JUMPHERE(alreadyfound);
2258  JUMPHERE(toolong);  JUMPHERE(toolong);
2259  return notfound;  return notfound;
# Line 1971  return notfound; Line 2262  return notfound;
2262  static void do_revertframes(compiler_common *common)  static void do_revertframes(compiler_common *common)
2263  {  {
2264  DEFINE_COMPILER;  DEFINE_COMPILER;
 struct sljit_jump *earlyexit;  
2265  struct sljit_jump *jump;  struct sljit_jump *jump;
2266  struct sljit_label *mainloop;  struct sljit_label *mainloop;
2267    
2268  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);
2269  OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS_HEAD);  OP1(SLJIT_MOV, TMP1, 0, STACK_TOP, 0);
2270    
2271  /* Drop frames until we reach STACK_TOP. */  /* Drop frames until we reach STACK_TOP. */
 earlyexit = CMP(SLJIT_C_LESS, TMP1, 0, STACK_TOP, 0);  
2272  mainloop = LABEL();  mainloop = LABEL();
2273  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), 0);  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), 0);
2274  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 1992  JUMPTO(SLJIT_JUMP, mainloop); Line 2281  JUMPTO(SLJIT_JUMP, mainloop);
2281  JUMPHERE(jump);  JUMPHERE(jump);
2282  jump = CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, frame_end);  jump = CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, frame_end);
2283  /* 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);  
2284  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
2285    
2286  JUMPHERE(jump);  JUMPHERE(jump);
 jump = CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, frame_setmaxindex);  
 /* Set max index. */  
 OP1(SLJIT_MOV, MAX_INDEX, 0, SLJIT_MEM1(TMP1), sizeof(sljit_w));  
 OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 2 * sizeof(sljit_w));  
 JUMPTO(SLJIT_JUMP, mainloop);  
   
 JUMPHERE(jump);  
2287  jump = CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, frame_setstrbegin);  jump = CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, frame_setstrbegin);
2288  /* Set max index. */  /* Set string begin. */
2289  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), sizeof(sljit_w));  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), sizeof(sljit_w));
2290  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));
2291  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 2022  JUMPTO(SLJIT_JUMP, mainloop); Line 2300  JUMPTO(SLJIT_JUMP, mainloop);
2300  static void check_wordboundary(compiler_common *common)  static void check_wordboundary(compiler_common *common)
2301  {  {
2302  DEFINE_COMPILER;  DEFINE_COMPILER;
2303  struct sljit_jump *beginend;  struct sljit_jump *skipread;
2304  #ifdef SUPPORT_UTF8  #if !(defined COMPILE_PCRE8) || defined SUPPORT_UTF
2305  struct sljit_jump *jump;  struct sljit_jump *jump;
2306  #endif  #endif
2307    
2308  SLJIT_ASSERT(ctype_word == 0x10);  SLJIT_COMPILE_ASSERT(ctype_word == 0x10, ctype_word_must_be_16);
2309    
2310  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);
2311  /* Get type of the previous char, and put it to LOCALS1. */  /* Get type of the previous char, and put it to LOCALS1. */
2312  OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);  OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
2313  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));
2314  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, SLJIT_IMM, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, SLJIT_IMM, 0);
2315  beginend = CMP(SLJIT_C_LESS_EQUAL, STR_PTR, 0, TMP1, 0);  skipread = CMP(SLJIT_C_LESS_EQUAL, STR_PTR, 0, TMP1, 0);
2316  skip_char_back(common);  skip_char_back(common);
2317    check_start_used_ptr(common);
2318  read_char(common);  read_char(common);
2319    
2320  /* Testing char type. */  /* Testing char type. */
2321  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
2322  if (common->useucp)  if (common->use_ucp)
2323    {    {
2324    OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 1);    OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 1);
2325    jump = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_UNDERSCORE);    jump = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_UNDERSCORE);
# Line 2057  if (common->useucp) Line 2336  if (common->useucp)
2336  else  else
2337  #endif  #endif
2338    {    {
2339  #ifdef SUPPORT_UTF8  #ifndef COMPILE_PCRE8
2340      jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);
2341    #elif defined SUPPORT_UTF
2342    /* Here LOCALS1 has already been zeroed. */    /* Here LOCALS1 has already been zeroed. */
2343    jump = NULL;    jump = NULL;
2344    if (common->utf8)    if (common->utf)
2345      jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);      jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);
2346  #endif  #endif /* COMPILE_PCRE8 */
2347    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), common->ctypes);    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), common->ctypes);
2348    OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 4 /* ctype_word */);    OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 4 /* ctype_word */);
2349    OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);    OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
2350    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, TMP1, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, TMP1, 0);
2351  #ifdef SUPPORT_UTF8  #ifndef COMPILE_PCRE8
2352      JUMPHERE(jump);
2353    #elif defined SUPPORT_UTF
2354    if (jump != NULL)    if (jump != NULL)
2355      JUMPHERE(jump);      JUMPHERE(jump);
2356  #endif  #endif /* COMPILE_PCRE8 */
2357    }    }
2358  JUMPHERE(beginend);  JUMPHERE(skipread);
2359    
2360  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0);  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0);
2361  beginend = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);  skipread = check_str_end(common);
2362  peek_char(common);  peek_char(common);
2363    
2364  /* Testing char type. This is a code duplication. */  /* Testing char type. This is a code duplication. */
2365  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
2366  if (common->useucp)  if (common->use_ucp)
2367    {    {
2368    OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 1);    OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 1);
2369    jump = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_UNDERSCORE);    jump = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_UNDERSCORE);
# Line 2096  if (common->useucp) Line 2379  if (common->useucp)
2379  else  else
2380  #endif  #endif
2381    {    {
2382  #ifdef SUPPORT_UTF8  #ifndef COMPILE_PCRE8
2383      /* TMP2 may be destroyed by peek_char. */
2384      OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0);
2385      jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);
2386    #elif defined SUPPORT_UTF
2387    OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0);    OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0);
2388    jump = NULL;    jump = NULL;
2389    if (common->utf8)    if (common->utf)
2390      jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);      jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);
2391  #endif  #endif
2392    OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP1), common->ctypes);    OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP1), common->ctypes);
2393    OP2(SLJIT_LSHR, TMP2, 0, TMP2, 0, SLJIT_IMM, 4 /* ctype_word */);    OP2(SLJIT_LSHR, TMP2, 0, TMP2, 0, SLJIT_IMM, 4 /* ctype_word */);
2394    OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 1);    OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 1);
2395  #ifdef SUPPORT_UTF8  #ifndef COMPILE_PCRE8
2396      JUMPHERE(jump);
2397    #elif defined SUPPORT_UTF
2398    if (jump != NULL)    if (jump != NULL)
2399      JUMPHERE(jump);      JUMPHERE(jump);
2400  #endif  #endif /* COMPILE_PCRE8 */
2401    }    }
2402  JUMPHERE(beginend);  JUMPHERE(skipread);
2403    
2404  OP2(SLJIT_XOR | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1);  OP2(SLJIT_XOR | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1);
2405  sljit_emit_fast_return(compiler, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);  sljit_emit_fast_return(compiler, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);
# Line 2127  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_I Line 2416  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_I
2416  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);
2417  COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS_EQUAL);  COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS_EQUAL);
2418  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);
2419  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF || defined COMPILE_PCRE16
2420  if (common->utf8)  #ifdef COMPILE_PCRE8
2421    if (common->utf)
2422    {    {
2423    #endif
2424    COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);    COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);
2425    OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x1);    OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x1);
2426    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);
2427    #ifdef COMPILE_PCRE8
2428    }    }
2429  #endif  #endif
2430    #endif /* SUPPORT_UTF || COMPILE_PCRE16 */
2431  COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);  COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);
2432  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
2433  }  }
# Line 2151  COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_E Line 2444  COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_E
2444  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);
2445  COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);  COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);
2446  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);
2447  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF || defined COMPILE_PCRE16
2448  if (common->utf8)  #ifdef COMPILE_PCRE8
2449    if (common->utf)
2450    {    {
2451    #endif
2452    COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);    COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);
2453    OP2(SLJIT_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);
2454    COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);    COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);
# Line 2167  if (common->utf8) Line 2462  if (common->utf8)
2462    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);
2463    COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);    COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);
2464    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);
2465    #ifdef COMPILE_PCRE8
2466    }    }
2467  #endif  #endif
2468    #endif /* SUPPORT_UTF || COMPILE_PCRE16 */
2469  COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);  COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);
2470    
2471  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
# Line 2185  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_I Line 2482  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_I
2482  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);
2483  COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS_EQUAL);  COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS_EQUAL);
2484  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);
2485  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF || defined COMPILE_PCRE16
2486  if (common->utf8)  #ifdef COMPILE_PCRE8
2487    if (common->utf)
2488    {    {
2489    #endif
2490    COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);    COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);
2491    OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x1);    OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x1);
2492    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);
2493    #ifdef COMPILE_PCRE8
2494    }    }
2495  #endif  #endif
2496    #endif /* SUPPORT_UTF || COMPILE_PCRE16 */
2497  COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);  COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);
2498    
2499  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
# Line 2211  sljit_emit_fast_enter(compiler, RETURN_A Line 2512  sljit_emit_fast_enter(compiler, RETURN_A
2512  OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);  OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
2513  OP1(SLJIT_MOV, TMP3, 0, CHAR1, 0);  OP1(SLJIT_MOV, TMP3, 0, CHAR1, 0);
2514  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, CHAR2, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, CHAR2, 0);
2515  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(1));
2516  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));
2517    
2518  label = LABEL();  label = LABEL();
2519  OP1(SLJIT_MOVU_UB, CHAR1, 0, SLJIT_MEM1(TMP1), 1);  OP1(MOVU_UCHAR, CHAR1, 0, SLJIT_MEM1(TMP1), IN_UCHARS(1));
2520  OP1(SLJIT_MOVU_UB, CHAR2, 0, SLJIT_MEM1(STR_PTR), 1);  OP1(MOVU_UCHAR, CHAR2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
2521  jump = CMP(SLJIT_C_NOT_EQUAL, CHAR1, 0, CHAR2, 0);  jump = CMP(SLJIT_C_NOT_EQUAL, CHAR1, 0, CHAR2, 0);
2522  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));
2523  JUMPTO(SLJIT_C_NOT_ZERO, label);  JUMPTO(SLJIT_C_NOT_ZERO, label);
2524    
2525  JUMPHERE(jump);  JUMPHERE(jump);
2526  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));
2527  OP1(SLJIT_MOV, CHAR1, 0, TMP3, 0);  OP1(SLJIT_MOV, CHAR1, 0, TMP3, 0);
2528  OP1(SLJIT_MOV, CHAR2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);  OP1(SLJIT_MOV, CHAR2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);
2529  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
# Line 2243  OP1(SLJIT_MOV, TMP3, 0, LCC_TABLE, 0); Line 2544  OP1(SLJIT_MOV, TMP3, 0, LCC_TABLE, 0);
2544  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, CHAR1, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, CHAR1, 0);
2545  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, CHAR2, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, CHAR2, 0);
2546  OP1(SLJIT_MOV, LCC_TABLE, 0, SLJIT_IMM, common->lcc);  OP1(SLJIT_MOV, LCC_TABLE, 0, SLJIT_IMM, common->lcc);
2547  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(1));
2548  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));
2549    
2550  label = LABEL();  label = LABEL();
2551  OP1(SLJIT_MOVU_UB, CHAR1, 0, SLJIT_MEM1(TMP1), 1);  OP1(MOVU_UCHAR, CHAR1, 0, SLJIT_MEM1(TMP1), IN_UCHARS(1));
2552  OP1(SLJIT_MOVU_UB, CHAR2, 0, SLJIT_MEM1(STR_PTR), 1);  OP1(MOVU_UCHAR, CHAR2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
2553    #ifndef COMPILE_PCRE8
2554    jump = CMP(SLJIT_C_GREATER, CHAR1, 0, SLJIT_IMM, 255);
2555    #endif
2556  OP1(SLJIT_MOV_UB, CHAR1, 0, SLJIT_MEM2(LCC_TABLE, CHAR1), 0);  OP1(SLJIT_MOV_UB, CHAR1, 0, SLJIT_MEM2(LCC_TABLE, CHAR1), 0);
2557    #ifndef COMPILE_PCRE8
2558    JUMPHERE(jump);
2559    jump = CMP(SLJIT_C_GREATER, CHAR2, 0, SLJIT_IMM, 255);
2560    #endif
2561  OP1(SLJIT_MOV_UB, CHAR2, 0, SLJIT_MEM2(LCC_TABLE, CHAR2), 0);  OP1(SLJIT_MOV_UB, CHAR2, 0, SLJIT_MEM2(LCC_TABLE, CHAR2), 0);
2562    #ifndef COMPILE_PCRE8
2563    JUMPHERE(jump);
2564    #endif
2565  jump = CMP(SLJIT_C_NOT_EQUAL, CHAR1, 0, CHAR2, 0);  jump = CMP(SLJIT_C_NOT_EQUAL, CHAR1, 0, CHAR2, 0);
2566  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));
2567  JUMPTO(SLJIT_C_NOT_ZERO, label);  JUMPTO(SLJIT_C_NOT_ZERO, label);
2568    
2569  JUMPHERE(jump);  JUMPHERE(jump);
2570  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));
2571  OP1(SLJIT_MOV, LCC_TABLE, 0, TMP3, 0);  OP1(SLJIT_MOV, LCC_TABLE, 0, TMP3, 0);
2572  OP1(SLJIT_MOV, CHAR1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);  OP1(SLJIT_MOV, CHAR1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);
2573  OP1(SLJIT_MOV, CHAR2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1);  OP1(SLJIT_MOV, CHAR2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1);
# Line 2267  sljit_emit_fast_return(compiler, RETURN_ Line 2578  sljit_emit_fast_return(compiler, RETURN_
2578  #undef CHAR1  #undef CHAR1
2579  #undef CHAR2  #undef CHAR2
2580    
2581  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF && defined SUPPORT_UCP
 #ifdef SUPPORT_UCP  
2582    
2583  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)
2584  {  {
2585  /* This function would be ineffective to do in JIT level. */  /* This function would be ineffective to do in JIT level. */
2586  int c1, c2;  int c1, c2;
2587  uschar *src2 = args->ptr;  const pcre_uchar *src2 = args->ptr;
2588  uschar *end2 = (uschar*)args->end;  const pcre_uchar *end2 = args->end;
2589    
2590  while (src1 < end1)  while (src1 < end1)
2591    {    {
2592    if (src2 >= end2)    if (src2 >= end2)
2593      return 0;      return (pcre_uchar*)1;
2594    GETCHARINC(c1, src1);    GETCHARINC(c1, src1);
2595    GETCHARINC(c2, src2);    GETCHARINC(c2, src2);
2596    if (c1 != c2 && c1 != UCD_OTHERCASE(c2)) return 0;    if (c1 != c2 && c1 != UCD_OTHERCASE(c2)) return NULL;
2597    }    }
2598  return src2;  return src2;
2599  }  }
2600    
2601  #endif  #endif /* SUPPORT_UTF && SUPPORT_UCP */
 #endif  
2602    
2603  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,
2604      compare_context* context, jump_list **fallbacks)      compare_context* context, jump_list **fallbacks)
2605  {  {
2606  DEFINE_COMPILER;  DEFINE_COMPILER;
2607  unsigned int othercasebit = 0;  unsigned int othercasebit = 0;
2608  uschar *othercasebyte = NULL;  pcre_uchar *othercasechar = NULL;
2609  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
2610  int utf8length;  int utflength;
2611  #endif  #endif
2612    
2613  if (caseless && char_has_othercase(common, cc))  if (caseless && char_has_othercase(common, cc))
# Line 2306  if (caseless && char_has_othercase(commo Line 2615  if (caseless && char_has_othercase(commo
2615    othercasebit = char_get_othercase_bit(common, cc);    othercasebit = char_get_othercase_bit(common, cc);
2616    SLJIT_ASSERT(othercasebit);    SLJIT_ASSERT(othercasebit);
2617    /* Extracting bit difference info. */    /* Extracting bit difference info. */
2618    othercasebyte = cc + (othercasebit >> 8);  #ifdef COMPILE_PCRE8
2619      othercasechar = cc + (othercasebit >> 8);
2620    othercasebit &= 0xff;    othercasebit &= 0xff;
2621    #else
2622    #ifdef COMPILE_PCRE16
2623      othercasechar = cc + (othercasebit >> 9);
2624      if ((othercasebit & 0x100) != 0)
2625        othercasebit = (othercasebit & 0xff) << 8;
2626      else
2627        othercasebit &= 0xff;
2628    #endif
2629    #endif
2630    }    }
2631    
2632  if (context->sourcereg == -1)  if (context->sourcereg == -1)
2633    {    {
2634    #ifdef COMPILE_PCRE8
2635  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
2636    if (context->length >= 4)    if (context->length >= 4)
2637      OP1(SLJIT_MOV_SI, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);      OP1(SLJIT_MOV_SI, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);
2638    else if (context->length >= 2)    else if (context->length >= 2)
2639      OP1(SLJIT_MOV_SH, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);      OP1(SLJIT_MOV_UH, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);
2640    else    else
2641  #endif  #endif
2642      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);
2643    #else
2644    #ifdef COMPILE_PCRE16
2645    #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
2646      if (context->length >= 4)
2647        OP1(SLJIT_MOV_SI, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);
2648      else
2649    #endif
2650        OP1(SLJIT_MOV_UH, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);
2651    #endif
2652    #endif /* COMPILE_PCRE8 */
2653    context->sourcereg = TMP2;    context->sourcereg = TMP2;
2654    }    }
2655    
2656  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
2657  utf8length = 1;  utflength = 1;
2658  if (common->utf8 && *cc >= 0xc0)  if (common->utf && HAS_EXTRALEN(*cc))
2659    utf8length += _pcre_utf8_table4[*cc & 0x3f];    utflength += GET_EXTRALEN(*cc);
2660    
2661  do  do
2662    {    {
2663  #endif  #endif
2664    
2665    context->length--;    context->length -= IN_UCHARS(1);
2666  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
2667    
2668    /* Unaligned read is supported. */    /* Unaligned read is supported. */
2669    if (othercasebit != 0 && othercasebyte == cc)    if (othercasebit != 0 && othercasechar == cc)
2670      {      {
2671      context->c.asbytes[context->byteptr] = *cc | othercasebit;      context->c.asuchars[context->ucharptr] = *cc | othercasebit;
2672      context->oc.asbytes[context->byteptr] = othercasebit;      context->oc.asuchars[context->ucharptr] = othercasebit;
2673      }      }
2674    else    else
2675      {      {
2676      context->c.asbytes[context->byteptr] = *cc;      context->c.asuchars[context->ucharptr] = *cc;
2677      context->oc.asbytes[context->byteptr] = 0;      context->oc.asuchars[context->ucharptr] = 0;
2678      }      }
2679    context->byteptr++;    context->ucharptr++;
2680    
2681    if (context->byteptr >= 4 || context->length == 0 || (context->byteptr == 2 && context->length == 1))  #ifdef COMPILE_PCRE8
2682      if (context->ucharptr >= 4 || context->length == 0 || (context->ucharptr == 2 && context->length == 1))
2683    #else
2684      if (context->ucharptr >= 2 || context->length == 0)
2685    #endif
2686      {      {
2687      if (context->length >= 4)      if (context->length >= 4)
2688        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);
2689    #ifdef COMPILE_PCRE8
2690      else if (context->length >= 2)      else if (context->length >= 2)
2691        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);
2692      else if (context->length >= 1)      else if (context->length >= 1)
2693        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);
2694    #else
2695        else if (context->length >= 2)
2696          OP1(SLJIT_MOV_UH, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);
2697    #endif
2698      context->sourcereg = context->sourcereg == TMP1 ? TMP2 : TMP1;      context->sourcereg = context->sourcereg == TMP1 ? TMP2 : TMP1;
2699    
2700      switch(context->byteptr)      switch(context->ucharptr)
2701        {        {
2702        case 4:        case 4 / sizeof(pcre_uchar):
2703        if (context->oc.asint != 0)        if (context->oc.asint != 0)
2704          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);
2705        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));
2706        break;        break;
2707    
2708        case 2:        case 2 / sizeof(pcre_uchar):
2709        if (context->oc.asshort != 0)        if (context->oc.asushort != 0)
2710          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);
2711        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));
2712        break;        break;
2713    
2714    #ifdef COMPILE_PCRE8
2715        case 1:        case 1:
2716        if (context->oc.asbyte != 0)        if (context->oc.asbyte != 0)
2717          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);
2718        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));
2719        break;        break;
2720    #endif
2721    
2722        default:        default:
2723        SLJIT_ASSERT_STOP();        SLJIT_ASSERT_STOP();
2724        break;        break;
2725        }        }
2726      context->byteptr = 0;      context->ucharptr = 0;
2727      }      }
2728    
2729  #else  #else
2730    
2731    /* Unaligned read is unsupported. */    /* Unaligned read is unsupported. */
2732    #ifdef COMPILE_PCRE8
2733    if (context->length > 0)    if (context->length > 0)
2734      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);
2735    #else
2736      if (context->length > 0)
2737        OP1(SLJIT_MOV_UH, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);
2738    #endif
2739    context->sourcereg = context->sourcereg == TMP1 ? TMP2 : TMP1;    context->sourcereg = context->sourcereg == TMP1 ? TMP2 : TMP1;
2740    
2741    if (othercasebit != 0 && othercasebyte == cc)    if (othercasebit != 0 && othercasechar == cc)
2742      {      {
2743      OP2(SLJIT_OR, context->sourcereg, 0, context->sourcereg, 0, SLJIT_IMM, othercasebit);      OP2(SLJIT_OR, context->sourcereg, 0, context->sourcereg, 0, SLJIT_IMM, othercasebit);
2744      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 2403  do Line 2749  do
2749  #endif  #endif
2750    
2751    cc++;    cc++;
2752  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
2753    utf8length--;    utflength--;
2754    }    }
2755  while (utf8length > 0);  while (utflength > 0);
2756  #endif  #endif
2757    
2758  return cc;  return cc;
2759  }  }
2760    
2761  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
2762    
2763  #define SET_TYPE_OFFSET(value) \  #define SET_TYPE_OFFSET(value) \
2764    if ((value) != typeoffset) \    if ((value) != typeoffset) \
# Line 2434  return cc; Line 2780  return cc;
2780      } \      } \
2781    charoffset = (value);    charoffset = (value);
2782    
2783  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)
2784  {  {
2785  DEFINE_COMPILER;  DEFINE_COMPILER;
2786  jump_list *found = NULL;  jump_list *found = NULL;
# Line 2442  jump_list **list = (*cc & XCL_NOT) == 0 Line 2788  jump_list **list = (*cc & XCL_NOT) == 0
2788  unsigned int c;  unsigned int c;
2789  int compares;  int compares;
2790  struct sljit_jump *jump = NULL;  struct sljit_jump *jump = NULL;
2791  uschar *ccbegin;  pcre_uchar *ccbegin;
2792  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
2793  BOOL needstype = FALSE, needsscript = FALSE, needschar = FALSE;  BOOL needstype = FALSE, needsscript = FALSE, needschar = FALSE;
2794  BOOL charsaved = FALSE;  BOOL charsaved = FALSE;
2795  int typereg = TMP1, scriptreg = TMP1, typeoffset;  int typereg = TMP1, scriptreg = TMP1;
2796    unsigned int typeoffset;
2797  #endif  #endif
2798  int charoffset, invertcmp, numberofcmps;  int invertcmp, numberofcmps;
2799    unsigned int charoffset;
2800    
2801  /* 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. */
2802  check_input_end(common, fallbacks);  fallback_at_str_end(common, fallbacks);
2803  read_char(common);  read_char(common);
2804    
2805  if ((*cc++ & XCL_MAP) != 0)  if ((*cc++ & XCL_MAP) != 0)
2806    {    {
2807    OP1(SLJIT_MOV, TMP3, 0, TMP1, 0);    OP1(SLJIT_MOV, TMP3, 0, TMP1, 0);
2808    if (common->utf8)  #ifndef COMPILE_PCRE8
2809      jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);
2810    #elif defined SUPPORT_UTF
2811      if (common->utf)
2812      jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);      jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);
2813    #endif
2814    
2815    OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);    OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);
2816    OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);    OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);
# Line 2467  if ((*cc++ & XCL_MAP) != 0) Line 2819  if ((*cc++ & XCL_MAP) != 0)
2819    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);
2820    add_jump(compiler, list, JUMP(SLJIT_C_NOT_ZERO));    add_jump(compiler, list, JUMP(SLJIT_C_NOT_ZERO));
2821    
2822    if (common->utf8)  #ifndef COMPILE_PCRE8
2823      JUMPHERE(jump);
2824    #elif defined SUPPORT_UTF
2825      if (common->utf)
2826      JUMPHERE(jump);      JUMPHERE(jump);
2827    #endif
2828    OP1(SLJIT_MOV, TMP1, 0, TMP3, 0);    OP1(SLJIT_MOV, TMP1, 0, TMP3, 0);
2829  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
2830    charsaved = TRUE;    charsaved = TRUE;
2831  #endif  #endif
2832    cc += 32;    cc += 32 / sizeof(pcre_uchar);
2833    }    }
2834    
2835  /* Scanning the necessary info. */  /* Scanning the necessary info. */
# Line 2485  while (*cc != XCL_END) Line 2841  while (*cc != XCL_END)
2841    if (*cc == XCL_SINGLE)    if (*cc == XCL_SINGLE)
2842      {      {
2843      cc += 2;      cc += 2;
2844  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
2845      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]);
2846  #endif  #endif
2847  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
2848      needschar = TRUE;      needschar = TRUE;
# Line 2495  while (*cc != XCL_END) Line 2851  while (*cc != XCL_END)
2851    else if (*cc == XCL_RANGE)    else if (*cc == XCL_RANGE)
2852      {      {
2853      cc += 2;      cc += 2;
2854  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
2855      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]);
2856  #endif  #endif
2857      cc++;      cc++;
2858  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
2859      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]);
2860  #endif  #endif
2861  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
2862      needschar = TRUE;      needschar = TRUE;
# Line 2570  if (needstype || needsscript) Line 2926  if (needstype || needsscript)
2926      {      {
2927      if (scriptreg == TMP1)      if (scriptreg == TMP1)
2928        {        {
2929        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));
2930        OP1(SLJIT_MOV_UB, scriptreg, 0, SLJIT_MEM2(scriptreg, TMP2), 3);        OP1(SLJIT_MOV_UB, scriptreg, 0, SLJIT_MEM2(scriptreg, TMP2), 3);
2931        }        }
2932      else      else
2933        {        {
2934        OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 3);        OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 3);
2935        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));
2936        OP1(SLJIT_MOV_UB, scriptreg, 0, SLJIT_MEM1(TMP2), 0);        OP1(SLJIT_MOV_UB, scriptreg, 0, SLJIT_MEM1(TMP2), 0);
2937        }        }
2938      }      }
# Line 2600  while (*cc != XCL_END) Line 2956  while (*cc != XCL_END)
2956    if (*cc == XCL_SINGLE)    if (*cc == XCL_SINGLE)
2957      {      {
2958      cc ++;      cc ++;
2959  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
2960      if (common->utf8)      if (common->utf)
2961        {        {
2962        GETCHARINC(c, cc);        GETCHARINC(c, cc);
2963        }        }
# Line 2631  while (*cc != XCL_END) Line 2987  while (*cc != XCL_END)
2987    else if (*cc == XCL_RANGE)    else if (*cc == XCL_RANGE)
2988      {      {
2989      cc ++;      cc ++;
2990  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
2991      if (common->utf8)      if (common->utf)
2992        {        {
2993        GETCHARINC(c, cc);        GETCHARINC(c, cc);
2994        }        }
# Line 2640  while (*cc != XCL_END) Line 2996  while (*cc != XCL_END)
2996  #endif  #endif
2997        c = *cc++;        c = *cc++;
2998      SET_CHAR_OFFSET(c);      SET_CHAR_OFFSET(c);
2999  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3000      if (common->utf8)      if (common->utf)
3001        {        {
3002        GETCHARINC(c, cc);        GETCHARINC(c, cc);
3003        }        }
# Line 2697  while (*cc != XCL_END) Line 3053  while (*cc != XCL_END)
3053        break;        break;
3054    
3055        case PT_GC:        case PT_GC:
3056        c = _pcre_ucp_typerange[(int)cc[1] * 2];        c = PRIV(ucp_typerange)[(int)cc[1] * 2];
3057        SET_TYPE_OFFSET(c);        SET_TYPE_OFFSET(c);
3058        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);
3059        break;        break;
3060    
3061        case PT_PC:        case PT_PC:
# Line 2761  if (found != NULL) Line 3117  if (found != NULL)
3117    
3118  #endif  #endif
3119    
3120  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)
3121  {  {
3122  DEFINE_COMPILER;  DEFINE_COMPILER;
3123  int length;  int length;
3124  unsigned int c, oc, bit;  unsigned int c, oc, bit;
3125  compare_context context;  compare_context context;
3126  struct sljit_jump *jump[4];  struct sljit_jump *jump[4];
3127  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3128  struct sljit_label *label;  struct sljit_label *label;
3129  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
3130  uschar propdata[5];  pcre_uchar propdata[5];
3131  #endif  #endif
3132  #endif  #endif
3133    
# Line 2797  switch(type) Line 3153  switch(type)
3153    
3154    case OP_NOT_DIGIT:    case OP_NOT_DIGIT:
3155    case OP_DIGIT:    case OP_DIGIT:
3156    check_input_end(common, fallbacks);    fallback_at_str_end(common, fallbacks);
3157    read_char8_type(common);    read_char8_type(common);
3158    OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ctype_digit);    OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ctype_digit);
3159    add_jump(compiler, fallbacks, JUMP(type == OP_DIGIT ? SLJIT_C_ZERO : SLJIT_C_NOT_ZERO));    add_jump(compiler, fallbacks, JUMP(type == OP_DIGIT ? SLJIT_C_ZERO : SLJIT_C_NOT_ZERO));
# Line 2805  switch(type) Line 3161  switch(type)
3161    
3162    case OP_NOT_WHITESPACE:    case OP_NOT_WHITESPACE:
3163    case OP_WHITESPACE:    case OP_WHITESPACE:
3164    check_input_end(common, fallbacks);    fallback_at_str_end(common, fallbacks);
3165    read_char8_type(common);    read_char8_type(common);
3166    OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ctype_space);    OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ctype_space);
3167    add_jump(compiler, fallbacks, JUMP(type == OP_WHITESPACE ? SLJIT_C_ZERO : SLJIT_C_NOT_ZERO));    add_jump(compiler, fallbacks, JUMP(type == OP_WHITESPACE ? SLJIT_C_ZERO : SLJIT_C_NOT_ZERO));
# Line 2813  switch(type) Line 3169  switch(type)
3169    
3170    case OP_NOT_WORDCHAR:    case OP_NOT_WORDCHAR:
3171    case OP_WORDCHAR:    case OP_WORDCHAR:
3172    check_input_end(common, fallbacks);    fallback_at_str_end(common, fallbacks);
3173    read_char8_type(common);    read_char8_type(common);
3174    OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ctype_word);    OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ctype_word);
3175    add_jump(compiler, fallbacks, JUMP(type == OP_WORDCHAR ? SLJIT_C_ZERO : SLJIT_C_NOT_ZERO));    add_jump(compiler, fallbacks, JUMP(type == OP_WORDCHAR ? SLJIT_C_ZERO : SLJIT_C_NOT_ZERO));
3176    return cc;    return cc;
3177    
3178    case OP_ANY:    case OP_ANY:
3179    check_input_end(common, fallbacks);    fallback_at_str_end(common, fallbacks);
3180    read_char(common);    read_char(common);
3181    if (common->nltype == NLTYPE_FIXED && common->newline > 255)    if (common->nltype == NLTYPE_FIXED && common->newline > 255)
3182      {      {
3183      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);
3184      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);
3185      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
3186      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));
3187      JUMPHERE(jump[1]);      JUMPHERE(jump[1]);
3188      JUMPHERE(jump[0]);      JUMPHERE(jump[0]);
# Line 2836  switch(type) Line 3192  switch(type)
3192    return cc;    return cc;
3193    
3194    case OP_ALLANY:    case OP_ALLANY:
3195    check_input_end(common, fallbacks);    fallback_at_str_end(common, fallbacks);
3196  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3197    if (common->utf8)    if (common->utf)
3198      {      {
3199      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
3200      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));
3201    #ifdef COMPILE_PCRE8
3202        jump[0] = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);
3203        OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)PRIV(utf8_table4) - 0xc0);
3204      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
3205    #else /* COMPILE_PCRE8 */
3206    #ifdef COMPILE_PCRE16
3207        jump[0] = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800);
3208        OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);
3209        OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xd800);
3210        COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);
3211        OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
3212        OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
3213    #endif /* COMPILE_PCRE16 */
3214    #endif /* COMPILE_PCRE8 */
3215        JUMPHERE(jump[0]);
3216      return cc;      return cc;
3217      }      }
3218  #endif  #endif
3219    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));
3220    return cc;    return cc;
3221    
3222  #ifdef SUPPORT_UTF8    case OP_ANYBYTE:
3223      fallback_at_str_end(common, fallbacks);
3224      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
3225      return cc;
3226    
3227    #ifdef SUPPORT_UTF
3228  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
3229    case OP_NOTPROP:    case OP_NOTPROP:
3230    case OP_PROP:    case OP_PROP:
# Line 2864  switch(type) Line 3239  switch(type)
3239  #endif  #endif
3240    
3241    case OP_ANYNL:    case OP_ANYNL:
3242    check_input_end(common, fallbacks);    fallback_at_str_end(common, fallbacks);
3243    read_char(common);    read_char(common);
3244    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);
3245    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);
3246    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
3247    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);
3248    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));
3249    jump[3] = JUMP(SLJIT_JUMP);    jump[3] = JUMP(SLJIT_JUMP);
3250    JUMPHERE(jump[0]);    JUMPHERE(jump[0]);
3251    check_newlinechar(common, common->bsr_nltype, fallbacks, FALSE);    check_newlinechar(common, common->bsr_nltype, fallbacks, FALSE);
# Line 2881  switch(type) Line 3256  switch(type)
3256    
3257    case OP_NOT_HSPACE:    case OP_NOT_HSPACE:
3258    case OP_HSPACE:    case OP_HSPACE:
3259    check_input_end(common, fallbacks);    fallback_at_str_end(common, fallbacks);
3260    read_char(common);    read_char(common);
3261    add_jump(compiler, &common->hspace, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->hspace, JUMP(SLJIT_FAST_CALL));
3262    add_jump(compiler, fallbacks, JUMP(type == OP_NOT_HSPACE ? SLJIT_C_NOT_ZERO : SLJIT_C_ZERO));    add_jump(compiler, fallbacks, JUMP(type == OP_NOT_HSPACE ? SLJIT_C_NOT_ZERO : SLJIT_C_ZERO));
# Line 2889  switch(type) Line 3264  switch(type)
3264    
3265    case OP_NOT_VSPACE:    case OP_NOT_VSPACE:
3266    case OP_VSPACE:    case OP_VSPACE:
3267    check_input_end(common, fallbacks);    fallback_at_str_end(common, fallbacks);
3268    read_char(common);    read_char(common);
3269    add_jump(compiler, &common->vspace, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->vspace, JUMP(SLJIT_FAST_CALL));
3270    add_jump(compiler, fallbacks, JUMP(type == OP_NOT_VSPACE ? SLJIT_C_NOT_ZERO : SLJIT_C_ZERO));    add_jump(compiler, fallbacks, JUMP(type == OP_NOT_VSPACE ? SLJIT_C_NOT_ZERO : SLJIT_C_ZERO));
# Line 2897  switch(type) Line 3272  switch(type)
3272    
3273  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
3274    case OP_EXTUNI:    case OP_EXTUNI:
3275    check_input_end(common, fallbacks);    fallback_at_str_end(common, fallbacks);
3276    read_char(common);    read_char(common);
3277    add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL));
3278    OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Mc);    OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Mc);
# Line 2913  switch(type) Line 3288  switch(type)
3288    
3289    OP1(SLJIT_MOV, STR_PTR, 0, TMP3, 0);    OP1(SLJIT_MOV, STR_PTR, 0, TMP3, 0);
3290    JUMPHERE(jump[0]);    JUMPHERE(jump[0]);
3291      if (common->mode == JIT_PARTIAL_HARD_COMPILE)
3292        {
3293        jump[0] = CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0);
3294        check_partial(common);
3295        JUMPHERE(jump[0]);
3296        }
3297    return cc;    return cc;
3298  #endif  #endif
3299    
# Line 2920  switch(type) Line 3301  switch(type)
3301    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);
3302    if (common->nltype == NLTYPE_FIXED && common->newline > 255)    if (common->nltype == NLTYPE_FIXED && common->newline > 255)
3303      {      {
3304      OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, 2);      OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2));
3305      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
3306      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));
3307      OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), 1);      OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
3308      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));
3309      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));
3310      }      }
3311    else if (common->nltype == NLTYPE_FIXED)    else if (common->nltype == NLTYPE_FIXED)
3312      {      {
3313      OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, 1);      OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
3314      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
3315      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));
3316      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));
3317      }      }
3318    else    else
3319      {      {
3320      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
3321      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);
3322      OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, 2);      OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2));
3323      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);
3324      jump[2] = JUMP(SLJIT_C_GREATER);      jump[2] = JUMP(SLJIT_C_GREATER);
3325      add_jump(compiler, fallbacks, JUMP(SLJIT_C_LESS));      add_jump(compiler, fallbacks, JUMP(SLJIT_C_LESS));
3326      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 1);      /* Equal. */
3327        OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
3328      jump[3] = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_NL);      jump[3] = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_NL);
3329      add_jump(compiler, fallbacks, JUMP(SLJIT_JUMP));      add_jump(compiler, fallbacks, JUMP(SLJIT_JUMP));
3330    
3331      JUMPHERE(jump[1]);      JUMPHERE(jump[1]);
3332      if (common->nltype == NLTYPE_ANYCRLF)      if (common->nltype == NLTYPE_ANYCRLF)
3333        {        {
3334        OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, 1);        OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
3335        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));
3336        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));
3337        }        }
# Line 2966  switch(type) Line 3348  switch(type)
3348      JUMPHERE(jump[3]);      JUMPHERE(jump[3]);
3349      }      }
3350    JUMPHERE(jump[0]);    JUMPHERE(jump[0]);
3351      check_partial(common);
3352    return cc;    return cc;
3353    
3354    case OP_EOD:    case OP_EOD:
3355    add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, STR_PTR, 0, STR_END, 0));    add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, STR_PTR, 0, STR_END, 0));
3356      check_partial(common);
3357    return cc;    return cc;
3358    
3359    case OP_CIRC:    case OP_CIRC:
# Line 2989  switch(type) Line 3373  switch(type)
3373    jump[0] = JUMP(SLJIT_JUMP);    jump[0] = JUMP(SLJIT_JUMP);
3374    JUMPHERE(jump[1]);    JUMPHERE(jump[1]);
3375    
3376    OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, end));    add_jump(compiler, fallbacks, CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0));
   add_jump(compiler, fallbacks, CMP(SLJIT_C_EQUAL, TMP2, 0, STR_PTR, 0));  
   
3377    if (common->nltype == NLTYPE_FIXED && common->newline > 255)    if (common->nltype == NLTYPE_FIXED && common->newline > 255)
3378      {      {
3379      OP2(SLJIT_SUB, TMP2, 0, STR_PTR, 0, SLJIT_IMM, 2);      OP2(SLJIT_SUB, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2));
3380      add_jump(compiler, fallbacks, CMP(SLJIT_C_LESS, TMP2, 0, TMP1, 0));      add_jump(compiler, fallbacks, CMP(SLJIT_C_LESS, TMP2, 0, TMP1, 0));
3381      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), -2);      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-2));
3382      OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), -1);      OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-1));
3383      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));
3384      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));
3385      }      }
# Line 3018  switch(type) Line 3400  switch(type)
3400    if (!common->endonly)    if (!common->endonly)
3401      compile_char1_hotpath(common, OP_EODN, cc, fallbacks);      compile_char1_hotpath(common, OP_EODN, cc, fallbacks);
3402    else    else
3403        {
3404      add_jump(compiler, fallbacks, CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0));      add_jump(compiler, fallbacks, CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0));
3405        check_partial(common);
3406        }
3407    return cc;    return cc;
3408    
3409    case OP_DOLLM:    case OP_DOLLM:
# Line 3026  switch(type) Line 3411  switch(type)
3411    OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0);    OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0);
3412    OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, noteol));    OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, noteol));
3413    add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0));    add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0));
3414      check_partial(common);
3415    jump[0] = JUMP(SLJIT_JUMP);    jump[0] = JUMP(SLJIT_JUMP);
3416    JUMPHERE(jump[1]);    JUMPHERE(jump[1]);
3417    
3418    if (common->nltype == NLTYPE_FIXED && common->newline > 255)    if (common->nltype == NLTYPE_FIXED && common->newline > 255)
3419      {      {
3420      OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, 2);      OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2));
3421      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));
3422      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
3423      OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), 1);      OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
3424      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));
3425      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));
3426      }      }
# Line 3049  switch(type) Line 3435  switch(type)
3435    case OP_CHAR:    case OP_CHAR:
3436    case OP_CHARI:    case OP_CHARI:
3437    length = 1;    length = 1;
3438  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3439    if (common->utf8 && *cc >= 0xc0) length += _pcre_utf8_table4[*cc & 0x3f];    if (common->utf && HAS_EXTRALEN(*cc)) length += GET_EXTRALEN(*cc);
3440  #endif  #endif
3441    if (type == OP_CHAR || !char_has_othercase(common, cc) || char_get_othercase_bit(common, cc) != 0)    if (common->mode == JIT_COMPILE && (type == OP_CHAR || !char_has_othercase(common, cc) || char_get_othercase_bit(common, cc) != 0))
3442      {      {
3443      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));
3444      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));
3445    
3446      context.length = length;      context.length = IN_UCHARS(length);
3447      context.sourcereg = -1;      context.sourcereg = -1;
3448  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
3449      context.byteptr = 0;      context.ucharptr = 0;
3450  #endif  #endif
3451      return byte_sequence_compare(common, type == OP_CHARI, cc, &context, fallbacks);      return byte_sequence_compare(common, type == OP_CHARI, cc, &context, fallbacks);
3452      }      }
3453    add_jump(compiler, fallbacks, CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0));    fallback_at_str_end(common, fallbacks);
3454    read_char(common);    read_char(common);
3455  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3456    if (common->utf8)    if (common->utf)
3457      {      {
3458      GETCHAR(c, cc);      GETCHAR(c, cc);
3459      }      }
3460    else    else
3461  #endif  #endif
3462      c = *cc;      c = *cc;
3463      if (type == OP_CHAR || !char_has_othercase(common, cc))
3464        {
3465        add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, c));
3466        return cc + length;
3467        }
3468      oc = char_othercase(common, c);
3469      bit = c ^ oc;
3470      if (ispowerof2(bit))
3471        {
3472        OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, bit);
3473        add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, c | bit));
3474        return cc + length;
3475        }
3476    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, c);    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, c);
3477    COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);    COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);
3478    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, char_othercase(common, c));    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, char_othercase(common, c));
# Line 3083  switch(type) Line 3482  switch(type)
3482    
3483    case OP_NOT:    case OP_NOT:
3484    case OP_NOTI:    case OP_NOTI:
3485      fallback_at_str_end(common, fallbacks);
3486    length = 1;    length = 1;
3487  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3488    if (common->utf8)    if (common->utf)
3489      {      {
3490      if (*cc >= 0xc0) length += _pcre_utf8_table4[*cc & 0x3f];  #ifdef COMPILE_PCRE8
3491        c = *cc;
3492      check_input_end(common, fallbacks);      if (c < 128)
     GETCHAR(c, cc);  
   
     if (c <= 127)  
3493        {        {
3494        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);  
3495        if (type == OP_NOT || !char_has_othercase(common, cc))        if (type == OP_NOT || !char_has_othercase(common, cc))
3496          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));
3497        else        else
3498          {          {
3499          /* 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. */
3500          OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x20);          OP2(SLJIT_OR, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x20);
3501          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));
3502          }          }
3503        /* Skip the variable-length character. */        /* Skip the variable-length character. */
3504        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));
3505        return cc + length;        jump[0] = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);
3506          OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)PRIV(utf8_table4) - 0xc0);
3507          OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
3508          JUMPHERE(jump[0]);
3509          return cc + 1;
3510        }        }
3511      else      else
3512    #endif /* COMPILE_PCRE8 */
3513          {
3514          GETCHARLEN(c, cc, length);
3515        read_char(common);        read_char(common);
3516          }
3517      }      }
3518    else    else
3519  #endif  #endif /* SUPPORT_UTF */
3520      {      {
3521      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);  
3522      c = *cc;      c = *cc;
3523      }      }
3524    
# Line 3137  switch(type) Line 3539  switch(type)
3539        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));
3540        }        }
3541      }      }
3542    return cc + length;    return cc + 1;
3543    
3544    case OP_CLASS:    case OP_CLASS:
3545    case OP_NCLASS:    case OP_NCLASS:
3546    check_input_end(common, fallbacks);    fallback_at_str_end(common, fallbacks);
3547    read_char(common);    read_char(common);
3548  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
3549    jump[0] = NULL;    jump[0] = NULL;
3550    if (common->utf8)  #ifdef COMPILE_PCRE8
3551      /* This check only affects 8 bit mode. In other modes, we
3552      always need to compare the value with 255. */
3553      if (common->utf)
3554    #endif /* COMPILE_PCRE8 */
3555      {      {
3556      jump[0] = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);      jump[0] = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);
3557      if (type == OP_CLASS)      if (type == OP_CLASS)
# Line 3154  switch(type) Line 3560  switch(type)
3560        jump[0] = NULL;        jump[0] = NULL;
3561        }        }
3562      }      }
3563  #endif  #endif /* SUPPORT_UTF || !COMPILE_PCRE8 */
3564    OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);    OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);
3565    OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);    OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);
3566    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)cc);    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)cc);
3567    OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0);    OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0);
3568    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);
3569    add_jump(compiler, fallbacks, JUMP(SLJIT_C_ZERO));    add_jump(compiler, fallbacks, JUMP(SLJIT_C_ZERO));
3570  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
3571    if (jump[0] != NULL)    if (jump[0] != NULL)
3572      JUMPHERE(jump[0]);      JUMPHERE(jump[0]);
3573  #endif  #endif /* SUPPORT_UTF || !COMPILE_PCRE8 */
3574    return cc + 32;    return cc + 32 / sizeof(pcre_uchar);
3575    
3576  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF || defined COMPILE_PCRE16
3577    case OP_XCLASS:    case OP_XCLASS:
3578    compile_xclass_hotpath(common, cc + LINK_SIZE, fallbacks);    compile_xclass_hotpath(common, cc + LINK_SIZE, fallbacks);
3579    return cc + GET(cc, 0) - 1;    return cc + GET(cc, 0) - 1;
# Line 3177  switch(type) Line 3583  switch(type)
3583    length = GET(cc, 0);    length = GET(cc, 0);
3584    SLJIT_ASSERT(length > 0);    SLJIT_ASSERT(length > 0);
3585    OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);    OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
3586    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin));  #ifdef SUPPORT_UTF
3587  #ifdef SUPPORT_UTF8    if (common->utf)
   if (common->utf8)  
3588      {      {
3589        OP1(SLJIT_MOV, TMP3, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin));
3590      OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, length);      OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, length);
3591      label = LABEL();      label = LABEL();
3592      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));
3593      skip_char_back(common);      skip_char_back(common);
3594      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);
3595      JUMPTO(SLJIT_C_NOT_ZERO, label);      JUMPTO(SLJIT_C_NOT_ZERO, label);
     return cc + LINK_SIZE;  
3596      }      }
3597      else
3598  #endif  #endif
3599    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, length);      {
3600    add_jump(compiler, fallbacks, CMP(SLJIT_C_LESS, STR_PTR, 0, TMP1, 0));      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin));
3601        OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(length));
3602        add_jump(compiler, fallbacks, CMP(SLJIT_C_LESS, STR_PTR, 0, TMP1, 0));
3603        }
3604      check_start_used_ptr(common);
3605    return cc + LINK_SIZE;    return cc + LINK_SIZE;
3606    }    }
3607  SLJIT_ASSERT_STOP();  SLJIT_ASSERT_STOP();
3608  return cc;  return cc;
3609  }  }
3610    
3611  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)
3612  {  {
3613  /* This function consumes at least one input character. */  /* This function consumes at least one input character. */
3614  /* 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. */
3615  DEFINE_COMPILER;  DEFINE_COMPILER;
3616  uschar *ccbegin = cc;  pcre_uchar *ccbegin = cc;
3617  compare_context context;  compare_context context;
3618  int size;  int size;
3619    
# Line 3216  do Line 3626  do
3626    if (*cc == OP_CHAR)    if (*cc == OP_CHAR)
3627      {      {
3628      size = 1;      size = 1;
3629  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3630      if (common->utf8 && cc[1] >= 0xc0)      if (common->utf && HAS_EXTRALEN(cc[1]))
3631        size += _pcre_utf8_table4[cc[1] & 0x3f];        size += GET_EXTRALEN(cc[1]);
3632  #endif  #endif
3633      }      }
3634    else if (*cc == OP_CHARI)    else if (*cc == OP_CHARI)
3635      {      {
3636      size = 1;      size = 1;
3637  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3638      if (common->utf8)      if (common->utf)
3639        {        {
3640        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)
3641          size = 0;          size = 0;
3642        else if (cc[1] >= 0xc0)        else if (HAS_EXTRALEN(cc[1]))
3643          size += _pcre_utf8_table4[cc[1] & 0x3f];          size += GET_EXTRALEN(cc[1]);
3644        }        }
3645      else      else
3646  #endif  #endif
3647      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)
3648        size = 0;        size = 0;
# Line 3241  do Line 3651  do
3651      size = 0;      size = 0;
3652    
3653    cc += 1 + size;    cc += 1 + size;
3654    context.length += size;    context.length += IN_UCHARS(size);
3655    }    }
3656  while (size > 0 && context.length <= 128);  while (size > 0 && context.length <= 128);
3657    
# Line 3254  if (context.length > 0) Line 3664  if (context.length > 0)
3664    
3665    context.sourcereg = -1;    context.sourcereg = -1;
3666  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
3667    context.byteptr = 0;    context.ucharptr = 0;
3668  #endif  #endif
3669    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);
3670    return cc;    return cc;
# Line 3264  if (context.length > 0) Line 3674  if (context.length > 0)
3674  return compile_char1_hotpath(common, *cc, cc + 1, fallbacks);  return compile_char1_hotpath(common, *cc, cc + 1, fallbacks);
3675  }  }
3676    
3677  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)
3678  {  {
3679  DEFINE_COMPILER;  DEFINE_COMPILER;
3680  int offset = GET2(cc, 1) << 1;  int offset = GET2(cc, 1) << 1;
# Line 3274  if (!common->jscript_compat) Line 3684  if (!common->jscript_compat)
3684    {    {
3685    if (fallbacks == NULL)    if (fallbacks == NULL)
3686      {      {
3687        /* OVECTOR(1) contains the "string begin - 1" constant. */
3688      OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1));      OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1));
3689      COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);      COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);
3690      OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1));      OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1));
# Line 3286  return CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT Line 3697  return CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT
3697  }  }
3698    
3699  /* Forward definitions. */  /* Forward definitions. */
3700  static void compile_hotpath(compiler_common *, uschar *, uschar *, fallback_common *);  static void compile_hotpath(compiler_common *, pcre_uchar *, pcre_uchar *, fallback_common *);
3701  static void compile_fallbackpath(compiler_common *, struct fallback_common *);  static void compile_fallbackpath(compiler_common *, struct fallback_common *);
3702    
3703  #define PUSH_FALLBACK(size, ccstart, error) \  #define PUSH_FALLBACK(size, ccstart, error) \
# Line 3315  static void compile_fallbackpath(compile Line 3726  static void compile_fallbackpath(compile
3726      } \      } \
3727    while (0)    while (0)
3728    
3729  #define FALLBACK_AS(type) ((type*)fallback)  #define FALLBACK_AS(type) ((type *)fallback)
3730    
3731  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)
3732  {  {
3733  DEFINE_COMPILER;  DEFINE_COMPILER;
3734  int offset = GET2(cc, 1) << 1;  int offset = GET2(cc, 1) << 1;
3735  struct sljit_jump *jump = NULL;  struct sljit_jump *jump = NULL;
3736    struct sljit_jump *partial;
3737    struct sljit_jump *nopartial;
3738    
3739  OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));  OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));
3740    /* OVECTOR(1) contains the "string begin - 1" constant. */
3741  if (withchecks && !common->jscript_compat)  if (withchecks && !common->jscript_compat)
3742    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)));
3743    
3744  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF && defined SUPPORT_UCP
3745  #ifdef SUPPORT_UCP  if (common->utf && *cc == OP_REFI)
 if (common->utf8 && *cc == OP_REFI)  
3746    {    {
3747    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);
3748    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 3340  if (common->utf8 && *cc == OP_REFI) Line 3753  if (common->utf8 && *cc == OP_REFI)
3753    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, STACK_TOP, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, STACK_TOP, 0);
3754    OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, ARGUMENTS, 0);    OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, ARGUMENTS, 0);
3755    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);
3756    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));
3757    OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);    OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);
3758    add_jump(compiler, fallbacks, CMP(SLJIT_C_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 0));    if (common->mode == JIT_COMPILE)
3759        add_jump(compiler, fallbacks, CMP(SLJIT_C_LESS_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 1));
3760      else
3761        {
3762        add_jump(compiler, fallbacks, CMP(SLJIT_C_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 0));
3763        nopartial = CMP(SLJIT_C_NOT_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 1);
3764        check_partial(common);
3765        add_jump(compiler, fallbacks, JUMP(SLJIT_JUMP));
3766        JUMPHERE(nopartial);
3767        }
3768    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_RETURN_REG, 0);    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_RETURN_REG, 0);
3769    }    }
3770  else  else
3771  #endif  #endif /* SUPPORT_UTF && SUPPORT_UCP */
 #endif  
3772    {    {
3773    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);
3774    if (withchecks)    if (withchecks)
3775      jump = JUMP(SLJIT_C_ZERO);      jump = JUMP(SLJIT_C_ZERO);
3776    
3777    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
3778      partial = CMP(SLJIT_C_GREATER, STR_PTR, 0, STR_END, 0);
3779      if (common->mode == JIT_COMPILE)
3780        add_jump(compiler, fallbacks, partial);
3781    
   add_jump(compiler, fallbacks, CMP(SLJIT_C_GREATER, STR_PTR, 0, STR_END, 0));  
3782    add_jump(compiler, *cc == OP_REF ? &common->casefulcmp : &common->caselesscmp, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, *cc == OP_REF ? &common->casefulcmp : &common->caselesscmp, JUMP(SLJIT_FAST_CALL));
3783    add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0));    add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0));
3784    
3785      if (common->mode != JIT_COMPILE)
3786        {
3787        nopartial = JUMP(SLJIT_JUMP);
3788        JUMPHERE(partial);
3789        /* TMP2 -= STR_END - STR_PTR */
3790        OP2(SLJIT_SUB, TMP2, 0, TMP2, 0, STR_PTR, 0);
3791        OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, STR_END, 0);
3792        partial = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, 0);
3793        OP1(SLJIT_MOV, STR_PTR, 0, STR_END, 0);
3794        add_jump(compiler, *cc == OP_REF ? &common->casefulcmp : &common->caselesscmp, JUMP(SLJIT_FAST_CALL));
3795        add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0));
3796        JUMPHERE(partial);
3797        check_partial(common);
3798        add_jump(compiler, fallbacks, JUMP(SLJIT_JUMP));
3799        JUMPHERE(nopartial);
3800        }
3801    }    }
3802    
3803  if (jump != NULL)  if (jump != NULL)
# Line 3366  if (jump != NULL) Line 3807  if (jump != NULL)
3807    else    else
3808      JUMPHERE(jump);      JUMPHERE(jump);
3809    }    }
3810  return cc + 3;  return cc + 1 + IMM2_SIZE;
3811  }  }
3812    
3813  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)
3814  {  {
3815  DEFINE_COMPILER;  DEFINE_COMPILER;
3816  fallback_common *fallback;  fallback_common *fallback;
3817  uschar type;  pcre_uchar type;
3818  struct sljit_label *label;  struct sljit_label *label;
3819  struct sljit_jump *zerolength;  struct sljit_jump *zerolength;
3820  struct sljit_jump *jump = NULL;  struct sljit_jump *jump = NULL;
3821  uschar *ccbegin = cc;  pcre_uchar *ccbegin = cc;
3822  int min = 0, max = 0;  int min = 0, max = 0;
3823  BOOL minimize;  BOOL minimize;
3824    
3825  PUSH_FALLBACK(sizeof(iterator_fallback), cc, NULL);  PUSH_FALLBACK(sizeof(iterator_fallback), cc, NULL);
3826    
3827  type = cc[3];  type = cc[1 + IMM2_SIZE];
3828  minimize = (type & 0x1) != 0;  minimize = (type & 0x1) != 0;
3829  switch(type)  switch(type)
3830    {    {
# Line 3391  switch(type) Line 3832  switch(type)
3832    case OP_CRMINSTAR:    case OP_CRMINSTAR:
3833    min = 0;    min = 0;
3834    max = 0;    max = 0;
3835    cc += 4;    cc += 1 + IMM2_SIZE + 1;
3836    break;    break;
3837    case OP_CRPLUS:    case OP_CRPLUS:
3838    case OP_CRMINPLUS:    case OP_CRMINPLUS:
3839    min = 1;    min = 1;
3840    max = 0;    max = 0;
3841    cc += 4;    cc += 1 + IMM2_SIZE + 1;
3842    break;    break;
3843    case OP_CRQUERY:    case OP_CRQUERY:
3844    case OP_CRMINQUERY:    case OP_CRMINQUERY:
3845    min = 0;    min = 0;
3846    max = 1;    max = 1;
3847    cc += 4;    cc += 1 + IMM2_SIZE + 1;
3848    break;    break;
3849    case OP_CRRANGE:    case OP_CRRANGE:
3850    case OP_CRMINRANGE:    case OP_CRMINRANGE:
3851    min = GET2(cc, 3 + 1);    min = GET2(cc, 1 + IMM2_SIZE + 1);
3852    max = GET2(cc, 3 + 3);    max = GET2(cc, 1 + IMM2_SIZE + 1 + IMM2_SIZE);
3853    cc += 8;    cc += 1 + IMM2_SIZE + 1 + 2 * IMM2_SIZE;
3854    break;    break;
3855    default:    default:
3856    SLJIT_ASSERT_STOP();    SLJIT_ASSERT_STOP();
# Line 3513  decrease_call_count(common); Line 3954  decrease_call_count(common);
3954  return cc;  return cc;
3955  }  }
3956    
3957  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)
3958  {  {
3959  DEFINE_COMPILER;  DEFINE_COMPILER;
3960  fallback_common *fallback;  fallback_common *fallback;
# Line 3559  add_jump(compiler, &fallback->topfallbac Line 4000  add_jump(compiler, &fallback->topfallbac
4000  return cc + 1 + LINK_SIZE;  return cc + 1 + LINK_SIZE;
4001  }  }
4002    
4003  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)
4004  {  {
4005  DEFINE_COMPILER;  DEFINE_COMPILER;
4006  int framesize;  int framesize;
4007  int localptr;  int localptr;
4008  fallback_common altfallback;  fallback_common altfallback;
4009  uschar *ccbegin;  pcre_uchar *ccbegin;
4010  uschar opcode;  pcre_uchar opcode;
4011  uschar bra = OP_BRA;  pcre_uchar bra = OP_BRA;
4012  jump_list *tmp = NULL;  jump_list *tmp = NULL;
4013  jump_list **target = (conditional) ? &fallback->condfailed : &fallback->common.topfallbacks;  jump_list **target = (conditional) ? &fallback->condfailed : &fallback->common.topfallbacks;
4014  jump_list **found;  jump_list **found;
# Line 3583  if (*cc == OP_BRAZERO || *cc == OP_BRAMI Line 4024  if (*cc == OP_BRAZERO || *cc == OP_BRAMI
4024    bra = *cc;    bra = *cc;
4025    cc++;    cc++;
4026    }    }
4027  localptr = PRIV(cc);  localptr = PRIV_DATA(cc);
4028  SLJIT_ASSERT(localptr != 0);  SLJIT_ASSERT(localptr != 0);
4029  framesize = get_framesize(common, cc, FALSE);  framesize = get_framesize(common, cc, FALSE);
4030  fallback->framesize = framesize;  fallback->framesize = framesize;
# Line 3642  while (1) Line 4083  while (1)
4083    if (common->accept != NULL)    if (common->accept != NULL)
4084      set_jumps(common->accept, common->acceptlabel);      set_jumps(common->accept, common->acceptlabel);
4085    
4086      /* Reset stack. */
4087    if (framesize < 0)    if (framesize < 0)
4088      OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);      OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
4089      else {
4090        if ((opcode != OP_ASSERT_NOT && opcode != OP_ASSERTBACK_NOT) || conditional)
4091          {
4092          /* We don't need to keep the STR_PTR, only the previous localptr. */
4093          OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_IMM, (framesize + 1) * sizeof(sljit_w));
4094          }
4095        else
4096          {
4097          OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
4098          add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
4099          }
4100      }
4101    
4102    if (opcode == OP_ASSERT_NOT || opcode == OP_ASSERTBACK_NOT)    if (opcode == OP_ASSERT_NOT || opcode == OP_ASSERTBACK_NOT)
4103      {      {
4104      /* 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. */
4105      if (conditional)      if (conditional)
4106        {        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));  
         }  
       }  
4107      else if (bra == OP_BRAZERO)      else if (bra == OP_BRAZERO)
4108        {        {
4109        if (framesize < 0)        if (framesize < 0)
4110          OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), 0);          OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), 0);
4111        else        else
4112          {          {
         OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);  
         add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));  
4113          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));
4114          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));
4115          OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP1, 0);          OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP1, 0);
# Line 3673  while (1) Line 4117  while (1)
4117        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));
4118        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
4119        }        }
4120      else if (bra == OP_BRAMINZERO)      else if (framesize >= 0)
4121        {        {
4122        if (framesize >= 0)        /* For OP_BRA and OP_BRAMINZERO. */
4123          {        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));  
         }  
4124        }        }
4125      }      }
4126    add_jump(compiler, found, JUMP(SLJIT_JUMP));    add_jump(compiler, found, JUMP(SLJIT_JUMP));
# Line 3707  if (opcode == OP_ASSERT || opcode == OP_ Line 4147  if (opcode == OP_ASSERT || opcode == OP_
4147    /* Assert is failed. */    /* Assert is failed. */
4148    if (conditional || bra == OP_BRAZERO)    if (conditional || bra == OP_BRAZERO)
4149      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
4150    
4151    if (framesize < 0)    if (framesize < 0)
4152      {      {
4153      /* The topmost item should be 0. */      /* The topmost item should be 0. */
# Line 3718  if (opcode == OP_ASSERT || opcode == OP_ Line 4159  if (opcode == OP_ASSERT || opcode == OP_
4159    else    else
4160      {      {
4161      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));  
4162      /* The topmost item should be 0. */      /* The topmost item should be 0. */
4163      if (bra == OP_BRAZERO)      if (bra == OP_BRAZERO)
4164        {        {
# Line 3729  if (opcode == OP_ASSERT || opcode == OP_ Line 4168  if (opcode == OP_ASSERT || opcode == OP_
4168      else      else
4169        free_stack(common, framesize + 2);        free_stack(common, framesize + 2);
4170      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);  
4171      }      }
4172    jump = JUMP(SLJIT_JUMP);    jump = JUMP(SLJIT_JUMP);
4173    if (bra != OP_BRAZERO)    if (bra != OP_BRAZERO)
# Line 3753  if (opcode == OP_ASSERT || opcode == OP_ Line 4190  if (opcode == OP_ASSERT || opcode == OP_
4190      }      }
4191    else    else
4192      {      {
4193      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)  
4194        {        {
4195        allocate_stack(common, 1);        /* We don't need to keep the STR_PTR, only the previous localptr. */
4196        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));
4197          OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), 0);
4198        }        }
4199      else if (bra == OP_BRAMINZERO)      else
4200        {        {
4201        allocate_stack(common, 1);        /* We don't need to keep the STR_PTR, only the previous localptr. */
4202        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));
4203          OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
4204          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), bra == OP_BRAZERO ? STR_PTR : SLJIT_IMM, 0);
4205        }        }
4206      }      }
4207    
# Line 3800  else Line 4238  else
4238      {      {
4239      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
4240      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));  
4241      /* The topmost item should be 0. */      /* The topmost item should be 0. */
4242      if (bra != OP_BRA)      if (bra != OP_BRA)
4243        {        {
# Line 3811  else Line 4247  else
4247      else      else
4248        free_stack(common, framesize + 2);        free_stack(common, framesize + 2);
4249      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);  
4250      }      }
4251    
4252    if (bra == OP_BRAZERO)    if (bra == OP_BRAZERO)
# Line 3836  common->accept = save_accept; Line 4270  common->accept = save_accept;
4270  return cc + 1 + LINK_SIZE;  return cc + 1 + LINK_SIZE;
4271  }  }
4272    
4273    static sljit_w SLJIT_CALL do_searchovector(sljit_w refno, sljit_w* locals, pcre_uchar *name_table)
4274    {
4275    int condition = FALSE;
4276    pcre_uchar *slotA = name_table;
4277    pcre_uchar *slotB;
4278    sljit_w name_count = locals[LOCALS0 / sizeof(sljit_w)];
4279    sljit_w name_entry_size = locals[LOCALS1 / sizeof(sljit_w)];
4280    sljit_w no_capture;
4281    int i;
4282    
4283    locals += OVECTOR_START / sizeof(sljit_w);
4284    no_capture = locals[1];
4285    
4286    for (i = 0; i < name_count; i++)
4287      {
4288      if (GET2(slotA, 0) == refno) break;
4289      slotA += name_entry_size;
4290      }
4291    
4292    if (i < name_count)
4293      {
4294      /* Found a name for the number - there can be only one; duplicate names
4295      for different numbers are allowed, but not vice versa. First scan down
4296      for duplicates. */
4297    
4298      slotB = slotA;
4299      while (slotB > name_table)
4300        {
4301        slotB -= name_entry_size;
4302        if (STRCMP_UC_UC(slotA + IMM2_SIZE, slotB + IMM2_SIZE) == 0)
4303          {
4304          condition = locals[GET2(slotB, 0) << 1] != no_capture;
4305          if (condition) break;
4306          }
4307        else break;
4308        }
4309    
4310      /* Scan up for duplicates */
4311      if (!condition)
4312        {
4313        slotB = slotA;
4314        for (i++; i < name_count; i++)
4315          {
4316          slotB += name_entry_size;
4317          if (STRCMP_UC_UC(slotA + IMM2_SIZE, slotB + IMM2_SIZE) == 0)
4318            {
4319            condition = locals[GET2(slotB, 0) << 1] != no_capture;
4320            if (condition) break;
4321            }
4322          else break;
4323          }
4324        }
4325      }
4326    return condition;
4327    }
4328    
4329    static sljit_w SLJIT_CALL do_searchgroups(sljit_w recno, sljit_w* locals, pcre_uchar *name_table)
4330    {
4331    int condition = FALSE;
4332    pcre_uchar *slotA = name_table;
4333    pcre_uchar *slotB;
4334    sljit_w name_count = locals[LOCALS0 / sizeof(sljit_w)];
4335    sljit_w name_entry_size = locals[LOCALS1 / sizeof(sljit_w)];
4336    sljit_w group_num = locals[POSSESSIVE0 / sizeof(sljit_w)];
4337    int i;
4338    
4339    for (i = 0; i < name_count; i++)
4340      {
4341      if (GET2(slotA, 0) == recno) break;
4342      slotA += name_entry_size;
4343      }
4344    
4345    if (i < name_count)
4346      {
4347      /* Found a name for the number - there can be only one; duplicate
4348      names for different numbers are allowed, but not vice versa. First
4349      scan down for duplicates. */
4350    
4351      slotB = slotA;
4352      while (slotB > name_table)
4353        {
4354        slotB -= name_entry_size;
4355        if (STRCMP_UC_UC(slotA + IMM2_SIZE, slotB + IMM2_SIZE) == 0)
4356          {
4357          condition = GET2(slotB, 0) == group_num;
4358          if (condition) break;
4359          }
4360        else break;
4361        }
4362    
4363      /* Scan up for duplicates */
4364      if (!condition)
4365        {
4366        slotB = slotA;
4367        for (i++; i < name_count; i++)
4368          {
4369          slotB += name_entry_size;
4370          if (STRCMP_UC_UC(slotA + IMM2_SIZE, slotB + IMM2_SIZE) == 0)
4371            {
4372            condition = GET2(slotB, 0) == group_num;
4373            if (condition) break;
4374            }
4375          else break;
4376          }
4377        }
4378      }
4379    return condition;
4380    }
4381    
4382  /*  /*
4383    Handling bracketed expressions is probably the most complex part.    Handling bracketed expressions is probably the most complex part.
4384    
# Line 3845  return cc + 1 + LINK_SIZE; Line 4388  return cc + 1 + LINK_SIZE;
4388      A - Push the current STR_PTR. Needed for restoring the STR_PTR      A - Push the current STR_PTR. Needed for restoring the STR_PTR
4389          before the next alternative. Not pushed if there are no alternatives.          before the next alternative. Not pushed if there are no alternatives.
4390      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.
4391      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.
4392      L - Push the previous local (pointed by localptr) to the stack      L - Push the previous local (pointed by localptr) to the stack
4393     () - opional values stored on the stack     () - opional values stored on the stack
4394    ()* - optonal, can be stored multiple times    ()* - optonal, can be stored multiple times
# Line 3883  return cc + 1 + LINK_SIZE; Line 4426  return cc + 1 + LINK_SIZE;
4426      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.
4427    
4428    The next list shows the possible content of a bracket:    The next list shows the possible content of a bracket:
4429    (|)     OP_*BRA  | OP_ALT ...         M A    (|)     OP_*BRA    | OP_ALT ...         M A
4430    (?()|)  OP_*COND | OP_ALT             M A    (?()|)  OP_*COND   | OP_ALT             M A
4431    (?>|)   OP_ONCE  | OP_ALT ...         [stack trace] M A    (?>|)   OP_ONCE    | OP_ALT ...         [stack trace] M A
4432                                          Or nothing, if trace is unnecessary    (?>|)   OP_ONCE_NC | OP_ALT ...         [stack trace] M A
4433                                              Or nothing, if trace is unnecessary
4434  */  */
4435    
4436  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)
4437  {  {
4438  DEFINE_COMPILER;  DEFINE_COMPILER;
4439  fallback_common *fallback;  fallback_common *fallback;
4440  uschar opcode;  pcre_uchar opcode;
4441  int localptr = 0;  int localptr = 0;
4442  int offset = 0;  int offset = 0;
4443  int stacksize;  int stacksize;
4444  uschar *ccbegin;  pcre_uchar *ccbegin;
4445  uschar *hotpath;  pcre_uchar *hotpath;
4446  uschar bra = OP_BRA;  pcre_uchar bra = OP_BRA;
4447  uschar ket;  pcre_uchar ket;
4448  assert_fallback *assert;  assert_fallback *assert;
4449  BOOL has_alternatives;  BOOL has_alternatives;
4450  struct sljit_jump *jump;  struct sljit_jump *jump;
# Line 3919  if (*cc == OP_BRAZERO || *cc == OP_BRAMI Line 4463  if (*cc == OP_BRAZERO || *cc == OP_BRAMI
4463    
4464  opcode = *cc;  opcode = *cc;
4465  ccbegin = cc;  ccbegin = cc;
4466    hotpath = ccbegin + 1 + LINK_SIZE;
4467    
4468  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)
4469    {    {
4470    /* Drop this bracket_fallback. */    /* Drop this bracket_fallback. */
# Line 3930  ket = *(bracketend(cc) - 1 - LINK_SIZE); Line 4476  ket = *(bracketend(cc) - 1 - LINK_SIZE);
4476  SLJIT_ASSERT(ket == OP_KET || ket == OP_KETRMAX || ket == OP_KETRMIN);  SLJIT_ASSERT(ket == OP_KET || ket == OP_KETRMAX || ket == OP_KETRMIN);
4477  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)));
4478  cc += GET(cc, 1);  cc += GET(cc, 1);
4479  has_alternatives = *cc == OP_ALT || opcode == OP_COND || opcode == OP_SCOND;  
4480    has_alternatives = *cc == OP_ALT;
4481    if (SLJIT_UNLIKELY(opcode == OP_COND) || SLJIT_UNLIKELY(opcode == OP_SCOND))
4482      {
4483      has_alternatives = (*hotpath == OP_RREF) ? FALSE : TRUE;
4484      if (*hotpath == OP_NRREF)
4485        {
4486        stacksize = GET2(hotpath, 1);
4487        if (common->currententry == NULL || stacksize == RREF_ANY)
4488          has_alternatives = FALSE;
4489        else if (common->currententry->start == 0)
4490          has_alternatives = stacksize != 0;
4491        else
4492          has_alternatives = stacksize != GET2(common->start, common->currententry->start + 1 + LINK_SIZE);
4493        }
4494      }
4495    
4496  if (SLJIT_UNLIKELY(opcode == OP_COND) && (*cc == OP_KETRMAX || *cc == OP_KETRMIN))  if (SLJIT_UNLIKELY(opcode == OP_COND) && (*cc == OP_KETRMAX || *cc == OP_KETRMIN))
4497    opcode = OP_SCOND;    opcode = OP_SCOND;
4498    if (SLJIT_UNLIKELY(opcode == OP_ONCE_NC))
4499      opcode = OP_ONCE;
4500    
4501  if (opcode == OP_CBRA || opcode == OP_SCBRA)  if (opcode == OP_CBRA || opcode == OP_SCBRA)
4502    {    {
# Line 3941  if (opcode == OP_CBRA || opcode == OP_SC Line 4505  if (opcode == OP_CBRA || opcode == OP_SC
4505    localptr = OVECTOR_PRIV(offset);    localptr = OVECTOR_PRIV(offset);
4506    offset <<= 1;    offset <<= 1;
4507    FALLBACK_AS(bracket_fallback)->localptr = localptr;    FALLBACK_AS(bracket_fallback)->localptr = localptr;
4508      hotpath += IMM2_SIZE;
4509    }    }
4510  else if (opcode == OP_ONCE || opcode == OP_SBRA || opcode == OP_SCOND)  else if (opcode == OP_ONCE || opcode == OP_SBRA || opcode == OP_SCOND)
4511    {    {
4512    /* Other brackets simply allocate the next entry. */    /* Other brackets simply allocate the next entry. */
4513    localptr = PRIV(ccbegin);    localptr = PRIV_DATA(ccbegin);
4514    SLJIT_ASSERT(localptr != 0);    SLJIT_ASSERT(localptr != 0);
4515    FALLBACK_AS(bracket_fallback)->localptr = localptr;    FALLBACK_AS(bracket_fallback)->localptr = localptr;
4516    if (opcode == OP_ONCE)    if (opcode == OP_ONCE)
# Line 4072  if (opcode == OP_ONCE) Line 4637  if (opcode == OP_ONCE)
4637  else if (opcode == OP_CBRA || opcode == OP_SCBRA)  else if (opcode == OP_CBRA || opcode == OP_SCBRA)
4638    {    {
4639    /* Saving the previous values. */    /* Saving the previous values. */
4640    allocate_stack(common, 4);    allocate_stack(common, 3);
4641    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));
4642    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));
4643    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0);
4644    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0);
4645    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
   OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(2), MAX_INDEX, 0);  
4646    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, STR_PTR, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, STR_PTR, 0);
4647    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(3), TMP1, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(2), TMP1, 0);
   /* Update MAX_INDEX if necessary. */  
   add_stub(common, max_index, (offset >> 1) + 1, CMP(SLJIT_C_LESS, MAX_INDEX, 0, SLJIT_IMM, (offset >> 1) + 1));  
4648    }    }
4649  else if (opcode == OP_SBRA || opcode == OP_SCOND)  else if (opcode == OP_SBRA || opcode == OP_SCOND)
4650    {    {
# Line 4100  else if (has_alternatives) Line 4662  else if (has_alternatives)
4662    }    }
4663    
4664  /* Generating code for the first alternative. */  /* Generating code for the first alternative. */
 hotpath = ccbegin + 1 + LINK_SIZE;  
 if (offset != 0)  
   hotpath += 2;  
4665  if (opcode == OP_COND || opcode == OP_SCOND)  if (opcode == OP_COND || opcode == OP_SCOND)
4666    {    {
4667    if (*hotpath == OP_CREF)    if (*hotpath == OP_CREF)
4668      {      {
4669        SLJIT_ASSERT(has_alternatives);
4670      add_jump(compiler, &(FALLBACK_AS(bracket_fallback)->u.condfailed),      add_jump(compiler, &(FALLBACK_AS(bracket_fallback)->u.condfailed),
4671        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)));
4672      hotpath += 3;      hotpath += 1 + IMM2_SIZE;
4673        }
4674      else if (*hotpath == OP_NCREF)
4675        {
4676        SLJIT_ASSERT(has_alternatives);
4677        stacksize = GET2(hotpath, 1);
4678        jump = CMP(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(stacksize << 1), SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1));
4679    
4680        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STACK_TOP, 0);
4681        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, SLJIT_IMM, common->name_count);
4682        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, SLJIT_IMM, common->name_entry_size);
4683        OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG1, 0, SLJIT_IMM, stacksize);
4684        OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, SLJIT_LOCALS_REG, 0);
4685        OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, common->name_table);
4686        sljit_emit_ijump(compiler, SLJIT_CALL3, SLJIT_IMM, SLJIT_FUNC_OFFSET(do_searchovector));
4687        OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1);
4688        add_jump(compiler, &(FALLBACK_AS(bracket_fallback)->u.condfailed), CMP(SLJIT_C_EQUAL, SLJIT_TEMPORARY_REG1, 0, SLJIT_IMM, 0));
4689    
4690        JUMPHERE(jump);
4691        hotpath += 1 + IMM2_SIZE;
4692        }
4693      else if (*hotpath == OP_RREF || *hotpath == OP_NRREF)
4694        {
4695        /* Never has other case. */
4696        FALLBACK_AS(bracket_fallback)->u.condfailed = NULL;
4697    
4698        stacksize = GET2(hotpath, 1);
4699        if (common->currententry == NULL)
4700          stacksize = 0;
4701        else if (stacksize == RREF_ANY)
4702          stacksize = 1;
4703        else if (common->currententry->start == 0)
4704          stacksize = stacksize == 0;
4705        else
4706          stacksize = stacksize == GET2(common->start, common->currententry->start + 1 + LINK_SIZE);
4707    
4708        if (*hotpath == OP_RREF || stacksize || common->currententry == NULL)
4709          {
4710          SLJIT_ASSERT(!has_alternatives);
4711          if (stacksize != 0)
4712            hotpath += 1 + IMM2_SIZE;
4713          else
4714            {
4715            if (*cc == OP_ALT)
4716              {
4717              hotpath = cc + 1 + LINK_SIZE;
4718              cc += GET(cc, 1);
4719              }
4720            else
4721              hotpath = cc;
4722            }
4723          }
4724        else
4725          {
4726          SLJIT_ASSERT(has_alternatives);
4727    
4728          stacksize = GET2(hotpath, 1);
4729          OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STACK_TOP, 0);
4730          OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, SLJIT_IMM, common->name_count);
4731          OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, SLJIT_IMM, common->name_entry_size);
4732          OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, GET2(common->start, common->currententry->start + 1 + LINK_SIZE));
4733          OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG1, 0, SLJIT_IMM, stacksize);
4734          OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, SLJIT_LOCALS_REG, 0);
4735          OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, common->name_table);
4736          sljit_emit_ijump(compiler, SLJIT_CALL3, SLJIT_IMM, SLJIT_FUNC_OFFSET(do_searchgroups));
4737          OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1);
4738          add_jump(compiler, &(FALLBACK_AS(bracket_fallback)->u.condfailed), CMP(SLJIT_C_EQUAL, SLJIT_TEMPORARY_REG1, 0, SLJIT_IMM, 0));
4739          hotpath += 1 + IMM2_SIZE;
4740          }
4741      }      }
4742    else    else
4743      {      {
4744      SLJIT_ASSERT(*hotpath >= OP_ASSERT && *hotpath <= OP_ASSERTBACK_NOT);      SLJIT_ASSERT(has_alternatives && *hotpath >= OP_ASSERT && *hotpath <= OP_ASSERTBACK_NOT);
4745      /* Similar code as PUSH_FALLBACK macro. */      /* Similar code as PUSH_FALLBACK macro. */
4746      assert = sljit_alloc_memory(compiler, sizeof(assert_fallback));      assert = sljit_alloc_memory(compiler, sizeof(assert_fallback));
4747      if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))      if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
# Line 4143  if (opcode == OP_ONCE) Line 4771  if (opcode == OP_ONCE)
4771        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);
4772        }        }
4773      }      }
4774    else if (ket == OP_KETRMAX)    else
4775      {      {
4776      /* TMP2 which is set here used by OP_KETRMAX below. */      stacksize = (ket == OP_KETRMIN || ket == OP_KETRMAX || has_alternatives) ? 2 : 1;
4777      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));
4778      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP2), (FALLBACK_AS(bracket_fallback)->u.framesize + 1) * sizeof(sljit_w));      if (ket == OP_KETRMAX)
4779          {
4780          /* TMP2 which is set here used by OP_KETRMAX below. */
4781          OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
4782          }
4783      }      }
4784    }    }
4785    
# Line 4212  if (bra == OP_BRAZERO) Line 4844  if (bra == OP_BRAZERO)
4844  if (bra == OP_BRAMINZERO)  if (bra == OP_BRAMINZERO)
4845    {    {
4846    /* This is a fallback path! (From the viewpoint of OP_BRAMINZERO) */    /* This is a fallback path! (From the viewpoint of OP_BRAMINZERO) */
4847    JUMPTO(SLJIT_JUMP, ((braminzero_fallback*)parent)->hotpath);    JUMPTO(SLJIT_JUMP, ((braminzero_fallback *)parent)->hotpath);
4848    if (braminzerojump != NULL)    if (braminzerojump != NULL)
4849      {      {
4850      JUMPHERE(braminzerojump);      JUMPHERE(braminzerojump);
# Line 4240  cc += 1 + LINK_SIZE; Line 4872  cc += 1 + LINK_SIZE;
4872  return cc;  return cc;
4873  }  }
4874    
4875  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)
4876  {  {
4877  DEFINE_COMPILER;  DEFINE_COMPILER;
4878  fallback_common *fallback;  fallback_common *fallback;
4879  uschar opcode;  pcre_uchar opcode;
4880  int localptr;  int localptr;
4881  int cbraprivptr = 0;  int cbraprivptr = 0;
4882  int framesize;  int framesize;
4883  int stacksize;  int stacksize;
4884  int offset = 0;  int offset = 0;
4885  BOOL zero = FALSE;  BOOL zero = FALSE;
4886  uschar *ccbegin = NULL;  pcre_uchar *ccbegin = NULL;
4887  int stack;  int stack;
4888  struct sljit_label *loop = NULL;  struct sljit_label *loop = NULL;
4889  struct jump_list *emptymatch = NULL;  struct jump_list *emptymatch = NULL;
# Line 4264  if (*cc == OP_BRAPOSZERO) Line 4896  if (*cc == OP_BRAPOSZERO)
4896    }    }
4897    
4898  opcode = *cc;  opcode = *cc;
4899  localptr = PRIV(cc);  localptr = PRIV_DATA(cc);
4900  SLJIT_ASSERT(localptr != 0);  SLJIT_ASSERT(localptr != 0);
4901  FALLBACK_AS(bracketpos_fallback)->localptr = localptr;  FALLBACK_AS(bracketpos_fallback)->localptr = localptr;
4902  switch(opcode)  switch(opcode)
# Line 4279  switch(opcode) Line 4911  switch(opcode)
4911    offset = GET2(cc, 1 + LINK_SIZE);    offset = GET2(cc, 1 + LINK_SIZE);
4912    cbraprivptr = OVECTOR_PRIV(offset);    cbraprivptr = OVECTOR_PRIV(offset);
4913    offset <<= 1;    offset <<= 1;
4914    ccbegin = cc + 1 + LINK_SIZE + 2;    ccbegin = cc + 1 + LINK_SIZE + IMM2_SIZE;
4915    break;    break;
4916    
4917    default:    default:
# Line 4291  framesize = get_framesize(common, cc, FA Line 4923  framesize = get_framesize(common, cc, FA
4923  FALLBACK_AS(bracketpos_fallback)->framesize = framesize;  FALLBACK_AS(bracketpos_fallback)->framesize = framesize;
4924  if (framesize < 0)  if (framesize < 0)
4925    {    {
4926    stacksize = (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS) ? 3 : 1;    stacksize = (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS) ? 2 : 1;
4927    if (!zero)    if (!zero)
4928      stacksize++;      stacksize++;
4929    FALLBACK_AS(bracketpos_fallback)->stacksize = stacksize;    FALLBACK_AS(bracketpos_fallback)->stacksize = stacksize;
# Line 4304  if (framesize < 0) Line 4936  if (framesize < 0)
4936      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));
4937      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0);
4938      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0);
     OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(2), MAX_INDEX, 0);  
4939      }      }
4940    else    else
4941      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 4362  while (*cc != OP_KETRPOS) Line 4993  while (*cc != OP_KETRPOS)
4993        {        {
4994        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr);        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr);
4995        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), STR_PTR, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), STR_PTR, 0);
       OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);  
       add_stub(common, max_index, (offset >> 1) + 1, CMP(SLJIT_C_LESS, MAX_INDEX, 0, SLJIT_IMM, (offset >> 1) + 1));  
4996        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr, STR_PTR, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr, STR_PTR, 0);
4997          OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);
4998        }        }
4999      else      else
5000        {        {
# Line 4383  while (*cc != OP_KETRPOS) Line 5013  while (*cc != OP_KETRPOS)
5013      {      {
5014      if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS)      if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS)
5015        {        {
5016          OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_IMM, stacksize * sizeof(sljit_w));
5017        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr);        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr);
       if (!zero)  
         OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);  
5018        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), STR_PTR, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), STR_PTR, 0);
       OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);  
       add_stub(common, max_index, (offset >> 1) + 1, CMP(SLJIT_C_LESS, MAX_INDEX, 0, SLJIT_IMM, (offset >> 1) + 1));  
5019        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr, STR_PTR, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr, STR_PTR, 0);
5020          OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);
5021        }        }
5022      else      else
5023        {        {
5024        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
5025          OP2(SLJIT_ADD, STACK_TOP, 0, TMP2, 0, SLJIT_IMM, stacksize * sizeof(sljit_w));
5026        if (opcode == OP_SBRAPOS)        if (opcode == OP_SBRAPOS)
5027          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));
5028        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 4402  while (*cc != OP_KETRPOS) Line 5031  while (*cc != OP_KETRPOS)
5031      if (opcode == OP_SBRAPOS || opcode == OP_SCBRAPOS)      if (opcode == OP_SBRAPOS || opcode == OP_SCBRAPOS)
5032        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));
5033    
     /* TMP2 must be set above. */  
5034      if (!zero)      if (!zero)
5035        {        {
5036        if (framesize < 0)        if (framesize < 0)
5037          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);
5038        else        else
5039          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);
5040        }        }
5041      }      }
5042    JUMPTO(SLJIT_JUMP, loop);    JUMPTO(SLJIT_JUMP, loop);
# Line 4430  while (*cc != OP_KETRPOS) Line 5058  while (*cc != OP_KETRPOS)
5058      {      {
5059      if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS)      if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS)
5060        {        {
5061          /* Last alternative. */
5062        if (*cc == OP_KETRPOS)        if (*cc == OP_KETRPOS)
5063          OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);          OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
5064        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 4461  decrease_call_count(common); Line 5090  decrease_call_count(common);
5090  return cc + 1 + LINK_SIZE;  return cc + 1 + LINK_SIZE;
5091  }  }
5092    
5093  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)
5094  {  {
5095  int class_len;  int class_len;
5096    
# Line 4500<