/[pcre]/code/trunk/pcre_jit_compile.c
ViewVC logotype

Diff of /code/trunk/pcre_jit_compile.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 695 by zherczeg, Sat Sep 17 06:05:38 2011 UTC revision 918 by zherczeg, Thu Feb 16 06:39:20 2012 UTC
# Line 6  Line 6 
6  and semantics are as close as possible to those of the Perl 5 language.  and semantics are as close as possible to those of the Perl 5 language.
7    
8                         Written by Philip Hazel                         Written by Philip Hazel
9             Copyright (c) 1997-2008 University of Cambridge             Copyright (c) 1997-2012 University of Cambridge
10    
11    The machine code generator part (this module) was written by Zoltan Herczeg    The machine code generator part (this module) was written by Zoltan Herczeg
12                        Copyright (c) 2010-2011                        Copyright (c) 2010-2012
13    
14  -----------------------------------------------------------------------------  -----------------------------------------------------------------------------
15  Redistribution and use in source and binary forms, with or without  Redistribution and use in source and binary forms, with or without
# Line 52  POSSIBILITY OF SUCH DAMAGE. Line 52  POSSIBILITY OF SUCH DAMAGE.
52  we just include it. This way we don't need to touch the build  we just include it. This way we don't need to touch the build
53  system files. */  system files. */
54    
55    #define SLJIT_MALLOC(size) (PUBL(malloc))(size)
56    #define SLJIT_FREE(ptr) (PUBL(free))(ptr)
57  #define SLJIT_CONFIG_AUTO 1  #define SLJIT_CONFIG_AUTO 1
58    #define SLJIT_CONFIG_STATIC 1
59  #define SLJIT_VERBOSE 0  #define SLJIT_VERBOSE 0
60  #define SLJIT_DEBUG 0  #define SLJIT_DEBUG 0
61    
62  #include "sljit/sljitLir.c"  #include "sljit/sljitLir.c"
63    
64  #if defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED  #if defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED
65  #error "Unsupported architecture"  #error Unsupported architecture
66  #endif  #endif
67    
68  /* Allocate memory on the stack. Fast, but limited size. */  /* Allocate memory on the stack. Fast, but limited size. */
# Line 145  Thus we can restore the locals to a part Line 148  Thus we can restore the locals to a part
148  typedef struct jit_arguments {  typedef struct jit_arguments {
149    /* Pointers first. */    /* Pointers first. */
150    struct sljit_stack *stack;    struct sljit_stack *stack;
151    PCRE_SPTR str;    const pcre_uchar *str;
152    PCRE_SPTR begin;    const pcre_uchar *begin;
153    PCRE_SPTR end;    const pcre_uchar *end;
154    int *offsets;    int *offsets;
155    uschar *ptr;    pcre_uchar *ptr;
156    /* Everything else after. */    /* Everything else after. */
157    int offsetcount;    int offsetcount;
158    int calllimit;    int calllimit;
159    uschar notbol;    pcre_uint8 notbol;
160    uschar noteol;    pcre_uint8 noteol;
161    uschar notempty;    pcre_uint8 notempty;
162    uschar notempty_atstart;    pcre_uint8 notempty_atstart;
163  } jit_arguments;  } jit_arguments;
164    
165  typedef struct executable_function {  typedef struct executable_functions {
166    void *executable_func;    void *executable_funcs[JIT_NUMBER_OF_COMPILE_MODES];
167    pcre_jit_callback callback;    PUBL(jit_callback) callback;
168    void *userdata;    void *userdata;
169  } executable_function;    sljit_uw executable_sizes[JIT_NUMBER_OF_COMPILE_MODES];
170    } executable_functions;
171    
172  typedef struct jump_list {  typedef struct jump_list {
173    struct sljit_jump *jump;    struct sljit_jump *jump;
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 CALL_COUNT    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 MAX_INDEX        (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 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, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), MAX_INDEX);  
       OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, frame_setmaxindex);  
       stackpos += (int)sizeof(sljit_w);  
       OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);  
       stackpos += (int)sizeof(sljit_w);  
       needs_maxindex = TRUE;  
       }  
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 846  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 856  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 873  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 884  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 911  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 920  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 975  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 989  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 1007  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 1171  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, SLJIT_MEM1(SLJIT_LOCALS_REG), MAX_INDEX, 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 1219  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, SLJIT_MEM1(SLJIT_LOCALS_REG), MAX_INDEX, SLJIT_IMM, 1);  OP2(SLJIT_SUB, SLJIT_TEMPORARY_REG1, 0, SLJIT_MEM1(SLJIT_SAVED_REG1), SLJIT_OFFSETOF(jit_arguments, begin), SLJIT_IMM, IN_UCHARS(1));
 OP2(SLJIT_SUB, SLJIT_TEMPORARY_REG1, 0, SLJIT_MEM1(SLJIT_GENERAL_REG1), SLJIT_OFFSETOF(jit_arguments, begin), SLJIT_IMM, 1);  
1218  if (length < 8)  if (length < 8)
1219    {    {
1220    for (i = 0; i < length; i++)    for (i = 0; i < length; i++)
# Line 1237  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 BOOL char_has_othercase(compiler_common *common, uschar* cc)  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 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 1278  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 1298  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 1327  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 1345  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 1356  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, BOOL force)
1456    {
1457    /* Checks whether a partial matching is occured. Does not modify registers. */
1458    DEFINE_COMPILER;
1459    struct sljit_jump *jump = NULL;
1460    
1461    SLJIT_ASSERT(!force || common->mode != JIT_COMPILE);
1462    
1463    if (common->mode == JIT_COMPILE)
1464      return;
1465    
1466    if (!force || common->mode == JIT_PARTIAL_SOFT_COMPILE)
1467      jump = CMP(SLJIT_C_GREATER_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), START_USED_PTR, STR_PTR, 0);
1468    
1469    if (common->mode == JIT_PARTIAL_SOFT_COMPILE)
1470      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), HIT_START, SLJIT_IMM, -1);
1471    else
1472      {
1473      if (common->partialmatchlabel != NULL)
1474        JUMPTO(SLJIT_JUMP, common->partialmatchlabel);
1475      else
1476        add_jump(compiler, &common->partialmatch, JUMP(SLJIT_JUMP));
1477      }
1478    
1479    if (jump != NULL)
1480      JUMPHERE(jump);
1481    }
1482    
1483    static struct sljit_jump *check_str_end(compiler_common *common)
1484    {
1485    /* Does not affect registers. Usually used in a tight spot. */
1486    DEFINE_COMPILER;
1487    struct sljit_jump *jump;
1488    struct sljit_jump *nohit;
1489    struct sljit_jump *return_value;
1490    
1491    if (common->mode == JIT_COMPILE)
1492      return CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
1493    
1494    jump = CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0);
1495    if (common->mode == JIT_PARTIAL_SOFT_COMPILE)
1496      {
1497      nohit = CMP(SLJIT_C_GREATER_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), START_USED_PTR, STR_PTR, 0);
1498      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), HIT_START, SLJIT_IMM, -1);
1499      JUMPHERE(nohit);
1500      return_value = JUMP(SLJIT_JUMP);
1501      }
1502    else
1503      {
1504      return_value = CMP(SLJIT_C_GREATER_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), START_USED_PTR, STR_PTR, 0);
1505      if (common->partialmatchlabel != NULL)
1506        JUMPTO(SLJIT_JUMP, common->partialmatchlabel);
1507      else
1508        add_jump(compiler, &common->partialmatch, JUMP(SLJIT_JUMP));
1509      }
1510    JUMPHERE(jump);
1511    return return_value;
1512  }  }
1513    
1514  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)
1515  {  {
1516  DEFINE_COMPILER;  DEFINE_COMPILER;
1517  add_jump(compiler, fallbacks, CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0));  struct sljit_jump *jump;
1518    
1519    if (common->mode == JIT_COMPILE)
1520      {
1521      add_jump(compiler, fallbacks, CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0));
1522      return;
1523      }
1524    
1525    /* Partial matching mode. */
1526    jump = CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0);
1527    add_jump(compiler, fallbacks, CMP(SLJIT_C_GREATER_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), START_USED_PTR, STR_PTR, 0));
1528    if (common->mode == JIT_PARTIAL_SOFT_COMPILE)
1529      {
1530      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), HIT_START, SLJIT_IMM, -1);
1531      add_jump(compiler, fallbacks, JUMP(SLJIT_JUMP));
1532      }
1533    else
1534      {
1535      if (common->partialmatchlabel != NULL)
1536        JUMPTO(SLJIT_JUMP, common->partialmatchlabel);
1537      else
1538        add_jump(compiler, &common->partialmatch, JUMP(SLJIT_JUMP));
1539      }
1540    JUMPHERE(jump);
1541  }  }
1542    
1543  static void read_char(compiler_common *common)  static void read_char(compiler_common *common)
# Line 1371  static void read_char(compiler_common *c Line 1545  static void read_char(compiler_common *c
1545  /* Reads the character into TMP1, updates STR_PTR.  /* Reads the character into TMP1, updates STR_PTR.
1546  Does not check STR_END. TMP2 Destroyed. */  Does not check STR_END. TMP2 Destroyed. */
1547  DEFINE_COMPILER;  DEFINE_COMPILER;
1548  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
1549  struct sljit_jump *jump;  struct sljit_jump *jump;
1550  #endif  #endif
1551    
1552  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
1553  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
1554  if (common->utf8)  if (common->utf)
1555    {    {
1556    /* Should not found a value between 128 and 192 here. */  #ifdef COMPILE_PCRE8
1557    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 192);    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);
1558    add_jump(compiler, &common->utf8readchar, JUMP(SLJIT_FAST_CALL));  #else
1559    #ifdef COMPILE_PCRE16
1560      jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800);
1561    #endif
1562    #endif /* COMPILE_PCRE8 */
1563      add_jump(compiler, &common->utfreadchar, JUMP(SLJIT_FAST_CALL));
1564    JUMPHERE(jump);    JUMPHERE(jump);
1565    }    }
1566  #endif  #endif
1567  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));
1568  }  }
1569    
1570  static void peek_char(compiler_common *common)  static void peek_char(compiler_common *common)
# Line 1393  static void peek_char(compiler_common *c Line 1572  static void peek_char(compiler_common *c
1572  /* Reads the character into TMP1, keeps STR_PTR.  /* Reads the character into TMP1, keeps STR_PTR.
1573  Does not check STR_END. TMP2 Destroyed. */  Does not check STR_END. TMP2 Destroyed. */
1574  DEFINE_COMPILER;  DEFINE_COMPILER;
1575  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
1576  struct sljit_jump *jump;  struct sljit_jump *jump;
1577  #endif  #endif
1578    
1579  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
1580  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
1581  if (common->utf8)  if (common->utf)
1582    {    {
1583    /* Should not found a value between 128 and 192 here. */  #ifdef COMPILE_PCRE8
1584    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 192);    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);
1585    add_jump(compiler, &common->utf8readchar, JUMP(SLJIT_FAST_CALL));  #else
1586    #ifdef COMPILE_PCRE16
1587      jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800);
1588    #endif
1589    #endif /* COMPILE_PCRE8 */
1590      add_jump(compiler, &common->utfreadchar, JUMP(SLJIT_FAST_CALL));
1591    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
1592    JUMPHERE(jump);    JUMPHERE(jump);
1593    }    }
# Line 1414  static void read_char8_type(compiler_com Line 1598  static void read_char8_type(compiler_com
1598  {  {
1599  /* 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. */
1600  DEFINE_COMPILER;  DEFINE_COMPILER;
1601  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF || defined COMPILE_PCRE16
1602  struct sljit_jump *jump;  struct sljit_jump *jump;
1603  #endif  #endif
1604    
1605  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
1606  if (common->utf8)  if (common->utf)
1607    {    {
1608    OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), 0);    OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), 0);
1609    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));
1610    #ifdef COMPILE_PCRE8
1611    /* This can be an extra read in some situations, but hopefully    /* This can be an extra read in some situations, but hopefully
1612    it is a clever early read in most cases. */    it is needed in most cases. */
1613    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);
1614    /* Should not found a value between 128 and 192 here. */    jump = CMP(SLJIT_C_LESS, TMP2, 0, SLJIT_IMM, 0xc0);
1615    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));  
1616    JUMPHERE(jump);    JUMPHERE(jump);
1617    #else
1618    #ifdef COMPILE_PCRE16
1619      OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);
1620      jump = CMP(SLJIT_C_GREATER, TMP2, 0, SLJIT_IMM, 255);
1621      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);
1622      JUMPHERE(jump);
1623      /* Skip low surrogate if necessary. */
1624      OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0xfc00);
1625      OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, 0xd800);
1626      COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);
1627      OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 1);
1628      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
1629    #endif
1630    #endif /* COMPILE_PCRE8 */
1631    return;    return;
1632    }    }
1633  #endif  #endif
1634  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);  OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), 0);
1635  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 1);  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
1636  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), common->ctypes);  #ifdef COMPILE_PCRE16
1637    /* The ctypes array contains only 256 values. */
1638    OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);
1639    jump = CMP(SLJIT_C_GREATER, TMP2, 0, SLJIT_IMM, 255);
1640    #endif
1641    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);
1642    #ifdef COMPILE_PCRE16
1643    JUMPHERE(jump);
1644    #endif
1645  }  }
1646    
1647  static void skip_char_back(compiler_common *common)  static void skip_char_back(compiler_common *common)
1648  {  {
1649  /* 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. */
1650  DEFINE_COMPILER;  DEFINE_COMPILER;
1651  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF && defined COMPILE_PCRE8
1652  struct sljit_label *label;  struct sljit_label *label;
1653    
1654  if (common->utf8)  if (common->utf)
1655    {    {
1656    label = LABEL();    label = LABEL();
1657    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 1);    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), -IN_UCHARS(1));
1658    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));
1659    OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xc0);    OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xc0);
1660    CMPTO(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, 0x80, label);    CMPTO(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, 0x80, label);
1661    return;    return;
1662    }    }
1663  #endif  #endif
1664  OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 1);  #if defined SUPPORT_UTF && defined COMPILE_PCRE16
1665    if (common->utf)
1666      {
1667      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), -IN_UCHARS(1));
1668      OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
1669      /* Skip low surrogate if necessary. */
1670      OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);
1671      OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xdc00);
1672      COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);
1673      OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
1674      OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
1675      return;
1676      }
1677    #endif
1678    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
1679  }  }
1680    
1681  static void check_newlinechar(compiler_common *common, int nltype, jump_list **fallbacks, BOOL jumpiftrue)  static void check_newlinechar(compiler_common *common, int nltype, jump_list **fallbacks, BOOL jumpiftrue)
# Line 1478  else if (nltype == NLTYPE_ANYCRLF) Line 1698  else if (nltype == NLTYPE_ANYCRLF)
1698    }    }
1699  else  else
1700    {    {
1701    SLJIT_ASSERT(nltype == NLTYPE_FIXED && common->newline <= 255);    SLJIT_ASSERT(nltype == NLTYPE_FIXED && common->newline < 256);
1702    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));
1703    }    }
1704  }  }
1705    
1706  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
1707  static void do_utf8readchar(compiler_common *common)  
1708    #ifdef COMPILE_PCRE8
1709    static void do_utfreadchar(compiler_common *common)
1710  {  {
1711  /* Fast decoding an utf8 character. TMP1 contains the first byte  /* Fast decoding a UTF-8 character. TMP1 contains the first byte
1712  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. */
1713  DEFINE_COMPILER;  DEFINE_COMPILER;
1714  struct sljit_jump *jump;  struct sljit_jump *jump;
1715    
# Line 1495  sljit_emit_fast_enter(compiler, RETURN_A Line 1717  sljit_emit_fast_enter(compiler, RETURN_A
1717  /* Searching for the first zero. */  /* Searching for the first zero. */
1718  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);
1719  jump = JUMP(SLJIT_C_NOT_ZERO);  jump = JUMP(SLJIT_C_NOT_ZERO);
1720  /* 2 byte sequence */  /* Two byte sequence. */
1721  OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), 1);  OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
1722  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));
1723  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x1f);  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x1f);
1724  OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 6);  OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 6);
1725  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
1726  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
1727  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 1);  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, IN_UCHARS(1));
1728  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
1729  JUMPHERE(jump);  JUMPHERE(jump);
1730    
1731  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);
1732  jump = JUMP(SLJIT_C_NOT_ZERO);  jump = JUMP(SLJIT_C_NOT_ZERO);
1733  /* 3 byte sequence */  /* Three byte sequence. */
1734  OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), 1);  OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
1735  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x0f);  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x0f);
1736  OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 12);  OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 12);
1737  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
1738  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6);  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6);
1739  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
1740  OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), 2);  OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(2));
1741  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));
1742  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
1743  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
1744  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 2);  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, IN_UCHARS(2));
1745  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
1746  JUMPHERE(jump);  JUMPHERE(jump);
1747    
1748  OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x08);  /* Four byte sequence. */
1749  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);  
1750  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x07);  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x07);
1751  OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 18);  OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 18);
1752  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
1753  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 12);  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 12);
1754  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
1755  OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), 2);  OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(2));
1756  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
1757  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6);  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6);
1758  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
1759  OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), 3);  OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(3));
1760  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 3);  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(3));
1761  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
1762  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
1763  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 3);  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, IN_UCHARS(3));
 sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  
 JUMPHERE(jump);  
   
 /* 5 byte sequence */  
 OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), 1);  
 OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x03);  
 OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 24);  
 OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);  
 OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 18);  
 OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);  
 OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), 2);  
 OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);  
 OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 12);  
 OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);  
 OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), 3);  
 OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);  
 OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6);  
 OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);  
 OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), 4);  
 OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 4);  
 OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);  
 OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);  
 OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 4);  
1764  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
1765  }  }
1766    
1767  static void do_utf8readtype8(compiler_common *common)  static void do_utfreadtype8(compiler_common *common)
1768  {  {
1769  /* Fast decoding an utf8 character type. TMP2 contains the first byte  /* Fast decoding a UTF-8 character type. TMP2 contains the first byte
1770  of the character (>= 192) and TMP1 is destroyed. Return value in TMP1. */  of the character (>= 0xc0). Return value in TMP1. */
1771  DEFINE_COMPILER;  DEFINE_COMPILER;
1772  struct sljit_jump *jump;  struct sljit_jump *jump;
1773  struct sljit_jump *compare;  struct sljit_jump *compare;
# Line 1579  sljit_emit_fast_enter(compiler, RETURN_A Line 1776  sljit_emit_fast_enter(compiler, RETURN_A
1776    
1777  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);
1778  jump = JUMP(SLJIT_C_NOT_ZERO);  jump = JUMP(SLJIT_C_NOT_ZERO);
1779  /* 2 byte sequence */  /* Two byte sequence. */
1780  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
1781  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));
1782  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x1f);  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x1f);
1783  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6);  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6);
1784  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x3f);  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x3f);
# Line 1596  sljit_emit_fast_return(compiler, RETURN_ Line 1793  sljit_emit_fast_return(compiler, RETURN_
1793  JUMPHERE(jump);  JUMPHERE(jump);
1794    
1795  /* We only have types for characters less than 256. */  /* We only have types for characters less than 256. */
1796  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);  
1797  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
1798  OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);  OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);
1799  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
1800  }  }
1801    
1802  #endif  #else /* COMPILE_PCRE8 */
1803    
1804    #ifdef COMPILE_PCRE16
1805    static void do_utfreadchar(compiler_common *common)
1806    {
1807    /* Fast decoding a UTF-16 character. TMP1 contains the first 16 bit char
1808    of the character (>= 0xd800). Return char value in TMP1, length - 1 in TMP2. */
1809    DEFINE_COMPILER;
1810    struct sljit_jump *jump;
1811    
1812    sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize);
1813    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xdc00);
1814    /* Do nothing, only return. */
1815    sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
1816    
1817    JUMPHERE(jump);
1818    /* Combine two 16 bit characters. */
1819    OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
1820    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
1821    OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x3ff);
1822    OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 10);
1823    OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3ff);
1824    OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
1825    OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, IN_UCHARS(1));
1826    OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x10000);
1827    sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
1828    }
1829    #endif /* COMPILE_PCRE16 */
1830    
1831    #endif /* COMPILE_PCRE8 */
1832    
1833    #endif /* SUPPORT_UTF */
1834    
1835  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
1836    
# Line 1621  SLJIT_ASSERT(UCD_BLOCK_SIZE == 128 && si Line 1848  SLJIT_ASSERT(UCD_BLOCK_SIZE == 128 && si
1848    
1849  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);
1850  OP2(SLJIT_LSHR, TMP2, 0, TMP1, 0, SLJIT_IMM, UCD_BLOCK_SHIFT);  OP2(SLJIT_LSHR, TMP2, 0, TMP1, 0, SLJIT_IMM, UCD_BLOCK_SHIFT);
1851  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));
1852  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, UCD_BLOCK_MASK);  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, UCD_BLOCK_MASK);
1853  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, UCD_BLOCK_SHIFT);  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, UCD_BLOCK_SHIFT);
1854  OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, TMP2, 0);  OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, TMP2, 0);
1855  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, (sljit_w)_pcre_ucd_stage2);  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, (sljit_w)PRIV(ucd_stage2));
1856  OP1(SLJIT_MOV_UH, TMP2, 0, SLJIT_MEM2(TMP2, TMP1), 1);  OP1(SLJIT_MOV_UH, TMP2, 0, SLJIT_MEM2(TMP2, TMP1), 1);
1857  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));
1858  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM2(TMP1, TMP2), 3);  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM2(TMP1, TMP2), 3);
1859  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
1860  }  }
# Line 1641  struct sljit_label *newlinelabel = NULL; Line 1868  struct sljit_label *newlinelabel = NULL;
1868  struct sljit_jump *start;  struct sljit_jump *start;
1869  struct sljit_jump *end = NULL;  struct sljit_jump *end = NULL;
1870  struct sljit_jump *nl = NULL;  struct sljit_jump *nl = NULL;
1871    #ifdef SUPPORT_UTF
1872    struct sljit_jump *singlechar;
1873    #endif
1874  jump_list *newline = NULL;  jump_list *newline = NULL;
1875  BOOL newlinecheck = FALSE;  BOOL newlinecheck = FALSE;
1876  BOOL readbyte = FALSE;  BOOL readuchar = FALSE;
1877    
1878  if (!(hascrorlf || firstline) && (common->nltype == NLTYPE_ANY ||  if (!(hascrorlf || firstline) && (common->nltype == NLTYPE_ANY ||
1879      common->nltype == NLTYPE_ANYCRLF || common->newline > 255))      common->nltype == NLTYPE_ANYCRLF || common->newline > 255))
# Line 1658  if (firstline) Line 1888  if (firstline)
1888    if (common->nltype == NLTYPE_FIXED && common->newline > 255)    if (common->nltype == NLTYPE_FIXED && common->newline > 255)
1889      {      {
1890      mainloop = LABEL();      mainloop = LABEL();
1891      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));
1892      end = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);      end = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
1893      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), -1);      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-1));
1894      OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), 0);      OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
1895      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);
1896      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);
1897      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));
1898      }      }
1899    else    else
1900      {      {
# Line 1688  start = JUMP(SLJIT_JUMP); Line 1918  start = JUMP(SLJIT_JUMP);
1918  if (newlinecheck)  if (newlinecheck)
1919    {    {
1920    newlinelabel = LABEL();    newlinelabel = LABEL();
1921    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));
1922    end = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);    end = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
1923    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
1924    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);
1925    COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);    COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);
1926    #ifdef COMPILE_PCRE16
1927      OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
1928    #endif
1929    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
1930    nl = JUMP(SLJIT_JUMP);    nl = JUMP(SLJIT_JUMP);
1931    }    }
# Line 1700  if (newlinecheck) Line 1933  if (newlinecheck)
1933  mainloop = LABEL();  mainloop = LABEL();
1934    
1935  /* 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. */
1936  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
1937  if (common->utf8) readbyte = TRUE;  if (common->utf) readuchar = TRUE;
1938  #endif  #endif
1939  if (newlinecheck) readbyte = TRUE;  if (newlinecheck) readuchar = TRUE;
1940    
1941  if (readbyte)  if (readuchar)
1942    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
1943    
1944  if (newlinecheck)  if (newlinecheck)
1945    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);
1946    
1947  #ifdef SUPPORT_UTF8  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
1948  if (common->utf8)  #if defined SUPPORT_UTF && defined COMPILE_PCRE8
1949    if (common->utf)
1950    {    {
1951    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);
1952      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)PRIV(utf8_table4) - 0xc0);
1953    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
1954      JUMPHERE(singlechar);
1955      }
1956    #endif
1957    #if defined SUPPORT_UTF && defined COMPILE_PCRE16
1958    if (common->utf)
1959      {
1960      singlechar = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800);
1961      OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);
1962      OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xd800);
1963      COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);
1964      OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
1965      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
1966      JUMPHERE(singlechar);
1967    }    }
 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);  
1968  #endif  #endif
1969  JUMPHERE(start);  JUMPHERE(start);
1970    
# Line 1733  if (newlinecheck) Line 1977  if (newlinecheck)
1977  return mainloop;  return mainloop;
1978  }  }
1979    
1980  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)
1981  {  {
1982  DEFINE_COMPILER;  DEFINE_COMPILER;
1983  struct sljit_label *start;  struct sljit_label *start;
1984  struct sljit_jump *leave;  struct sljit_jump *leave;
1985  struct sljit_jump *found;  struct sljit_jump *found;
1986  pcre_uint16 oc, bit;  pcre_uchar oc, bit;
1987    
1988  if (firstline)  if (firstline)
1989    {    {
# Line 1749  if (firstline) Line 1993  if (firstline)
1993    
1994  start = LABEL();  start = LABEL();
1995  leave = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);  leave = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
1996  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
1997    
1998  if ((firstbyte & REQ_CASELESS) == 0)  oc = first_char;
1999    found = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, firstbyte & 0xff);  if (caseless)
2000      {
2001      oc = TABLE_GET(first_char, common->fcc, first_char);
2002    #if defined SUPPORT_UCP && !(defined COMPILE_PCRE8)
2003      if (first_char > 127 && common->utf)
2004        oc = UCD_OTHERCASE(first_char);
2005    #endif
2006      }
2007    if (first_char == oc)
2008      found = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, first_char);
2009  else  else
2010    {    {
2011    firstbyte &= 0xff;    bit = first_char ^ oc;
   oc = common->fcc[firstbyte];  
   bit = firstbyte ^ oc;  
2012    if (ispowerof2(bit))    if (ispowerof2(bit))
2013      {      {
2014      OP2(SLJIT_OR, TMP2, 0, TMP1, 0, SLJIT_IMM, bit);      OP2(SLJIT_OR, TMP2, 0, TMP1, 0, SLJIT_IMM, bit);
2015      found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, firstbyte | bit);      found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, first_char | bit);
2016      }      }
2017    else    else
2018      {      {
2019      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);
2020      COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);      COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);
2021      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);
2022      COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);      COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);
# Line 1773  else Line 2024  else
2024      }      }
2025    }    }
2026    
2027  #ifdef SUPPORT_UTF8  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2028  if (common->utf8)  #if defined SUPPORT_UTF && defined COMPILE_PCRE8
2029    if (common->utf)
2030    {    {
2031    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);
2032      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)PRIV(utf8_table4) - 0xc0);
2033      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2034      }
2035    #endif
2036    #if defined SUPPORT_UTF && defined COMPILE_PCRE16
2037    if (common->utf)
2038      {
2039      CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800, start);
2040      OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);
2041      OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xd800);
2042      COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);
2043      OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
2044    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2045    }    }
 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);  
2046  #endif  #endif
2047  JUMPTO(SLJIT_JUMP, start);  JUMPTO(SLJIT_JUMP, start);
2048  JUMPHERE(found);  JUMPHERE(found);
# Line 1817  if (common->nltype == NLTYPE_FIXED && co Line 2077  if (common->nltype == NLTYPE_FIXED && co
2077    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));
2078    firstchar = CMP(SLJIT_C_LESS_EQUAL, STR_PTR, 0, TMP2, 0);    firstchar = CMP(SLJIT_C_LESS_EQUAL, STR_PTR, 0, TMP2, 0);
2079    
2080    OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 2);    OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(2));
2081    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);
2082    COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_GREATER_EQUAL);    COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_GREATER_EQUAL);
2083    #ifdef COMPILE_PCRE16
2084      OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 1);
2085    #endif
2086    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
2087    
2088    loop = LABEL();    loop = LABEL();
2089    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));
2090    leave = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);    leave = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
2091    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), -2);    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-2));
2092    OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), -1);    OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-1));
2093    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);
2094    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);
2095    
# Line 1857  if (common->nltype == NLTYPE_ANY || comm Line 2120  if (common->nltype == NLTYPE_ANY || comm
2120    leave = JUMP(SLJIT_JUMP);    leave = JUMP(SLJIT_JUMP);
2121    JUMPHERE(foundcr);    JUMPHERE(foundcr);
2122    notfoundnl = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);    notfoundnl = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
2123    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
2124    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);
2125    COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);    COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);
2126    #ifdef COMPILE_PCRE16
2127      OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
2128    #endif
2129    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2130    JUMPHERE(notfoundnl);    JUMPHERE(notfoundnl);
2131    JUMPHERE(leave);    JUMPHERE(leave);
# Line 1877  DEFINE_COMPILER; Line 2143  DEFINE_COMPILER;
2143  struct sljit_label *start;  struct sljit_label *start;
2144  struct sljit_jump *leave;  struct sljit_jump *leave;
2145  struct sljit_jump *found;  struct sljit_jump *found;
2146    #ifndef COMPILE_PCRE8
2147    struct sljit_jump *jump;
2148    #endif
2149    
2150  if (firstline)  if (firstline)
2151    {    {
# Line 1886  if (firstline) Line 2155  if (firstline)
2155    
2156  start = LABEL();  start = LABEL();
2157  leave = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);  leave = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
2158  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
2159  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
2160  if (common->utf8)  if (common->utf)
2161    OP1(SLJIT_MOV_UB, TMP3, 0, SLJIT_MEM1(TMP1), (sljit_w)_pcre_utf8_char_sizes);    OP1(SLJIT_MOV, TMP3, 0, TMP1, 0);
2162    #endif
2163    #ifndef COMPILE_PCRE8
2164    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 255);
2165    OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 255);
2166    JUMPHERE(jump);
2167  #endif  #endif
2168  OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);  OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);
2169  OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);  OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);
# Line 1898  OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TM Line 2172  OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TM
2172  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);
2173  found = JUMP(SLJIT_C_NOT_ZERO);  found = JUMP(SLJIT_C_NOT_ZERO);
2174    
2175  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
2176  if (common->utf8)  if (common->utf)
2177    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP3, 0);    OP1(SLJIT_MOV, TMP1, 0, TMP3, 0);
2178  else  #endif
2179    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));
2180  #else  #if defined SUPPORT_UTF && defined COMPILE_PCRE8
2181  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 1);  if (common->utf)
2182      {
2183      CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0, start);
2184      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)PRIV(utf8_table4) - 0xc0);
2185      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2186      }
2187    #endif
2188    #if defined SUPPORT_UTF && defined COMPILE_PCRE16
2189    if (common->utf)
2190      {
2191      CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800, start);
2192      OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);
2193      OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xd800);
2194      COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);
2195      OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
2196      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2197      }
2198  #endif  #endif
2199  JUMPTO(SLJIT_JUMP, start);  JUMPTO(SLJIT_JUMP, start);
2200  JUMPHERE(found);  JUMPHERE(found);
# Line 1914  if (firstline) Line 2204  if (firstline)
2204    OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0);    OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0);
2205  }  }
2206    
2207  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)
2208  {  {
2209  DEFINE_COMPILER;  DEFINE_COMPILER;
2210  struct sljit_label *loop;  struct sljit_label *loop;
# Line 1923  struct sljit_jump *alreadyfound; Line 2213  struct sljit_jump *alreadyfound;
2213  struct sljit_jump *found;  struct sljit_jump *found;
2214  struct sljit_jump *foundoc = NULL;  struct sljit_jump *foundoc = NULL;
2215  struct sljit_jump *notfound;  struct sljit_jump *notfound;
2216  pcre_uint16 oc, bit;  pcre_uchar oc, bit;
2217    
2218  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);
2219  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);
2220  toolong = CMP(SLJIT_C_LESS, TMP1, 0, STR_END, 0);  toolong = CMP(SLJIT_C_LESS, TMP1, 0, STR_END, 0);
2221  alreadyfound = CMP(SLJIT_C_LESS, STR_PTR, 0, TMP2, 0);  alreadyfound = CMP(SLJIT_C_LESS, STR_PTR, 0, TMP2, 0);
2222    
2223  if (has_firstbyte)  if (has_firstchar)
2224    OP2(SLJIT_ADD, TMP1, 0, STR_PTR, 0, SLJIT_IMM, 1);    OP2(SLJIT_ADD, TMP1, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2225  else  else
2226    OP1(SLJIT_MOV, TMP1, 0, STR_PTR, 0);    OP1(SLJIT_MOV, TMP1, 0, STR_PTR, 0);
2227    
2228  loop = LABEL();  loop = LABEL();
2229  notfound = CMP(SLJIT_C_GREATER_EQUAL, TMP1, 0, STR_END, 0);  notfound = CMP(SLJIT_C_GREATER_EQUAL, TMP1, 0, STR_END, 0);
2230    
2231  OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP1), 0);  OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(TMP1), 0);
2232  if ((reqbyte & REQ_CASELESS) == 0)  oc = req_char;
2233    found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, reqbyte & 0xff);  if (caseless)
2234      {
2235      oc = TABLE_GET(req_char, common->fcc, req_char);
2236    #if defined SUPPORT_UCP && !(defined COMPILE_PCRE8)
2237      if (req_char > 127 && common->utf)
2238        oc = UCD_OTHERCASE(req_char);
2239    #endif
2240      }
2241    if (req_char == oc)
2242      found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, req_char);
2243  else  else
2244    {    {
2245    reqbyte &= 0xff;    bit = req_char ^ oc;
   oc = common->fcc[reqbyte];  
   bit = reqbyte ^ oc;  
2246    if (ispowerof2(bit))    if (ispowerof2(bit))
2247      {      {
2248      OP2(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_IMM, bit);      OP2(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_IMM, bit);
2249      found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, reqbyte | bit);      found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, req_char | bit);
2250      }      }
2251    else    else
2252      {      {
2253      found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, reqbyte);      found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, req_char);
2254      foundoc = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, oc);      foundoc = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, oc);
2255      }      }
2256    }    }
2257  OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);  OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(1));
2258  JUMPTO(SLJIT_JUMP, loop);  JUMPTO(SLJIT_JUMP, loop);
2259    
2260  JUMPHERE(found);  JUMPHERE(found);
2261  if (foundoc)  if (foundoc)
2262    JUMPHERE(foundoc);    JUMPHERE(foundoc);
2263  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);
2264  JUMPHERE(alreadyfound);  JUMPHERE(alreadyfound);
2265  JUMPHERE(toolong);  JUMPHERE(toolong);
2266  return notfound;  return notfound;
# Line 1972  return notfound; Line 2269  return notfound;
2269  static void do_revertframes(compiler_common *common)  static void do_revertframes(compiler_common *common)
2270  {  {
2271  DEFINE_COMPILER;  DEFINE_COMPILER;
 struct sljit_jump *earlyexit;  
2272  struct sljit_jump *jump;  struct sljit_jump *jump;
2273  struct sljit_label *mainloop;  struct sljit_label *mainloop;
2274    
2275  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);
2276  OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS_HEAD);  OP1(SLJIT_MOV, TMP1, 0, STACK_TOP, 0);
2277    
2278  /* Drop frames until we reach STACK_TOP. */  /* Drop frames until we reach STACK_TOP. */
 earlyexit = CMP(SLJIT_C_LESS, TMP1, 0, STACK_TOP, 0);  
2279  mainloop = LABEL();  mainloop = LABEL();
2280  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), 0);  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), 0);
2281  jump = CMP(SLJIT_C_SIG_LESS_EQUAL, TMP2, 0, SLJIT_IMM, frame_end);  jump = CMP(SLJIT_C_SIG_LESS_EQUAL, TMP2, 0, SLJIT_IMM, frame_end);
# Line 1993  JUMPTO(SLJIT_JUMP, mainloop); Line 2288  JUMPTO(SLJIT_JUMP, mainloop);
2288  JUMPHERE(jump);  JUMPHERE(jump);
2289  jump = CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, frame_end);  jump = CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, frame_end);
2290  /* 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);  
2291  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
2292    
2293  JUMPHERE(jump);  JUMPHERE(jump);
 jump = CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, frame_setmaxindex);  
 /* Set max index. */  
 OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), sizeof(sljit_w));  
 OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 2 * sizeof(sljit_w));  
 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), MAX_INDEX, TMP2, 0);  
 JUMPTO(SLJIT_JUMP, mainloop);  
   
 JUMPHERE(jump);  
2294  jump = CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, frame_setstrbegin);  jump = CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, frame_setstrbegin);
2295  /* Set max index. */  /* Set string begin. */
2296  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), sizeof(sljit_w));  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), sizeof(sljit_w));
2297  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));
2298  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 2024  JUMPTO(SLJIT_JUMP, mainloop); Line 2307  JUMPTO(SLJIT_JUMP, mainloop);
2307  static void check_wordboundary(compiler_common *common)  static void check_wordboundary(compiler_common *common)
2308  {  {
2309  DEFINE_COMPILER;  DEFINE_COMPILER;
2310  struct sljit_jump *beginend;  struct sljit_jump *skipread;
2311  #ifdef SUPPORT_UTF8  #if !(defined COMPILE_PCRE8) || defined SUPPORT_UTF
2312  struct sljit_jump *jump;  struct sljit_jump *jump;
2313  #endif  #endif
2314    
2315  SLJIT_ASSERT(ctype_word == 0x10);  SLJIT_COMPILE_ASSERT(ctype_word == 0x10, ctype_word_must_be_16);
2316    
2317  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);
2318  /* Get type of the previous char, and put it to LOCALS1. */  /* Get type of the previous char, and put it to LOCALS1. */
2319  OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);  OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
2320  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));
2321  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, SLJIT_IMM, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, SLJIT_IMM, 0);
2322  beginend = CMP(SLJIT_C_LESS_EQUAL, STR_PTR, 0, TMP1, 0);  skipread = CMP(SLJIT_C_LESS_EQUAL, STR_PTR, 0, TMP1, 0);
2323  skip_char_back(common);  skip_char_back(common);
2324    check_start_used_ptr(common);
2325  read_char(common);  read_char(common);
2326    
2327  /* Testing char type. */  /* Testing char type. */
2328  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
2329  if (common->useucp)  if (common->use_ucp)
2330    {    {
2331    OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 1);    OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 1);
2332    jump = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_UNDERSCORE);    jump = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_UNDERSCORE);
# Line 2059  if (common->useucp) Line 2343  if (common->useucp)
2343  else  else
2344  #endif  #endif
2345    {    {
2346  #ifdef SUPPORT_UTF8  #ifndef COMPILE_PCRE8
2347      jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);
2348    #elif defined SUPPORT_UTF
2349    /* Here LOCALS1 has already been zeroed. */    /* Here LOCALS1 has already been zeroed. */
2350    jump = NULL;    jump = NULL;
2351    if (common->utf8)    if (common->utf)
2352      jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);      jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);
2353  #endif  #endif /* COMPILE_PCRE8 */
2354    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), common->ctypes);    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), common->ctypes);
2355    OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 4 /* ctype_word */);    OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 4 /* ctype_word */);
2356    OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);    OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
2357    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, TMP1, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, TMP1, 0);
2358  #ifdef SUPPORT_UTF8  #ifndef COMPILE_PCRE8
2359      JUMPHERE(jump);
2360    #elif defined SUPPORT_UTF
2361    if (jump != NULL)    if (jump != NULL)
2362      JUMPHERE(jump);      JUMPHERE(jump);
2363  #endif  #endif /* COMPILE_PCRE8 */
2364    }    }
2365  JUMPHERE(beginend);  JUMPHERE(skipread);
2366    
2367  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0);  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0);
2368  beginend = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);  skipread = check_str_end(common);
2369  peek_char(common);  peek_char(common);
2370    
2371  /* Testing char type. This is a code duplication. */  /* Testing char type. This is a code duplication. */
2372  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
2373  if (common->useucp)  if (common->use_ucp)
2374    {    {
2375    OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 1);    OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 1);
2376    jump = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_UNDERSCORE);    jump = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_UNDERSCORE);
# Line 2098  if (common->useucp) Line 2386  if (common->useucp)
2386  else  else
2387  #endif  #endif
2388    {    {
2389  #ifdef SUPPORT_UTF8  #ifndef COMPILE_PCRE8
2390      /* TMP2 may be destroyed by peek_char. */
2391      OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0);
2392      jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);
2393    #elif defined SUPPORT_UTF
2394    OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0);    OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0);
2395    jump = NULL;    jump = NULL;
2396    if (common->utf8)    if (common->utf)
2397      jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);      jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);
2398  #endif  #endif
2399    OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP1), common->ctypes);    OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP1), common->ctypes);
2400    OP2(SLJIT_LSHR, TMP2, 0, TMP2, 0, SLJIT_IMM, 4 /* ctype_word */);    OP2(SLJIT_LSHR, TMP2, 0, TMP2, 0, SLJIT_IMM, 4 /* ctype_word */);
2401    OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 1);    OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 1);
2402  #ifdef SUPPORT_UTF8  #ifndef COMPILE_PCRE8
2403      JUMPHERE(jump);
2404    #elif defined SUPPORT_UTF
2405    if (jump != NULL)    if (jump != NULL)
2406      JUMPHERE(jump);      JUMPHERE(jump);
2407  #endif  #endif /* COMPILE_PCRE8 */
2408    }    }
2409  JUMPHERE(beginend);  JUMPHERE(skipread);
2410    
2411  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);
2412  sljit_emit_fast_return(compiler, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);  sljit_emit_fast_return(compiler, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);
# Line 2129  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_I Line 2423  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_I
2423  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);
2424  COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS_EQUAL);  COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS_EQUAL);
2425  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);
2426  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF || defined COMPILE_PCRE16
2427  if (common->utf8)  #ifdef COMPILE_PCRE8
2428    if (common->utf)
2429    {    {
2430    #endif
2431    COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);    COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);
2432    OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x1);    OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x1);
2433    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);
2434    #ifdef COMPILE_PCRE8
2435    }    }
2436  #endif  #endif
2437    #endif /* SUPPORT_UTF || COMPILE_PCRE16 */
2438  COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);  COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);
2439  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
2440  }  }
# Line 2153  COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_E Line 2451  COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_E
2451  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);
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, 0xa0);  OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xa0);
2454  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF || defined COMPILE_PCRE16
2455  if (common->utf8)  #ifdef COMPILE_PCRE8
2456    if (common->utf)
2457    {    {
2458    #endif
2459    COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);    COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);
2460    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);
2461    COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);    COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);
# Line 2169  if (common->utf8) Line 2469  if (common->utf8)
2469    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);
2470    COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);    COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);
2471    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);
2472    #ifdef COMPILE_PCRE8
2473    }    }
2474  #endif  #endif
2475    #endif /* SUPPORT_UTF || COMPILE_PCRE16 */
2476  COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);  COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);
2477    
2478  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
# Line 2187  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_I Line 2489  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_I
2489  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);
2490  COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS_EQUAL);  COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS_EQUAL);
2491  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);
2492  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF || defined COMPILE_PCRE16
2493  if (common->utf8)  #ifdef COMPILE_PCRE8
2494    if (common->utf)
2495    {    {
2496    #endif
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    OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x1);    OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x1);
2499    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);
2500    #ifdef COMPILE_PCRE8
2501    }    }
2502  #endif  #endif
2503    #endif /* SUPPORT_UTF || COMPILE_PCRE16 */
2504  COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);  COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);
2505    
2506  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
# Line 2213  sljit_emit_fast_enter(compiler, RETURN_A Line 2519  sljit_emit_fast_enter(compiler, RETURN_A
2519  OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);  OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
2520  OP1(SLJIT_MOV, TMP3, 0, CHAR1, 0);  OP1(SLJIT_MOV, TMP3, 0, CHAR1, 0);
2521  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, CHAR2, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, CHAR2, 0);
2522  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(1));
2523  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));
2524    
2525  label = LABEL();  label = LABEL();
2526  OP1(SLJIT_MOVU_UB, CHAR1, 0, SLJIT_MEM1(TMP1), 1);  OP1(MOVU_UCHAR, CHAR1, 0, SLJIT_MEM1(TMP1), IN_UCHARS(1));
2527  OP1(SLJIT_MOVU_UB, CHAR2, 0, SLJIT_MEM1(STR_PTR), 1);  OP1(MOVU_UCHAR, CHAR2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
2528  jump = CMP(SLJIT_C_NOT_EQUAL, CHAR1, 0, CHAR2, 0);  jump = CMP(SLJIT_C_NOT_EQUAL, CHAR1, 0, CHAR2, 0);
2529  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));
2530  JUMPTO(SLJIT_C_NOT_ZERO, label);  JUMPTO(SLJIT_C_NOT_ZERO, label);
2531    
2532  JUMPHERE(jump);  JUMPHERE(jump);
2533  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));
2534  OP1(SLJIT_MOV, CHAR1, 0, TMP3, 0);  OP1(SLJIT_MOV, CHAR1, 0, TMP3, 0);
2535  OP1(SLJIT_MOV, CHAR2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);  OP1(SLJIT_MOV, CHAR2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);
2536  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
# Line 2245  OP1(SLJIT_MOV, TMP3, 0, LCC_TABLE, 0); Line 2551  OP1(SLJIT_MOV, TMP3, 0, LCC_TABLE, 0);
2551  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, CHAR1, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, CHAR1, 0);
2552  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, CHAR2, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, CHAR2, 0);
2553  OP1(SLJIT_MOV, LCC_TABLE, 0, SLJIT_IMM, common->lcc);  OP1(SLJIT_MOV, LCC_TABLE, 0, SLJIT_IMM, common->lcc);
2554  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(1));
2555  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));
2556    
2557  label = LABEL();  label = LABEL();
2558  OP1(SLJIT_MOVU_UB, CHAR1, 0, SLJIT_MEM1(TMP1), 1);  OP1(MOVU_UCHAR, CHAR1, 0, SLJIT_MEM1(TMP1), IN_UCHARS(1));
2559  OP1(SLJIT_MOVU_UB, CHAR2, 0, SLJIT_MEM1(STR_PTR), 1);  OP1(MOVU_UCHAR, CHAR2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
2560    #ifndef COMPILE_PCRE8
2561    jump = CMP(SLJIT_C_GREATER, CHAR1, 0, SLJIT_IMM, 255);
2562    #endif
2563  OP1(SLJIT_MOV_UB, CHAR1, 0, SLJIT_MEM2(LCC_TABLE, CHAR1), 0);  OP1(SLJIT_MOV_UB, CHAR1, 0, SLJIT_MEM2(LCC_TABLE, CHAR1), 0);
2564    #ifndef COMPILE_PCRE8
2565    JUMPHERE(jump);
2566    jump = CMP(SLJIT_C_GREATER, CHAR2, 0, SLJIT_IMM, 255);
2567    #endif
2568  OP1(SLJIT_MOV_UB, CHAR2, 0, SLJIT_MEM2(LCC_TABLE, CHAR2), 0);  OP1(SLJIT_MOV_UB, CHAR2, 0, SLJIT_MEM2(LCC_TABLE, CHAR2), 0);
2569    #ifndef COMPILE_PCRE8
2570    JUMPHERE(jump);
2571    #endif
2572  jump = CMP(SLJIT_C_NOT_EQUAL, CHAR1, 0, CHAR2, 0);  jump = CMP(SLJIT_C_NOT_EQUAL, CHAR1, 0, CHAR2, 0);
2573  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));
2574  JUMPTO(SLJIT_C_NOT_ZERO, label);  JUMPTO(SLJIT_C_NOT_ZERO, label);
2575    
2576  JUMPHERE(jump);  JUMPHERE(jump);
2577  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));
2578  OP1(SLJIT_MOV, LCC_TABLE, 0, TMP3, 0);  OP1(SLJIT_MOV, LCC_TABLE, 0, TMP3, 0);
2579  OP1(SLJIT_MOV, CHAR1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);  OP1(SLJIT_MOV, CHAR1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);
2580  OP1(SLJIT_MOV, CHAR2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1);  OP1(SLJIT_MOV, CHAR2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1);
# Line 2269  sljit_emit_fast_return(compiler, RETURN_ Line 2585  sljit_emit_fast_return(compiler, RETURN_
2585  #undef CHAR1  #undef CHAR1
2586  #undef CHAR2  #undef CHAR2
2587    
2588  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF && defined SUPPORT_UCP
 #ifdef SUPPORT_UCP  
2589    
2590  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)
2591  {  {
2592  /* This function would be ineffective to do in JIT level. */  /* This function would be ineffective to do in JIT level. */
2593  int c1, c2;  int c1, c2;
2594  uschar *src2 = args->ptr;  const pcre_uchar *src2 = args->ptr;
2595  uschar *end2 = (uschar*)args->end;  const pcre_uchar *end2 = args->end;
2596    
2597  while (src1 < end1)  while (src1 < end1)
2598    {    {
2599    if (src2 >= end2)    if (src2 >= end2)
2600      return 0;      return (pcre_uchar*)1;
2601    GETCHARINC(c1, src1);    GETCHARINC(c1, src1);
2602    GETCHARINC(c2, src2);    GETCHARINC(c2, src2);
2603    if (c1 != c2 && c1 != UCD_OTHERCASE(c2)) return 0;    if (c1 != c2 && c1 != UCD_OTHERCASE(c2)) return NULL;
2604    }    }
2605  return src2;  return src2;
2606  }  }
2607    
2608  #endif  #endif /* SUPPORT_UTF && SUPPORT_UCP */
 #endif  
2609    
2610  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,
2611      compare_context* context, jump_list **fallbacks)      compare_context* context, jump_list **fallbacks)
2612  {  {
2613  DEFINE_COMPILER;  DEFINE_COMPILER;
2614  unsigned int othercasebit = 0;  unsigned int othercasebit = 0;
2615  uschar *othercasebyte = NULL;  pcre_uchar *othercasechar = NULL;
2616  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
2617  int utf8length;  int utflength;
2618  #endif  #endif
2619    
2620  if (caseless && char_has_othercase(common, cc))  if (caseless && char_has_othercase(common, cc))
# Line 2308  if (caseless && char_has_othercase(commo Line 2622  if (caseless && char_has_othercase(commo
2622    othercasebit = char_get_othercase_bit(common, cc);    othercasebit = char_get_othercase_bit(common, cc);
2623    SLJIT_ASSERT(othercasebit);    SLJIT_ASSERT(othercasebit);
2624    /* Extracting bit difference info. */    /* Extracting bit difference info. */
2625    othercasebyte = cc + (othercasebit >> 8);  #ifdef COMPILE_PCRE8
2626      othercasechar = cc + (othercasebit >> 8);
2627    othercasebit &= 0xff;    othercasebit &= 0xff;
2628    #else
2629    #ifdef COMPILE_PCRE16
2630      othercasechar = cc + (othercasebit >> 9);
2631      if ((othercasebit & 0x100) != 0)
2632        othercasebit = (othercasebit & 0xff) << 8;
2633      else
2634        othercasebit &= 0xff;
2635    #endif
2636    #endif
2637    }    }
2638    
2639  if (context->sourcereg == -1)  if (context->sourcereg == -1)
2640    {    {
2641    #ifdef COMPILE_PCRE8
2642  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
2643    if (context->length >= 4)    if (context->length >= 4)
2644      OP1(SLJIT_MOV_SI, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);      OP1(SLJIT_MOV_SI, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);
2645    else if (context->length >= 2)    else if (context->length >= 2)
2646      OP1(SLJIT_MOV_SH, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);      OP1(SLJIT_MOV_UH, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);
2647    else    else
2648  #endif  #endif
2649      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);
2650    #else
2651    #ifdef COMPILE_PCRE16
2652    #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
2653      if (context->length >= 4)
2654        OP1(SLJIT_MOV_SI, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);
2655      else
2656    #endif
2657        OP1(SLJIT_MOV_UH, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);
2658    #endif
2659    #endif /* COMPILE_PCRE8 */
2660    context->sourcereg = TMP2;    context->sourcereg = TMP2;
2661    }    }
2662    
2663  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
2664  utf8length = 1;  utflength = 1;
2665  if (common->utf8 && *cc >= 0xc0)  if (common->utf && HAS_EXTRALEN(*cc))
2666    utf8length += _pcre_utf8_table4[*cc & 0x3f];    utflength += GET_EXTRALEN(*cc);
2667    
2668  do  do
2669    {    {
2670  #endif  #endif
2671    
2672    context->length--;    context->length -= IN_UCHARS(1);
2673  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
2674    
2675    /* Unaligned read is supported. */    /* Unaligned read is supported. */
2676    if (othercasebit != 0 && othercasebyte == cc)    if (othercasebit != 0 && othercasechar == cc)
2677      {      {
2678      context->c.asbytes[context->byteptr] = *cc | othercasebit;      context->c.asuchars[context->ucharptr] = *cc | othercasebit;
2679      context->oc.asbytes[context->byteptr] = othercasebit;      context->oc.asuchars[context->ucharptr] = othercasebit;
2680      }      }
2681    else    else
2682      {      {
2683      context->c.asbytes[context->byteptr] = *cc;      context->c.asuchars[context->ucharptr] = *cc;
2684      context->oc.asbytes[context->byteptr] = 0;      context->oc.asuchars[context->ucharptr] = 0;
2685      }      }
2686    context->byteptr++;    context->ucharptr++;
2687    
2688    if (context->byteptr >= 4 || context->length == 0 || (context->byteptr == 2 && context->length == 1))  #ifdef COMPILE_PCRE8
2689      if (context->ucharptr >= 4 || context->length == 0 || (context->ucharptr == 2 && context->length == 1))
2690    #else
2691      if (context->ucharptr >= 2 || context->length == 0)
2692    #endif
2693      {      {
2694      if (context->length >= 4)      if (context->length >= 4)
2695        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);
2696    #ifdef COMPILE_PCRE8
2697      else if (context->length >= 2)      else if (context->length >= 2)
2698        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);
2699      else if (context->length >= 1)      else if (context->length >= 1)
2700        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);
2701    #else
2702        else if (context->length >= 2)
2703          OP1(SLJIT_MOV_UH, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);
2704    #endif
2705      context->sourcereg = context->sourcereg == TMP1 ? TMP2 : TMP1;      context->sourcereg = context->sourcereg == TMP1 ? TMP2 : TMP1;
2706    
2707      switch(context->byteptr)      switch(context->ucharptr)
2708        {        {
2709        case 4:        case 4 / sizeof(pcre_uchar):
2710        if (context->oc.asint != 0)        if (context->oc.asint != 0)
2711          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);
2712        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));
2713        break;        break;
2714    
2715        case 2:        case 2 / sizeof(pcre_uchar):
2716        if (context->oc.asshort != 0)        if (context->oc.asushort != 0)
2717          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);
2718        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));
2719        break;        break;
2720    
2721    #ifdef COMPILE_PCRE8
2722        case 1:        case 1:
2723        if (context->oc.asbyte != 0)        if (context->oc.asbyte != 0)
2724          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);
2725        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));
2726        break;        break;
2727    #endif
2728    
2729        default:        default:
2730        SLJIT_ASSERT_STOP();        SLJIT_ASSERT_STOP();
2731        break;        break;
2732        }        }
2733      context->byteptr = 0;      context->ucharptr = 0;
2734      }      }
2735    
2736  #else  #else
2737    
2738    /* Unaligned read is unsupported. */    /* Unaligned read is unsupported. */
2739    #ifdef COMPILE_PCRE8
2740    if (context->length > 0)    if (context->length > 0)
2741      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);
2742    #else
2743      if (context->length > 0)
2744        OP1(SLJIT_MOV_UH, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);
2745    #endif
2746    context->sourcereg = context->sourcereg == TMP1 ? TMP2 : TMP1;    context->sourcereg = context->sourcereg == TMP1 ? TMP2 : TMP1;
2747    
2748    if (othercasebit != 0 && othercasebyte == cc)    if (othercasebit != 0 && othercasechar == cc)
2749      {      {
2750      OP2(SLJIT_OR, context->sourcereg, 0, context->sourcereg, 0, SLJIT_IMM, othercasebit);      OP2(SLJIT_OR, context->sourcereg, 0, context->sourcereg, 0, SLJIT_IMM, othercasebit);
2751      add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, context->sourcereg, 0, SLJIT_IMM, *cc | othercasebit));      add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, context->sourcereg, 0, SLJIT_IMM, *cc | othercasebit));
# Line 2405  do Line 2756  do
2756  #endif  #endif
2757    
2758    cc++;    cc++;
2759  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
2760    utf8length--;    utflength--;
2761    }    }
2762  while (utf8length > 0);  while (utflength > 0);
2763  #endif  #endif
2764    
2765  return cc;  return cc;
2766  }  }
2767    
2768  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
2769    
2770  #define SET_TYPE_OFFSET(value) \  #define SET_TYPE_OFFSET(value) \
2771    if ((value) != typeoffset) \    if ((value) != typeoffset) \
# Line 2436  return cc; Line 2787  return cc;
2787      } \      } \
2788    charoffset = (value);    charoffset = (value);
2789    
2790  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)
2791  {  {
2792  DEFINE_COMPILER;  DEFINE_COMPILER;
2793  jump_list *found = NULL;  jump_list *found = NULL;
# Line 2444  jump_list **list = (*cc & XCL_NOT) == 0 Line 2795  jump_list **list = (*cc & XCL_NOT) == 0
2795  unsigned int c;  unsigned int c;
2796  int compares;  int compares;
2797  struct sljit_jump *jump = NULL;  struct sljit_jump *jump = NULL;
2798  uschar *ccbegin;  pcre_uchar *ccbegin;
2799  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
2800  BOOL needstype = FALSE, needsscript = FALSE, needschar = FALSE;  BOOL needstype = FALSE, needsscript = FALSE, needschar = FALSE;
2801  BOOL charsaved = FALSE;  BOOL charsaved = FALSE;
2802  int typereg = TMP1, scriptreg = TMP1, typeoffset;  int typereg = TMP1, scriptreg = TMP1;
2803    unsigned int typeoffset;
2804  #endif  #endif
2805  int charoffset, invertcmp, numberofcmps;  int invertcmp, numberofcmps;
2806    unsigned int charoffset;
2807    
2808  /* 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. */
2809  check_input_end(common, fallbacks);  fallback_at_str_end(common, fallbacks);
2810  read_char(common);  read_char(common);
2811    
2812  if ((*cc++ & XCL_MAP) != 0)  if ((*cc++ & XCL_MAP) != 0)
2813    {    {
2814    OP1(SLJIT_MOV, TMP3, 0, TMP1, 0);    OP1(SLJIT_MOV, TMP3, 0, TMP1, 0);
2815    if (common->utf8)  #ifndef COMPILE_PCRE8
2816      jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);
2817    #elif defined SUPPORT_UTF
2818      if (common->utf)
2819      jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);      jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);
2820    #endif
2821    
2822    OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);    OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);
2823    OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);    OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);
# Line 2469  if ((*cc++ & XCL_MAP) != 0) Line 2826  if ((*cc++ & XCL_MAP) != 0)
2826    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);
2827    add_jump(compiler, list, JUMP(SLJIT_C_NOT_ZERO));    add_jump(compiler, list, JUMP(SLJIT_C_NOT_ZERO));
2828    
2829    if (common->utf8)  #ifndef COMPILE_PCRE8
2830      JUMPHERE(jump);
2831    #elif defined SUPPORT_UTF
2832      if (common->utf)
2833      JUMPHERE(jump);      JUMPHERE(jump);
2834    #endif
2835    OP1(SLJIT_MOV, TMP1, 0, TMP3, 0);    OP1(SLJIT_MOV, TMP1, 0, TMP3, 0);
2836  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
2837    charsaved = TRUE;    charsaved = TRUE;
2838  #endif  #endif
2839    cc += 32;    cc += 32 / sizeof(pcre_uchar);
2840    }    }
2841    
2842  /* Scanning the necessary info. */  /* Scanning the necessary info. */
# Line 2487  while (*cc != XCL_END) Line 2848  while (*cc != XCL_END)
2848    if (*cc == XCL_SINGLE)    if (*cc == XCL_SINGLE)
2849      {      {
2850      cc += 2;      cc += 2;
2851  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
2852      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]);
2853  #endif  #endif
2854  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
2855      needschar = TRUE;      needschar = TRUE;
# Line 2497  while (*cc != XCL_END) Line 2858  while (*cc != XCL_END)
2858    else if (*cc == XCL_RANGE)    else if (*cc == XCL_RANGE)
2859      {      {
2860      cc += 2;      cc += 2;
2861  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
2862      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]);
2863  #endif  #endif
2864      cc++;      cc++;
2865  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
2866      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]);
2867  #endif  #endif
2868  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
2869      needschar = TRUE;      needschar = TRUE;
# Line 2572  if (needstype || needsscript) Line 2933  if (needstype || needsscript)
2933      {      {
2934      if (scriptreg == TMP1)      if (scriptreg == TMP1)
2935        {        {
2936        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));
2937        OP1(SLJIT_MOV_UB, scriptreg, 0, SLJIT_MEM2(scriptreg, TMP2), 3);        OP1(SLJIT_MOV_UB, scriptreg, 0, SLJIT_MEM2(scriptreg, TMP2), 3);
2938        }        }
2939      else      else
2940        {        {
2941        OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 3);        OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 3);
2942        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));
2943        OP1(SLJIT_MOV_UB, scriptreg, 0, SLJIT_MEM1(TMP2), 0);        OP1(SLJIT_MOV_UB, scriptreg, 0, SLJIT_MEM1(TMP2), 0);
2944        }        }
2945      }      }
# Line 2602  while (*cc != XCL_END) Line 2963  while (*cc != XCL_END)
2963    if (*cc == XCL_SINGLE)    if (*cc == XCL_SINGLE)
2964      {      {
2965      cc ++;      cc ++;
2966  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
2967      if (common->utf8)      if (common->utf)
2968        {        {
2969        GETCHARINC(c, cc);        GETCHARINC(c, cc);
2970        }        }
# Line 2633  while (*cc != XCL_END) Line 2994  while (*cc != XCL_END)
2994    else if (*cc == XCL_RANGE)    else if (*cc == XCL_RANGE)
2995      {      {
2996      cc ++;      cc ++;
2997  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
2998      if (common->utf8)      if (common->utf)
2999        {        {
3000        GETCHARINC(c, cc);        GETCHARINC(c, cc);
3001        }        }
# Line 2642  while (*cc != XCL_END) Line 3003  while (*cc != XCL_END)
3003  #endif  #endif
3004        c = *cc++;        c = *cc++;
3005      SET_CHAR_OFFSET(c);      SET_CHAR_OFFSET(c);
3006  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3007      if (common->utf8)      if (common->utf)
3008        {        {
3009        GETCHARINC(c, cc);        GETCHARINC(c, cc);
3010        }        }
# Line 2699  while (*cc != XCL_END) Line 3060  while (*cc != XCL_END)
3060        break;        break;
3061    
3062        case PT_GC:        case PT_GC:
3063        c = _pcre_ucp_typerange[(int)cc[1] * 2];        c = PRIV(ucp_typerange)[(int)cc[1] * 2];
3064        SET_TYPE_OFFSET(c);        SET_TYPE_OFFSET(c);
3065        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);
3066        break;        break;
3067    
3068        case PT_PC:        case PT_PC:
# Line 2763  if (found != NULL) Line 3124  if (found != NULL)
3124    
3125  #endif  #endif
3126    
3127  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)
3128  {  {
3129  DEFINE_COMPILER;  DEFINE_COMPILER;
3130  int length;  int length;
3131  unsigned int c, oc, bit;  unsigned int c, oc, bit;
3132  compare_context context;  compare_context context;
3133  struct sljit_jump *jump[4];  struct sljit_jump *jump[4];
3134  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3135  struct sljit_label *label;  struct sljit_label *label;
3136  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
3137  uschar propdata[5];  pcre_uchar propdata[5];
3138  #endif  #endif
3139  #endif  #endif
3140    
# Line 2799  switch(type) Line 3160  switch(type)
3160    
3161    case OP_NOT_DIGIT:    case OP_NOT_DIGIT:
3162    case OP_DIGIT:    case OP_DIGIT:
3163    check_input_end(common, fallbacks);    fallback_at_str_end(common, fallbacks);
3164    read_char8_type(common);    read_char8_type(common);
3165    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);
3166    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 2807  switch(type) Line 3168  switch(type)
3168    
3169    case OP_NOT_WHITESPACE:    case OP_NOT_WHITESPACE:
3170    case OP_WHITESPACE:    case OP_WHITESPACE:
3171    check_input_end(common, fallbacks);    fallback_at_str_end(common, fallbacks);
3172    read_char8_type(common);    read_char8_type(common);
3173    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);
3174    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 2815  switch(type) Line 3176  switch(type)
3176    
3177    case OP_NOT_WORDCHAR:    case OP_NOT_WORDCHAR:
3178    case OP_WORDCHAR:    case OP_WORDCHAR:
3179    check_input_end(common, fallbacks);    fallback_at_str_end(common, fallbacks);
3180    read_char8_type(common);    read_char8_type(common);
3181    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);
3182    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));
3183    return cc;    return cc;
3184    
3185    case OP_ANY:    case OP_ANY:
3186    check_input_end(common, fallbacks);    fallback_at_str_end(common, fallbacks);
3187    read_char(common);    read_char(common);
3188    if (common->nltype == NLTYPE_FIXED && common->newline > 255)    if (common->nltype == NLTYPE_FIXED && common->newline > 255)
3189      {      {
3190      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);
3191      jump[1] = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);      if (common->mode == JIT_COMPILE)
3192      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);        jump[1] = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
3193        else
3194          {
3195          jump[1] = CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0);
3196          /* Since we successfully read a char above, partial matching must occure. */
3197          check_partial(common, TRUE);
3198          add_jump(compiler, fallbacks, JUMP(SLJIT_JUMP));
3199          JUMPHERE(jump[1]);
3200          jump[1] = NULL;
3201          }
3202    
3203        OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
3204      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));
3205      JUMPHERE(jump[1]);      if (jump[1] != NULL)
3206          JUMPHERE(jump[1]);
3207      JUMPHERE(jump[0]);      JUMPHERE(jump[0]);
3208      }      }
3209    else    else
# Line 2838  switch(type) Line 3211  switch(type)
3211    return cc;    return cc;
3212    
3213    case OP_ALLANY:    case OP_ALLANY:
3214    check_input_end(common, fallbacks);    fallback_at_str_end(common, fallbacks);
3215  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3216    if (common->utf8)    if (common->utf)
3217      {      {
3218      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
3219      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));
3220    #ifdef COMPILE_PCRE8
3221        jump[0] = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);
3222        OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)PRIV(utf8_table4) - 0xc0);
3223        OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
3224    #else /* COMPILE_PCRE8 */
3225    #ifdef COMPILE_PCRE16
3226        jump[0] = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800);
3227        OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);
3228        OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xd800);
3229        COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);
3230        OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
3231      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
3232    #endif /* COMPILE_PCRE16 */
3233    #endif /* COMPILE_PCRE8 */
3234        JUMPHERE(jump[0]);
3235      return cc;      return cc;
3236      }      }
3237  #endif  #endif
3238    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));
3239      return cc;
3240    
3241      case OP_ANYBYTE:
3242      fallback_at_str_end(common, fallbacks);
3243      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
3244    return cc;    return cc;
3245    
3246  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3247  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
3248    case OP_NOTPROP:    case OP_NOTPROP:
3249    case OP_PROP:    case OP_PROP:
# Line 2866  switch(type) Line 3258  switch(type)
3258  #endif  #endif
3259    
3260    case OP_ANYNL:    case OP_ANYNL:
3261    check_input_end(common, fallbacks);    fallback_at_str_end(common, fallbacks);
3262    read_char(common);    read_char(common);
3263    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);
3264    jump[1] = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);    /* We don't need to handle soft partial matching case. */
3265    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);    if (common->mode != JIT_PARTIAL_HARD_COMPILE)
3266        jump[1] = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
3267      else
3268        jump[1] = check_str_end(common);
3269      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
3270    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);
3271    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));
3272    jump[3] = JUMP(SLJIT_JUMP);    jump[3] = JUMP(SLJIT_JUMP);
3273    JUMPHERE(jump[0]);    JUMPHERE(jump[0]);
3274    check_newlinechar(common, common->bsr_nltype, fallbacks, FALSE);    check_newlinechar(common, common->bsr_nltype, fallbacks, FALSE);
# Line 2883  switch(type) Line 3279  switch(type)
3279    
3280    case OP_NOT_HSPACE:    case OP_NOT_HSPACE:
3281    case OP_HSPACE:    case OP_HSPACE:
3282    check_input_end(common, fallbacks);    fallback_at_str_end(common, fallbacks);
3283    read_char(common);    read_char(common);
3284    add_jump(compiler, &common->hspace, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->hspace, JUMP(SLJIT_FAST_CALL));
3285    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 2891  switch(type) Line 3287  switch(type)
3287    
3288    case OP_NOT_VSPACE:    case OP_NOT_VSPACE:
3289    case OP_VSPACE:    case OP_VSPACE:
3290    check_input_end(common, fallbacks);    fallback_at_str_end(common, fallbacks);
3291    read_char(common);    read_char(common);
3292    add_jump(compiler, &common->vspace, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->vspace, JUMP(SLJIT_FAST_CALL));
3293    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 2899  switch(type) Line 3295  switch(type)
3295    
3296  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
3297    case OP_EXTUNI:    case OP_EXTUNI:
3298    check_input_end(common, fallbacks);    fallback_at_str_end(common, fallbacks);
3299    read_char(common);    read_char(common);
3300    add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL));
3301    OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Mc);    OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Mc);
# Line 2915  switch(type) Line 3311  switch(type)
3311    
3312    OP1(SLJIT_MOV, STR_PTR, 0, TMP3, 0);    OP1(SLJIT_MOV, STR_PTR, 0, TMP3, 0);
3313    JUMPHERE(jump[0]);    JUMPHERE(jump[0]);
3314      if (common->mode == JIT_PARTIAL_HARD_COMPILE)
3315        {
3316        jump[0] = CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0);
3317        /* Since we successfully read a char above, partial matching must occure. */
3318        check_partial(common, TRUE);
3319        JUMPHERE(jump[0]);
3320        }
3321    return cc;    return cc;
3322  #endif  #endif
3323    
3324    case OP_EODN:    case OP_EODN:
3325      /* Requires rather complex checks. */
3326    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);
3327    if (common->nltype == NLTYPE_FIXED && common->newline > 255)    if (common->nltype == NLTYPE_FIXED && common->newline > 255)
3328      {      {
3329      OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, 2);      OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2));
3330      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
3331      add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, STR_END, 0));      if (common->mode == JIT_COMPILE)
3332      OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), 1);        add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, STR_END, 0));
3333        else
3334          {
3335          jump[1] = CMP(SLJIT_C_EQUAL, TMP2, 0, STR_END, 0);
3336          OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP2, 0, STR_END, 0);
3337          COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS);
3338          OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff);
3339          COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_NOT_EQUAL);
3340          add_jump(compiler, fallbacks, JUMP(SLJIT_C_NOT_EQUAL));
3341          check_partial(common, TRUE);
3342          add_jump(compiler, fallbacks, JUMP(SLJIT_JUMP));
3343          JUMPHERE(jump[1]);
3344          }
3345        OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
3346      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));
3347      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));
3348      }      }
3349    else if (common->nltype == NLTYPE_FIXED)    else if (common->nltype == NLTYPE_FIXED)
3350      {      {
3351      OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, 1);      OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
3352      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
3353      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));
3354      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));
3355      }      }
3356    else    else
3357      {      {
3358      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
3359      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);
3360      OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, 2);      OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2));
3361      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);
3362      jump[2] = JUMP(SLJIT_C_GREATER);      jump[2] = JUMP(SLJIT_C_GREATER);
3363      add_jump(compiler, fallbacks, JUMP(SLJIT_C_LESS));      add_jump(compiler, fallbacks, JUMP(SLJIT_C_LESS));
3364      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 1);      /* Equal. */
3365        OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
3366      jump[3] = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_NL);      jump[3] = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_NL);
3367      add_jump(compiler, fallbacks, JUMP(SLJIT_JUMP));      add_jump(compiler, fallbacks, JUMP(SLJIT_JUMP));
3368    
3369      JUMPHERE(jump[1]);      JUMPHERE(jump[1]);
3370      if (common->nltype == NLTYPE_ANYCRLF)      if (common->nltype == NLTYPE_ANYCRLF)
3371        {        {
3372        OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, 1);        OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
3373        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));
3374        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));
3375        }        }
# Line 2968  switch(type) Line 3386  switch(type)
3386      JUMPHERE(jump[3]);      JUMPHERE(jump[3]);
3387      }      }
3388    JUMPHERE(jump[0]);    JUMPHERE(jump[0]);
3389      check_partial(common, FALSE);
3390    return cc;    return cc;
3391    
3392    case OP_EOD:    case OP_EOD:
3393    add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, STR_PTR, 0, STR_END, 0));    add_jump(compiler, fallbacks, CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0));
3394      check_partial(common, FALSE);
3395    return cc;    return cc;
3396    
3397    case OP_CIRC:    case OP_CIRC:
# Line 2991  switch(type) Line 3411  switch(type)
3411    jump[0] = JUMP(SLJIT_JUMP);    jump[0] = JUMP(SLJIT_JUMP);
3412    JUMPHERE(jump[1]);    JUMPHERE(jump[1]);
3413    
3414    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));  
   
3415    if (common->nltype == NLTYPE_FIXED && common->newline > 255)    if (common->nltype == NLTYPE_FIXED && common->newline > 255)
3416      {      {
3417      OP2(SLJIT_SUB, TMP2, 0, STR_PTR, 0, SLJIT_IMM, 2);      OP2(SLJIT_SUB, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2));
3418      add_jump(compiler, fallbacks, CMP(SLJIT_C_LESS, TMP2, 0, TMP1, 0));      add_jump(compiler, fallbacks, CMP(SLJIT_C_LESS, TMP2, 0, TMP1, 0));
3419      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), -2);      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-2));
3420      OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), -1);      OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-1));
3421      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));
3422      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));
3423      }      }
# Line 3020  switch(type) Line 3438  switch(type)
3438    if (!common->endonly)    if (!common->endonly)
3439      compile_char1_hotpath(common, OP_EODN, cc, fallbacks);      compile_char1_hotpath(common, OP_EODN, cc, fallbacks);
3440    else    else
3441        {
3442      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));
3443        check_partial(common, FALSE);
3444        }
3445    return cc;    return cc;
3446    
3447    case OP_DOLLM:    case OP_DOLLM:
# Line 3028  switch(type) Line 3449  switch(type)
3449    OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0);    OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0);
3450    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));
3451    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));
3452      check_partial(common, FALSE);
3453    jump[0] = JUMP(SLJIT_JUMP);    jump[0] = JUMP(SLJIT_JUMP);
3454    JUMPHERE(jump[1]);    JUMPHERE(jump[1]);
3455    
3456    if (common->nltype == NLTYPE_FIXED && common->newline > 255)    if (common->nltype == NLTYPE_FIXED && common->newline > 255)
3457      {      {
3458      OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, 2);      OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2));
3459      add_jump(compiler, fallbacks, CMP(SLJIT_C_GREATER, TMP2, 0, STR_END, 0));      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
3460      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);      if (common->mode == JIT_COMPILE)
3461      OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), 1);        add_jump(compiler, fallbacks, CMP(SLJIT_C_GREATER, TMP2, 0, STR_END, 0));
3462        else
3463          {
3464          jump[1] = CMP(SLJIT_C_LESS_EQUAL, TMP2, 0, STR_END, 0);
3465          /* STR_PTR = STR_END - IN_UCHARS(1) */
3466          add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff));
3467          check_partial(common, TRUE);
3468          add_jump(compiler, fallbacks, JUMP(SLJIT_JUMP));
3469          JUMPHERE(jump[1]);
3470          }
3471    
3472        OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
3473      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));
3474      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));
3475      }      }
# Line 3051  switch(type) Line 3484  switch(type)
3484    case OP_CHAR:    case OP_CHAR:
3485    case OP_CHARI:    case OP_CHARI:
3486    length = 1;    length = 1;
3487  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3488    if (common->utf8 && *cc >= 0xc0) length += _pcre_utf8_table4[*cc & 0x3f];    if (common->utf && HAS_EXTRALEN(*cc)) length += GET_EXTRALEN(*cc);
3489  #endif  #endif
3490    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))
3491      {      {
3492      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));
3493      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));
3494    
3495      context.length = length;      context.length = IN_UCHARS(length);
3496      context.sourcereg = -1;      context.sourcereg = -1;
3497  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
3498      context.byteptr = 0;      context.ucharptr = 0;
3499  #endif  #endif
3500      return byte_sequence_compare(common, type == OP_CHARI, cc, &context, fallbacks);      return byte_sequence_compare(common, type == OP_CHARI, cc, &context, fallbacks);
3501      }      }
3502    add_jump(compiler, fallbacks, CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0));    fallback_at_str_end(common, fallbacks);
3503    read_char(common);    read_char(common);
3504  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3505    if (common->utf8)    if (common->utf)
3506      {      {
3507      GETCHAR(c, cc);      GETCHAR(c, cc);
3508      }      }
3509    else    else
3510  #endif  #endif
3511      c = *cc;      c = *cc;
3512      if (type == OP_CHAR || !char_has_othercase(common, cc))
3513        {
3514        add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, c));
3515        return cc + length;
3516        }
3517      oc = char_othercase(common, c);
3518      bit = c ^ oc;
3519      if (ispowerof2(bit))
3520        {
3521        OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, bit);
3522        add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, c | bit));
3523        return cc + length;
3524        }
3525    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);
3526    COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);    COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);
3527    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 3085  switch(type) Line 3531  switch(type)
3531    
3532    case OP_NOT:    case OP_NOT:
3533    case OP_NOTI:    case OP_NOTI:
3534      fallback_at_str_end(common, fallbacks);
3535    length = 1;    length = 1;
3536  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3537    if (common->utf8)    if (common->utf)
3538      {      {
3539      if (*cc >= 0xc0) length += _pcre_utf8_table4[*cc & 0x3f];  #ifdef COMPILE_PCRE8
3540        c = *cc;
3541      check_input_end(common, fallbacks);      if (c < 128)
     GETCHAR(c, cc);  
   
     if (c <= 127)  
3542        {        {
3543        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);  
3544        if (type == OP_NOT || !char_has_othercase(common, cc))        if (type == OP_NOT || !char_has_othercase(common, cc))
3545          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));
3546        else        else
3547          {          {
3548          /* 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. */
3549          OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x20);          OP2(SLJIT_OR, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x20);
3550          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));
3551          }          }
3552        /* Skip the variable-length character. */        /* Skip the variable-length character. */
3553        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));
3554        return cc + length;        jump[0] = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);
3555          OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)PRIV(utf8_table4) - 0xc0);
3556          OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
3557          JUMPHERE(jump[0]);
3558          return cc + 1;
3559        }        }
3560      else      else
3561    #endif /* COMPILE_PCRE8 */
3562          {
3563          GETCHARLEN(c, cc, length);
3564        read_char(common);        read_char(common);
3565          }
3566      }      }
3567    else    else
3568  #endif  #endif /* SUPPORT_UTF */
3569      {      {
3570      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);  
3571      c = *cc;      c = *cc;
3572      }      }
3573    
# Line 3139  switch(type) Line 3588  switch(type)
3588        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));
3589        }        }
3590      }      }
3591    return cc + length;    return cc + 1;
3592    
3593    case OP_CLASS:    case OP_CLASS:
3594    case OP_NCLASS:    case OP_NCLASS:
3595    check_input_end(common, fallbacks);    fallback_at_str_end(common, fallbacks);
3596    read_char(common);    read_char(common);
3597  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
3598    jump[0] = NULL;    jump[0] = NULL;
3599    if (common->utf8)  #ifdef COMPILE_PCRE8
3600      /* This check only affects 8 bit mode. In other modes, we
3601      always need to compare the value with 255. */
3602      if (common->utf)
3603    #endif /* COMPILE_PCRE8 */
3604      {      {
3605      jump[0] = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);      jump[0] = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);
3606      if (type == OP_CLASS)      if (type == OP_CLASS)
# Line 3156  switch(type) Line 3609  switch(type)
3609        jump[0] = NULL;        jump[0] = NULL;
3610        }        }
3611      }      }
3612  #endif  #endif /* SUPPORT_UTF || !COMPILE_PCRE8 */
3613    OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);    OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);
3614    OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);    OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);
3615    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)cc);    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)cc);
3616    OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0);    OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0);
3617    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);
3618    add_jump(compiler, fallbacks, JUMP(SLJIT_C_ZERO));    add_jump(compiler, fallbacks, JUMP(SLJIT_C_ZERO));
3619  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
3620    if (jump[0] != NULL)    if (jump[0] != NULL)
3621      JUMPHERE(jump[0]);      JUMPHERE(jump[0]);
3622  #endif  #endif /* SUPPORT_UTF || !COMPILE_PCRE8 */
3623    return cc + 32;    return cc + 32 / sizeof(pcre_uchar);
3624    
3625  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF || defined COMPILE_PCRE16
3626    case OP_XCLASS:    case OP_XCLASS:
3627    compile_xclass_hotpath(common, cc + LINK_SIZE, fallbacks);    compile_xclass_hotpath(common, cc + LINK_SIZE, fallbacks);
3628    return cc + GET(cc, 0) - 1;    return cc + GET(cc, 0) - 1;
# Line 3179  switch(type) Line 3632  switch(type)
3632    length = GET(cc, 0);    length = GET(cc, 0);
3633    SLJIT_ASSERT(length > 0);    SLJIT_ASSERT(length > 0);
3634    OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);    OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
3635    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin));  #ifdef SUPPORT_UTF
3636  #ifdef SUPPORT_UTF8    if (common->utf)
   if (common->utf8)  
3637      {      {
3638        OP1(SLJIT_MOV, TMP3, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin));
3639      OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, length);      OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, length);
3640      label = LABEL();      label = LABEL();
3641      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));
3642      skip_char_back(common);      skip_char_back(common);
3643      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);
3644      JUMPTO(SLJIT_C_NOT_ZERO, label);      JUMPTO(SLJIT_C_NOT_ZERO, label);
     return cc + LINK_SIZE;  
3645      }      }
3646      else
3647  #endif  #endif
3648    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, length);      {
3649    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));
3650        OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(length));
3651        add_jump(compiler, fallbacks, CMP(SLJIT_C_LESS, STR_PTR, 0, TMP1, 0));
3652        }
3653      check_start_used_ptr(common);
3654    return cc + LINK_SIZE;    return cc + LINK_SIZE;
3655    }    }
3656  SLJIT_ASSERT_STOP();  SLJIT_ASSERT_STOP();
3657  return cc;  return cc;
3658  }  }
3659    
3660  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)
3661  {  {
3662  /* This function consumes at least one input character. */  /* This function consumes at least one input character. */
3663  /* 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. */
3664  DEFINE_COMPILER;  DEFINE_COMPILER;
3665  uschar *ccbegin = cc;  pcre_uchar *ccbegin = cc;
3666  compare_context context;  compare_context context;
3667  int size;  int size;
3668    
# Line 3218  do Line 3675  do
3675    if (*cc == OP_CHAR)    if (*cc == OP_CHAR)
3676      {      {
3677      size = 1;      size = 1;
3678  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3679      if (common->utf8 && cc[1] >= 0xc0)      if (common->utf && HAS_EXTRALEN(cc[1]))
3680        size += _pcre_utf8_table4[cc[1] & 0x3f];        size += GET_EXTRALEN(cc[1]);
3681  #endif  #endif
3682      }      }
3683    else if (*cc == OP_CHARI)    else if (*cc == OP_CHARI)
3684      {      {
3685      size = 1;      size = 1;
3686  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3687      if (common->utf8)      if (common->utf)
3688        {        {
3689        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)
3690          size = 0;          size = 0;
3691        else if (cc[1] >= 0xc0)        else if (HAS_EXTRALEN(cc[1]))
3692          size += _pcre_utf8_table4[cc[1] & 0x3f];          size += GET_EXTRALEN(cc[1]);
3693        }        }
3694      else      else
3695  #endif  #endif
# Line 3243  do Line 3700  do
3700      size = 0;      size = 0;
3701    
3702    cc += 1 + size;    cc += 1 + size;
3703    context.length += size;    context.length += IN_UCHARS(size);
3704    }    }
3705  while (size > 0 && context.length <= 128);  while (size > 0 && context.length <= 128);
3706    
# Line 3256  if (context.length > 0) Line 3713  if (context.length > 0)
3713    
3714    context.sourcereg = -1;    context.sourcereg = -1;
3715  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
3716    context.byteptr = 0;    context.ucharptr = 0;
3717  #endif  #endif
3718    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);
3719    return cc;    return cc;
# Line 3266  if (context.length > 0) Line 3723  if (context.length > 0)
3723  return compile_char1_hotpath(common, *cc, cc + 1, fallbacks);  return compile_char1_hotpath(common, *cc, cc + 1, fallbacks);
3724  }  }
3725    
3726  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)
3727  {  {
3728  DEFINE_COMPILER;  DEFINE_COMPILER;
3729  int offset = GET2(cc, 1) << 1;  int offset = GET2(cc, 1) << 1;
# Line 3276  if (!common->jscript_compat) Line 3733  if (!common->jscript_compat)
3733    {    {
3734    if (fallbacks == NULL)    if (fallbacks == NULL)
3735      {      {
3736        /* OVECTOR(1) contains the "string begin - 1" constant. */
3737      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));
3738      COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);      COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);
3739      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 3288  return CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT Line 3746  return CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT
3746  }  }
3747    
3748  /* Forward definitions. */  /* Forward definitions. */
3749  static void compile_hotpath(compiler_common *, uschar *, uschar *, fallback_common *);  static void compile_hotpath(compiler_common *, pcre_uchar *, pcre_uchar *, fallback_common *);
3750  static void compile_fallbackpath(compiler_common *, struct fallback_common *);  static void compile_fallbackpath(compiler_common *, struct fallback_common *);
3751    
3752  #define PUSH_FALLBACK(size, ccstart, error) \  #define PUSH_FALLBACK(size, ccstart, error) \
# Line 3317  static void compile_fallbackpath(compile Line 3775  static void compile_fallbackpath(compile
3775      } \      } \
3776    while (0)    while (0)
3777    
3778  #define FALLBACK_AS(type) ((type*)fallback)  #define FALLBACK_AS(type) ((type *)fallback)
3779    
3780  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)
3781  {  {
3782  DEFINE_COMPILER;  DEFINE_COMPILER;
3783  int offset = GET2(cc, 1) << 1;  int offset = GET2(cc, 1) << 1;
3784  struct sljit_jump *jump = NULL;  struct sljit_jump *jump = NULL;
3785    struct sljit_jump *partial;
3786    struct sljit_jump *nopartial;
3787    
3788  OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));  OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));
3789    /* OVECTOR(1) contains the "string begin - 1" constant. */
3790  if (withchecks && !common->jscript_compat)  if (withchecks && !common->jscript_compat)
3791    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)));
3792    
3793  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF && defined SUPPORT_UCP
3794  #ifdef SUPPORT_UCP  if (common->utf && *cc == OP_REFI)
 if (common->utf8 && *cc == OP_REFI)  
3795    {    {
3796    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);
3797    OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1));    OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1));
# Line 3342  if (common->utf8 && *cc == OP_REFI) Line 3802  if (common->utf8 && *cc == OP_REFI)
3802    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, STACK_TOP, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, STACK_TOP, 0);
3803    OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, ARGUMENTS, 0);    OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, ARGUMENTS, 0);
3804    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);
3805    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));
3806    OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);    OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);
3807    add_jump(compiler, fallbacks, CMP(SLJIT_C_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 0));    if (common->mode == JIT_COMPILE)
3808        add_jump(compiler, fallbacks, CMP(SLJIT_C_LESS_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 1));
3809      else
3810        {
3811        add_jump(compiler, fallbacks, CMP(SLJIT_C_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 0));
3812        nopartial = CMP(SLJIT_C_NOT_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 1);
3813        check_partial(common, FALSE);
3814        add_jump(compiler, fallbacks, JUMP(SLJIT_JUMP));
3815        JUMPHERE(nopartial);
3816        }
3817    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_RETURN_REG, 0);    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_RETURN_REG, 0);
3818    }    }
3819  else  else
3820  #endif  #endif /* SUPPORT_UTF && SUPPORT_UCP */
 #endif  
3821    {    {
3822    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);
3823    if (withchecks)    if (withchecks)
3824      jump = JUMP(SLJIT_C_ZERO);      jump = JUMP(SLJIT_C_ZERO);
3825    
3826    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
3827      partial = CMP(SLJIT_C_GREATER, STR_PTR, 0, STR_END, 0);
3828      if (common->mode == JIT_COMPILE)
3829        add_jump(compiler, fallbacks, partial);
3830    
   add_jump(compiler, fallbacks, CMP(SLJIT_C_GREATER, STR_PTR, 0, STR_END, 0));  
3831    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));
3832    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));
3833    
3834      if (common->mode != JIT_COMPILE)
3835        {
3836        nopartial = JUMP(SLJIT_JUMP);
3837        JUMPHERE(partial);
3838        /* TMP2 -= STR_END - STR_PTR */
3839        OP2(SLJIT_SUB, TMP2, 0, TMP2, 0, STR_PTR, 0);
3840        OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, STR_END, 0);
3841        partial = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, 0);
3842        OP1(SLJIT_MOV, STR_PTR, 0, STR_END, 0);
3843        add_jump(compiler, *cc == OP_REF ? &common->casefulcmp : &common->caselesscmp, JUMP(SLJIT_FAST_CALL));
3844        add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0));
3845        JUMPHERE(partial);
3846        check_partial(common, FALSE);
3847        add_jump(compiler, fallbacks, JUMP(SLJIT_JUMP));
3848        JUMPHERE(nopartial);
3849        }
3850    }    }
3851    
3852  if (jump != NULL)  if (jump != NULL)
# Line 3368  if (jump != NULL) Line 3856  if (jump != NULL)
3856    else    else
3857      JUMPHERE(jump);      JUMPHERE(jump);
3858    }    }
3859  return cc + 3;  return cc + 1 + IMM2_SIZE;
3860  }  }
3861    
3862  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)
3863  {  {
3864  DEFINE_COMPILER;  DEFINE_COMPILER;
3865  fallback_common *fallback;  fallback_common *fallback;
3866  uschar type;  pcre_uchar type;
3867  struct sljit_label *label;  struct sljit_label *label;
3868  struct sljit_jump *zerolength;  struct sljit_jump *zerolength;
3869  struct sljit_jump *jump = NULL;  struct sljit_jump *jump = NULL;
3870  uschar *ccbegin = cc;  pcre_uchar *ccbegin = cc;
3871  int min = 0, max = 0;  int min = 0, max = 0;
3872  BOOL minimize;  BOOL minimize;
3873    
3874  PUSH_FALLBACK(sizeof(iterator_fallback), cc, NULL);  PUSH_FALLBACK(sizeof(iterator_fallback), cc, NULL);
3875    
3876  type = cc[3];  type = cc[1 + IMM2_SIZE];
3877  minimize = (type & 0x1) != 0;  minimize = (type & 0x1) != 0;
3878  switch(type)  switch(type)
3879    {    {
# Line 3393  switch(type) Line 3881  switch(type)
3881    case OP_CRMINSTAR:    case OP_CRMINSTAR:
3882    min = 0;    min = 0;
3883    max = 0;    max = 0;
3884    cc += 4;    cc += 1 + IMM2_SIZE + 1;
3885    break;    break;
3886    case OP_CRPLUS:    case OP_CRPLUS:
3887    case OP_CRMINPLUS:    case OP_CRMINPLUS:
3888    min = 1;    min = 1;
3889    max = 0;    max = 0;
3890    cc += 4;    cc += 1 + IMM2_SIZE + 1;
3891    break;    break;
3892    case OP_CRQUERY:    case OP_CRQUERY:
3893    case OP_CRMINQUERY:    case OP_CRMINQUERY:
3894    min = 0;    min = 0;
3895    max = 1;    max = 1;
3896    cc += 4;    cc += 1 + IMM2_SIZE + 1;
3897    break;    break;
3898    case OP_CRRANGE:    case OP_CRRANGE:
3899    case OP_CRMINRANGE:    case OP_CRMINRANGE:
3900    min = GET2(cc, 3 + 1);    min = GET2(cc, 1 + IMM2_SIZE + 1);
3901    max = GET2(cc, 3 + 3);    max = GET2(cc, 1 + IMM2_SIZE + 1 + IMM2_SIZE);
3902    cc += 8;    cc += 1 + IMM2_SIZE + 1 + 2 * IMM2_SIZE;
3903    break;    break;
3904    default:    default:
3905    SLJIT_ASSERT_STOP();    SLJIT_ASSERT_STOP();
# Line 3515  decrease_call_count(common); Line 4003  decrease_call_count(common);
4003  return cc;  return cc;
4004  }  }
4005    
4006  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)
4007  {  {
4008  DEFINE_COMPILER;  DEFINE_COMPILER;
4009  fallback_common *fallback;  fallback_common *fallback;
# Line 3561  add_jump(compiler, &fallback->topfallbac Line 4049  add_jump(compiler, &fallback->topfallbac
4049  return cc + 1 + LINK_SIZE;  return cc + 1 + LINK_SIZE;
4050  }  }
4051    
4052  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)
4053  {  {
4054  DEFINE_COMPILER;  DEFINE_COMPILER;
4055  int framesize;  int framesize;
4056  int localptr;  int localptr;
4057  fallback_common altfallback;  fallback_common altfallback;
4058  uschar *ccbegin;  pcre_uchar *ccbegin;
4059  uschar opcode;  pcre_uchar opcode;
4060  uschar bra = OP_BRA;  pcre_uchar bra = OP_BRA;
4061  jump_list *tmp = NULL;  jump_list *tmp = NULL;
4062  jump_list **target = (conditional) ? &fallback->condfailed : &fallback->common.topfallbacks;  jump_list **target = (conditional) ? &fallback->condfailed : &fallback->common.topfallbacks;
4063  jump_list **found;  jump_list **found;
# Line 3585  if (*cc == OP_BRAZERO || *cc == OP_BRAMI Line 4073  if (*cc == OP_BRAZERO || *cc == OP_BRAMI
4073    bra = *cc;    bra = *cc;
4074    cc++;    cc++;
4075    }    }
4076  localptr = PRIV(cc);  localptr = PRIV_DATA(cc);
4077  SLJIT_ASSERT(localptr != 0);  SLJIT_ASSERT(localptr != 0);
4078  framesize = get_framesize(common, cc, FALSE);  framesize = get_framesize(common, cc, FALSE);
4079  fallback->framesize = framesize;  fallback->framesize = framesize;
# Line 3644  while (1) Line 4132  while (1)
4132    if (common->accept != NULL)    if (common->accept != NULL)
4133      set_jumps(common->accept, common->acceptlabel);      set_jumps(common->accept, common->acceptlabel);
4134    
4135      /* Reset stack. */
4136    if (framesize < 0)    if (framesize < 0)
4137      OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);      OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
4138      else {
4139        if ((opcode != OP_ASSERT_NOT && opcode != OP_ASSERTBACK_NOT) || conditional)
4140          {
4141          /* We don't need to keep the STR_PTR, only the previous localptr. */
4142          OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_IMM, (framesize + 1) * sizeof(sljit_w));
4143          }
4144        else
4145          {
4146          OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
4147          add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
4148          }
4149      }
4150    
4151    if (opcode == OP_ASSERT_NOT || opcode == OP_ASSERTBACK_NOT)    if (opcode == OP_ASSERT_NOT || opcode == OP_ASSERTBACK_NOT)
4152      {      {
4153      /* 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. */
4154      if (conditional)      if (conditional)
4155        {        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));  
         }  
       }  
4156      else if (bra == OP_BRAZERO)      else if (bra == OP_BRAZERO)
4157        {        {
4158        if (framesize < 0)        if (framesize < 0)
4159          OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), 0);          OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), 0);
4160        else        else
4161          {          {
         OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);  
         add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));  
4162          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));
4163          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));
4164          OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP1, 0);          OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP1, 0);
# Line 3675  while (1) Line 4166  while (1)
4166        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));
4167        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
4168        }        }
4169      else if (bra == OP_BRAMINZERO)      else if (framesize >= 0)
4170        {        {
4171        if (framesize >= 0)        /* For OP_BRA and OP_BRAMINZERO. */
4172          {        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));  
         }  
4173        }        }
4174      }      }
4175    add_jump(compiler, found, JUMP(SLJIT_JUMP));    add_jump(compiler, found, JUMP(SLJIT_JUMP));
# Line 3709  if (opcode == OP_ASSERT || opcode == OP_ Line 4196  if (opcode == OP_ASSERT || opcode == OP_
4196    /* Assert is failed. */    /* Assert is failed. */
4197    if (conditional || bra == OP_BRAZERO)    if (conditional || bra == OP_BRAZERO)
4198      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
4199    
4200    if (framesize < 0)    if (framesize < 0)
4201      {      {
4202      /* The topmost item should be 0. */      /* The topmost item should be 0. */
# Line 3720  if (opcode == OP_ASSERT || opcode == OP_ Line 4208  if (opcode == OP_ASSERT || opcode == OP_
4208    else    else
4209      {      {
4210      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));  
4211      /* The topmost item should be 0. */      /* The topmost item should be 0. */
4212      if (bra == OP_BRAZERO)      if (bra == OP_BRAZERO)
4213        {        {
# Line 3731  if (opcode == OP_ASSERT || opcode == OP_ Line 4217  if (opcode == OP_ASSERT || opcode == OP_
4217      else      else
4218        free_stack(common, framesize + 2);        free_stack(common, framesize + 2);
4219      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);  
4220      }      }
4221    jump = JUMP(SLJIT_JUMP);    jump = JUMP(SLJIT_JUMP);
4222    if (bra != OP_BRAZERO)    if (bra != OP_BRAZERO)
# Line 3755  if (opcode == OP_ASSERT || opcode == OP_ Line 4239  if (opcode == OP_ASSERT || opcode == OP_
4239      }      }
4240    else    else
4241      {      {
4242      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)  
4243        {        {
4244        allocate_stack(common, 1);        /* We don't need to keep the STR_PTR, only the previous localptr. */
4245        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));
4246          OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), 0);
4247        }        }
4248      else if (bra == OP_BRAMINZERO)      else
4249        {        {
4250        allocate_stack(common, 1);        /* We don't need to keep the STR_PTR, only the previous localptr. */
4251        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));
4252          OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
4253          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), bra == OP_BRAZERO ? STR_PTR : SLJIT_IMM, 0);
4254        }        }
4255      }      }
4256    
# Line 3802  else Line 4287  else
4287      {      {
4288      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
4289      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));  
4290      /* The topmost item should be 0. */      /* The topmost item should be 0. */
4291      if (bra != OP_BRA)      if (bra != OP_BRA)
4292        {        {
# Line 3813  else Line 4296  else
4296      else      else
4297        free_stack(common, framesize + 2);        free_stack(common, framesize + 2);
4298      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);  
4299      }      }
4300    
4301    if (bra == OP_BRAZERO)    if (bra == OP_BRAZERO)
# Line 3838  common->accept = save_accept; Line 4319  common->accept = save_accept;
4319  return cc + 1 + LINK_SIZE;  return cc + 1 + LINK_SIZE;
4320  }  }
4321    
4322    static sljit_w SLJIT_CALL do_searchovector(sljit_w refno, sljit_w* locals, pcre_uchar *name_table)
4323    {
4324    int condition = FALSE;
4325    pcre_uchar *slotA = name_table;
4326    pcre_uchar *slotB;
4327    sljit_w name_count = locals[LOCALS0 / sizeof(sljit_w)];
4328    sljit_w name_entry_size = locals[LOCALS1 / sizeof(sljit_w)];
4329    sljit_w no_capture;
4330    int i;
4331    
4332    locals += OVECTOR_START / sizeof(sljit_w);
4333    no_capture = locals[1];
4334    
4335    for (i = 0; i < name_count; i++)
4336      {
4337      if (GET2(slotA, 0) == refno) break;
4338      slotA += name_entry_size;
4339      }
4340    
4341    if (i < name_count)
4342      {
4343      /* Found a name for the number - there can be only one; duplicate names
4344      for different numbers are allowed, but not vice versa. First scan down
4345      for duplicates. */
4346    
4347      slotB = slotA;
4348      while (slotB > name_table)
4349        {
4350        slotB -= name_entry_size;
4351        if (STRCMP_UC_UC(slotA + IMM2_SIZE, slotB + IMM2_SIZE) == 0)
4352          {
4353          condition = locals[GET2(slotB, 0) << 1] != no_capture;
4354          if (condition) break;
4355          }
4356        else break;
4357        }
4358    
4359      /* Scan up for duplicates */
4360      if (!condition)
4361        {
4362        slotB = slotA;
4363        for (i++; i < name_count; i++)
4364          {
4365          slotB += name_entry_size;
4366          if (STRCMP_UC_UC(slotA + IMM2_SIZE, slotB + IMM2_SIZE) == 0)
4367            {
4368            condition = locals[GET2(slotB, 0) << 1] != no_capture;
4369            if (condition) break;
4370            }
4371          else break;
4372          }
4373        }
4374      }
4375    return condition;
4376    }
4377    
4378    static sljit_w SLJIT_CALL do_searchgroups(sljit_w recno, sljit_w* locals, pcre_uchar *name_table)
4379    {
4380    int condition = FALSE;
4381    pcre_uchar *slotA = name_table;
4382    pcre_uchar *slotB;
4383    sljit_w name_count = locals[LOCALS0 / sizeof(sljit_w)];
4384    sljit_w name_entry_size = locals[LOCALS1 / sizeof(sljit_w)];
4385    sljit_w group_num = locals[POSSESSIVE0 / sizeof(sljit_w)];
4386    int i;
4387    
4388    for (i = 0; i < name_count; i++)
4389      {
4390      if (GET2(slotA, 0) == recno) break;
4391      slotA += name_entry_size;
4392      }
4393    
4394    if (i < name_count)
4395      {
4396      /* Found a name for the number - there can be only one; duplicate
4397      names for different numbers are allowed, but not vice versa. First
4398      scan down for duplicates. */
4399    
4400      slotB = slotA;
4401      while (slotB > name_table)
4402        {
4403        slotB -= name_entry_size;
4404        if (STRCMP_UC_UC(slotA + IMM2_SIZE, slotB + IMM2_SIZE) == 0)
4405          {
4406          condition = GET2(slotB, 0) == group_num;
4407          if (condition) break;
4408          }
4409        else break;
4410        }
4411    
4412      /* Scan up for duplicates */
4413      if (!condition)
4414        {
4415        slotB = slotA;
4416        for (i++; i < name_count; i++)
4417          {
4418          slotB += name_entry_size;
4419          if (STRCMP_UC_UC(slotA + IMM2_SIZE, slotB + IMM2_SIZE) == 0)
4420            {
4421            condition = GET2(slotB, 0) == group_num;
4422            if (condition) break;
4423            }
4424          else break;
4425          }
4426        }
4427      }
4428    return condition;
4429    }
4430    
4431  /*  /*
4432    Handling bracketed expressions is probably the most complex part.    Handling bracketed expressions is probably the most complex part.
4433    
# Line 3847  return cc + 1 + LINK_SIZE; Line 4437  return cc + 1 + LINK_SIZE;
4437      A - Push the current STR_PTR. Needed for restoring the STR_PTR      A - Push the current STR_PTR. Needed for restoring the STR_PTR
4438          before the next alternative. Not pushed if there are no alternatives.          before the next alternative. Not pushed if there are no alternatives.
4439      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.
4440      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.
4441      L - Push the previous local (pointed by localptr) to the stack      L - Push the previous local (pointed by localptr) to the stack
4442     () - opional values stored on the stack     () - opional values stored on the stack
4443    ()* - optonal, can be stored multiple times    ()* - optonal, can be stored multiple times
# Line 3885  return cc + 1 + LINK_SIZE; Line 4475  return cc + 1 + LINK_SIZE;
4475      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.
4476    
4477    The next list shows the possible content of a bracket:    The next list shows the possible content of a bracket:
4478    (|)     OP_*BRA  | OP_ALT ...         M A    (|)     OP_*BRA    | OP_ALT ...         M A
4479    (?()|)  OP_*COND | OP_ALT             M A    (?()|)  OP_*COND   | OP_ALT             M A
4480    (?>|)   OP_ONCE  | OP_ALT ...         [stack trace] M A    (?>|)   OP_ONCE    | OP_ALT ...         [stack trace] M A
4481                                          Or nothing, if trace is unnecessary    (?>|)   OP_ONCE_NC | OP_ALT ...         [stack trace] M A
4482                                              Or nothing, if trace is unnecessary
4483  */  */
4484    
4485  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)
4486  {  {
4487  DEFINE_COMPILER;  DEFINE_COMPILER;
4488  fallback_common *fallback;  fallback_common *fallback;
4489  uschar opcode;  pcre_uchar opcode;
4490  int localptr = 0;  int localptr = 0;
4491  int offset = 0;  int offset = 0;
4492  int stacksize;  int stacksize;
4493  uschar *ccbegin;  pcre_uchar *ccbegin;
4494  uschar *hotpath;  pcre_uchar *hotpath;
4495  uschar bra = OP_BRA;  pcre_uchar bra = OP_BRA;
4496  uschar ket;  pcre_uchar ket;
4497  assert_fallback *assert;  assert_fallback *assert;
4498  BOOL has_alternatives;  BOOL has_alternatives;
4499  struct sljit_jump *jump;  struct sljit_jump *jump;
# Line 3921  if (*cc == OP_BRAZERO || *cc == OP_BRAMI Line 4512  if (*cc == OP_BRAZERO || *cc == OP_BRAMI
4512    
4513  opcode = *cc;  opcode = *cc;
4514  ccbegin = cc;  ccbegin = cc;
4515    hotpath = ccbegin + 1 + LINK_SIZE;
4516    
4517  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)
4518    {    {
4519    /* Drop this bracket_fallback. */    /* Drop this bracket_fallback. */
# Line 3932  ket = *(bracketend(cc) - 1 - LINK_SIZE); Line 4525  ket = *(bracketend(cc) - 1 - LINK_SIZE);
4525  SLJIT_ASSERT(ket == OP_KET || ket == OP_KETRMAX || ket == OP_KETRMIN);  SLJIT_ASSERT(ket == OP_KET || ket == OP_KETRMAX || ket == OP_KETRMIN);
4526  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)));
4527  cc += GET(cc, 1);  cc += GET(cc, 1);
4528  has_alternatives = *cc == OP_ALT || opcode == OP_COND || opcode == OP_SCOND;  
4529    has_alternatives = *cc == OP_ALT;
4530    if (SLJIT_UNLIKELY(opcode == OP_COND) || SLJIT_UNLIKELY(opcode == OP_SCOND))
4531      {
4532      has_alternatives = (*hotpath == OP_RREF) ? FALSE : TRUE;
4533      if (*hotpath == OP_NRREF)
4534        {
4535        stacksize = GET2(hotpath, 1);
4536        if (common->currententry == NULL || stacksize == RREF_ANY)
4537          has_alternatives = FALSE;
4538        else if (common->currententry->start == 0)
4539          has_alternatives = stacksize != 0;
4540        else
4541          has_alternatives = stacksize != GET2(common->start, common->currententry->start + 1 + LINK_SIZE);
4542        }
4543      }
4544    
4545  if (SLJIT_UNLIKELY(opcode == OP_COND) && (*cc == OP_KETRMAX || *cc == OP_KETRMIN))  if (SLJIT_UNLIKELY(opcode == OP_COND) && (*cc == OP_KETRMAX || *cc == OP_KETRMIN))
4546    opcode = OP_SCOND;    opcode = OP_SCOND;
4547    if (SLJIT_UNLIKELY(opcode == OP_ONCE_NC))
4548      opcode = OP_ONCE;
4549    
4550  if (opcode == OP_CBRA || opcode == OP_SCBRA)  if (opcode == OP_CBRA || opcode == OP_SCBRA)
4551    {    {
# Line 3943  if (opcode == OP_CBRA || opcode == OP_SC Line 4554  if (opcode == OP_CBRA || opcode == OP_SC
4554    localptr = OVECTOR_PRIV(offset);    localptr = OVECTOR_PRIV(offset);
4555    offset <<= 1;    offset <<= 1;
4556    FALLBACK_AS(bracket_fallback)->localptr = localptr;    FALLBACK_AS(bracket_fallback)->localptr = localptr;
4557      hotpath += IMM2_SIZE;
4558    }    }
4559  else if (opcode == OP_ONCE || opcode == OP_SBRA || opcode == OP_SCOND)  else if (opcode == OP_ONCE || opcode == OP_SBRA || opcode == OP_SCOND)
4560    {    {
4561    /* Other brackets simply allocate the next entry. */    /* Other brackets simply allocate the next entry. */
4562    localptr = PRIV(ccbegin);    localptr = PRIV_DATA(ccbegin);
4563    SLJIT_ASSERT(localptr != 0);    SLJIT_ASSERT(localptr != 0);
4564    FALLBACK_AS(bracket_fallback)->localptr = localptr;    FALLBACK_AS(bracket_fallback)->localptr = localptr;
4565    if (opcode == OP_ONCE)    if (opcode == OP_ONCE)
# Line 4074  if (opcode == OP_ONCE) Line 4686  if (opcode == OP_ONCE)
4686  else if (opcode == OP_CBRA || opcode == OP_SCBRA)  else if (opcode == OP_CBRA || opcode == OP_SCBRA)
4687    {    {
4688    /* Saving the previous values. */    /* Saving the previous values. */
4689    allocate_stack(common, 4);    allocate_stack(common, 3);
4690    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));
4691    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));
4692    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0);
4693    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0);
4694    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), MAX_INDEX);    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
   OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);  
4695    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, STR_PTR, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, STR_PTR, 0);
4696    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(2), TMP1, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(2), TMP1, 0);
   OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(3), TMP2, 0);  
   /* Update MAX_INDEX if necessary. */  
   add_stub(common, max_index, (offset >> 1) + 1, CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, (offset >> 1) + 1));  
4697    }    }
4698  else if (opcode == OP_SBRA || opcode == OP_SCOND)  else if (opcode == OP_SBRA || opcode == OP_SCOND)
4699    {    {
# Line 4103  else if (has_alternatives) Line 4711  else if (has_alternatives)
4711    }    }
4712    
4713  /* Generating code for the first alternative. */  /* Generating code for the first alternative. */
 hotpath = ccbegin + 1 + LINK_SIZE;  
 if (offset != 0)  
   hotpath += 2;  
4714  if (opcode == OP_COND || opcode == OP_SCOND)  if (opcode == OP_COND || opcode == OP_SCOND)
4715    {    {
4716    if (*hotpath == OP_CREF)    if (*hotpath == OP_CREF)
4717      {      {
4718        SLJIT_ASSERT(has_alternatives);
4719      add_jump(compiler, &(FALLBACK_AS(bracket_fallback)->u.condfailed),      add_jump(compiler, &(FALLBACK_AS(bracket_fallback)->u.condfailed),
4720        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)));
4721      hotpath += 3;      hotpath += 1 + IMM2_SIZE;
4722        }
4723      else if (*hotpath == OP_NCREF)
4724        {
4725        SLJIT_ASSERT(has_alternatives);
4726        stacksize = GET2(hotpath, 1);
4727        jump = CMP(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(stacksize << 1), SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1));
4728    
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_TEMPORARY_REG1, 0, SLJIT_IMM, stacksize);
4733        OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, SLJIT_LOCALS_REG, 0);
4734        OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, common->name_table);
4735        sljit_emit_ijump(compiler, SLJIT_CALL3, SLJIT_IMM, SLJIT_FUNC_OFFSET(do_searchovector));
4736        OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1);
4737        add_jump(compiler, &(FALLBACK_AS(bracket_fallback)->u.condfailed), CMP(SLJIT_C_EQUAL, SLJIT_TEMPORARY_REG1, 0, SLJIT_IMM, 0));
4738    
4739        JUMPHERE(jump);
4740        hotpath += 1 + IMM2_SIZE;
4741        }
4742      else if (*hotpath == OP_RREF || *hotpath == OP_NRREF)
4743        {
4744        /* Never has other case. */
4745        FALLBACK_AS(bracket_fallback)->u.condfailed = NULL;
4746    
4747        stacksize = GET2(hotpath, 1);
4748        if (common->currententry == NULL)
4749          stacksize = 0;
4750        else if (stacksize == RREF_ANY)
4751          stacksize = 1;
4752        else if (common->currententry->start == 0)
4753          stacksize = stacksize == 0;
4754        else
4755          stacksize = stacksize == GET2(common->start, common->currententry->start + 1 + LINK_SIZE);
4756    
4757        if (*hotpath == OP_RREF || stacksize || common->currententry == NULL)
4758          {
4759          SLJIT_ASSERT(!has_alternatives);
4760          if (stacksize != 0)
4761            hotpath += 1 + IMM2_SIZE;
4762          else
4763            {
4764            if (*cc == OP_ALT)
4765              {
4766              hotpath = cc + 1 + LINK_SIZE;
4767              cc += GET(cc, 1);
4768              }
4769            else
4770              hotpath = cc;
4771            }
4772          }
4773        else
4774          {
4775          SLJIT_ASSERT(has_alternatives);
4776    
4777          stacksize = GET2(hotpath, 1);
4778          OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STACK_TOP, 0);
4779          OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, SLJIT_IMM, common->name_count);
4780          OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, SLJIT_IMM, common->name_entry_size);
4781          OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, GET2(common->start, common->currententry->start + 1 + LINK_SIZE));
4782          OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG1, 0, SLJIT_IMM, stacksize);
4783          OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, SLJIT_LOCALS_REG, 0);
4784          OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, common->name_table);
4785          sljit_emit_ijump(compiler, SLJIT_CALL3, SLJIT_IMM, SLJIT_FUNC_OFFSET(do_searchgroups));
4786          OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1);
4787          add_jump(compiler, &(FALLBACK_AS(bracket_fallback)->u.condfailed), CMP(SLJIT_C_EQUAL, SLJIT_TEMPORARY_REG1, 0, SLJIT_IMM, 0));
4788          hotpath += 1 + IMM2_SIZE;
4789          }
4790      }      }
4791    else    else
4792      {      {
4793      SLJIT_ASSERT(*hotpath >= OP_ASSERT && *hotpath <= OP_ASSERTBACK_NOT);      SLJIT_ASSERT(has_alternatives && *hotpath >= OP_ASSERT && *hotpath <= OP_ASSERTBACK_NOT);
4794      /* Similar code as PUSH_FALLBACK macro. */      /* Similar code as PUSH_FALLBACK macro. */
4795      assert = sljit_alloc_memory(compiler, sizeof(assert_fallback));      assert = sljit_alloc_memory(compiler, sizeof(assert_fallback));
4796      if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))      if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
# Line 4146  if (opcode == OP_ONCE) Line 4820  if (opcode == OP_ONCE)
4820        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);
4821        }        }
4822      }      }
4823    else if (ket == OP_KETRMAX)    else
4824      {      {
4825      /* TMP2 which is set here used by OP_KETRMAX below. */      stacksize = (ket == OP_KETRMIN || ket == OP_KETRMAX || has_alternatives) ? 2 : 1;
4826      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));
4827      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP2), (FALLBACK_AS(bracket_fallback)->u.framesize + 1) * sizeof(sljit_w));      if (ket == OP_KETRMAX)
4828          {
4829          /* TMP2 which is set here used by OP_KETRMAX below. */
4830          OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
4831          }
4832      }      }
4833    }    }
4834    
# Line 4215  if (bra == OP_BRAZERO) Line 4893  if (bra == OP_BRAZERO)
4893  if (bra == OP_BRAMINZERO)  if (bra == OP_BRAMINZERO)
4894    {    {
4895    /* This is a fallback path! (From the viewpoint of OP_BRAMINZERO) */    /* This is a fallback path! (From the viewpoint of OP_BRAMINZERO) */
4896    JUMPTO(SLJIT_JUMP, ((braminzero_fallback*)parent)->hotpath);    JUMPTO(SLJIT_JUMP, ((braminzero_fallback *)parent)->hotpath);
4897    if (braminzerojump != NULL)    if (braminzerojump != NULL)
4898      {      {
4899      JUMPHERE(braminzerojump);      JUMPHERE(braminzerojump);
# Line 4243  cc += 1 + LINK_SIZE; Line 4921  cc += 1 + LINK_SIZE;
4921  return cc;  return cc;
4922  }  }
4923    
4924  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)
4925  {  {
4926  DEFINE_COMPILER;  DEFINE_COMPILER;
4927  fallback_common *fallback;  fallback_common *fallback;
4928  uschar opcode;  pcre_uchar opcode;
4929  int localptr;  int localptr;
4930  int cbraprivptr = 0;  int cbraprivptr = 0;
4931  int framesize;  int framesize;
4932  int stacksize;  int stacksize;
4933  int offset = 0;  int offset = 0;
4934  BOOL zero = FALSE;  BOOL zero = FALSE;
4935  uschar *ccbegin = NULL;  pcre_uchar *ccbegin = NULL;
4936  int stack;  int stack;
4937  struct sljit_label *loop = NULL;  struct sljit_label *loop = NULL;
4938  struct jump_list *emptymatch = NULL;  struct jump_list *emptymatch = NULL;
# Line 4267  if (*cc == OP_BRAPOSZERO) Line 4945  if (*cc == OP_BRAPOSZERO)
4945    }    }
4946    
4947  opcode = *cc;  opcode = *cc;
4948  localptr = PRIV(cc);  localptr = PRIV_DATA(cc);
4949  SLJIT_ASSERT(localptr != 0);  SLJIT_ASSERT(localptr != 0);
4950  FALLBACK_AS(bracketpos_fallback)->localptr = localptr;  FALLBACK_AS(bracketpos_fallback)->localptr = localptr;
4951  switch(opcode)  switch(opcode)
# Line 4282  switch(opcode) Line 4960  switch(opcode)
4960    offset = GET2(cc, 1 + LINK_SIZE);    offset = GET2(cc, 1 + LINK_SIZE);
4961    cbraprivptr = OVECTOR_PRIV(offset);    cbraprivptr = OVECTOR_PRIV(offset);
4962    offset <<= 1;    offset <<= 1;
4963    ccbegin = cc + 1 + LINK_SIZE + 2;    ccbegin = cc + 1 + LINK_SIZE + IMM2_SIZE;
4964    break;    break;
4965    
4966    default:    default:
# Line 4294  framesize = get_framesize(common, cc, FA Line 4972  framesize = get_framesize(common, cc, FA
4972  FALLBACK_AS(bracketpos_fallback)->framesize = framesize;  FALLBACK_AS(bracketpos_fallback)->framesize = framesize;
4973  if (framesize < 0)  if (framesize < 0)
4974    {    {
4975    stacksize = (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS) ? 3 : 1;    stacksize = (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS) ? 2 : 1;
4976    if (!zero)    if (!zero)
4977      stacksize++;      stacksize++;
4978    FALLBACK_AS(bracketpos_fallback)->stacksize = stacksize;    FALLBACK_AS(bracketpos_fallback)->stacksize = stacksize;
# Line 4306  if (framesize < 0) Line 4984  if (framesize < 0)
4984      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));
4985      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));
4986      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0);
     OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), MAX_INDEX);  
4987      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0);
     OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(2), TMP1, 0);  
4988      }      }
4989    else    else
4990      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
# Line 4365  while (*cc != OP_KETRPOS) Line 5041  while (*cc != OP_KETRPOS)
5041      if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS)      if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS)
5042        {        {
5043        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr);        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr);
       OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), MAX_INDEX);  
5044        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), STR_PTR, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), STR_PTR, 0);
       OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);  
       add_stub(common, max_index, (offset >> 1) + 1, CMP(SLJIT_C_LESS, TMP2, 0, SLJIT_IMM, (offset >> 1) + 1));  
5045        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr, STR_PTR, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr, STR_PTR, 0);
5046          OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);
5047        }        }
5048      else      else
5049        {        {
# Line 4388  while (*cc != OP_KETRPOS) Line 5062  while (*cc != OP_KETRPOS)
5062      {      {
5063      if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS)      if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS)
5064        {        {
5065          OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_IMM, stacksize * sizeof(sljit_w));
5066        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr);        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr);
       OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), MAX_INDEX);  
5067        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), STR_PTR, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), STR_PTR, 0);
       OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);  
       add_stub(common, max_index, (offset >> 1) + 1, CMP(SLJIT_C_LESS, TMP2, 0, SLJIT_IMM, (offset >> 1) + 1));  
       if (!zero)  
         OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);  
5068        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr, STR_PTR, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr, STR_PTR, 0);
5069          OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);
5070        }        }
5071      else      else
5072        {        {
5073        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
5074          OP2(SLJIT_ADD, STACK_TOP, 0, TMP2, 0, SLJIT_IMM, stacksize * sizeof(sljit_w));
5075        if (opcode == OP_SBRAPOS)        if (opcode == OP_SBRAPOS)
5076          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));
5077        OP1(SLJIT_MOV, SLJIT_MEM1(TMP2), (framesize + 1) * sizeof(sljit_w), STR_PTR, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(TMP2), (framesize + 1) * sizeof(sljit_w), STR_PTR, 0);
# Line 4408  while (*cc != OP_KETRPOS) Line 5080  while (*cc != OP_KETRPOS)