/[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 669 by ph10, Tue Aug 23 09:56:11 2011 UTC revision 953 by zherczeg, Thu Mar 29 17:41:57 2012 UTC
# Line 6  Line 6 
6  and semantics are as close as possible to those of the Perl 5 language.  and semantics are as close as possible to those of the Perl 5 language.
7    
8                         Written by Philip Hazel                         Written by Philip Hazel
9             Copyright (c) 1997-2008 University of Cambridge             Copyright (c) 1997-2012 University of Cambridge
10    
11    The machine code generator part (this module) was written by Zoltan Herczeg    The machine code generator part (this module) was written by Zoltan Herczeg
12                        Copyright (c) 2010-2011                        Copyright (c) 2010-2012
13    
14  -----------------------------------------------------------------------------  -----------------------------------------------------------------------------
15  Redistribution and use in source and binary forms, with or without  Redistribution and use in source and binary forms, with or without
# Line 52  POSSIBILITY OF SUCH DAMAGE. Line 52  POSSIBILITY OF SUCH DAMAGE.
52  we just include it. This way we don't need to touch the build  we just include it. This way we don't need to touch the build
53  system files. */  system files. */
54    
55    #define SLJIT_MALLOC(size) (PUBL(malloc))(size)
56    #define SLJIT_FREE(ptr) (PUBL(free))(ptr)
57  #define SLJIT_CONFIG_AUTO 1  #define SLJIT_CONFIG_AUTO 1
58    #define SLJIT_CONFIG_STATIC 1
59  #define SLJIT_VERBOSE 0  #define SLJIT_VERBOSE 0
60  #define SLJIT_DEBUG 0  #define SLJIT_DEBUG 0
61    
62  #include "sljit/sljitLir.c"  #include "sljit/sljitLir.c"
63    
64  #if defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED  #if defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED
65  #error "Unsupported architecture"  #error Unsupported architecture
66  #endif  #endif
67    
68  /* Allocate memory on the stack. Fast, but limited size. */  /* Allocate memory on the stack. Fast, but limited size. */
# Line 119  The generated code will be the following Line 122  The generated code will be the following
122   jump to D hot path   jump to D hot path
123   C fallback path   C fallback path
124   A fallback path   A fallback path
125    
126   Notice, that the order of fallback code paths are the opposite of the fast   Notice, that the order of fallback code paths are the opposite of the fast
127   code paths. In this way the topmost value on the stack is always belong   code paths. In this way the topmost value on the stack is always belong
128   to the current fallback code path. The fallback code path must check   to the current fallback code path. The fallback code path must check
# Line 145  Thus we can restore the locals to a part Line 148  Thus we can restore the locals to a part
148  typedef struct jit_arguments {  typedef struct jit_arguments {
149    /* Pointers first. */    /* Pointers first. */
150    struct sljit_stack *stack;    struct sljit_stack *stack;
151    PCRE_SPTR str;    const pcre_uchar *str;
152    PCRE_SPTR begin;    const pcre_uchar *begin;
153    PCRE_SPTR end;    const pcre_uchar *end;
154    int *offsets;    int *offsets;
155    uschar *ptr;    pcre_uchar *uchar_ptr;
156      pcre_uchar *mark_ptr;
157    /* Everything else after. */    /* Everything else after. */
158    int offsetcount;    int offsetcount;
159    uschar notbol;    int calllimit;
160    uschar noteol;    pcre_uint8 notbol;
161    uschar notempty;    pcre_uint8 noteol;
162    uschar notempty_atstart;    pcre_uint8 notempty;
163      pcre_uint8 notempty_atstart;
164  } jit_arguments;  } jit_arguments;
165    
166  typedef struct executable_function {  typedef struct executable_functions {
167    void *executable_func;    void *executable_funcs[JIT_NUMBER_OF_COMPILE_MODES];
168    pcre_jit_callback callback;    PUBL(jit_callback) callback;
169    void *userdata;    void *userdata;
170  } executable_function;    sljit_uw executable_sizes[JIT_NUMBER_OF_COMPILE_MODES];
171    } executable_functions;
172    
173  typedef struct jump_list {  typedef struct jump_list {
174    struct sljit_jump *jump;    struct sljit_jump *jump;
175    struct jump_list *next;    struct jump_list *next;
176  } jump_list;  } jump_list;
177    
178  enum stub_types { stack_alloc, max_index };  enum stub_types { stack_alloc };
179    
180  typedef struct stub_list {  typedef struct stub_list {
181    enum stub_types type;    enum stub_types type;
# Line 193  typedef struct fallback_common { Line 199  typedef struct fallback_common {
199    struct fallback_common *top;    struct fallback_common *top;
200    jump_list *topfallbacks;    jump_list *topfallbacks;
201    /* Opcode pointer. */    /* Opcode pointer. */
202    uschar *cc;    pcre_uchar *cc;
203  } fallback_common;  } fallback_common;
204    
205  typedef struct assert_fallback {  typedef struct assert_fallback {
# Line 264  typedef struct recurse_fallback { Line 270  typedef struct recurse_fallback {
270    
271  typedef struct compiler_common {  typedef struct compiler_common {
272    struct sljit_compiler *compiler;    struct sljit_compiler *compiler;
273    uschar *start;    pcre_uchar *start;
274    
275      /* Local stack area size and variable pointers. */
276    int localsize;    int localsize;
277    int *localptrs;    int *localptrs;
   const uschar *fcc;  
   sljit_w lcc;  
278    int cbraptr;    int cbraptr;
279      /* OVector starting point. Must be divisible by 2. */
280      int ovector_start;
281      /* Last known position of the requested byte. */
282      int req_char_ptr;
283      /* Head of the last recursion. */
284      int recursive_head;
285      /* First inspected character for partial matching. */
286      int start_used_ptr;
287      /* Starting pointer for partial soft matches. */
288      int hit_start;
289      /* End pointer of the first line. */
290      int first_line_end;
291      /* Points to the marked string. */
292      int mark_ptr;
293    
294      /* Other  */
295      const pcre_uint8 *fcc;
296      sljit_w lcc;
297      int mode;
298    int nltype;    int nltype;
299    int newline;    int newline;
300    int bsr_nltype;    int bsr_nltype;
301    int endonly;    int endonly;
302      BOOL has_set_som;
303    sljit_w ctypes;    sljit_w ctypes;
304      sljit_uw name_table;
305      sljit_w name_count;
306      sljit_w name_entry_size;
307    
308      /* Labels and jump lists. */
309      struct sljit_label *partialmatchlabel;
310      struct sljit_label *leavelabel;
311    struct sljit_label *acceptlabel;    struct sljit_label *acceptlabel;
312    stub_list *stubs;    stub_list *stubs;
313    recurse_entry *entries;    recurse_entry *entries;
314    recurse_entry *currententry;    recurse_entry *currententry;
315      jump_list *partialmatch;
316      jump_list *leave;
317    jump_list *accept;    jump_list *accept;
318      jump_list *calllimit;
319    jump_list *stackalloc;    jump_list *stackalloc;
320    jump_list *revertframes;    jump_list *revertframes;
321    jump_list *wordboundary;    jump_list *wordboundary;
# Line 289  typedef struct compiler_common { Line 325  typedef struct compiler_common {
325    jump_list *casefulcmp;    jump_list *casefulcmp;
326    jump_list *caselesscmp;    jump_list *caselesscmp;
327    BOOL jscript_compat;    BOOL jscript_compat;
328  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
329    BOOL utf8;    BOOL utf;
330  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
331    BOOL useucp;    BOOL use_ucp;
332  #endif  #endif
333    jump_list *utf8readchar;    jump_list *utfreadchar;
334    jump_list *utf8readtype8;  #ifdef COMPILE_PCRE8
335      jump_list *utfreadtype8;
336  #endif  #endif
337    #endif /* SUPPORT_UTF */
338  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
339    jump_list *getucd;    jump_list *getucd;
340  #endif  #endif
# Line 308  typedef struct compare_context { Line 346  typedef struct compare_context {
346    int length;    int length;
347    int sourcereg;    int sourcereg;
348  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
349    int byteptr;    int ucharptr;
350    union {    union {
351      int asint;      sljit_i asint;
352      short asshort;      sljit_uh asushort;
353    #ifdef COMPILE_PCRE8
354      sljit_ub asbyte;      sljit_ub asbyte;
355      sljit_ub asbytes[4];      sljit_ub asuchars[4];
356    #else
357    #ifdef COMPILE_PCRE16
358        sljit_uh asuchars[2];
359    #endif
360    #endif
361    } c;    } c;
362    union {    union {
363      int asint;      sljit_i asint;
364      short asshort;      sljit_uh asushort;
365    #ifdef COMPILE_PCRE8
366      sljit_ub asbyte;      sljit_ub asbyte;
367      sljit_ub asbytes[4];      sljit_ub asuchars[4];
368    #else
369    #ifdef COMPILE_PCRE16
370        sljit_uh asuchars[2];
371    #endif
372    #endif
373    } oc;    } oc;
374  #endif  #endif
375  } compare_context;  } compare_context;
376    
377  enum {  enum {
378    frame_end = 0,    frame_end = 0,
379    frame_setmaxindex = -1,    frame_setstrbegin = -1,
380    frame_setstrbegin = -2    frame_setmark = -2
381  };  };
382    
383    /* Undefine sljit macros. */
384    #undef CMP
385    
386  /* Used for accessing the elements of the stack. */  /* Used for accessing the elements of the stack. */
387  #define STACK(i)      ((-(i) - 1) * (int)sizeof(sljit_w))  #define STACK(i)      ((-(i) - 1) * (int)sizeof(sljit_w))
388    
389  #define TMP1          SLJIT_TEMPORARY_REG1  #define TMP1          SLJIT_TEMPORARY_REG1
390  #define TMP2          SLJIT_TEMPORARY_REG3  #define TMP2          SLJIT_TEMPORARY_REG3
391  #define TMP3          SLJIT_TEMPORARY_EREG2  #define TMP3          SLJIT_TEMPORARY_EREG2
392  #define STR_PTR       SLJIT_GENERAL_REG1  #define STR_PTR       SLJIT_SAVED_REG1
393  #define STR_END       SLJIT_GENERAL_REG2  #define STR_END       SLJIT_SAVED_REG2
394  #define STACK_TOP     SLJIT_TEMPORARY_REG2  #define STACK_TOP     SLJIT_TEMPORARY_REG2
395  #define STACK_LIMIT   SLJIT_GENERAL_REG3  #define STACK_LIMIT   SLJIT_SAVED_REG3
396  #define ARGUMENTS     SLJIT_GENERAL_EREG1  #define ARGUMENTS     SLJIT_SAVED_EREG1
397  #define MAX_INDEX     SLJIT_GENERAL_EREG2  #define CALL_COUNT    SLJIT_SAVED_EREG2
398  #define RETURN_ADDR   SLJIT_TEMPORARY_EREG1  #define RETURN_ADDR   SLJIT_TEMPORARY_EREG1
399    
400  /* Locals layout. */  /* Locals layout. */
# Line 351  enum { Line 404  enum {
404  /* Two local variables for possessive quantifiers (char1 cannot use them). */  /* Two local variables for possessive quantifiers (char1 cannot use them). */
405  #define POSSESSIVE0      (2 * sizeof(sljit_w))  #define POSSESSIVE0      (2 * sizeof(sljit_w))
406  #define POSSESSIVE1      (3 * sizeof(sljit_w))  #define POSSESSIVE1      (3 * sizeof(sljit_w))
407  /* Head of the saved local variables */  /* Max limit of recursions. */
408  #define LOCALS_HEAD      (4 * sizeof(sljit_w))  #define CALL_LIMIT       (4 * sizeof(sljit_w))
 /* Head of the last recursion. */  
 #define RECURSIVE_HEAD   (5 * sizeof(sljit_w))  
 /* Last known position of the requested byte. */  
 #define REQ_BYTE_PTR     (6 * sizeof(sljit_w))  
 /* End pointer of the first line. */  
 #define FIRSTLINE_END    (7 * sizeof(sljit_w))  
409  /* The output vector is stored on the stack, and contains pointers  /* The output vector is stored on the stack, and contains pointers
410  to characters. The vector data is divided into two groups: the first  to characters. The vector data is divided into two groups: the first
411  group contains the start / end character pointers, and the second is  group contains the start / end character pointers, and the second is
412  the start pointers when the end of the capturing group has not yet reached. */  the start pointers when the end of the capturing group has not yet reached. */
413  #define OVECTOR_START    (8 * sizeof(sljit_w))  #define OVECTOR_START    (common->ovector_start)
414  #define OVECTOR(i)       (OVECTOR_START + (i) * sizeof(sljit_w))  #define OVECTOR(i)       (OVECTOR_START + (i) * sizeof(sljit_w))
415  #define OVECTOR_PRIV(i)  (common->cbraptr + (i) * sizeof(sljit_w))  #define OVECTOR_PRIV(i)  (common->cbraptr + (i) * sizeof(sljit_w))
416  #define PRIV(cc)         (common->localptrs[(cc) - common->start])  #define PRIV_DATA(cc)    (common->localptrs[(cc) - common->start])
417    
418    #ifdef COMPILE_PCRE8
419    #define MOV_UCHAR  SLJIT_MOV_UB
420    #define MOVU_UCHAR SLJIT_MOVU_UB
421    #else
422    #ifdef COMPILE_PCRE16
423    #define MOV_UCHAR  SLJIT_MOV_UH
424    #define MOVU_UCHAR SLJIT_MOVU_UH
425    #else
426    #error Unsupported compiling mode
427    #endif
428    #endif
429    
430  /* Shortcuts. */  /* Shortcuts. */
431  #define DEFINE_COMPILER \  #define DEFINE_COMPILER \
# Line 390  the start pointers when the end of the c Line 449  the start pointers when the end of the c
449  #define COND_VALUE(op, dst, dstw, type) \  #define COND_VALUE(op, dst, dstw, type) \
450    sljit_emit_cond_value(compiler, (op), (dst), (dstw), (type))    sljit_emit_cond_value(compiler, (op), (dst), (dstw), (type))
451    
452  static uschar* bracketend(uschar* cc)  static pcre_uchar* bracketend(pcre_uchar* cc)
453  {  {
454  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));
455  do cc += GET(cc, 1); while (*cc == OP_ALT);  do cc += GET(cc, 1); while (*cc == OP_ALT);
# Line 399  cc += 1 + LINK_SIZE; Line 458  cc += 1 + LINK_SIZE;
458  return cc;  return cc;
459  }  }
460    
461  /* Functions whose might need modification for all new supported opcodes:  /* Functions whose might need modification for all new supported opcodes:
462   next_opcode   next_opcode
463   get_localspace   get_localspace
464   set_localptrs   set_localptrs
# Line 411  return cc; Line 470  return cc;
470   compile_fallbackpath   compile_fallbackpath
471  */  */
472    
473  static uschar *next_opcode(compiler_common *common, uschar *cc)  static pcre_uchar *next_opcode(compiler_common *common, pcre_uchar *cc)
474  {  {
475  SLJIT_UNUSED_ARG(common);  SLJIT_UNUSED_ARG(common);
476  switch(*cc)  switch(*cc)
# Line 460  switch(*cc) Line 519  switch(*cc)
519    case OP_BRAZERO:    case OP_BRAZERO:
520    case OP_BRAMINZERO:    case OP_BRAMINZERO:
521    case OP_BRAPOSZERO:    case OP_BRAPOSZERO:
522      case OP_COMMIT:
523    case OP_FAIL:    case OP_FAIL:
524    case OP_ACCEPT:    case OP_ACCEPT:
525    case OP_ASSERT_ACCEPT:    case OP_ASSERT_ACCEPT:
526    case OP_SKIPZERO:    case OP_SKIPZERO:
527    return cc + 1;    return cc + 1;
528    
529      case OP_ANYBYTE:
530    #ifdef SUPPORT_UTF
531      if (common->utf) return NULL;
532    #endif
533      return cc + 1;
534    
535    case OP_CHAR:    case OP_CHAR:
536    case OP_CHARI:    case OP_CHARI:
537    case OP_NOT:    case OP_NOT:
538    case OP_NOTI:    case OP_NOTI:
   
539    case OP_STAR:    case OP_STAR:
540    case OP_MINSTAR:    case OP_MINSTAR:
541    case OP_PLUS:    case OP_PLUS:
# Line 508  switch(*cc) Line 573  switch(*cc)
573    case OP_NOTPOSPLUSI:    case OP_NOTPOSPLUSI:
574    case OP_NOTPOSQUERYI:    case OP_NOTPOSQUERYI:
575    cc += 2;    cc += 2;
576  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
577    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]);
578  #endif  #endif
579    return cc;    return cc;
580    
# Line 529  switch(*cc) Line 594  switch(*cc)
594    case OP_NOTMINUPTOI:    case OP_NOTMINUPTOI:
595    case OP_NOTEXACTI:    case OP_NOTEXACTI:
596    case OP_NOTPOSUPTOI:    case OP_NOTPOSUPTOI:
597    cc += 4;    cc += 2 + IMM2_SIZE;
598  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
599    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]);
600  #endif  #endif
601    return cc;    return cc;
602    
603    case OP_NOTPROP:    case OP_NOTPROP:
604    case OP_PROP:    case OP_PROP:
605      return cc + 1 + 2;
606    
607    case OP_TYPEUPTO:    case OP_TYPEUPTO:
608    case OP_TYPEMINUPTO:    case OP_TYPEMINUPTO:
609    case OP_TYPEEXACT:    case OP_TYPEEXACT:
# Line 544  switch(*cc) Line 611  switch(*cc)
611    case OP_REF:    case OP_REF:
612    case OP_REFI:    case OP_REFI:
613    case OP_CREF:    case OP_CREF:
614      case OP_NCREF:
615      case OP_RREF:
616      case OP_NRREF:
617    case OP_CLOSE:    case OP_CLOSE:
618    cc += 3;    cc += 1 + IMM2_SIZE;
619    return cc;    return cc;
620    
621    case OP_CRRANGE:    case OP_CRRANGE:
622    case OP_CRMINRANGE:    case OP_CRMINRANGE:
623    return cc + 5;    return cc + 1 + 2 * IMM2_SIZE;
624    
625    case OP_CLASS:    case OP_CLASS:
626    case OP_NCLASS:    case OP_NCLASS:
627    return cc + 33;    return cc + 1 + 32 / sizeof(pcre_uchar);
628    
629  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
630    case OP_XCLASS:    case OP_XCLASS:
631    return cc + GET(cc, 1);    return cc + GET(cc, 1);
632  #endif  #endif
# Line 568  switch(*cc) Line 638  switch(*cc)
638    case OP_ASSERTBACK_NOT:    case OP_ASSERTBACK_NOT:
639    case OP_REVERSE:    case OP_REVERSE:
640    case OP_ONCE:    case OP_ONCE:
641      case OP_ONCE_NC:
642    case OP_BRA:    case OP_BRA:
643    case OP_BRAPOS:    case OP_BRAPOS:
644    case OP_COND:    case OP_COND:
# Line 585  switch(*cc) Line 656  switch(*cc)
656    case OP_CBRAPOS:    case OP_CBRAPOS:
657    case OP_SCBRA:    case OP_SCBRA:
658    case OP_SCBRAPOS:    case OP_SCBRAPOS:
659    return cc + 1 + LINK_SIZE + 2;    return cc + 1 + LINK_SIZE + IMM2_SIZE;
660    
661      case OP_MARK:
662      return cc + 1 + 2 + cc[1];
663    
664    default:    default:
665    return NULL;    return NULL;
666    }    }
667  }  }
668    
669  static int get_localspace(compiler_common *common, uschar *cc, uschar *ccend)  static int get_localspace(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend)
670  {  {
671  int localspace = 0;  int localspace = 0;
672  uschar *alternative;  pcre_uchar *alternative;
673  /* 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. */
674  while (cc < ccend)  while (cc < ccend)
675    {    {
676    switch(*cc)    switch(*cc)
677      {      {
678        case OP_SET_SOM:
679        common->has_set_som = TRUE;
680        cc += 1;
681        break;
682    
683      case OP_ASSERT:      case OP_ASSERT:
684      case OP_ASSERT_NOT:      case OP_ASSERT_NOT:
685      case OP_ASSERTBACK:      case OP_ASSERTBACK:
686      case OP_ASSERTBACK_NOT:      case OP_ASSERTBACK_NOT:
687      case OP_ONCE:      case OP_ONCE:
688        case OP_ONCE_NC:
689      case OP_BRAPOS:      case OP_BRAPOS:
690      case OP_SBRA:      case OP_SBRA:
691      case OP_SBRAPOS:      case OP_SBRAPOS:
# Line 617  while (cc < ccend) Line 697  while (cc < ccend)
697      case OP_CBRAPOS:      case OP_CBRAPOS:
698      case OP_SCBRAPOS:      case OP_SCBRAPOS:
699      localspace += sizeof(sljit_w);      localspace += sizeof(sljit_w);
700      cc += 1 + LINK_SIZE + 2;      cc += 1 + LINK_SIZE + IMM2_SIZE;
701      break;      break;
702    
703      case OP_COND:      case OP_COND:
# Line 628  while (cc < ccend) Line 708  while (cc < ccend)
708      cc += 1 + LINK_SIZE;      cc += 1 + LINK_SIZE;
709      break;      break;
710    
711        case OP_RECURSE:
712        /* Set its value only once. */
713        if (common->recursive_head == 0)
714          {
715          common->recursive_head = common->ovector_start;
716          common->ovector_start += sizeof(sljit_w);
717          }
718        cc += 1 + LINK_SIZE;
719        break;
720    
721        case OP_MARK:
722        if (common->mark_ptr == 0)
723          {
724          common->mark_ptr = common->ovector_start;
725          common->ovector_start += sizeof(sljit_w);
726          }
727        cc += 1 + 2 + cc[1];
728        break;
729    
730      default:      default:
731      cc = next_opcode(common, cc);      cc = next_opcode(common, cc);
732      if (cc == NULL)      if (cc == NULL)
# Line 638  while (cc < ccend) Line 737  while (cc < ccend)
737  return localspace;  return localspace;
738  }  }
739    
740  static void set_localptrs(compiler_common *common, int localptr, uschar *ccend)  static void set_localptrs(compiler_common *common, int localptr, pcre_uchar *ccend)
741  {  {
742  uschar *cc = common->start;  pcre_uchar *cc = common->start;
743  uschar *alternative;  pcre_uchar *alternative;
744  while (cc < ccend)  while (cc < ccend)
745    {    {
746    switch(*cc)    switch(*cc)
# Line 651  while (cc < ccend) Line 750  while (cc < ccend)
750      case OP_ASSERTBACK:      case OP_ASSERTBACK:
751      case OP_ASSERTBACK_NOT:      case OP_ASSERTBACK_NOT:
752      case OP_ONCE:      case OP_ONCE:
753        case OP_ONCE_NC:
754      case OP_BRAPOS:      case OP_BRAPOS:
755      case OP_SBRA:      case OP_SBRA:
756      case OP_SBRAPOS:      case OP_SBRAPOS:
# Line 664  while (cc < ccend) Line 764  while (cc < ccend)
764      case OP_SCBRAPOS:      case OP_SCBRAPOS:
765      common->localptrs[cc - common->start] = localptr;      common->localptrs[cc - common->start] = localptr;
766      localptr += sizeof(sljit_w);      localptr += sizeof(sljit_w);
767      cc += 1 + LINK_SIZE + 2;      cc += 1 + LINK_SIZE + IMM2_SIZE;
768      break;      break;
769    
770      case OP_COND:      case OP_COND:
# Line 687  while (cc < ccend) Line 787  while (cc < ccend)
787  }  }
788    
789  /* Returns with -1 if no need for frame. */  /* Returns with -1 if no need for frame. */
790  static int get_framesize(compiler_common *common, uschar *cc, BOOL recursive)  static int get_framesize(compiler_common *common, pcre_uchar *cc, BOOL recursive)
791  {  {
792  uschar *ccend = bracketend(cc);  pcre_uchar *ccend = bracketend(cc);
 uschar *end;  
793  int length = 0;  int length = 0;
794  BOOL possessive = FALSE;  BOOL possessive = FALSE;
795  BOOL needs_frame = FALSE;  BOOL setsom_found = recursive;
796  BOOL needs_maxindex = FALSE;  BOOL setmark_found = recursive;
 BOOL setsom_found = FALSE;  
797    
798  if (!recursive && (*cc == OP_CBRAPOS || *cc == OP_SCBRAPOS))  if (!recursive && (*cc == OP_CBRAPOS || *cc == OP_SCBRAPOS))
799    {    {
800    length = 3 + 2;    length = 3;
   needs_maxindex = TRUE;  
801    possessive = TRUE;    possessive = TRUE;
802    }    }
803    
# Line 710  while (cc < ccend) Line 807  while (cc < ccend)
807    switch(*cc)    switch(*cc)
808      {      {
809      case OP_SET_SOM:      case OP_SET_SOM:
810      case OP_RECURSE:      SLJIT_ASSERT(common->has_set_som);
811      if (!setsom_found)      if (!setsom_found)
812        {        {
813        length += 2;        length += 2;
814        setsom_found = TRUE;        setsom_found = TRUE;
815        }        }
816      cc += (*cc == OP_SET_SOM) ? 1 : 1 + LINK_SIZE;      cc += 1;
817      break;      break;
818    
819      case OP_ASSERT:      case OP_MARK:
820      case OP_ASSERT_NOT:      SLJIT_ASSERT(common->mark_ptr != 0);
821      case OP_ASSERTBACK:      if (!setmark_found)
     case OP_ASSERTBACK_NOT:  
     case OP_ONCE:  
     if (needs_frame || length > 0)  
822        {        {
823        cc = bracketend(cc);        length += 2;
824        break;        setmark_found = TRUE;
825        }        }
826      /* Check whether a frame must be created. */      cc += 1 + 2 + cc[1];
827      end = bracketend(cc);      break;
828      while (cc < end)  
829        {      case OP_RECURSE:
830        if (*cc == OP_SET_SOM || *cc == OP_CBRA || *cc == OP_CBRAPOS      if (common->has_set_som && !setsom_found)
831            || *cc == OP_SCBRA || *cc == OP_SCBRAPOS || *cc == OP_RECURSE)        {
832          needs_frame = TRUE;        length += 2;
833        cc = next_opcode(common, cc);        setsom_found = TRUE;
834        SLJIT_ASSERT(cc != NULL);        }
835        if (common->mark_ptr != 0 && !setmark_found)
836          {
837          length += 2;
838          setmark_found = TRUE;
839        }        }
840        cc += 1 + LINK_SIZE;
841      break;      break;
842    
843      case OP_CBRA:      case OP_CBRA:
844      case OP_CBRAPOS:      case OP_CBRAPOS:
845      case OP_SCBRA:      case OP_SCBRA:
846      case OP_SCBRAPOS:      case OP_SCBRAPOS:
     if (!needs_maxindex)  
       {  
       needs_maxindex = TRUE;  
       length += 2;  
       }  
847      length += 3;      length += 3;
848      cc += 1 + LINK_SIZE + 2;      cc += 1 + LINK_SIZE + IMM2_SIZE;
849      break;      break;
850    
851      default:      default:
# Line 761  while (cc < ccend) Line 855  while (cc < ccend)
855      }      }
856    
857  /* Possessive quantifiers can use a special case. */  /* Possessive quantifiers can use a special case. */
858  if (SLJIT_UNLIKELY(possessive) && !needs_frame && length == 3 + 2)  if (SLJIT_UNLIKELY(possessive) && length == 3)
859    return -1;    return -1;
860    
861  if (length > 0)  if (length > 0)
862    return length + 2;    return length + 1;
863  return needs_frame ? 0 : -1;  return -1;
864  }  }
865    
866  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)
867  {  {
 /* TMP2 must contain STACK_TOP - (-STACK(stackpos)) */  
868  DEFINE_COMPILER;  DEFINE_COMPILER;
869  uschar *ccend = bracketend(cc);  pcre_uchar *ccend = bracketend(cc);
870  BOOL needs_maxindex = FALSE;  BOOL setsom_found = recursive;
871  BOOL setsom_found = FALSE;  BOOL setmark_found = recursive;
872  int offset;  int offset;
873    
874  if (stackpos < stacktop)  /* >= 1 + shortest item size (2) */
875    {  SLJIT_UNUSED_ARG(stacktop);
876    SLJIT_ASSERT(stackpos + 1 == stacktop);  SLJIT_ASSERT(stackpos >= stacktop + 2);
   return;  
   }  
877    
878  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);  
   
879  if (recursive || (*cc != OP_CBRAPOS && *cc != OP_SCBRAPOS))  if (recursive || (*cc != OP_CBRAPOS && *cc != OP_SCBRAPOS))
880    cc = next_opcode(common, cc);    cc = next_opcode(common, cc);
881  SLJIT_ASSERT(cc != NULL);  SLJIT_ASSERT(cc != NULL);
# Line 796  while (cc < ccend) Line 883  while (cc < ccend)
883    switch(*cc)    switch(*cc)
884      {      {
885      case OP_SET_SOM:      case OP_SET_SOM:
886      case OP_RECURSE:      SLJIT_ASSERT(common->has_set_som);
887      if (!setsom_found)      if (!setsom_found)
888        {        {
889        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0));        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0));
# Line 806  while (cc < ccend) Line 893  while (cc < ccend)
893        stackpos += (int)sizeof(sljit_w);        stackpos += (int)sizeof(sljit_w);
894        setsom_found = TRUE;        setsom_found = TRUE;
895        }        }
896      cc += (*cc == OP_SET_SOM) ? 1 : 1 + LINK_SIZE;      cc += 1;
897      break;      break;
898    
899      case OP_ASSERT:      case OP_MARK:
900      case OP_ASSERT_NOT:      SLJIT_ASSERT(common->mark_ptr != 0);
901      case OP_ASSERTBACK:      if (!setmark_found)
902      case OP_ASSERTBACK_NOT:        {
903      case OP_ONCE:        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr);
904      cc = bracketend(cc);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, frame_setmark);
905          stackpos += (int)sizeof(sljit_w);
906          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);
907          stackpos += (int)sizeof(sljit_w);
908          setmark_found = TRUE;
909          }
910        cc += 1 + 2 + cc[1];
911      break;      break;
912    
913      case OP_CBRA:      case OP_RECURSE:
914      case OP_CBRAPOS:      if (common->has_set_som && !setsom_found)
     case OP_SCBRA:  
     case OP_SCBRAPOS:  
     if (!needs_maxindex)  
915        {        {
916        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, frame_setmaxindex);        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0));
917          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, frame_setstrbegin);
918        stackpos += (int)sizeof(sljit_w);        stackpos += (int)sizeof(sljit_w);
919        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, MAX_INDEX, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);
920        stackpos += (int)sizeof(sljit_w);        stackpos += (int)sizeof(sljit_w);
921        needs_maxindex = TRUE;        setsom_found = TRUE;
922        }        }
923        if (common->mark_ptr != 0 && !setmark_found)
924          {
925          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr);
926          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, frame_setmark);
927          stackpos += (int)sizeof(sljit_w);
928          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);
929          stackpos += (int)sizeof(sljit_w);
930          setmark_found = TRUE;
931          }
932        cc += 1 + LINK_SIZE;
933        break;
934    
935        case OP_CBRA:
936        case OP_CBRAPOS:
937        case OP_SCBRA:
938        case OP_SCBRAPOS:
939      offset = (GET2(cc, 1 + LINK_SIZE)) << 1;      offset = (GET2(cc, 1 + LINK_SIZE)) << 1;
940      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, OVECTOR(offset));      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, OVECTOR(offset));
941      stackpos += (int)sizeof(sljit_w);      stackpos += (int)sizeof(sljit_w);
# Line 839  while (cc < ccend) Line 946  while (cc < ccend)
946      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP2, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP2, 0);
947      stackpos += (int)sizeof(sljit_w);      stackpos += (int)sizeof(sljit_w);
948    
949      cc += 1 + LINK_SIZE + 2;      cc += 1 + LINK_SIZE + IMM2_SIZE;
950      break;      break;
951    
952      default:      default:
# Line 849  while (cc < ccend) Line 956  while (cc < ccend)
956      }      }
957    
958  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, frame_end);  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, frame_end);
959  SLJIT_ASSERT(stackpos == STACK(stacktop + 1));  SLJIT_ASSERT(stackpos == STACK(stacktop));
960  }  }
961    
962  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)
963  {  {
964  int localsize = 2;  int localsize = 2;
965  uschar *alternative;  pcre_uchar *alternative;
966  /* Calculate the sum of the local variables. */  /* Calculate the sum of the local variables. */
967  while (cc < ccend)  while (cc < ccend)
968    {    {
# Line 866  while (cc < ccend) Line 973  while (cc < ccend)
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:
# Line 877  while (cc < ccend) Line 985  while (cc < ccend)
985      case OP_CBRA:      case OP_CBRA:
986      case OP_SCBRA:      case OP_SCBRA:
987      localsize++;      localsize++;
988      cc += 1 + LINK_SIZE + 2;      cc += 1 + LINK_SIZE + IMM2_SIZE;
989      break;      break;
990    
991      case OP_CBRAPOS:      case OP_CBRAPOS:
992      case OP_SCBRAPOS:      case OP_SCBRAPOS:
993      localsize += 2;      localsize += 2;
994      cc += 1 + LINK_SIZE + 2;      cc += 1 + LINK_SIZE + IMM2_SIZE;
995      break;      break;
996    
997      case OP_COND:      case OP_COND:
# Line 904  SLJIT_ASSERT(cc == ccend); Line 1012  SLJIT_ASSERT(cc == ccend);
1012  return localsize;  return localsize;
1013  }  }
1014    
1015  static void copy_locals(compiler_common *common, uschar *cc, uschar *ccend,  static void copy_locals(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend,
1016    BOOL save, int stackptr, int stacktop)    BOOL save, int stackptr, int stacktop)
1017  {  {
1018  DEFINE_COMPILER;  DEFINE_COMPILER;
# Line 913  int count; Line 1021  int count;
1021  BOOL tmp1next = TRUE;  BOOL tmp1next = TRUE;
1022  BOOL tmp1empty = TRUE;  BOOL tmp1empty = TRUE;
1023  BOOL tmp2empty = TRUE;  BOOL tmp2empty = TRUE;
1024  uschar *alternative;  pcre_uchar *alternative;
1025  enum {  enum {
1026    start,    start,
1027    loop,    loop,
# Line 948  while (status != end) Line 1056  while (status != end)
1056    switch(status)    switch(status)
1057      {      {
1058      case start:      case start:
1059      SLJIT_ASSERT(save);      SLJIT_ASSERT(save && common->recursive_head != 0);
1060      count = 1;      count = 1;
1061      srcw[0] = RECURSIVE_HEAD;      srcw[0] = common->recursive_head;
1062      status = loop;      status = loop;
1063      break;      break;
1064    
# Line 968  while (status != end) Line 1076  while (status != end)
1076        case OP_ASSERTBACK:        case OP_ASSERTBACK:
1077        case OP_ASSERTBACK_NOT:        case OP_ASSERTBACK_NOT:
1078        case OP_ONCE:        case OP_ONCE:
1079          case OP_ONCE_NC:
1080        case OP_BRAPOS:        case OP_BRAPOS:
1081        case OP_SBRA:        case OP_SBRA:
1082        case OP_SBRAPOS:        case OP_SBRAPOS:
1083        case OP_SCOND:        case OP_SCOND:
1084        count = 1;        count = 1;
1085        srcw[0] = PRIV(cc);        srcw[0] = PRIV_DATA(cc);
1086        SLJIT_ASSERT(srcw[0] != 0);        SLJIT_ASSERT(srcw[0] != 0);
1087        cc += 1 + LINK_SIZE;        cc += 1 + LINK_SIZE;
1088        break;        break;
# Line 982  while (status != end) Line 1091  while (status != end)
1091        case OP_SCBRA:        case OP_SCBRA:
1092        count = 1;        count = 1;
1093        srcw[0] = OVECTOR_PRIV(GET2(cc, 1 + LINK_SIZE));        srcw[0] = OVECTOR_PRIV(GET2(cc, 1 + LINK_SIZE));
1094        cc += 1 + LINK_SIZE + 2;        cc += 1 + LINK_SIZE + IMM2_SIZE;
1095        break;        break;
1096    
1097        case OP_CBRAPOS:        case OP_CBRAPOS:
1098        case OP_SCBRAPOS:        case OP_SCBRAPOS:
1099        count = 2;        count = 2;
1100        srcw[1] = OVECTOR_PRIV(GET2(cc, 1 + LINK_SIZE));        srcw[1] = OVECTOR_PRIV(GET2(cc, 1 + LINK_SIZE));
1101        srcw[0] = PRIV(cc);        srcw[0] = PRIV_DATA(cc);
1102        SLJIT_ASSERT(srcw[0] != 0);        SLJIT_ASSERT(srcw[0] != 0);
1103        cc += 1 + LINK_SIZE + 2;        cc += 1 + LINK_SIZE + IMM2_SIZE;
1104        break;        break;
1105    
1106        case OP_COND:        case OP_COND:
# Line 1000  while (status != end) Line 1109  while (status != end)
1109        if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)        if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)
1110          {          {
1111          count = 1;          count = 1;
1112          srcw[0] = PRIV(cc);          srcw[0] = PRIV_DATA(cc);
1113          SLJIT_ASSERT(srcw[0] != 0);          SLJIT_ASSERT(srcw[0] != 0);
1114          }          }
1115        cc += 1 + LINK_SIZE;        cc += 1 + LINK_SIZE;
# Line 1164  while (list_item) Line 1273  while (list_item)
1273      case stack_alloc:      case stack_alloc:
1274      add_jump(compiler, &common->stackalloc, JUMP(SLJIT_FAST_CALL));      add_jump(compiler, &common->stackalloc, JUMP(SLJIT_FAST_CALL));
1275      break;      break;
   
     case max_index:  
     OP1(SLJIT_MOV, MAX_INDEX, 0, SLJIT_IMM, list_item->data);  
     break;  
1276      }      }
1277    JUMPTO(SLJIT_JUMP, list_item->leave);    JUMPTO(SLJIT_JUMP, list_item->leave);
1278    list_item = list_item->next;    list_item = list_item->next;
# Line 1175  while (list_item) Line 1280  while (list_item)
1280  common->stubs = NULL;  common->stubs = NULL;
1281  }  }
1282    
1283    static SLJIT_INLINE void decrease_call_count(compiler_common *common)
1284    {
1285    DEFINE_COMPILER;
1286    
1287    OP2(SLJIT_SUB | SLJIT_SET_E, CALL_COUNT, 0, CALL_COUNT, 0, SLJIT_IMM, 1);
1288    add_jump(compiler, &common->calllimit, JUMP(SLJIT_C_ZERO));
1289    }
1290    
1291  static SLJIT_INLINE void allocate_stack(compiler_common *common, int size)  static SLJIT_INLINE void allocate_stack(compiler_common *common, int size)
1292  {  {
1293  /* May destroy all locals and registers except TMP2. */  /* May destroy all locals and registers except TMP2. */
# Line 1204  struct sljit_label *loop; Line 1317  struct sljit_label *loop;
1317  int i;  int i;
1318  /* At this point we can freely use all temporary registers. */  /* At this point we can freely use all temporary registers. */
1319  /* TMP1 returns with begin - 1. */  /* TMP1 returns with begin - 1. */
1320  OP1(SLJIT_MOV, MAX_INDEX, 0, SLJIT_IMM, 1);  OP2(SLJIT_SUB, SLJIT_TEMPORARY_REG1, 0, SLJIT_MEM1(SLJIT_SAVED_REG1), SLJIT_OFFSETOF(jit_arguments, begin), SLJIT_IMM, IN_UCHARS(1));
 OP2(SLJIT_SUB, SLJIT_TEMPORARY_REG1, 0, SLJIT_MEM1(SLJIT_GENERAL_REG1), SLJIT_OFFSETOF(jit_arguments, begin), SLJIT_IMM, 1);  
1321  if (length < 8)  if (length < 8)
1322    {    {
1323    for (i = 0; i < length; i++)    for (i = 0; i < length; i++)
# Line 1222  else Line 1334  else
1334    }    }
1335  }  }
1336    
1337  static SLJIT_INLINE void copy_ovector(compiler_common *common)  static SLJIT_INLINE void copy_ovector(compiler_common *common, int topbracket)
1338  {  {
1339  DEFINE_COMPILER;  DEFINE_COMPILER;
1340  struct sljit_label *loop;  struct sljit_label *loop;
1341  struct sljit_jump *earlyexit;  struct sljit_jump *earlyexit;
1342    
1343  /* At this point we can freely use all registers. */  /* At this point we can freely use all registers. */
1344    OP1(SLJIT_MOV, SLJIT_SAVED_REG3, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1));
1345    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1), STR_PTR, 0);
1346    
1347  OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG1, 0, ARGUMENTS, 0);  OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG1, 0, ARGUMENTS, 0);
1348    if (common->mark_ptr != 0)
1349      OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG3, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr);
1350  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));
1351    if (common->mark_ptr != 0)
1352      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_TEMPORARY_REG1), SLJIT_OFFSETOF(jit_arguments, mark_ptr), SLJIT_TEMPORARY_REG3, 0);
1353  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));
1354  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));
1355  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);
1356  /* Unlikely, but possible */  /* Unlikely, but possible */
1357  earlyexit = CMP(SLJIT_C_EQUAL, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, 0);  earlyexit = CMP(SLJIT_C_EQUAL, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, 0);
1358  loop = LABEL();  loop = LABEL();
1359  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);
1360  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));
1361  /* Copy the integer value to the output buffer */  /* Copy the integer value to the output buffer */
1362  OP1(SLJIT_MOVU_SI, SLJIT_MEM1(SLJIT_TEMPORARY_REG3), sizeof(int), SLJIT_GENERAL_REG2, 0);  #ifdef COMPILE_PCRE16
1363    OP2(SLJIT_ASHR, SLJIT_SAVED_REG2, 0, SLJIT_SAVED_REG2, 0, SLJIT_IMM, 1);
1364    #endif
1365    OP1(SLJIT_MOVU_SI, SLJIT_MEM1(SLJIT_TEMPORARY_REG3), sizeof(int), SLJIT_SAVED_REG2, 0);
1366  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);
1367  JUMPTO(SLJIT_C_NOT_ZERO, loop);  JUMPTO(SLJIT_C_NOT_ZERO, loop);
1368  JUMPHERE(earlyexit);  JUMPHERE(earlyexit);
1369    
1370    /* Calculate the return value, which is the maximum ovector value. */
1371    if (topbracket > 1)
1372      {
1373      OP2(SLJIT_ADD, SLJIT_TEMPORARY_REG1, 0, SLJIT_LOCALS_REG, 0, SLJIT_IMM, OVECTOR_START + topbracket * 2 * sizeof(sljit_w));
1374      OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, topbracket + 1);
1375    
1376      /* OVECTOR(0) is never equal to SLJIT_SAVED_REG3. */
1377      loop = LABEL();
1378      OP1(SLJIT_MOVU, SLJIT_TEMPORARY_REG3, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG1), -(2 * (sljit_w)sizeof(sljit_w)));
1379      OP2(SLJIT_SUB, SLJIT_TEMPORARY_REG2, 0, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, 1);
1380      CMPTO(SLJIT_C_EQUAL, SLJIT_TEMPORARY_REG3, 0, SLJIT_SAVED_REG3, 0, loop);
1381      OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_TEMPORARY_REG2, 0);
1382      }
1383    else
1384      OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, 1);
1385    }
1386    
1387    static SLJIT_INLINE void return_with_partial_match(compiler_common *common, struct sljit_label *leave)
1388    {
1389    DEFINE_COMPILER;
1390    
1391    SLJIT_COMPILE_ASSERT(STR_END == SLJIT_SAVED_REG2, str_end_must_be_saved_reg2);
1392    SLJIT_ASSERT(common->start_used_ptr != 0 && (common->mode == JIT_PARTIAL_SOFT_COMPILE ? common->hit_start != 0 : common->hit_start == 0));
1393    
1394    OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, ARGUMENTS, 0);
1395    OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_PARTIAL);
1396    OP1(SLJIT_MOV_SI, SLJIT_TEMPORARY_REG3, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), SLJIT_OFFSETOF(jit_arguments, offsetcount));
1397    CMPTO(SLJIT_C_LESS, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, 2, leave);
1398    
1399    /* Store match begin and end. */
1400    OP1(SLJIT_MOV, SLJIT_SAVED_REG1, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), SLJIT_OFFSETOF(jit_arguments, begin));
1401    OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), SLJIT_OFFSETOF(jit_arguments, offsets));
1402    OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG3, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mode == JIT_PARTIAL_HARD_COMPILE ? common->start_used_ptr : common->hit_start);
1403    OP2(SLJIT_SUB, SLJIT_SAVED_REG2, 0, STR_END, 0, SLJIT_SAVED_REG1, 0);
1404    #ifdef COMPILE_PCRE16
1405    OP2(SLJIT_ASHR, SLJIT_SAVED_REG2, 0, SLJIT_SAVED_REG2, 0, SLJIT_IMM, 1);
1406    #endif
1407    OP1(SLJIT_MOV_SI, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), sizeof(int), SLJIT_SAVED_REG2, 0);
1408    
1409    OP2(SLJIT_SUB, SLJIT_TEMPORARY_REG3, 0, SLJIT_TEMPORARY_REG3, 0, SLJIT_SAVED_REG1, 0);
1410    #ifdef COMPILE_PCRE16
1411    OP2(SLJIT_ASHR, SLJIT_TEMPORARY_REG3, 0, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, 1);
1412    #endif
1413    OP1(SLJIT_MOV_SI, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), 0, SLJIT_TEMPORARY_REG3, 0);
1414    
1415    JUMPTO(SLJIT_JUMP, leave);
1416    }
1417    
1418    static SLJIT_INLINE void check_start_used_ptr(compiler_common *common)
1419    {
1420    /* May destroy TMP1. */
1421    DEFINE_COMPILER;
1422    struct sljit_jump *jump;
1423    
1424    if (common->mode == JIT_PARTIAL_SOFT_COMPILE)
1425      {
1426      /* The value of -1 must be kept for start_used_ptr! */
1427      OP2(SLJIT_ADD, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, SLJIT_IMM, 1);
1428      /* Jumps if start_used_ptr < STR_PTR, or start_used_ptr == -1. Although overwriting
1429      is not necessary if start_used_ptr == STR_PTR, it does not hurt as well. */
1430      jump = CMP(SLJIT_C_LESS_EQUAL, TMP1, 0, STR_PTR, 0);
1431      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0);
1432      JUMPHERE(jump);
1433      }
1434    else if (common->mode == JIT_PARTIAL_HARD_COMPILE)
1435      {
1436      jump = CMP(SLJIT_C_LESS_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0);
1437      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0);
1438      JUMPHERE(jump);
1439      }
1440  }  }
1441    
1442  static SLJIT_INLINE BOOL char_has_othercase(compiler_common *common, uschar* cc)  static SLJIT_INLINE BOOL char_has_othercase(compiler_common *common, pcre_uchar* cc)
1443  {  {
1444  /* Detects if the character has an othercase. */  /* Detects if the character has an othercase. */
1445  unsigned int c;  unsigned int c;
1446    
1447  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
1448  if (common->utf8)  if (common->utf)
1449    {    {
1450    GETCHAR(c, cc);    GETCHAR(c, cc);
1451    if (c > 127)    if (c > 127)
# Line 1263  if (common->utf8) Line 1456  if (common->utf8)
1456      return FALSE;      return FALSE;
1457  #endif  #endif
1458      }      }
1459    #ifndef COMPILE_PCRE8
1460      return common->fcc[c] != c;
1461    #endif
1462    }    }
1463  else  else
1464  #endif  #endif
1465    c = *cc;    c = *cc;
1466  return common->fcc[c] != c;  return MAX_255(c) ? common->fcc[c] != c : FALSE;
1467  }  }
1468    
1469  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)
1470  {  {
1471  /* Returns with the othercase. */  /* Returns with the othercase. */
1472  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
1473  if (common->utf8 && c > 127)  if (common->utf && c > 127)
1474    {    {
1475  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
1476    return UCD_OTHERCASE(c);    return UCD_OTHERCASE(c);
# Line 1283  if (common->utf8 && c > 127) Line 1479  if (common->utf8 && c > 127)
1479  #endif  #endif
1480    }    }
1481  #endif  #endif
1482  return common->fcc[c];  return TABLE_GET(c, common->fcc, c);
1483  }  }
1484    
1485  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)
1486  {  {
1487  /* Detects if the character and its othercase has only 1 bit difference. */  /* Detects if the character and its othercase has only 1 bit difference. */
1488  unsigned int c, oc, bit;  unsigned int c, oc, bit;
1489  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF && defined COMPILE_PCRE8
1490  int n;  int n;
1491  #endif  #endif
1492    
1493  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
1494  if (common->utf8)  if (common->utf)
1495    {    {
1496    GETCHAR(c, cc);    GETCHAR(c, cc);
1497    if (c <= 127)    if (c <= 127)
# Line 1312  if (common->utf8) Line 1508  if (common->utf8)
1508  else  else
1509    {    {
1510    c = *cc;    c = *cc;
1511    oc = common->fcc[c];    oc = TABLE_GET(c, common->fcc, c);
1512    }    }
1513  #else  #else
1514  c = *cc;  c = *cc;
1515  oc = common->fcc[c];  oc = TABLE_GET(c, common->fcc, c);
1516  #endif  #endif
1517    
1518  SLJIT_ASSERT(c != oc);  SLJIT_ASSERT(c != oc);
# Line 1330  if (c <= 127 && bit == 0x20) Line 1526  if (c <= 127 && bit == 0x20)
1526  if (!ispowerof2(bit))  if (!ispowerof2(bit))
1527    return 0;    return 0;
1528    
1529  #ifdef SUPPORT_UTF8  #ifdef COMPILE_PCRE8
1530  if (common->utf8 && c > 127)  
1531    #ifdef SUPPORT_UTF
1532    if (common->utf && c > 127)
1533    {    {
1534    n = _pcre_utf8_table4[*cc & 0x3f];    n = GET_EXTRALEN(*cc);
1535    while ((bit & 0x3f) == 0)    while ((bit & 0x3f) == 0)
1536      {      {
1537      n--;      n--;
# Line 1341  if (common->utf8 && c > 127) Line 1539  if (common->utf8 && c > 127)
1539      }      }
1540    return (n << 8) | bit;    return (n << 8) | bit;
1541    }    }
1542  #endif  #endif /* SUPPORT_UTF */
1543  return (0 << 8) | bit;  return (0 << 8) | bit;
1544    
1545    #else /* COMPILE_PCRE8 */
1546    
1547    #ifdef COMPILE_PCRE16
1548    #ifdef SUPPORT_UTF
1549    if (common->utf && c > 65535)
1550      {
1551      if (bit >= (1 << 10))
1552        bit >>= 10;
1553      else
1554        return (bit < 256) ? ((2 << 8) | bit) : ((3 << 8) | (bit >> 8));
1555      }
1556    #endif /* SUPPORT_UTF */
1557    return (bit < 256) ? ((0 << 8) | bit) : ((1 << 8) | (bit >> 8));
1558    #endif /* COMPILE_PCRE16 */
1559    
1560    #endif /* COMPILE_PCRE8 */
1561    }
1562    
1563    static void check_partial(compiler_common *common, BOOL force)
1564    {
1565    /* Checks whether a partial matching is occured. Does not modify registers. */
1566    DEFINE_COMPILER;
1567    struct sljit_jump *jump = NULL;
1568    
1569    SLJIT_ASSERT(!force || common->mode != JIT_COMPILE);
1570    
1571    if (common->mode == JIT_COMPILE)
1572      return;
1573    
1574    if (!force)
1575      jump = CMP(SLJIT_C_GREATER_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0);
1576    else if (common->mode == JIT_PARTIAL_SOFT_COMPILE)
1577      jump = CMP(SLJIT_C_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, SLJIT_IMM, -1);
1578    
1579    if (common->mode == JIT_PARTIAL_SOFT_COMPILE)
1580      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, -1);
1581    else
1582      {
1583      if (common->partialmatchlabel != NULL)
1584        JUMPTO(SLJIT_JUMP, common->partialmatchlabel);
1585      else
1586        add_jump(compiler, &common->partialmatch, JUMP(SLJIT_JUMP));
1587      }
1588    
1589    if (jump != NULL)
1590      JUMPHERE(jump);
1591    }
1592    
1593    static struct sljit_jump *check_str_end(compiler_common *common)
1594    {
1595    /* Does not affect registers. Usually used in a tight spot. */
1596    DEFINE_COMPILER;
1597    struct sljit_jump *jump;
1598    struct sljit_jump *nohit;
1599    struct sljit_jump *return_value;
1600    
1601    if (common->mode == JIT_COMPILE)
1602      return CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
1603    
1604    jump = CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0);
1605    if (common->mode == JIT_PARTIAL_SOFT_COMPILE)
1606      {
1607      nohit = CMP(SLJIT_C_GREATER_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0);
1608      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, -1);
1609      JUMPHERE(nohit);
1610      return_value = JUMP(SLJIT_JUMP);
1611      }
1612    else
1613      {
1614      return_value = CMP(SLJIT_C_GREATER_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0);
1615      if (common->partialmatchlabel != NULL)
1616        JUMPTO(SLJIT_JUMP, common->partialmatchlabel);
1617      else
1618        add_jump(compiler, &common->partialmatch, JUMP(SLJIT_JUMP));
1619      }
1620    JUMPHERE(jump);
1621    return return_value;
1622  }  }
1623    
1624  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)
1625  {  {
1626  DEFINE_COMPILER;  DEFINE_COMPILER;
1627  add_jump(compiler, fallbacks, CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0));  struct sljit_jump *jump;
1628    
1629    if (common->mode == JIT_COMPILE)
1630      {
1631      add_jump(compiler, fallbacks, CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0));
1632      return;
1633      }
1634    
1635    /* Partial matching mode. */
1636    jump = CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0);
1637    add_jump(compiler, fallbacks, CMP(SLJIT_C_GREATER_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0));
1638    if (common->mode == JIT_PARTIAL_SOFT_COMPILE)
1639      {
1640      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, -1);
1641      add_jump(compiler, fallbacks, JUMP(SLJIT_JUMP));
1642      }
1643    else
1644      {
1645      if (common->partialmatchlabel != NULL)
1646        JUMPTO(SLJIT_JUMP, common->partialmatchlabel);
1647      else
1648        add_jump(compiler, &common->partialmatch, JUMP(SLJIT_JUMP));
1649      }
1650    JUMPHERE(jump);
1651  }  }
1652    
1653  static void read_char(compiler_common *common)  static void read_char(compiler_common *common)
# Line 1356  static void read_char(compiler_common *c Line 1655  static void read_char(compiler_common *c
1655  /* Reads the character into TMP1, updates STR_PTR.  /* Reads the character into TMP1, updates STR_PTR.
1656  Does not check STR_END. TMP2 Destroyed. */  Does not check STR_END. TMP2 Destroyed. */
1657  DEFINE_COMPILER;  DEFINE_COMPILER;
1658  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
1659  struct sljit_jump *jump;  struct sljit_jump *jump;
1660  #endif  #endif
1661    
1662  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
1663  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
1664  if (common->utf8)  if (common->utf)
1665    {    {
1666    /* Should not found a value between 128 and 192 here. */  #ifdef COMPILE_PCRE8
1667    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 192);    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);
1668    add_jump(compiler, &common->utf8readchar, JUMP(SLJIT_FAST_CALL));  #else
1669    #ifdef COMPILE_PCRE16
1670      jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800);
1671    #endif
1672    #endif /* COMPILE_PCRE8 */
1673      add_jump(compiler, &common->utfreadchar, JUMP(SLJIT_FAST_CALL));
1674    JUMPHERE(jump);    JUMPHERE(jump);
1675    }    }
1676  #endif  #endif
1677  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));
1678  }  }
1679    
1680  static void peek_char(compiler_common *common)  static void peek_char(compiler_common *common)
# Line 1378  static void peek_char(compiler_common *c Line 1682  static void peek_char(compiler_common *c
1682  /* Reads the character into TMP1, keeps STR_PTR.  /* Reads the character into TMP1, keeps STR_PTR.
1683  Does not check STR_END. TMP2 Destroyed. */  Does not check STR_END. TMP2 Destroyed. */
1684  DEFINE_COMPILER;  DEFINE_COMPILER;
1685  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
1686  struct sljit_jump *jump;  struct sljit_jump *jump;
1687  #endif  #endif
1688    
1689  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
1690  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
1691  if (common->utf8)  if (common->utf)
1692    {    {
1693    /* Should not found a value between 128 and 192 here. */  #ifdef COMPILE_PCRE8
1694    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 192);    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);
1695    add_jump(compiler, &common->utf8readchar, JUMP(SLJIT_FAST_CALL));  #else
1696    #ifdef COMPILE_PCRE16
1697      jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800);
1698    #endif
1699    #endif /* COMPILE_PCRE8 */
1700      add_jump(compiler, &common->utfreadchar, JUMP(SLJIT_FAST_CALL));
1701    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
1702    JUMPHERE(jump);    JUMPHERE(jump);
1703    }    }
# Line 1399  static void read_char8_type(compiler_com Line 1708  static void read_char8_type(compiler_com
1708  {  {
1709  /* 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. */
1710  DEFINE_COMPILER;  DEFINE_COMPILER;
1711  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF || defined COMPILE_PCRE16
1712  struct sljit_jump *jump;  struct sljit_jump *jump;
1713  #endif  #endif
1714    
1715  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
1716  if (common->utf8)  if (common->utf)
1717    {    {
1718    OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), 0);    OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), 0);
1719    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));
1720    #ifdef COMPILE_PCRE8
1721    /* This can be an extra read in some situations, but hopefully    /* This can be an extra read in some situations, but hopefully
1722    it is a clever early read in most cases. */    it is needed in most cases. */
1723    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);
1724    /* Should not found a value between 128 and 192 here. */    jump = CMP(SLJIT_C_LESS, TMP2, 0, SLJIT_IMM, 0xc0);
1725    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));  
1726    JUMPHERE(jump);    JUMPHERE(jump);
1727    #else
1728    #ifdef COMPILE_PCRE16
1729      OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);
1730      jump = CMP(SLJIT_C_GREATER, TMP2, 0, SLJIT_IMM, 255);
1731      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);
1732      JUMPHERE(jump);
1733      /* Skip low surrogate if necessary. */
1734      OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0xfc00);
1735      OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, 0xd800);
1736      COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);
1737      OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 1);
1738      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
1739    #endif
1740    #endif /* COMPILE_PCRE8 */
1741    return;    return;
1742    }    }
1743  #endif  #endif
1744  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);  OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), 0);
1745  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 1);  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
1746  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), common->ctypes);  #ifdef COMPILE_PCRE16
1747    /* The ctypes array contains only 256 values. */
1748    OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);
1749    jump = CMP(SLJIT_C_GREATER, TMP2, 0, SLJIT_IMM, 255);
1750    #endif
1751    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);
1752    #ifdef COMPILE_PCRE16
1753    JUMPHERE(jump);
1754    #endif
1755  }  }
1756    
1757  static void skip_char_back(compiler_common *common)  static void skip_char_back(compiler_common *common)
1758  {  {
1759  /* 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. */
1760  DEFINE_COMPILER;  DEFINE_COMPILER;
1761  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF && defined COMPILE_PCRE8
1762  struct sljit_label *label;  struct sljit_label *label;
1763    
1764  if (common->utf8)  if (common->utf)
1765    {    {
1766    label = LABEL();    label = LABEL();
1767    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 1);    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), -IN_UCHARS(1));
1768    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));
1769    OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xc0);    OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xc0);
1770    CMPTO(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, 0x80, label);    CMPTO(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, 0x80, label);
1771    return;    return;
1772    }    }
1773  #endif  #endif
1774  OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 1);  #if defined SUPPORT_UTF && defined COMPILE_PCRE16
1775    if (common->utf)
1776      {
1777      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), -IN_UCHARS(1));
1778      OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
1779      /* Skip low surrogate if necessary. */
1780      OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);
1781      OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xdc00);
1782      COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);
1783      OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
1784      OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
1785      return;
1786      }
1787    #endif
1788    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
1789  }  }
1790    
1791  static void check_newlinechar(compiler_common *common, int nltype, jump_list **fallbacks, BOOL jumpiftrue)  static void check_newlinechar(compiler_common *common, int nltype, jump_list **fallbacks, BOOL jumpiftrue)
# Line 1463  else if (nltype == NLTYPE_ANYCRLF) Line 1808  else if (nltype == NLTYPE_ANYCRLF)
1808    }    }
1809  else  else
1810    {    {
1811    SLJIT_ASSERT(nltype == NLTYPE_FIXED && common->newline <= 255);    SLJIT_ASSERT(nltype == NLTYPE_FIXED && common->newline < 256);
1812    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));
1813    }    }
1814  }  }
1815    
1816  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
1817  static void do_utf8readchar(compiler_common *common)  
1818    #ifdef COMPILE_PCRE8
1819    static void do_utfreadchar(compiler_common *common)
1820  {  {
1821  /* Fast decoding an utf8 character. TMP1 contains the first byte  /* Fast decoding a UTF-8 character. TMP1 contains the first byte
1822  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. */
1823  DEFINE_COMPILER;  DEFINE_COMPILER;
1824  struct sljit_jump *jump;  struct sljit_jump *jump;
1825    
# Line 1480  sljit_emit_fast_enter(compiler, RETURN_A Line 1827  sljit_emit_fast_enter(compiler, RETURN_A
1827  /* Searching for the first zero. */  /* Searching for the first zero. */
1828  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);
1829  jump = JUMP(SLJIT_C_NOT_ZERO);  jump = JUMP(SLJIT_C_NOT_ZERO);
1830  /* 2 byte sequence */  /* Two byte sequence. */
1831  OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), 1);  OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
1832  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));
1833  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x1f);  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x1f);
1834  OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 6);  OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 6);
1835  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
1836  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
1837  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 1);  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, IN_UCHARS(1));
1838  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
1839  JUMPHERE(jump);  JUMPHERE(jump);
1840    
1841  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);
1842  jump = JUMP(SLJIT_C_NOT_ZERO);  jump = JUMP(SLJIT_C_NOT_ZERO);
1843  /* 3 byte sequence */  /* Three byte sequence. */
1844  OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), 1);  OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
1845  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x0f);  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x0f);
1846  OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 12);  OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 12);
1847  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
1848  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6);  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6);
1849  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
1850  OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), 2);  OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(2));
1851  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));
1852  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
1853  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
1854  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 2);  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, IN_UCHARS(2));
1855  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
1856  JUMPHERE(jump);  JUMPHERE(jump);
1857    
1858  OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x08);  /* Four byte sequence. */
1859  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);  
1860  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x07);  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x07);
1861  OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 18);  OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 18);
1862  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
1863  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 12);  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 12);
1864  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
1865  OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), 2);  OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(2));
1866  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
1867  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6);  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6);
1868  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
1869  OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), 3);  OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(3));
1870  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));
1871  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
1872  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
1873  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);  
1874  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
1875  }  }
1876    
1877  static void do_utf8readtype8(compiler_common *common)  static void do_utfreadtype8(compiler_common *common)
1878  {  {
1879  /* Fast decoding an utf8 character type. TMP2 contains the first byte  /* Fast decoding a UTF-8 character type. TMP2 contains the first byte
1880  of the character (>= 192) and TMP1 is destroyed. Return value in TMP1. */  of the character (>= 0xc0). Return value in TMP1. */
1881  DEFINE_COMPILER;  DEFINE_COMPILER;
1882  struct sljit_jump *jump;  struct sljit_jump *jump;
1883  struct sljit_jump *compare;  struct sljit_jump *compare;
# Line 1564  sljit_emit_fast_enter(compiler, RETURN_A Line 1886  sljit_emit_fast_enter(compiler, RETURN_A
1886    
1887  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);
1888  jump = JUMP(SLJIT_C_NOT_ZERO);  jump = JUMP(SLJIT_C_NOT_ZERO);
1889  /* 2 byte sequence */  /* Two byte sequence. */
1890  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
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  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x1f);  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x1f);
1893  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6);  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6);
1894  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x3f);  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x3f);
# Line 1581  sljit_emit_fast_return(compiler, RETURN_ Line 1903  sljit_emit_fast_return(compiler, RETURN_
1903  JUMPHERE(jump);  JUMPHERE(jump);
1904    
1905  /* We only have types for characters less than 256. */  /* We only have types for characters less than 256. */
1906  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);  
1907  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
1908  OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);  OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);
1909  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
1910  }  }
1911    
1912  #endif  #else /* COMPILE_PCRE8 */
1913    
1914    #ifdef COMPILE_PCRE16
1915    static void do_utfreadchar(compiler_common *common)
1916    {
1917    /* Fast decoding a UTF-16 character. TMP1 contains the first 16 bit char
1918    of the character (>= 0xd800). Return char value in TMP1, length - 1 in TMP2. */
1919    DEFINE_COMPILER;
1920    struct sljit_jump *jump;
1921    
1922    sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize);
1923    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xdc00);
1924    /* Do nothing, only return. */
1925    sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
1926    
1927    JUMPHERE(jump);
1928    /* Combine two 16 bit characters. */
1929    OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
1930    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
1931    OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x3ff);
1932    OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 10);
1933    OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3ff);
1934    OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
1935    OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, IN_UCHARS(1));
1936    OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x10000);
1937    sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
1938    }
1939    #endif /* COMPILE_PCRE16 */
1940    
1941    #endif /* COMPILE_PCRE8 */
1942    
1943    #endif /* SUPPORT_UTF */
1944    
1945  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
1946    
# Line 1606  SLJIT_ASSERT(UCD_BLOCK_SIZE == 128 && si Line 1958  SLJIT_ASSERT(UCD_BLOCK_SIZE == 128 && si
1958    
1959  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);
1960  OP2(SLJIT_LSHR, TMP2, 0, TMP1, 0, SLJIT_IMM, UCD_BLOCK_SHIFT);  OP2(SLJIT_LSHR, TMP2, 0, TMP1, 0, SLJIT_IMM, UCD_BLOCK_SHIFT);
1961  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));
1962  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, UCD_BLOCK_MASK);  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, UCD_BLOCK_MASK);
1963  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, UCD_BLOCK_SHIFT);  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, UCD_BLOCK_SHIFT);
1964  OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, TMP2, 0);  OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, TMP2, 0);
1965  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, (sljit_w)_pcre_ucd_stage2);  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, (sljit_w)PRIV(ucd_stage2));
1966  OP1(SLJIT_MOV_UH, TMP2, 0, SLJIT_MEM2(TMP2, TMP1), 1);  OP1(SLJIT_MOV_UH, TMP2, 0, SLJIT_MEM2(TMP2, TMP1), 1);
1967  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));
1968  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM2(TMP1, TMP2), 3);  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM2(TMP1, TMP2), 3);
1969  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
1970  }  }
# Line 1626  struct sljit_label *newlinelabel = NULL; Line 1978  struct sljit_label *newlinelabel = NULL;
1978  struct sljit_jump *start;  struct sljit_jump *start;
1979  struct sljit_jump *end = NULL;  struct sljit_jump *end = NULL;
1980  struct sljit_jump *nl = NULL;  struct sljit_jump *nl = NULL;
1981    #ifdef SUPPORT_UTF
1982    struct sljit_jump *singlechar;
1983    #endif
1984  jump_list *newline = NULL;  jump_list *newline = NULL;
1985  BOOL newlinecheck = FALSE;  BOOL newlinecheck = FALSE;
1986  BOOL readbyte = FALSE;  BOOL readuchar = FALSE;
1987    
1988  if (!(hascrorlf || firstline) && (common->nltype == NLTYPE_ANY ||  if (!(hascrorlf || firstline) && (common->nltype == NLTYPE_ANY ||
1989      common->nltype == NLTYPE_ANYCRLF || common->newline > 255))      common->nltype == NLTYPE_ANYCRLF || common->newline > 255))
# Line 1637  if (!(hascrorlf || firstline) && (common Line 1992  if (!(hascrorlf || firstline) && (common
1992  if (firstline)  if (firstline)
1993    {    {
1994    /* Search for the end of the first line. */    /* Search for the end of the first line. */
1995      SLJIT_ASSERT(common->first_line_end != 0);
1996    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, STR_PTR, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, STR_PTR, 0);
1997    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), FIRSTLINE_END, STR_END, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end, STR_END, 0);
1998    
1999    if (common->nltype == NLTYPE_FIXED && common->newline > 255)    if (common->nltype == NLTYPE_FIXED && common->newline > 255)
2000      {      {
2001      mainloop = LABEL();      mainloop = LABEL();
2002      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));
2003      end = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);      end = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
2004      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), -1);      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-1));
2005      OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), 0);      OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
2006      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);
2007      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);
2008      OP2(SLJIT_SUB, SLJIT_MEM1(SLJIT_LOCALS_REG), FIRSTLINE_END, STR_PTR, 0, SLJIT_IMM, 1);      OP2(SLJIT_SUB, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2009      }      }
2010    else    else
2011      {      {
2012      end = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);      end = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
2013      mainloop = LABEL();      mainloop = LABEL();
2014      /* Continual stores does not cause data dependency. */      /* Continual stores does not cause data dependency. */
2015      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), FIRSTLINE_END, STR_PTR, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end, STR_PTR, 0);
2016      read_char(common);      read_char(common);
2017      check_newlinechar(common, common->nltype, &newline, TRUE);      check_newlinechar(common, common->nltype, &newline, TRUE);
2018      CMPTO(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0, mainloop);      CMPTO(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0, mainloop);
2019      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), FIRSTLINE_END, STR_PTR, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end, STR_PTR, 0);
2020      set_jumps(newline, LABEL());      set_jumps(newline, LABEL());
2021      }      }
2022    
# Line 1673  start = JUMP(SLJIT_JUMP); Line 2029  start = JUMP(SLJIT_JUMP);
2029  if (newlinecheck)  if (newlinecheck)
2030    {    {
2031    newlinelabel = LABEL();    newlinelabel = LABEL();
2032    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));
2033    end = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);    end = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
2034    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
2035    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);
2036    COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);    COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);
2037    #ifdef COMPILE_PCRE16
2038      OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
2039    #endif
2040    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2041    nl = JUMP(SLJIT_JUMP);    nl = JUMP(SLJIT_JUMP);
2042    }    }
# Line 1685  if (newlinecheck) Line 2044  if (newlinecheck)
2044  mainloop = LABEL();  mainloop = LABEL();
2045    
2046  /* 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. */
2047  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
2048  if (common->utf8) readbyte = TRUE;  if (common->utf) readuchar = TRUE;
2049  #endif  #endif
2050  if (newlinecheck) readbyte = TRUE;  if (newlinecheck) readuchar = TRUE;
2051    
2052  if (readbyte)  if (readuchar)
2053    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
2054    
2055  if (newlinecheck)  if (newlinecheck)
2056    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);
2057    
2058  #ifdef SUPPORT_UTF8  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2059  if (common->utf8)  #if defined SUPPORT_UTF && defined COMPILE_PCRE8
2060    if (common->utf)
2061    {    {
2062    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);
2063      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)PRIV(utf8_table4) - 0xc0);
2064    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2065      JUMPHERE(singlechar);
2066      }
2067    #endif
2068    #if defined SUPPORT_UTF && defined COMPILE_PCRE16
2069    if (common->utf)
2070      {
2071      singlechar = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800);
2072      OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);
2073      OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xd800);
2074      COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);
2075      OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
2076      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2077      JUMPHERE(singlechar);
2078    }    }
 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);  
2079  #endif  #endif
2080  JUMPHERE(start);  JUMPHERE(start);
2081    
# Line 1718  if (newlinecheck) Line 2088  if (newlinecheck)
2088  return mainloop;  return mainloop;
2089  }  }
2090    
2091  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)
2092  {  {
2093  DEFINE_COMPILER;  DEFINE_COMPILER;
2094  struct sljit_label *start;  struct sljit_label *start;
2095  struct sljit_jump *leave;  struct sljit_jump *leave;
2096  struct sljit_jump *found;  struct sljit_jump *found;
2097  pcre_uint16 oc, bit;  pcre_uchar oc, bit;
2098    
2099  if (firstline)  if (firstline)
2100    {    {
2101    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, STR_END, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, STR_END, 0);
2102    OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), FIRSTLINE_END);    OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end);
2103    }    }
2104    
2105  start = LABEL();  start = LABEL();
2106  leave = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);  leave = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
2107  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
2108    
2109  if ((firstbyte & REQ_CASELESS) == 0)  oc = first_char;
2110    found = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, firstbyte & 0xff);  if (caseless)
2111      {
2112      oc = TABLE_GET(first_char, common->fcc, first_char);
2113    #if defined SUPPORT_UCP && !(defined COMPILE_PCRE8)
2114      if (first_char > 127 && common->utf)
2115        oc = UCD_OTHERCASE(first_char);
2116    #endif
2117      }
2118    if (first_char == oc)
2119      found = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, first_char);
2120  else  else
2121    {    {
2122    firstbyte &= 0xff;    bit = first_char ^ oc;
   oc = common->fcc[firstbyte];  
   bit = firstbyte ^ oc;  
2123    if (ispowerof2(bit))    if (ispowerof2(bit))
2124      {      {
2125      OP2(SLJIT_OR, TMP2, 0, TMP1, 0, SLJIT_IMM, bit);      OP2(SLJIT_OR, TMP2, 0, TMP1, 0, SLJIT_IMM, bit);
2126      found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, firstbyte | bit);      found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, first_char | bit);
2127      }      }
2128    else    else
2129      {      {
2130      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);
2131      COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);      COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);
2132      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);
2133      COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);      COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);
# Line 1758  else Line 2135  else
2135      }      }
2136    }    }
2137    
2138  #ifdef SUPPORT_UTF8  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2139  if (common->utf8)  #if defined SUPPORT_UTF && defined COMPILE_PCRE8
2140    if (common->utf)
2141    {    {
2142    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);
2143      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)PRIV(utf8_table4) - 0xc0);
2144      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2145      }
2146    #endif
2147    #if defined SUPPORT_UTF && defined COMPILE_PCRE16
2148    if (common->utf)
2149      {
2150      CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800, start);
2151      OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);
2152      OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xd800);
2153      COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);
2154      OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
2155    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2156    }    }
 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);  
2157  #endif  #endif
2158  JUMPTO(SLJIT_JUMP, start);  JUMPTO(SLJIT_JUMP, start);
2159  JUMPHERE(found);  JUMPHERE(found);
# Line 1791  jump_list *newline = NULL; Line 2177  jump_list *newline = NULL;
2177  if (firstline)  if (firstline)
2178    {    {
2179    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, STR_END, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, STR_END, 0);
2180    OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), FIRSTLINE_END);    OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end);
2181    }    }
2182    
2183  if (common->nltype == NLTYPE_FIXED && common->newline > 255)  if (common->nltype == NLTYPE_FIXED && common->newline > 255)
# Line 1802  if (common->nltype == NLTYPE_FIXED && co Line 2188  if (common->nltype == NLTYPE_FIXED && co
2188    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));
2189    firstchar = CMP(SLJIT_C_LESS_EQUAL, STR_PTR, 0, TMP2, 0);    firstchar = CMP(SLJIT_C_LESS_EQUAL, STR_PTR, 0, TMP2, 0);
2190    
2191    OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 2);    OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(2));
2192    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);
2193    COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_GREATER_EQUAL);    COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_GREATER_EQUAL);
2194    #ifdef COMPILE_PCRE16
2195      OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 1);
2196    #endif
2197    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
2198    
2199    loop = LABEL();    loop = LABEL();
2200    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));
2201    leave = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);    leave = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
2202    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), -2);    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-2));
2203    OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), -1);    OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-1));
2204    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);
2205    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);
2206    
# Line 1842  if (common->nltype == NLTYPE_ANY || comm Line 2231  if (common->nltype == NLTYPE_ANY || comm
2231    leave = JUMP(SLJIT_JUMP);    leave = JUMP(SLJIT_JUMP);
2232    JUMPHERE(foundcr);    JUMPHERE(foundcr);
2233    notfoundnl = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);    notfoundnl = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
2234    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
2235    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);
2236    COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);    COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);
2237    #ifdef COMPILE_PCRE16
2238      OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
2239    #endif
2240    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2241    JUMPHERE(notfoundnl);    JUMPHERE(notfoundnl);
2242    JUMPHERE(leave);    JUMPHERE(leave);
# Line 1862  DEFINE_COMPILER; Line 2254  DEFINE_COMPILER;
2254  struct sljit_label *start;  struct sljit_label *start;
2255  struct sljit_jump *leave;  struct sljit_jump *leave;
2256  struct sljit_jump *found;  struct sljit_jump *found;
2257    #ifndef COMPILE_PCRE8
2258    struct sljit_jump *jump;
2259    #endif
2260    
2261  if (firstline)  if (firstline)
2262    {    {
2263    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, STR_END, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, STR_END, 0);
2264    OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), FIRSTLINE_END);    OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end);
2265    }    }
2266    
2267  start = LABEL();  start = LABEL();
2268  leave = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);  leave = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
2269  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
2270  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
2271  if (common->utf8)  if (common->utf)
2272    OP1(SLJIT_MOV_UB, TMP3, 0, SLJIT_MEM1(TMP1), (sljit_w)_pcre_utf8_char_sizes);    OP1(SLJIT_MOV, TMP3, 0, TMP1, 0);
2273    #endif
2274    #ifndef COMPILE_PCRE8
2275    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 255);
2276    OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 255);
2277    JUMPHERE(jump);
2278  #endif  #endif
2279  OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);  OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);
2280  OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);  OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);
# Line 1883  OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TM Line 2283  OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TM
2283  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);
2284  found = JUMP(SLJIT_C_NOT_ZERO);  found = JUMP(SLJIT_C_NOT_ZERO);
2285    
2286  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
2287  if (common->utf8)  if (common->utf)
2288    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP3, 0);    OP1(SLJIT_MOV, TMP1, 0, TMP3, 0);
2289  else  #endif
2290    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));
2291  #else  #if defined SUPPORT_UTF && defined COMPILE_PCRE8
2292  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 1);  if (common->utf)
2293      {
2294      CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0, start);
2295      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)PRIV(utf8_table4) - 0xc0);
2296      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2297      }
2298    #endif
2299    #if defined SUPPORT_UTF && defined COMPILE_PCRE16
2300    if (common->utf)
2301      {
2302      CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800, start);
2303      OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);
2304      OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xd800);
2305      COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);
2306      OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
2307      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2308      }
2309  #endif  #endif
2310  JUMPTO(SLJIT_JUMP, start);  JUMPTO(SLJIT_JUMP, start);
2311  JUMPHERE(found);  JUMPHERE(found);
# Line 1899  if (firstline) Line 2315  if (firstline)
2315    OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0);    OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0);
2316  }  }
2317    
2318  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)
2319  {  {
2320  DEFINE_COMPILER;  DEFINE_COMPILER;
2321  struct sljit_label *loop;  struct sljit_label *loop;
# Line 1908  struct sljit_jump *alreadyfound; Line 2324  struct sljit_jump *alreadyfound;
2324  struct sljit_jump *found;  struct sljit_jump *found;
2325  struct sljit_jump *foundoc = NULL;  struct sljit_jump *foundoc = NULL;
2326  struct sljit_jump *notfound;  struct sljit_jump *notfound;
2327  pcre_uint16 oc, bit;  pcre_uchar oc, bit;
2328    
2329  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), REQ_BYTE_PTR);  SLJIT_ASSERT(common->req_char_ptr != 0);
2330    OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->req_char_ptr);
2331  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);
2332  toolong = CMP(SLJIT_C_LESS, TMP1, 0, STR_END, 0);  toolong = CMP(SLJIT_C_LESS, TMP1, 0, STR_END, 0);
2333  alreadyfound = CMP(SLJIT_C_LESS, STR_PTR, 0, TMP2, 0);  alreadyfound = CMP(SLJIT_C_LESS, STR_PTR, 0, TMP2, 0);
2334    
2335  if (has_firstbyte)  if (has_firstchar)
2336    OP2(SLJIT_ADD, TMP1, 0, STR_PTR, 0, SLJIT_IMM, 1);    OP2(SLJIT_ADD, TMP1, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2337  else  else
2338    OP1(SLJIT_MOV, TMP1, 0, STR_PTR, 0);    OP1(SLJIT_MOV, TMP1, 0, STR_PTR, 0);
2339    
2340  loop = LABEL();  loop = LABEL();
2341  notfound = CMP(SLJIT_C_GREATER_EQUAL, TMP1, 0, STR_END, 0);  notfound = CMP(SLJIT_C_GREATER_EQUAL, TMP1, 0, STR_END, 0);
2342    
2343  OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP1), 0);  OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(TMP1), 0);
2344  if ((reqbyte & REQ_CASELESS) == 0)  oc = req_char;
2345    found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, reqbyte & 0xff);  if (caseless)
2346      {
2347      oc = TABLE_GET(req_char, common->fcc, req_char);
2348    #if defined SUPPORT_UCP && !(defined COMPILE_PCRE8)
2349      if (req_char > 127 && common->utf)
2350        oc = UCD_OTHERCASE(req_char);
2351    #endif
2352      }
2353    if (req_char == oc)
2354      found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, req_char);
2355  else  else
2356    {    {
2357    reqbyte &= 0xff;    bit = req_char ^ oc;
   oc = common->fcc[reqbyte];  
   bit = reqbyte ^ oc;  
2358    if (ispowerof2(bit))    if (ispowerof2(bit))
2359      {      {
2360      OP2(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_IMM, bit);      OP2(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_IMM, bit);
2361      found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, reqbyte | bit);      found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, req_char | bit);
2362      }      }
2363    else    else
2364      {      {
2365      found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, reqbyte);      found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, req_char);
2366      foundoc = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, oc);      foundoc = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, oc);
2367      }      }
2368    }    }
2369  OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);  OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(1));
2370  JUMPTO(SLJIT_JUMP, loop);  JUMPTO(SLJIT_JUMP, loop);
2371    
2372  JUMPHERE(found);  JUMPHERE(found);
2373  if (foundoc)  if (foundoc)
2374    JUMPHERE(foundoc);    JUMPHERE(foundoc);
2375  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), REQ_BYTE_PTR, TMP1, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->req_char_ptr, TMP1, 0);
2376  JUMPHERE(alreadyfound);  JUMPHERE(alreadyfound);
2377  JUMPHERE(toolong);  JUMPHERE(toolong);
2378  return notfound;  return notfound;
# Line 1957  return notfound; Line 2381  return notfound;
2381  static void do_revertframes(compiler_common *common)  static void do_revertframes(compiler_common *common)
2382  {  {
2383  DEFINE_COMPILER;  DEFINE_COMPILER;
 struct sljit_jump *earlyexit;  
2384  struct sljit_jump *jump;  struct sljit_jump *jump;
2385  struct sljit_label *mainloop;  struct sljit_label *mainloop;
2386    
2387  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);
2388  OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS_HEAD);  OP1(SLJIT_MOV, TMP1, 0, STACK_TOP, 0);
2389    
2390  /* Drop frames until we reach STACK_TOP. */  /* Drop frames until we reach STACK_TOP. */
 earlyexit = CMP(SLJIT_C_LESS, TMP1, 0, STACK_TOP, 0);  
2391  mainloop = LABEL();  mainloop = LABEL();
2392  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), 0);  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), 0);
2393  jump = CMP(SLJIT_C_SIG_LESS_EQUAL, TMP2, 0, SLJIT_IMM, frame_end);  jump = CMP(SLJIT_C_SIG_LESS_EQUAL, TMP2, 0, SLJIT_IMM, frame_end);
# Line 1978  JUMPTO(SLJIT_JUMP, mainloop); Line 2400  JUMPTO(SLJIT_JUMP, mainloop);
2400  JUMPHERE(jump);  JUMPHERE(jump);
2401  jump = CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, frame_end);  jump = CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, frame_end);
2402  /* 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);  
2403  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
2404    
2405  JUMPHERE(jump);  JUMPHERE(jump);
 jump = CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, frame_setmaxindex);  
 /* Set max index. */  
 OP1(SLJIT_MOV, MAX_INDEX, 0, SLJIT_MEM1(TMP1), sizeof(sljit_w));  
 OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 2 * sizeof(sljit_w));  
 JUMPTO(SLJIT_JUMP, mainloop);  
   
 JUMPHERE(jump);  
2406  jump = CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, frame_setstrbegin);  jump = CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, frame_setstrbegin);
2407  /* Set max index. */  /* Set string begin. */
2408  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), sizeof(sljit_w));  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), sizeof(sljit_w));
2409  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));
2410  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0), TMP2, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0), TMP2, 0);
2411  JUMPTO(SLJIT_JUMP, mainloop);  JUMPTO(SLJIT_JUMP, mainloop);
2412    
2413  JUMPHERE(jump);  JUMPHERE(jump);
2414    if (common->mark_ptr != 0)
2415      {
2416      jump = CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, frame_setmark);
2417      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), sizeof(sljit_w));
2418      OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 2 * sizeof(sljit_w));
2419      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr, TMP2, 0);
2420      JUMPTO(SLJIT_JUMP, mainloop);
2421    
2422      JUMPHERE(jump);
2423      }
2424    
2425  /* Unknown command. */  /* Unknown command. */
2426  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));
2427  JUMPTO(SLJIT_JUMP, mainloop);  JUMPTO(SLJIT_JUMP, mainloop);
# Line 2008  JUMPTO(SLJIT_JUMP, mainloop); Line 2430  JUMPTO(SLJIT_JUMP, mainloop);
2430  static void check_wordboundary(compiler_common *common)  static void check_wordboundary(compiler_common *common)
2431  {  {
2432  DEFINE_COMPILER;  DEFINE_COMPILER;
2433  struct sljit_jump *beginend;  struct sljit_jump *skipread;
2434    #if !(defined COMPILE_PCRE8) || defined SUPPORT_UTF
2435  struct sljit_jump *jump;  struct sljit_jump *jump;
2436    #endif
2437    
2438  SLJIT_ASSERT(ctype_word == 0x10);  SLJIT_COMPILE_ASSERT(ctype_word == 0x10, ctype_word_must_be_16);
2439    
2440  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);
2441  /* Get type of the previous char, and put it to LOCALS1. */  /* Get type of the previous char, and put it to LOCALS1. */
2442  OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);  OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
2443  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));
2444  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, SLJIT_IMM, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, SLJIT_IMM, 0);
2445  beginend = CMP(SLJIT_C_LESS_EQUAL, STR_PTR, 0, TMP1, 0);  skipread = CMP(SLJIT_C_LESS_EQUAL, STR_PTR, 0, TMP1, 0);
2446  skip_char_back(common);  skip_char_back(common);
2447    check_start_used_ptr(common);
2448  read_char(common);  read_char(common);
2449    
2450  /* Testing char type. */  /* Testing char type. */
2451  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
2452  if (common->useucp)  if (common->use_ucp)
2453    {    {
2454    OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 1);    OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 1);
2455    jump = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_UNDERSCORE);    jump = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_UNDERSCORE);
# Line 2041  if (common->useucp) Line 2466  if (common->useucp)
2466  else  else
2467  #endif  #endif
2468    {    {
2469  #ifdef SUPPORT_UTF8  #ifndef COMPILE_PCRE8
2470      jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);
2471    #elif defined SUPPORT_UTF
2472    /* Here LOCALS1 has already been zeroed. */    /* Here LOCALS1 has already been zeroed. */
2473    jump = NULL;    jump = NULL;
2474    if (common->utf8)    if (common->utf)
2475      jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);      jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);
2476  #endif  #endif /* COMPILE_PCRE8 */
2477    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), common->ctypes);    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), common->ctypes);
2478    OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 4 /* ctype_word */);    OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 4 /* ctype_word */);
2479    OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);    OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
2480    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, TMP1, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, TMP1, 0);
2481  #ifdef SUPPORT_UTF8  #ifndef COMPILE_PCRE8
2482      JUMPHERE(jump);
2483    #elif defined SUPPORT_UTF
2484    if (jump != NULL)    if (jump != NULL)
2485      JUMPHERE(jump);      JUMPHERE(jump);
2486  #endif  #endif /* COMPILE_PCRE8 */
2487    }    }
2488  JUMPHERE(beginend);  JUMPHERE(skipread);
2489    
2490  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0);  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0);
2491  beginend = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);  skipread = check_str_end(common);
2492  peek_char(common);  peek_char(common);
2493    
2494  /* Testing char type. This is a code duplication. */  /* Testing char type. This is a code duplication. */
2495  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
2496  if (common->useucp)  if (common->use_ucp)
2497    {    {
2498    OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 1);    OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 1);
2499    jump = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_UNDERSCORE);    jump = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_UNDERSCORE);
# Line 2080  if (common->useucp) Line 2509  if (common->useucp)
2509  else  else
2510  #endif  #endif
2511    {    {
2512  #ifdef SUPPORT_UTF8  #ifndef COMPILE_PCRE8
2513      /* TMP2 may be destroyed by peek_char. */
2514      OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0);
2515      jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);
2516    #elif defined SUPPORT_UTF
2517    OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0);    OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0);
2518    jump = NULL;    jump = NULL;
2519    if (common->utf8)    if (common->utf)
2520      jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);      jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);
2521  #endif  #endif
2522    OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP1), common->ctypes);    OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP1), common->ctypes);
2523    OP2(SLJIT_LSHR, TMP2, 0, TMP2, 0, SLJIT_IMM, 4 /* ctype_word */);    OP2(SLJIT_LSHR, TMP2, 0, TMP2, 0, SLJIT_IMM, 4 /* ctype_word */);
2524    OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 1);    OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 1);
2525  #ifdef SUPPORT_UTF8  #ifndef COMPILE_PCRE8
2526      JUMPHERE(jump);
2527    #elif defined SUPPORT_UTF
2528    if (jump != NULL)    if (jump != NULL)
2529      JUMPHERE(jump);      JUMPHERE(jump);
2530  #endif  #endif /* COMPILE_PCRE8 */
2531    }    }
2532  JUMPHERE(beginend);  JUMPHERE(skipread);
2533    
2534  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);
2535  sljit_emit_fast_return(compiler, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);  sljit_emit_fast_return(compiler, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);
# Line 2111  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_I Line 2546  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_I
2546  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);
2547  COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS_EQUAL);  COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS_EQUAL);
2548  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);
2549  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF || defined COMPILE_PCRE16
2550  if (common->utf8)  #ifdef COMPILE_PCRE8
2551    if (common->utf)
2552    {    {
2553    #endif
2554    COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);    COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);
2555    OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x1);    OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x1);
2556    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);
2557    #ifdef COMPILE_PCRE8
2558    }    }
2559  #endif  #endif
2560    #endif /* SUPPORT_UTF || COMPILE_PCRE16 */
2561  COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);  COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);
2562  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
2563  }  }
# Line 2135  COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_E Line 2574  COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_E
2574  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);
2575  COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);  COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);
2576  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);
2577  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF || defined COMPILE_PCRE16
2578  if (common->utf8)  #ifdef COMPILE_PCRE8
2579    if (common->utf)
2580    {    {
2581    #endif
2582    COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);    COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);
2583    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);
2584    COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);    COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);
# Line 2151  if (common->utf8) Line 2592  if (common->utf8)
2592    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);
2593    COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);    COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);
2594    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);
2595    #ifdef COMPILE_PCRE8
2596    }    }
2597  #endif  #endif
2598    #endif /* SUPPORT_UTF || COMPILE_PCRE16 */
2599  COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);  COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);
2600    
2601  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
# Line 2169  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_I Line 2612  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_I
2612  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);
2613  COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS_EQUAL);  COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS_EQUAL);
2614  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);
2615  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF || defined COMPILE_PCRE16
2616  if (common->utf8)  #ifdef COMPILE_PCRE8
2617    if (common->utf)
2618    {    {
2619    #endif
2620    COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);    COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);
2621    OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x1);    OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x1);
2622    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);
2623    #ifdef COMPILE_PCRE8
2624    }    }
2625  #endif  #endif
2626    #endif /* SUPPORT_UTF || COMPILE_PCRE16 */
2627  COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);  COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);
2628    
2629  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
# Line 2195  sljit_emit_fast_enter(compiler, RETURN_A Line 2642  sljit_emit_fast_enter(compiler, RETURN_A
2642  OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);  OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
2643  OP1(SLJIT_MOV, TMP3, 0, CHAR1, 0);  OP1(SLJIT_MOV, TMP3, 0, CHAR1, 0);
2644  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, CHAR2, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, CHAR2, 0);
2645  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(1));
2646  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));
2647    
2648  label = LABEL();  label = LABEL();
2649  OP1(SLJIT_MOVU_UB, CHAR1, 0, SLJIT_MEM1(TMP1), 1);  OP1(MOVU_UCHAR, CHAR1, 0, SLJIT_MEM1(TMP1), IN_UCHARS(1));
2650  OP1(SLJIT_MOVU_UB, CHAR2, 0, SLJIT_MEM1(STR_PTR), 1);  OP1(MOVU_UCHAR, CHAR2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
2651  jump = CMP(SLJIT_C_NOT_EQUAL, CHAR1, 0, CHAR2, 0);  jump = CMP(SLJIT_C_NOT_EQUAL, CHAR1, 0, CHAR2, 0);
2652  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));
2653  JUMPTO(SLJIT_C_NOT_ZERO, label);  JUMPTO(SLJIT_C_NOT_ZERO, label);
2654    
2655  JUMPHERE(jump);  JUMPHERE(jump);
2656  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));
2657  OP1(SLJIT_MOV, CHAR1, 0, TMP3, 0);  OP1(SLJIT_MOV, CHAR1, 0, TMP3, 0);
2658  OP1(SLJIT_MOV, CHAR2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);  OP1(SLJIT_MOV, CHAR2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);
2659  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
# Line 2227  OP1(SLJIT_MOV, TMP3, 0, LCC_TABLE, 0); Line 2674  OP1(SLJIT_MOV, TMP3, 0, LCC_TABLE, 0);
2674  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, CHAR1, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, CHAR1, 0);
2675  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, CHAR2, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, CHAR2, 0);
2676  OP1(SLJIT_MOV, LCC_TABLE, 0, SLJIT_IMM, common->lcc);  OP1(SLJIT_MOV, LCC_TABLE, 0, SLJIT_IMM, common->lcc);
2677  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(1));
2678  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));
2679    
2680  label = LABEL();  label = LABEL();
2681  OP1(SLJIT_MOVU_UB, CHAR1, 0, SLJIT_MEM1(TMP1), 1);  OP1(MOVU_UCHAR, CHAR1, 0, SLJIT_MEM1(TMP1), IN_UCHARS(1));
2682  OP1(SLJIT_MOVU_UB, CHAR2, 0, SLJIT_MEM1(STR_PTR), 1);  OP1(MOVU_UCHAR, CHAR2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
2683    #ifndef COMPILE_PCRE8
2684    jump = CMP(SLJIT_C_GREATER, CHAR1, 0, SLJIT_IMM, 255);
2685    #endif
2686  OP1(SLJIT_MOV_UB, CHAR1, 0, SLJIT_MEM2(LCC_TABLE, CHAR1), 0);  OP1(SLJIT_MOV_UB, CHAR1, 0, SLJIT_MEM2(LCC_TABLE, CHAR1), 0);
2687    #ifndef COMPILE_PCRE8
2688    JUMPHERE(jump);
2689    jump = CMP(SLJIT_C_GREATER, CHAR2, 0, SLJIT_IMM, 255);
2690    #endif
2691  OP1(SLJIT_MOV_UB, CHAR2, 0, SLJIT_MEM2(LCC_TABLE, CHAR2), 0);  OP1(SLJIT_MOV_UB, CHAR2, 0, SLJIT_MEM2(LCC_TABLE, CHAR2), 0);
2692    #ifndef COMPILE_PCRE8
2693    JUMPHERE(jump);
2694    #endif
2695  jump = CMP(SLJIT_C_NOT_EQUAL, CHAR1, 0, CHAR2, 0);  jump = CMP(SLJIT_C_NOT_EQUAL, CHAR1, 0, CHAR2, 0);
2696  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));
2697  JUMPTO(SLJIT_C_NOT_ZERO, label);  JUMPTO(SLJIT_C_NOT_ZERO, label);
2698    
2699  JUMPHERE(jump);  JUMPHERE(jump);
2700  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));
2701  OP1(SLJIT_MOV, LCC_TABLE, 0, TMP3, 0);  OP1(SLJIT_MOV, LCC_TABLE, 0, TMP3, 0);
2702  OP1(SLJIT_MOV, CHAR1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);  OP1(SLJIT_MOV, CHAR1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);
2703  OP1(SLJIT_MOV, CHAR2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1);  OP1(SLJIT_MOV, CHAR2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1);
# Line 2251  sljit_emit_fast_return(compiler, RETURN_ Line 2708  sljit_emit_fast_return(compiler, RETURN_
2708  #undef CHAR1  #undef CHAR1
2709  #undef CHAR2  #undef CHAR2
2710    
2711  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF && defined SUPPORT_UCP
 #ifdef SUPPORT_UCP  
2712    
2713  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)
2714  {  {
2715  /* This function would be ineffective to do in JIT level. */  /* This function would be ineffective to do in JIT level. */
2716  int c1, c2;  int c1, c2;
2717  uschar *src2 = args->ptr;  const pcre_uchar *src2 = args->uchar_ptr;
2718  uschar *end2 = (uschar*)args->end;  const pcre_uchar *end2 = args->end;
2719    
2720  while (src1 < end1)  while (src1 < end1)
2721    {    {
2722    if (src2 >= end2)    if (src2 >= end2)
2723      return 0;      return (pcre_uchar*)1;
2724    GETCHARINC(c1, src1);    GETCHARINC(c1, src1);
2725    GETCHARINC(c2, src2);    GETCHARINC(c2, src2);
2726    if (c1 != c2 && c1 != UCD_OTHERCASE(c2)) return 0;    if (c1 != c2 && c1 != UCD_OTHERCASE(c2)) return NULL;
2727    }    }
2728  return src2;  return src2;
2729  }  }
2730    
2731  #endif  #endif /* SUPPORT_UTF && SUPPORT_UCP */
 #endif  
2732    
2733  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,
2734      compare_context* context, jump_list **fallbacks)      compare_context* context, jump_list **fallbacks)
2735  {  {
2736  DEFINE_COMPILER;  DEFINE_COMPILER;
2737  unsigned int othercasebit = 0;  unsigned int othercasebit = 0;
2738  uschar *othercasebyte = NULL;  pcre_uchar *othercasechar = NULL;
2739  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
2740  int utf8length;  int utflength;
2741  #endif  #endif
2742    
2743  if (caseless && char_has_othercase(common, cc))  if (caseless && char_has_othercase(common, cc))
# Line 2290  if (caseless && char_has_othercase(commo Line 2745  if (caseless && char_has_othercase(commo
2745    othercasebit = char_get_othercase_bit(common, cc);    othercasebit = char_get_othercase_bit(common, cc);
2746    SLJIT_ASSERT(othercasebit);    SLJIT_ASSERT(othercasebit);
2747    /* Extracting bit difference info. */    /* Extracting bit difference info. */
2748    othercasebyte = cc + (othercasebit >> 8);  #ifdef COMPILE_PCRE8
2749      othercasechar = cc + (othercasebit >> 8);
2750    othercasebit &= 0xff;    othercasebit &= 0xff;
2751    #else
2752    #ifdef COMPILE_PCRE16
2753      othercasechar = cc + (othercasebit >> 9);
2754      if ((othercasebit & 0x100) != 0)
2755        othercasebit = (othercasebit & 0xff) << 8;
2756      else
2757        othercasebit &= 0xff;
2758    #endif
2759    #endif
2760    }    }
2761    
2762  if (context->sourcereg == -1)  if (context->sourcereg == -1)
2763    {    {
2764    #ifdef COMPILE_PCRE8
2765  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
2766    if (context->length >= 4)    if (context->length >= 4)
2767      OP1(SLJIT_MOV_SI, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);      OP1(SLJIT_MOV_SI, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);
2768    else if (context->length >= 2)    else if (context->length >= 2)
2769      OP1(SLJIT_MOV_SH, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);      OP1(SLJIT_MOV_UH, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);
2770    else    else
2771  #endif  #endif
2772      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);
2773    #else
2774    #ifdef COMPILE_PCRE16
2775    #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
2776      if (context->length >= 4)
2777        OP1(SLJIT_MOV_SI, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);
2778      else
2779    #endif
2780        OP1(SLJIT_MOV_UH, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);
2781    #endif
2782    #endif /* COMPILE_PCRE8 */
2783    context->sourcereg = TMP2;    context->sourcereg = TMP2;
2784    }    }
2785    
2786  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
2787  utf8length = 1;  utflength = 1;
2788  if (common->utf8 && *cc >= 0xc0)  if (common->utf && HAS_EXTRALEN(*cc))
2789    utf8length += _pcre_utf8_table4[*cc & 0x3f];    utflength += GET_EXTRALEN(*cc);
2790    
2791  do  do
2792    {    {
2793  #endif  #endif
2794    
2795    context->length--;    context->length -= IN_UCHARS(1);
2796  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
2797    
2798    /* Unaligned read is supported. */    /* Unaligned read is supported. */
2799    if (othercasebit != 0 && othercasebyte == cc)    if (othercasebit != 0 && othercasechar == cc)
2800      {      {
2801      context->c.asbytes[context->byteptr] = *cc | othercasebit;      context->c.asuchars[context->ucharptr] = *cc | othercasebit;
2802      context->oc.asbytes[context->byteptr] = othercasebit;      context->oc.asuchars[context->ucharptr] = othercasebit;
2803      }      }
2804    else    else
2805      {      {
2806      context->c.asbytes[context->byteptr] = *cc;      context->c.asuchars[context->ucharptr] = *cc;
2807      context->oc.asbytes[context->byteptr] = 0;      context->oc.asuchars[context->ucharptr] = 0;
2808      }      }
2809    context->byteptr++;    context->ucharptr++;
2810    
2811    if (context->byteptr >= 4 || context->length == 0 || (context->byteptr == 2 && context->length == 1))  #ifdef COMPILE_PCRE8
2812      if (context->ucharptr >= 4 || context->length == 0 || (context->ucharptr == 2 && context->length == 1))
2813    #else
2814      if (context->ucharptr >= 2 || context->length == 0)
2815    #endif
2816      {      {
2817      if (context->length >= 4)      if (context->length >= 4)
2818        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);
2819    #ifdef COMPILE_PCRE8
2820      else if (context->length >= 2)      else if (context->length >= 2)
2821        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);
2822      else if (context->length >= 1)      else if (context->length >= 1)
2823        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);
2824    #else
2825        else if (context->length >= 2)
2826          OP1(SLJIT_MOV_UH, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);
2827    #endif
2828      context->sourcereg = context->sourcereg == TMP1 ? TMP2 : TMP1;      context->sourcereg = context->sourcereg == TMP1 ? TMP2 : TMP1;
2829    
2830      switch(context->byteptr)      switch(context->ucharptr)
2831        {        {
2832        case 4:        case 4 / sizeof(pcre_uchar):
2833        if (context->oc.asint != 0)        if (context->oc.asint != 0)
2834          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);
2835        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));
2836        break;        break;
2837    
2838        case 2:        case 2 / sizeof(pcre_uchar):
2839        if (context->oc.asshort != 0)        if (context->oc.asushort != 0)
2840          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);
2841        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));
2842        break;        break;
2843    
2844    #ifdef COMPILE_PCRE8
2845        case 1:        case 1:
2846        if (context->oc.asbyte != 0)        if (context->oc.asbyte != 0)
2847          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);
2848        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));
2849        break;        break;
2850    #endif
2851    
2852        default:        default:
2853        SLJIT_ASSERT_STOP();        SLJIT_ASSERT_STOP();
2854        break;        break;
2855        }        }
2856      context->byteptr = 0;      context->ucharptr = 0;
2857      }      }
2858    
2859  #else  #else
2860    
2861    /* Unaligned read is unsupported. */    /* Unaligned read is unsupported. */
2862    #ifdef COMPILE_PCRE8
2863    if (context->length > 0)    if (context->length > 0)
2864      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);
2865    #else
2866      if (context->length > 0)
2867        OP1(SLJIT_MOV_UH, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);
2868    #endif
2869    context->sourcereg = context->sourcereg == TMP1 ? TMP2 : TMP1;    context->sourcereg = context->sourcereg == TMP1 ? TMP2 : TMP1;
2870    
2871    if (othercasebit != 0 && othercasebyte == cc)    if (othercasebit != 0 && othercasechar == cc)
2872      {      {
2873      OP2(SLJIT_OR, context->sourcereg, 0, context->sourcereg, 0, SLJIT_IMM, othercasebit);      OP2(SLJIT_OR, context->sourcereg, 0, context->sourcereg, 0, SLJIT_IMM, othercasebit);
2874      add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, context->sourcereg, 0, SLJIT_IMM, *cc | othercasebit));      add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, context->sourcereg, 0, SLJIT_IMM, *cc | othercasebit));
# Line 2387  do Line 2879  do
2879  #endif  #endif
2880    
2881    cc++;    cc++;
2882  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
2883    utf8length--;    utflength--;
2884    }    }
2885  while (utf8length > 0);  while (utflength > 0);
2886  #endif  #endif
2887    
2888  return cc;  return cc;
2889  }  }
2890    
2891  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
2892    
2893  #define SET_TYPE_OFFSET(value) \  #define SET_TYPE_OFFSET(value) \
2894    if ((value) != typeoffset) \    if ((value) != typeoffset) \
# Line 2418  return cc; Line 2910  return cc;
2910      } \      } \
2911    charoffset = (value);    charoffset = (value);
2912    
2913  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)
2914  {  {
2915  DEFINE_COMPILER;  DEFINE_COMPILER;
2916  jump_list *found = NULL;  jump_list *found = NULL;
# Line 2426  jump_list **list = (*cc & XCL_NOT) == 0 Line 2918  jump_list **list = (*cc & XCL_NOT) == 0
2918  unsigned int c;  unsigned int c;
2919  int compares;  int compares;
2920  struct sljit_jump *jump = NULL;  struct sljit_jump *jump = NULL;
2921  uschar *ccbegin;  pcre_uchar *ccbegin;
2922  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
2923  BOOL needstype = FALSE, needsscript = FALSE, needschar = FALSE;  BOOL needstype = FALSE, needsscript = FALSE, needschar = FALSE;
2924  BOOL charsaved = FALSE;  BOOL charsaved = FALSE;
2925  int typereg = TMP1, scriptreg = TMP1, typeoffset;  int typereg = TMP1, scriptreg = TMP1;
2926    unsigned int typeoffset;
2927  #endif  #endif
2928  int charoffset, invertcmp, numberofcmps;  int invertcmp, numberofcmps;
2929    unsigned int charoffset;
2930    
2931  /* 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. */
2932  check_input_end(common, fallbacks);  fallback_at_str_end(common, fallbacks);
2933  read_char(common);  read_char(common);
2934    
2935  if ((*cc++ & XCL_MAP) != 0)  if ((*cc++ & XCL_MAP) != 0)
2936    {    {
2937    OP1(SLJIT_MOV, TMP3, 0, TMP1, 0);    OP1(SLJIT_MOV, TMP3, 0, TMP1, 0);
2938    if (common->utf8)  #ifndef COMPILE_PCRE8
2939      jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);
2940    #elif defined SUPPORT_UTF
2941      if (common->utf)
2942      jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);      jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);
2943    #endif
2944    
2945    OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);    OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);
2946    OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);    OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);
# Line 2451  if ((*cc++ & XCL_MAP) != 0) Line 2949  if ((*cc++ & XCL_MAP) != 0)
2949    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);
2950    add_jump(compiler, list, JUMP(SLJIT_C_NOT_ZERO));    add_jump(compiler, list, JUMP(SLJIT_C_NOT_ZERO));
2951    
2952    if (common->utf8)  #ifndef COMPILE_PCRE8
2953      JUMPHERE(jump);
2954    #elif defined SUPPORT_UTF
2955      if (common->utf)
2956      JUMPHERE(jump);      JUMPHERE(jump);
2957    #endif
2958    OP1(SLJIT_MOV, TMP1, 0, TMP3, 0);    OP1(SLJIT_MOV, TMP1, 0, TMP3, 0);
2959  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
2960    charsaved = TRUE;    charsaved = TRUE;
2961  #endif  #endif
2962    cc += 32;    cc += 32 / sizeof(pcre_uchar);
2963    }    }
2964    
2965  /* Scanning the necessary info. */  /* Scanning the necessary info. */
# Line 2469  while (*cc != XCL_END) Line 2971  while (*cc != XCL_END)
2971    if (*cc == XCL_SINGLE)    if (*cc == XCL_SINGLE)
2972      {      {
2973      cc += 2;      cc += 2;
2974  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
2975      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]);
2976  #endif  #endif
2977  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
2978      needschar = TRUE;      needschar = TRUE;
# Line 2479  while (*cc != XCL_END) Line 2981  while (*cc != XCL_END)
2981    else if (*cc == XCL_RANGE)    else if (*cc == XCL_RANGE)
2982      {      {
2983      cc += 2;      cc += 2;
2984  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
2985      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]);
2986  #endif  #endif
2987      cc++;      cc++;
2988  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
2989      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]);
2990  #endif  #endif
2991  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
2992      needschar = TRUE;      needschar = TRUE;
# Line 2554  if (needstype || needsscript) Line 3056  if (needstype || needsscript)
3056      {      {
3057      if (scriptreg == TMP1)      if (scriptreg == TMP1)
3058        {        {
3059        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));
3060        OP1(SLJIT_MOV_UB, scriptreg, 0, SLJIT_MEM2(scriptreg, TMP2), 3);        OP1(SLJIT_MOV_UB, scriptreg, 0, SLJIT_MEM2(scriptreg, TMP2), 3);
3061        }        }
3062      else      else
3063        {        {
3064        OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 3);        OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 3);
3065        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));
3066        OP1(SLJIT_MOV_UB, scriptreg, 0, SLJIT_MEM1(TMP2), 0);        OP1(SLJIT_MOV_UB, scriptreg, 0, SLJIT_MEM1(TMP2), 0);
3067        }        }
3068      }      }
# Line 2584  while (*cc != XCL_END) Line 3086  while (*cc != XCL_END)
3086    if (*cc == XCL_SINGLE)    if (*cc == XCL_SINGLE)
3087      {      {
3088      cc ++;      cc ++;
3089  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3090      if (common->utf8)      if (common->utf)
3091        {        {
3092        GETCHARINC(c, cc);        GETCHARINC(c, cc);
3093        }        }
# Line 2615  while (*cc != XCL_END) Line 3117  while (*cc != XCL_END)
3117    else if (*cc == XCL_RANGE)    else if (*cc == XCL_RANGE)
3118      {      {
3119      cc ++;      cc ++;
3120  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3121      if (common->utf8)      if (common->utf)
3122        {        {
3123        GETCHARINC(c, cc);        GETCHARINC(c, cc);
3124        }        }
# Line 2624  while (*cc != XCL_END) Line 3126  while (*cc != XCL_END)
3126  #endif  #endif
3127        c = *cc++;        c = *cc++;
3128      SET_CHAR_OFFSET(c);      SET_CHAR_OFFSET(c);
3129  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3130      if (common->utf8)      if (common->utf)
3131        {        {
3132        GETCHARINC(c, cc);        GETCHARINC(c, cc);
3133        }        }
# Line 2681  while (*cc != XCL_END) Line 3183  while (*cc != XCL_END)
3183        break;        break;
3184    
3185        case PT_GC:        case PT_GC:
3186        c = _pcre_ucp_typerange[(int)cc[1] * 2];        c = PRIV(ucp_typerange)[(int)cc[1] * 2];
3187        SET_TYPE_OFFSET(c);        SET_TYPE_OFFSET(c);
3188        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);
3189        break;        break;
3190    
3191        case PT_PC:        case PT_PC:
# Line 2745  if (found != NULL) Line 3247  if (found != NULL)
3247    
3248  #endif  #endif
3249    
3250  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)
3251  {  {
3252  DEFINE_COMPILER;  DEFINE_COMPILER;
3253  int length;  int length;
3254  unsigned int c, oc, bit;  unsigned int c, oc, bit;
3255  compare_context context;  compare_context context;
 struct sljit_label *label;  
3256  struct sljit_jump *jump[4];  struct sljit_jump *jump[4];
3257  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3258    struct sljit_label *label;
3259  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
3260  uschar propdata[5];  pcre_uchar propdata[5];
3261  #endif  #endif
3262  #endif  #endif
3263    
# Line 2781  switch(type) Line 3283  switch(type)
3283    
3284    case OP_NOT_DIGIT:    case OP_NOT_DIGIT:
3285    case OP_DIGIT:    case OP_DIGIT:
3286    check_input_end(common, fallbacks);    fallback_at_str_end(common, fallbacks);
3287    read_char8_type(common);    read_char8_type(common);
3288    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);
3289    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 2789  switch(type) Line 3291  switch(type)
3291    
3292    case OP_NOT_WHITESPACE:    case OP_NOT_WHITESPACE:
3293    case OP_WHITESPACE:    case OP_WHITESPACE:
3294    check_input_end(common, fallbacks);    fallback_at_str_end(common, fallbacks);
3295    read_char8_type(common);    read_char8_type(common);
3296    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);
3297    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 2797  switch(type) Line 3299  switch(type)
3299    
3300    case OP_NOT_WORDCHAR:    case OP_NOT_WORDCHAR:
3301    case OP_WORDCHAR:    case OP_WORDCHAR:
3302    check_input_end(common, fallbacks);    fallback_at_str_end(common, fallbacks);
3303    read_char8_type(common);    read_char8_type(common);
3304    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);
3305    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));
3306    return cc;    return cc;
3307    
3308    case OP_ANY:    case OP_ANY:
3309    check_input_end(common, fallbacks);    fallback_at_str_end(common, fallbacks);
3310    read_char(common);    read_char(common);
3311    if (common->nltype == NLTYPE_FIXED && common->newline > 255)    if (common->nltype == NLTYPE_FIXED && common->newline > 255)
3312      {      {
3313      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);
3314      jump[1] = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);      if (common->mode != JIT_PARTIAL_HARD_COMPILE)
3315      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);        jump[1] = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
3316        else
3317          jump[1] = check_str_end(common);
3318    
3319        OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
3320      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));
3321      JUMPHERE(jump[1]);      if (jump[1] != NULL)
3322          JUMPHERE(jump[1]);
3323      JUMPHERE(jump[0]);      JUMPHERE(jump[0]);
3324      }      }
3325    else    else
# Line 2820  switch(type) Line 3327  switch(type)
3327    return cc;    return cc;
3328    
3329    case OP_ALLANY:    case OP_ALLANY:
3330    check_input_end(common, fallbacks);    fallback_at_str_end(common, fallbacks);
3331  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3332    if (common->utf8)    if (common->utf)
3333      {      {
3334      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
3335      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));
3336    #ifdef COMPILE_PCRE8
3337        jump[0] = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);
3338        OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)PRIV(utf8_table4) - 0xc0);
3339      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
3340    #else /* COMPILE_PCRE8 */
3341    #ifdef COMPILE_PCRE16
3342        jump[0] = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800);
3343        OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);
3344        OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xd800);
3345        COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);
3346        OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
3347        OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
3348    #endif /* COMPILE_PCRE16 */
3349    #endif /* COMPILE_PCRE8 */
3350        JUMPHERE(jump[0]);
3351      return cc;      return cc;
3352      }      }
3353  #endif  #endif
3354    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));
3355      return cc;
3356    
3357      case OP_ANYBYTE:
3358      fallback_at_str_end(common, fallbacks);
3359      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
3360    return cc;    return cc;
3361    
3362  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3363  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
3364    case OP_NOTPROP:    case OP_NOTPROP:
3365    case OP_PROP:    case OP_PROP:
# Line 2848  switch(type) Line 3374  switch(type)
3374  #endif  #endif
3375    
3376    case OP_ANYNL:    case OP_ANYNL:
3377    check_input_end(common, fallbacks);    fallback_at_str_end(common, fallbacks);
3378    read_char(common);    read_char(common);
3379    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);
3380    jump[1] = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);    /* We don't need to handle soft partial matching case. */
3381    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);    if (common->mode != JIT_PARTIAL_HARD_COMPILE)
3382        jump[1] = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
3383      else
3384        jump[1] = check_str_end(common);
3385      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
3386    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);
3387    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));
3388    jump[3] = JUMP(SLJIT_JUMP);    jump[3] = JUMP(SLJIT_JUMP);
3389    JUMPHERE(jump[0]);    JUMPHERE(jump[0]);
3390    check_newlinechar(common, common->bsr_nltype, fallbacks, FALSE);    check_newlinechar(common, common->bsr_nltype, fallbacks, FALSE);
# Line 2865  switch(type) Line 3395  switch(type)
3395    
3396    case OP_NOT_HSPACE:    case OP_NOT_HSPACE:
3397    case OP_HSPACE:    case OP_HSPACE:
3398    check_input_end(common, fallbacks);    fallback_at_str_end(common, fallbacks);
3399    read_char(common);    read_char(common);
3400    add_jump(compiler, &common->hspace, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->hspace, JUMP(SLJIT_FAST_CALL));
3401    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 2873  switch(type) Line 3403  switch(type)
3403    
3404    case OP_NOT_VSPACE:    case OP_NOT_VSPACE:
3405    case OP_VSPACE:    case OP_VSPACE:
3406    check_input_end(common, fallbacks);    fallback_at_str_end(common, fallbacks);
3407    read_char(common);    read_char(common);
3408    add_jump(compiler, &common->vspace, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->vspace, JUMP(SLJIT_FAST_CALL));
3409    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 2881  switch(type) Line 3411  switch(type)
3411    
3412  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
3413    case OP_EXTUNI:    case OP_EXTUNI:
3414    check_input_end(common, fallbacks);    fallback_at_str_end(common, fallbacks);
3415    read_char(common);    read_char(common);
3416    add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL));
3417    OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Mc);    OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Mc);
# Line 2897  switch(type) Line 3427  switch(type)
3427    
3428    OP1(SLJIT_MOV, STR_PTR, 0, TMP3, 0);    OP1(SLJIT_MOV, STR_PTR, 0, TMP3, 0);
3429    JUMPHERE(jump[0]);    JUMPHERE(jump[0]);
3430      if (common->mode == JIT_PARTIAL_HARD_COMPILE)
3431        {
3432        jump[0] = CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0);
3433        /* Since we successfully read a char above, partial matching must occure. */
3434        check_partial(common, TRUE);
3435        JUMPHERE(jump[0]);
3436        }
3437    return cc;    return cc;
3438  #endif  #endif
3439    
3440    case OP_EODN:    case OP_EODN:
3441      /* Requires rather complex checks. */
3442    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);
3443    if (common->nltype == NLTYPE_FIXED && common->newline > 255)    if (common->nltype == NLTYPE_FIXED && common->newline > 255)
3444      {      {
3445      OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, 2);      OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2));
3446      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
3447      add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, STR_END, 0));      if (common->mode == JIT_COMPILE)
3448      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));
3449        else
3450          {
3451          jump[1] = CMP(SLJIT_C_EQUAL, TMP2, 0, STR_END, 0);
3452          OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP2, 0, STR_END, 0);
3453          COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS);
3454          OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff);
3455          COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_NOT_EQUAL);
3456          add_jump(compiler, fallbacks, JUMP(SLJIT_C_NOT_EQUAL));
3457          check_partial(common, TRUE);
3458          add_jump(compiler, fallbacks, JUMP(SLJIT_JUMP));
3459          JUMPHERE(jump[1]);
3460          }
3461        OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
3462      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));
3463      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));
3464      }      }
3465    else if (common->nltype == NLTYPE_FIXED)    else if (common->nltype == NLTYPE_FIXED)
3466      {      {
3467      OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, 1);      OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
3468      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
3469      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));
3470      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));
3471      }      }
3472    else    else
3473      {      {
3474      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
3475      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);
3476      OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, 2);      OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2));
3477      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);
3478      jump[2] = JUMP(SLJIT_C_GREATER);      jump[2] = JUMP(SLJIT_C_GREATER);
3479      add_jump(compiler, fallbacks, JUMP(SLJIT_C_LESS));      add_jump(compiler, fallbacks, JUMP(SLJIT_C_LESS));
3480      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 1);      /* Equal. */
3481        OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
3482      jump[3] = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_NL);      jump[3] = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_NL);
3483      add_jump(compiler, fallbacks, JUMP(SLJIT_JUMP));      add_jump(compiler, fallbacks, JUMP(SLJIT_JUMP));
3484    
3485      JUMPHERE(jump[1]);      JUMPHERE(jump[1]);
3486      if (common->nltype == NLTYPE_ANYCRLF)      if (common->nltype == NLTYPE_ANYCRLF)
3487        {        {
3488        OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, 1);        OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
3489        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));
3490        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));
3491        }        }
# Line 2950  switch(type) Line 3502  switch(type)
3502      JUMPHERE(jump[3]);      JUMPHERE(jump[3]);
3503      }      }
3504    JUMPHERE(jump[0]);    JUMPHERE(jump[0]);
3505      check_partial(common, FALSE);
3506    return cc;    return cc;
3507    
3508    case OP_EOD:    case OP_EOD:
3509    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));
3510      check_partial(common, FALSE);
3511    return cc;    return cc;
3512    
3513    case OP_CIRC:    case OP_CIRC:
# Line 2973  switch(type) Line 3527  switch(type)
3527    jump[0] = JUMP(SLJIT_JUMP);    jump[0] = JUMP(SLJIT_JUMP);
3528    JUMPHERE(jump[1]);    JUMPHERE(jump[1]);
3529    
3530    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));  
   
3531    if (common->nltype == NLTYPE_FIXED && common->newline > 255)    if (common->nltype == NLTYPE_FIXED && common->newline > 255)
3532      {      {
3533      OP2(SLJIT_SUB, TMP2, 0, STR_PTR, 0, SLJIT_IMM, 2);      OP2(SLJIT_SUB, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2));
3534      add_jump(compiler, fallbacks, CMP(SLJIT_C_LESS, TMP2, 0, TMP1, 0));      add_jump(compiler, fallbacks, CMP(SLJIT_C_LESS, TMP2, 0, TMP1, 0));
3535      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), -2);      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-2));
3536      OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), -1);      OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-1));
3537      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));
3538      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));
3539      }      }
# Line 3002  switch(type) Line 3554  switch(type)
3554    if (!common->endonly)    if (!common->endonly)
3555      compile_char1_hotpath(common, OP_EODN, cc, fallbacks);      compile_char1_hotpath(common, OP_EODN, cc, fallbacks);
3556    else    else
3557        {
3558      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));
3559        check_partial(common, FALSE);
3560        }
3561    return cc;    return cc;
3562    
3563    case OP_DOLLM:    case OP_DOLLM:
# Line 3010  switch(type) Line 3565  switch(type)
3565    OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0);    OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0);
3566    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));
3567    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));
3568      check_partial(common, FALSE);
3569    jump[0] = JUMP(SLJIT_JUMP);    jump[0] = JUMP(SLJIT_JUMP);
3570    JUMPHERE(jump[1]);    JUMPHERE(jump[1]);
3571    
3572    if (common->nltype == NLTYPE_FIXED && common->newline > 255)    if (common->nltype == NLTYPE_FIXED && common->newline > 255)
3573      {      {
3574      OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, 2);      OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2));
3575      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));
3576      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);      if (common->mode == JIT_COMPILE)
3577      OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), 1);        add_jump(compiler, fallbacks, CMP(SLJIT_C_GREATER, TMP2, 0, STR_END, 0));
3578        else
3579          {
3580          jump[1] = CMP(SLJIT_C_LESS_EQUAL, TMP2, 0, STR_END, 0);
3581          /* STR_PTR = STR_END - IN_UCHARS(1) */
3582          add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff));
3583          check_partial(common, TRUE);
3584          add_jump(compiler, fallbacks, JUMP(SLJIT_JUMP));
3585          JUMPHERE(jump[1]);
3586          }
3587    
3588        OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
3589      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));
3590      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));
3591      }      }
# Line 3033  switch(type) Line 3600  switch(type)
3600    case OP_CHAR:    case OP_CHAR:
3601    case OP_CHARI:    case OP_CHARI:
3602    length = 1;    length = 1;
3603  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3604    if (common->utf8 && *cc >= 0xc0) length += _pcre_utf8_table4[*cc & 0x3f];    if (common->utf && HAS_EXTRALEN(*cc)) length += GET_EXTRALEN(*cc);
3605  #endif  #endif
3606    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))
3607      {      {
3608      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));
3609      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));
3610    
3611      context.length = length;      context.length = IN_UCHARS(length);
3612      context.sourcereg = -1;      context.sourcereg = -1;
3613  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
3614      context.byteptr = 0;      context.ucharptr = 0;
3615  #endif  #endif
3616      return byte_sequence_compare(common, type == OP_CHARI, cc, &context, fallbacks);      return byte_sequence_compare(common, type == OP_CHARI, cc, &context, fallbacks);
3617      }      }
3618    add_jump(compiler, fallbacks, CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0));    fallback_at_str_end(common, fallbacks);
3619    read_char(common);    read_char(common);
3620  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3621    if (common->utf8)    if (common->utf)
3622      {      {
3623      GETCHAR(c, cc);      GETCHAR(c, cc);
3624      }      }
3625    else    else
3626  #endif  #endif
3627      c = *cc;      c = *cc;
3628      if (type == OP_CHAR || !char_has_othercase(common, cc))
3629        {
3630        add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, c));
3631        return cc + length;
3632        }
3633      oc = char_othercase(common, c);
3634      bit = c ^ oc;
3635      if (ispowerof2(bit))
3636        {
3637        OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, bit);
3638        add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, c | bit));
3639        return cc + length;
3640        }
3641    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);
3642    COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);    COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);
3643    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 3067  switch(type) Line 3647  switch(type)
3647    
3648    case OP_NOT:    case OP_NOT:
3649    case OP_NOTI:    case OP_NOTI:
3650      fallback_at_str_end(common, fallbacks);
3651    length = 1;    length = 1;
3652  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3653    if (common->utf8)    if (common->utf)
3654      {      {
3655      if (*cc >= 0xc0) length += _pcre_utf8_table4[*cc & 0x3f];  #ifdef COMPILE_PCRE8
3656        c = *cc;
3657      check_input_end(common, fallbacks);      if (c < 128)
     GETCHAR(c, cc);  
   
     if (c <= 127)  
3658        {        {
3659        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);  
3660        if (type == OP_NOT || !char_has_othercase(common, cc))        if (type == OP_NOT || !char_has_othercase(common, cc))
3661          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));
3662        else        else
3663          {          {
3664          /* 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. */
3665          OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x20);          OP2(SLJIT_OR, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x20);
3666          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));
3667          }          }
3668        /* Skip the variable-length character. */        /* Skip the variable-length character. */
3669        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));
3670        return cc + length;        jump[0] = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);
3671          OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)PRIV(utf8_table4) - 0xc0);
3672          OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
3673          JUMPHERE(jump[0]);
3674          return cc + 1;
3675        }        }
3676      else      else
3677    #endif /* COMPILE_PCRE8 */
3678          {
3679          GETCHARLEN(c, cc, length);
3680        read_char(common);        read_char(common);
3681          }
3682      }      }
3683    else    else
3684  #endif  #endif /* SUPPORT_UTF */
3685      {      {
3686      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);  
3687      c = *cc;      c = *cc;
3688      }      }
3689    
# Line 3125  switch(type) Line 3708  switch(type)
3708    
3709    case OP_CLASS:    case OP_CLASS:
3710    case OP_NCLASS:    case OP_NCLASS:
3711    check_input_end(common, fallbacks);    fallback_at_str_end(common, fallbacks);
3712    read_char(common);    read_char(common);
3713  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
3714    jump[0] = NULL;    jump[0] = NULL;
3715    if (common->utf8)  #ifdef COMPILE_PCRE8
3716      /* This check only affects 8 bit mode. In other modes, we
3717      always need to compare the value with 255. */
3718      if (common->utf)
3719    #endif /* COMPILE_PCRE8 */
3720      {      {
3721      jump[0] = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);      jump[0] = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);
3722      if (type == OP_CLASS)      if (type == OP_CLASS)
# Line 3138  switch(type) Line 3725  switch(type)
3725        jump[0] = NULL;        jump[0] = NULL;
3726        }        }
3727      }      }
3728  #endif  #endif /* SUPPORT_UTF || !COMPILE_PCRE8 */
3729    OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);    OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);
3730    OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);    OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);
3731    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)cc);    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)cc);
3732    OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0);    OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0);
3733    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);
3734    add_jump(compiler, fallbacks, JUMP(SLJIT_C_ZERO));    add_jump(compiler, fallbacks, JUMP(SLJIT_C_ZERO));
3735  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
3736    if (jump[0] != NULL)    if (jump[0] != NULL)
3737      JUMPHERE(jump[0]);      JUMPHERE(jump[0]);
3738  #endif  #endif /* SUPPORT_UTF || !COMPILE_PCRE8 */
3739    return cc + 32;    return cc + 32 / sizeof(pcre_uchar);
3740    
3741  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF || defined COMPILE_PCRE16
3742    case OP_XCLASS:    case OP_XCLASS:
3743    compile_xclass_hotpath(common, cc + LINK_SIZE, fallbacks);    compile_xclass_hotpath(common, cc + LINK_SIZE, fallbacks);
3744    return cc + GET(cc, 0) - 1;    return cc + GET(cc, 0) - 1;
# Line 3159  switch(type) Line 3746  switch(type)
3746    
3747    case OP_REVERSE:    case OP_REVERSE:
3748    length = GET(cc, 0);    length = GET(cc, 0);
3749    SLJIT_ASSERT(length > 0);    if (length == 0)
3750        return cc + LINK_SIZE;
3751    OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);    OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
3752    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin));  #ifdef SUPPORT_UTF
3753  #ifdef SUPPORT_UTF8    if (common->utf)
   if (common->utf8)  
3754      {      {
3755        OP1(SLJIT_MOV, TMP3, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin));
3756      OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, length);      OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, length);
3757      label = LABEL();      label = LABEL();
3758      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));
3759      skip_char_back(common);      skip_char_back(common);
3760      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);
3761      JUMPTO(SLJIT_C_NOT_ZERO, label);      JUMPTO(SLJIT_C_NOT_ZERO, label);
     return cc + LINK_SIZE;  
3762      }      }
3763      else
3764  #endif  #endif
3765    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, length);      {
3766    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));
3767        OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(length));
3768        add_jump(compiler, fallbacks, CMP(SLJIT_C_LESS, STR_PTR, 0, TMP1, 0));
3769        }
3770      check_start_used_ptr(common);
3771    return cc + LINK_SIZE;    return cc + LINK_SIZE;
3772    }    }
3773  SLJIT_ASSERT_STOP();  SLJIT_ASSERT_STOP();
3774  return cc;  return cc;
3775  }  }
3776    
3777  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)
3778  {  {
3779  /* This function consumes at least one input character. */  /* This function consumes at least one input character. */
3780  /* 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. */
3781  DEFINE_COMPILER;  DEFINE_COMPILER;
3782  uschar *ccbegin = cc;  pcre_uchar *ccbegin = cc;
3783  compare_context context;  compare_context context;
3784  int size;  int size;
3785    
# Line 3200  do Line 3792  do
3792    if (*cc == OP_CHAR)    if (*cc == OP_CHAR)
3793      {      {
3794      size = 1;      size = 1;
3795  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3796      if (common->utf8 && cc[1] >= 0xc0)      if (common->utf && HAS_EXTRALEN(cc[1]))
3797        size += _pcre_utf8_table4[cc[1] & 0x3f];        size += GET_EXTRALEN(cc[1]);
3798  #endif  #endif
3799      }      }
3800    else if (*cc == OP_CHARI)    else if (*cc == OP_CHARI)
3801      {      {
3802      size = 1;      size = 1;
3803  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3804      if (common->utf8)      if (common->utf)
3805        {        {
3806        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)
3807          size = 0;          size = 0;
3808        else if (cc[1] >= 0xc0)        else if (HAS_EXTRALEN(cc[1]))
3809          size += _pcre_utf8_table4[cc[1] & 0x3f];          size += GET_EXTRALEN(cc[1]);
3810        }        }
3811      else      else
3812  #endif  #endif
3813      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)
3814        size = 0;        size = 0;
# Line 3225  do Line 3817  do
3817      size = 0;      size = 0;
3818    
3819    cc += 1 + size;    cc += 1 + size;
3820    context.length += size;    context.length += IN_UCHARS(size);
3821    }    }
3822  while (size > 0 && context.length <= 128);  while (size > 0 && context.length <= 128);
3823    
# Line 3238  if (context.length > 0) Line 3830  if (context.length > 0)
3830    
3831    context.sourcereg = -1;    context.sourcereg = -1;
3832  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
3833    context.byteptr = 0;    context.ucharptr = 0;
3834  #endif  #endif
3835    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);
3836    return cc;    return cc;
# Line 3248  if (context.length > 0) Line 3840  if (context.length > 0)
3840  return compile_char1_hotpath(common, *cc, cc + 1, fallbacks);  return compile_char1_hotpath(common, *cc, cc + 1, fallbacks);
3841  }  }
3842    
3843  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)
3844  {  {
3845  DEFINE_COMPILER;  DEFINE_COMPILER;
3846  int offset = GET2(cc, 1) << 1;  int offset = GET2(cc, 1) << 1;
# Line 3258  if (!common->jscript_compat) Line 3850  if (!common->jscript_compat)
3850    {    {
3851    if (fallbacks == NULL)    if (fallbacks == NULL)
3852      {      {
3853        /* OVECTOR(1) contains the "string begin - 1" constant. */
3854      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));
3855      COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);      COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);
3856      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 3270  return CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT Line 3863  return CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT
3863  }  }
3864    
3865  /* Forward definitions. */  /* Forward definitions. */
3866  static void compile_hotpath(compiler_common *, uschar *, uschar *, fallback_common *);  static void compile_hotpath(compiler_common *, pcre_uchar *, pcre_uchar *, fallback_common *);
3867  static void compile_fallbackpath(compiler_common *, struct fallback_common *);  static void compile_fallbackpath(compiler_common *, struct fallback_common *);
3868    
3869  #define PUSH_FALLBACK(size, ccstart, error) \  #define PUSH_FALLBACK(size, ccstart, error) \
# Line 3299  static void compile_fallbackpath(compile Line 3892  static void compile_fallbackpath(compile
3892      } \      } \
3893    while (0)    while (0)
3894    
3895  #define FALLBACK_AS(type) ((type*)fallback)  #define FALLBACK_AS(type) ((type *)fallback)
3896    
3897  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)
3898  {  {
3899  DEFINE_COMPILER;  DEFINE_COMPILER;
3900  int offset = GET2(cc, 1) << 1;  int offset = GET2(cc, 1) << 1;
3901  struct sljit_jump *jump = NULL;  struct sljit_jump *jump = NULL;
3902    struct sljit_jump *partial;
3903    struct sljit_jump *nopartial;
3904    
3905  OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));  OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));
3906    /* OVECTOR(1) contains the "string begin - 1" constant. */
3907  if (withchecks && !common->jscript_compat)  if (withchecks && !common->jscript_compat)
3908    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)));
3909    
3910  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF && defined SUPPORT_UCP
3911  #ifdef SUPPORT_UCP  if (common->utf && *cc == OP_REFI)
 if (common->utf8 && *cc == OP_REFI)  
3912    {    {
3913    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);
3914    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 3323  if (common->utf8 && *cc == OP_REFI) Line 3918  if (common->utf8 && *cc == OP_REFI)
3918    /* Needed to save important temporary registers. */    /* Needed to save important temporary registers. */
3919    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, STACK_TOP, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, STACK_TOP, 0);
3920    OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, ARGUMENTS, 0);    OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, ARGUMENTS, 0);
3921    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, uchar_ptr), STR_PTR, 0);
3922    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));
3923    OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);    OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);
3924    add_jump(compiler, fallbacks, CMP(SLJIT_C_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 0));    if (common->mode == JIT_COMPILE)
3925        add_jump(compiler, fallbacks, CMP(SLJIT_C_LESS_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 1));
3926      else
3927        {
3928        add_jump(compiler, fallbacks, CMP(SLJIT_C_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 0));
3929        nopartial = CMP(SLJIT_C_NOT_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 1);
3930        check_partial(common, FALSE);
3931        add_jump(compiler, fallbacks, JUMP(SLJIT_JUMP));
3932        JUMPHERE(nopartial);
3933        }
3934    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_RETURN_REG, 0);    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_RETURN_REG, 0);
3935    }    }
3936  else  else
3937  #endif  #endif /* SUPPORT_UTF && SUPPORT_UCP */
 #endif  
3938    {    {
3939    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);
3940    if (withchecks)    if (withchecks)
3941      jump = JUMP(SLJIT_C_ZERO);      jump = JUMP(SLJIT_C_ZERO);
3942    
3943    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
3944      partial = CMP(SLJIT_C_GREATER, STR_PTR, 0, STR_END, 0);
3945      if (common->mode == JIT_COMPILE)
3946        add_jump(compiler, fallbacks, partial);
3947    
   add_jump(compiler, fallbacks, CMP(SLJIT_C_GREATER, STR_PTR, 0, STR_END, 0));  
3948    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));
3949    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));
3950    
3951      if (common->mode != JIT_COMPILE)
3952        {
3953        nopartial = JUMP(SLJIT_JUMP);
3954        JUMPHERE(partial);
3955        /* TMP2 -= STR_END - STR_PTR */
3956        OP2(SLJIT_SUB, TMP2, 0, TMP2, 0, STR_PTR, 0);
3957        OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, STR_END, 0);
3958        partial = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, 0);
3959        OP1(SLJIT_MOV, STR_PTR, 0, STR_END, 0);
3960        add_jump(compiler, *cc == OP_REF ? &common->casefulcmp : &common->caselesscmp, JUMP(SLJIT_FAST_CALL));
3961        add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0));
3962        JUMPHERE(partial);
3963        check_partial(common, FALSE);
3964        add_jump(compiler, fallbacks, JUMP(SLJIT_JUMP));
3965        JUMPHERE(nopartial);
3966        }
3967    }    }
3968    
3969  if (jump != NULL)  if (jump != NULL)
# Line 3350  if (jump != NULL) Line 3973  if (jump != NULL)
3973    else    else
3974      JUMPHERE(jump);      JUMPHERE(jump);
3975    }    }
3976  return cc + 3;  return cc + 1 + IMM2_SIZE;
3977  }  }
3978    
3979  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)
3980  {  {
3981  DEFINE_COMPILER;  DEFINE_COMPILER;
3982  fallback_common *fallback;  fallback_common *fallback;
3983  uschar type;  pcre_uchar type;
3984  struct sljit_label *label;  struct sljit_label *label;
3985  struct sljit_jump *zerolength;  struct sljit_jump *zerolength;
3986  struct sljit_jump *jump = NULL;  struct sljit_jump *jump = NULL;
3987  uschar *ccbegin = cc;  pcre_uchar *ccbegin = cc;
3988  int min = 0, max = 0;  int min = 0, max = 0;
3989  BOOL minimize;  BOOL minimize;
3990    
3991  PUSH_FALLBACK(sizeof(iterator_fallback), cc, NULL);  PUSH_FALLBACK(sizeof(iterator_fallback), cc, NULL);
3992    
3993  type = cc[3];  type = cc[1 + IMM2_SIZE];
3994  minimize = (type & 0x1) != 0;  minimize = (type & 0x1) != 0;
3995  switch(type)  switch(type)
3996    {    {
# Line 3375  switch(type) Line 3998  switch(type)
3998    case OP_CRMINSTAR:    case OP_CRMINSTAR:
3999    min = 0;    min = 0;
4000    max = 0;    max = 0;
4001    cc += 4;    cc += 1 + IMM2_SIZE + 1;
4002    break;    break;
4003    case OP_CRPLUS:    case OP_CRPLUS:
4004    case OP_CRMINPLUS:    case OP_CRMINPLUS:
4005    min = 1;    min = 1;
4006    max = 0;    max = 0;
4007    cc += 4;    cc += 1 + IMM2_SIZE + 1;
4008    break;    break;
4009    case OP_CRQUERY:    case OP_CRQUERY:
4010    case OP_CRMINQUERY:    case OP_CRMINQUERY:
4011    min = 0;    min = 0;
4012    max = 1;    max = 1;
4013    cc += 4;    cc += 1 + IMM2_SIZE + 1;
4014    break;    break;
4015    case OP_CRRANGE:    case OP_CRRANGE:
4016    case OP_CRMINRANGE:    case OP_CRMINRANGE:
4017    min = GET2(cc, 3 + 1);    min = GET2(cc, 1 + IMM2_SIZE + 1);
4018    max = GET2(cc, 3 + 3);    max = GET2(cc, 1 + IMM2_SIZE + 1 + IMM2_SIZE);
4019    cc += 8;    cc += 1 + IMM2_SIZE + 1 + 2 * IMM2_SIZE;
4020    break;    break;
4021    default:    default:
4022    SLJIT_ASSERT_STOP();    SLJIT_ASSERT_STOP();
# Line 3453  if (!minimize) Line 4076  if (!minimize)
4076    
4077    JUMPHERE(zerolength);    JUMPHERE(zerolength);
4078    FALLBACK_AS(iterator_fallback)->hotpath = LABEL();    FALLBACK_AS(iterator_fallback)->hotpath = LABEL();
4079    
4080      decrease_call_count(common);
4081    return cc;    return cc;
4082    }    }
4083    
# Line 3490  else if (max > 0) Line 4115  else if (max > 0)
4115  if (jump != NULL)  if (jump != NULL)
4116    JUMPHERE(jump);    JUMPHERE(jump);
4117  JUMPHERE(zerolength);  JUMPHERE(zerolength);
4118    
4119    decrease_call_count(common);
4120  return cc;  return cc;
4121  }  }
4122    
4123  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)
4124  {  {
4125  DEFINE_COMPILER;  DEFINE_COMPILER;
4126  fallback_common *fallback;  fallback_common *fallback;
# Line 3526  if (entry == NULL) Line 4153  if (entry == NULL)
4153      common->entries = entry;      common->entries = entry;
4154    }    }
4155    
4156  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0));  if (common->has_set_som && common->mark_ptr != 0)
4157  allocate_stack(common, 1);    {
4158  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0);    OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0));
4159      allocate_stack(common, 2);
4160      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr);
4161      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0);
4162      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);
4163      }
4164    else if (common->has_set_som || common->mark_ptr != 0)
4165      {
4166      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->has_set_som ? (int)(OVECTOR(0)) : common->mark_ptr);
4167      allocate_stack(common, 1);
4168      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0);
4169      }
4170    
4171  if (entry->entry == NULL)  if (entry->entry == NULL)
4172    add_jump(compiler, &entry->calls, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &entry->calls, JUMP(SLJIT_FAST_CALL));
# Line 3539  add_jump(compiler, &fallback->topfallbac Line 4177  add_jump(compiler, &fallback->topfallbac
4177  return cc + 1 + LINK_SIZE;  return cc + 1 + LINK_SIZE;
4178  }  }
4179    
4180  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)
4181  {  {
4182  DEFINE_COMPILER;  DEFINE_COMPILER;
4183  int framesize;  int framesize;
4184  int localptr;  int localptr;
4185  fallback_common altfallback;  fallback_common altfallback;
4186  uschar *ccbegin;  pcre_uchar *ccbegin;
4187  uschar opcode;  pcre_uchar opcode;
4188  uschar bra = OP_BRA;  pcre_uchar bra = OP_BRA;
4189  jump_list *tmp = NULL;  jump_list *tmp = NULL;
4190  jump_list **target = (conditional) ? &fallback->condfailed : &fallback->common.topfallbacks;  jump_list **target = (conditional) ? &fallback->condfailed : &fallback->common.topfallbacks;
4191  jump_list **found;  jump_list **found;
4192  /* Saving previous accept variables. */  /* Saving previous accept variables. */
4193    struct sljit_label *save_leavelabel = common->leavelabel;
4194  struct sljit_label *save_acceptlabel = common->acceptlabel;  struct sljit_label *save_acceptlabel = common->acceptlabel;
4195    jump_list *save_leave = common->leave;
4196    jump_list *save_accept = common->accept;
4197  struct sljit_jump *jump;  struct sljit_jump *jump;
4198  struct sljit_jump *brajump = NULL;  struct sljit_jump *brajump = NULL;
 jump_list *save_accept = common->accept;  
4199    
4200  if (*cc == OP_BRAZERO || *cc == OP_BRAMINZERO)  if (*cc == OP_BRAZERO || *cc == OP_BRAMINZERO)
4201    {    {
# Line 3563  if (*cc == OP_BRAZERO || *cc == OP_BRAMI Line 4203  if (*cc == OP_BRAZERO || *cc == OP_BRAMI
4203    bra = *cc;    bra = *cc;
4204    cc++;    cc++;
4205    }    }
4206  localptr = PRIV(cc);  localptr = PRIV_DATA(cc);
4207  SLJIT_ASSERT(localptr != 0);  SLJIT_ASSERT(localptr != 0);
4208  framesize = get_framesize(common, cc, FALSE);  framesize = get_framesize(common, cc, FALSE);
4209  fallback->framesize = framesize;  fallback->framesize = framesize;
# Line 3600  else Line 4240  else
4240    }    }
4241    
4242  memset(&altfallback, 0, sizeof(fallback_common));  memset(&altfallback, 0, sizeof(fallback_common));
4243    common->leavelabel = NULL;
4244    common->leave = NULL;
4245  while (1)  while (1)
4246    {    {
4247    common->acceptlabel = NULL;    common->acceptlabel = NULL;
# Line 3614  while (1) Line 4256  while (1)
4256    compile_hotpath(common, ccbegin + 1 + LINK_SIZE, cc, &altfallback);    compile_hotpath(common, ccbegin + 1 + LINK_SIZE, cc, &altfallback);
4257    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
4258      {      {
4259        common->leavelabel = save_leavelabel;
4260      common->acceptlabel = save_acceptlabel;      common->acceptlabel = save_acceptlabel;
4261        common->leave = save_leave;
4262      common->accept = save_accept;      common->accept = save_accept;
4263      return NULL;      return NULL;
4264      }      }
# Line 3622  while (1) Line 4266  while (1)
4266    if (common->accept != NULL)    if (common->accept != NULL)
4267      set_jumps(common->accept, common->acceptlabel);      set_jumps(common->accept, common->acceptlabel);
4268    
4269      /* Reset stack. */
4270    if (framesize < 0)    if (framesize < 0)
4271      OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);      OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
4272      else {
4273        if ((opcode != OP_ASSERT_NOT && opcode != OP_ASSERTBACK_NOT) || conditional)
4274          {
4275          /* We don't need to keep the STR_PTR, only the previous localptr. */
4276          OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_IMM, (framesize + 1) * sizeof(sljit_w));
4277          }
4278        else
4279          {
4280          OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
4281          add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
4282          }
4283      }
4284    
4285    if (opcode == OP_ASSERT_NOT || opcode == OP_ASSERTBACK_NOT)    if (opcode == OP_ASSERT_NOT || opcode == OP_ASSERTBACK_NOT)
4286      {      {
4287      /* 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. */
4288      if (conditional)      if (conditional)
4289        {        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));  
         }  
       }  
4290      else if (bra == OP_BRAZERO)      else if (bra == OP_BRAZERO)
4291        {        {
4292        if (framesize < 0)        if (framesize < 0)
4293          OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), 0);          OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), 0);
4294        else        else
4295          {          {
         OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);  
         add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));  
4296          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));
4297          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));
4298          OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP1, 0);          OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP1, 0);
# Line 3653  while (1) Line 4300  while (1)
4300        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));
4301        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
4302        }        }
4303      else if (bra == OP_BRAMINZERO)      else if (framesize >= 0)
4304        {        {
4305        if (framesize >= 0)        /* For OP_BRA and OP_BRAMINZERO. */
4306          {        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));  
         }  
4307        }        }
4308      }      }
4309    add_jump(compiler, found, JUMP(SLJIT_JUMP));    add_jump(compiler, found, JUMP(SLJIT_JUMP));
# Line 3668  while (1) Line 4311  while (1)
4311    compile_fallbackpath(common, altfallback.top);    compile_fallbackpath(common, altfallback.top);
4312    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
4313      {      {
4314        common->leavelabel = save_leavelabel;
4315      common->acceptlabel = save_acceptlabel;      common->acceptlabel = save_acceptlabel;
4316        common->leave = save_leave;
4317      common->accept = save_accept;      common->accept = save_accept;
4318      return NULL;      return NULL;
4319      }      }
# Line 3681  while (1) Line 4326  while (1)
4326    cc += GET(cc, 1);    cc += GET(cc, 1);
4327    }    }
4328  /* None of them matched. */  /* None of them matched. */
4329    if (common->leave != NULL)
4330      set_jumps(common->leave, LABEL());
4331    
4332  if (opcode == OP_ASSERT || opcode == OP_ASSERTBACK)  if (opcode == OP_ASSERT || opcode == OP_ASSERTBACK)
4333    {    {
4334    /* Assert is failed. */    /* Assert is failed. */
4335    if (conditional || bra == OP_BRAZERO)    if (conditional || bra == OP_BRAZERO)
4336      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
4337    
4338    if (framesize < 0)    if (framesize < 0)
4339      {      {
4340      /* The topmost item should be 0. */      /* The topmost item should be 0. */
# Line 3698  if (opcode == OP_ASSERT || opcode == OP_ Line 4346  if (opcode == OP_ASSERT || opcode == OP_
4346    else    else
4347      {      {
4348      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));  
4349      /* The topmost item should be 0. */      /* The topmost item should be 0. */
4350      if (bra == OP_BRAZERO)      if (bra == OP_BRAZERO)
4351        {        {
# Line 3709  if (opcode == OP_ASSERT || opcode == OP_ Line 4355  if (opcode == OP_ASSERT || opcode == OP_
4355      else      else
4356        free_stack(common, framesize + 2);        free_stack(common, framesize + 2);
4357      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);  
4358      }      }
4359    jump = JUMP(SLJIT_JUMP);    jump = JUMP(SLJIT_JUMP);
4360    if (bra != OP_BRAZERO)    if (bra != OP_BRAZERO)
# Line 3733  if (opcode == OP_ASSERT || opcode == OP_ Line 4377  if (opcode == OP_ASSERT || opcode == OP_
4377      }      }
4378    else    else
4379      {      {
4380      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);      if (bra == OP_BRA)
4381      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(TMP1), (framesize + 1) * sizeof(sljit_w));        {
4382      if (bra == OP_BRAZERO)        /* We don't need to keep the STR_PTR, only the previous localptr. */
4383        {        OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_IMM, (framesize + 1) * sizeof(sljit_w));
4384        allocate_stack(common, 1);        OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), 0);
       OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);  
4385        }        }
4386      else if (bra == OP_BRAMINZERO)      else
4387        {        {
4388        allocate_stack(common, 1);        /* We don't need to keep the STR_PTR, only the previous localptr. */
4389        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));
4390          OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
4391          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), bra == OP_BRAZERO ? STR_PTR : SLJIT_IMM, 0);
4392        }        }
4393      }      }
4394    
# Line 3780  else Line 4425  else
4425      {      {
4426      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
4427      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));  
4428      /* The topmost item should be 0. */      /* The topmost item should be 0. */
4429      if (bra != OP_BRA)      if (bra != OP_BRA)
4430        {        {
# Line 3791  else Line 4434  else
4434      else      else
4435        free_stack(common, framesize + 2);        free_stack(common, framesize + 2);
4436      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);  
4437      }      }
4438    
4439    if (bra == OP_BRAZERO)    if (bra == OP_BRAZERO)
# Line 3811  else Line 4452  else
4452      }      }
4453    }    }
4454    
4455    common->leavelabel = save_leavelabel;
4456  common->acceptlabel = save_acceptlabel;  common->acceptlabel = save_acceptlabel;
4457    common->leave = save_leave;
4458  common->accept = save_accept;  common->accept = save_accept;
4459  return cc + 1 + LINK_SIZE;  return cc + 1 + LINK_SIZE;
4460  }  }
4461    
4462    static sljit_w SLJIT_CALL do_searchovector(sljit_w refno, sljit_w* locals, pcre_uchar *name_table)
4463    {
4464    int condition = FALSE;
4465    pcre_uchar *slotA = name_table;
4466    pcre_uchar *slotB;
4467    sljit_w name_count = locals[LOCALS0 / sizeof(sljit_w)];
4468    sljit_w name_entry_size = locals[LOCALS1 / sizeof(sljit_w)];
4469    sljit_w no_capture;
4470    int i;
4471    
4472    locals += refno & 0xff;
4473    refno >>= 8;
4474    no_capture = locals[1];
4475    
4476    for (i = 0; i < name_count; i++)
4477      {
4478      if (GET2(slotA, 0) == refno) break;
4479      slotA += name_entry_size;
4480      }
4481    
4482    if (i < name_count)
4483      {
4484      /* Found a name for the number - there can be only one; duplicate names
4485      for different numbers are allowed, but not vice versa. First scan down
4486      for duplicates. */
4487    
4488      slotB = slotA;
4489      while (slotB > name_table)
4490        {
4491        slotB -= name_entry_size;
4492        if (STRCMP_UC_UC(slotA + IMM2_SIZE, slotB + IMM2_SIZE) == 0)
4493          {
4494          condition = locals[GET2(slotB, 0) << 1] != no_capture;
4495          if (condition) break;
4496          }
4497        else break;
4498        }
4499    
4500      /* Scan up for duplicates */
4501      if (!condition)
4502        {
4503        slotB = slotA;
4504        for (i++; i < name_count; i++)
4505          {
4506          slotB += name_entry_size;
4507          if (STRCMP_UC_UC(slotA + IMM2_SIZE, slotB + IMM2_SIZE) == 0)
4508            {
4509            condition = locals[GET2(slotB, 0) << 1] != no_capture;
4510            if (condition) break;
4511            }
4512          else break;
4513          }
4514        }
4515      }
4516    return condition;
4517    }
4518    
4519    static sljit_w SLJIT_CALL do_searchgroups(sljit_w recno, sljit_w* locals, pcre_uchar *name_table)
4520    {
4521    int condition = FALSE;
4522    pcre_uchar *slotA = name_table;
4523    pcre_uchar *slotB;
4524    sljit_w name_count = locals[LOCALS0 / sizeof(sljit_w)];
4525    sljit_w name_entry_size = locals[LOCALS1 / sizeof(sljit_w)];
4526    sljit_w group_num = locals[POSSESSIVE0 / sizeof(sljit_w)];
4527    int i;
4528    
4529    for (i = 0; i < name_count; i++)
4530      {
4531      if (GET2(slotA, 0) == recno) break;
4532      slotA += name_entry_size;
4533      }
4534    
4535    if (i < name_count)
4536      {
4537      /* Found a name for the number - there can be only one; duplicate
4538      names for different numbers are allowed, but not vice versa. First
4539      scan down for duplicates. */
4540    
4541      slotB = slotA;
4542      while (slotB > name_table)
4543        {
4544        slotB -= name_entry_size;
4545        if (STRCMP_UC_UC(slotA + IMM2_SIZE, slotB + IMM2_SIZE) == 0)
4546          {
4547          condition = GET2(slotB, 0) == group_num;
4548          if (condition) break;
4549          }
4550        else break;
4551        }
4552    
4553      /* Scan up for duplicates */
4554      if (!condition)
4555        {
4556        slotB = slotA;
4557        for (i++; i < name_count; i++)
4558          {
4559          slotB += name_entry_size;
4560          if (STRCMP_UC_UC(slotA + IMM2_SIZE, slotB + IMM2_SIZE) == 0)
4561            {
4562            condition = GET2(slotB, 0) == group_num;
4563            if (condition) break;
4564            }
4565          else break;
4566          }
4567        }
4568      }
4569    return condition;
4570    }
4571    
4572  /*  /*
4573    Handling bracketed expressions is probably the most complex part.    Handling bracketed expressions is probably the most complex part.
4574    
# Line 3825  return cc + 1 + LINK_SIZE; Line 4578  return cc + 1 + LINK_SIZE;
4578      A - Push the current STR_PTR. Needed for restoring the STR_PTR      A - Push the current STR_PTR. Needed for restoring the STR_PTR
4579          before the next alternative. Not pushed if there are no alternatives.          before the next alternative. Not pushed if there are no alternatives.
4580      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.
4581      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.
4582      L - Push the previous local (pointed by localptr) to the stack      L - Push the previous local (pointed by localptr) to the stack
4583     () - opional values stored on the stack     () - opional values stored on the stack
4584    ()* - optonal, can be stored multiple times    ()* - optonal, can be stored multiple times
# Line 3863  return cc + 1 + LINK_SIZE; Line 4616  return cc + 1 + LINK_SIZE;
4616      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.
4617    
4618    The next list shows the possible content of a bracket:    The next list shows the possible content of a bracket:
4619    (|)     OP_*BRA  | OP_ALT ...         M A    (|)     OP_*BRA    | OP_ALT ...         M A
4620    (?()|)  OP_*COND | OP_ALT             M A    (?()|)  OP_*COND   | OP_ALT             M A
4621    (?>|)   OP_ONCE  | OP_ALT ...         [stack trace] M A    (?>|)   OP_ONCE    | OP_ALT ...         [stack trace] M A
4622                                          Or nothing, if trace is unnecessary    (?>|)   OP_ONCE_NC | OP_ALT ...         [stack trace] M A
4623                                              Or nothing, if trace is unnecessary
4624  */  */
4625    
4626  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)
4627  {  {
4628  DEFINE_COMPILER;  DEFINE_COMPILER;
4629  fallback_common *fallback;  fallback_common *fallback;
4630  uschar opcode;  pcre_uchar opcode;
4631  int localptr = 0;  int localptr = 0;
4632  int offset = 0;  int offset = 0;
4633  int stacksize;  int stacksize;
4634  uschar *ccbegin;  pcre_uchar *ccbegin;
4635  uschar *hotpath;  pcre_uchar *hotpath;
4636  uschar bra = OP_BRA;  pcre_uchar bra = OP_BRA;
4637  uschar ket;  pcre_uchar ket;
4638  assert_fallback *assert;  assert_fallback *assert;
4639  BOOL has_alternatives;  BOOL has_alternatives;
4640  struct sljit_jump *jump;  struct sljit_jump *jump;
# Line 3899  if (*cc == OP_BRAZERO || *cc == OP_BRAMI Line 4653  if (*cc == OP_BRAZERO || *cc == OP_BRAMI
4653    
4654  opcode = *cc;  opcode = *cc;
4655  ccbegin = cc;  ccbegin = cc;
4656    hotpath = ccbegin + 1 + LINK_SIZE;
4657    
4658  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)
4659    {    {
4660    /* Drop this bracket_fallback. */    /* Drop this bracket_fallback. */
# Line 3910  ket = *(bracketend(cc) - 1 - LINK_SIZE); Line 4666  ket = *(bracketend(cc) - 1 - LINK_SIZE);
4666  SLJIT_ASSERT(ket == OP_KET || ket == OP_KETRMAX || ket == OP_KETRMIN);  SLJIT_ASSERT(ket == OP_KET || ket == OP_KETRMAX || ket == OP_KETRMIN);
4667  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)));
4668  cc += GET(cc, 1);  cc += GET(cc, 1);
4669  has_alternatives = *cc == OP_ALT || opcode == OP_COND || opcode == OP_SCOND;  
4670    has_alternatives = *cc == OP_ALT;
4671    if (SLJIT_UNLIKELY(opcode == OP_COND) || SLJIT_UNLIKELY(opcode == OP_SCOND))
4672      {
4673      has_alternatives = (*hotpath == OP_RREF) ? FALSE : TRUE;
4674      if (*hotpath == OP_NRREF)
4675        {
4676        stacksize = GET2(hotpath, 1);
4677        if (common->currententry == NULL || stacksize == RREF_ANY)
4678          has_alternatives = FALSE;
4679        else if (common->currententry->start == 0)
4680          has_alternatives = stacksize != 0;
4681        else
4682          has_alternatives = stacksize != GET2(common->start, common->currententry->start + 1 + LINK_SIZE);
4683        }
4684      }
4685    
4686  if (SLJIT_UNLIKELY(opcode == OP_COND) && (*cc == OP_KETRMAX || *cc == OP_KETRMIN))  if (SLJIT_UNLIKELY(opcode == OP_COND) && (*cc == OP_KETRMAX || *cc == OP_KETRMIN))
4687    opcode = OP_SCOND;    opcode = OP_SCOND;
4688    if (SLJIT_UNLIKELY(opcode == OP_ONCE_NC))
4689      opcode = OP_ONCE;
4690    
4691  if (opcode == OP_CBRA || opcode == OP_SCBRA)  if (opcode == OP_CBRA || opcode == OP_SCBRA)
4692    {    {
# Line 3921  if (opcode == OP_CBRA || opcode == OP_SC Line 4695  if (opcode == OP_CBRA || opcode == OP_SC
4695    localptr = OVECTOR_PRIV(offset);    localptr = OVECTOR_PRIV(offset);
4696    offset <<= 1;    offset <<= 1;
4697    FALLBACK_AS(bracket_fallback)->localptr = localptr;    FALLBACK_AS(bracket_fallback)->localptr = localptr;
4698      hotpath += IMM2_SIZE;
4699    }    }
4700  else if (opcode == OP_ONCE || opcode == OP_SBRA || opcode == OP_SCOND)  else if (opcode == OP_ONCE || opcode == OP_SBRA || opcode == OP_SCOND)
4701    {    {
4702    /* Other brackets simply allocate the next entry. */    /* Other brackets simply allocate the next entry. */
4703    localptr = PRIV(ccbegin);    localptr = PRIV_DATA(ccbegin);
4704    SLJIT_ASSERT(localptr != 0);    SLJIT_ASSERT(localptr != 0);
4705    FALLBACK_AS(bracket_fallback)->localptr = localptr;    FALLBACK_AS(bracket_fallback)->localptr = localptr;
4706    if (opcode == OP_ONCE)    if (opcode == OP_ONCE)
# Line 4052  if (opcode == OP_ONCE) Line 4827  if (opcode == OP_ONCE)
4827  else if (opcode == OP_CBRA || opcode == OP_SCBRA)  else if (opcode == OP_CBRA || opcode == OP_SCBRA)
4828    {    {
4829    /* Saving the previous values. */    /* Saving the previous values. */
4830    allocate_stack(common, 4);    allocate_stack(common, 3);
4831    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));
4832    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));
4833    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0);
4834    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0);
4835    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
   OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(2), MAX_INDEX, 0);  
4836    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, STR_PTR, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, STR_PTR, 0);
4837    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(3), TMP1, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(2), TMP1, 0);
   /* Update MAX_INDEX if necessary. */  
   add_stub(common, max_index, (offset >> 1) + 1, CMP(SLJIT_C_LESS, MAX_INDEX, 0, SLJIT_IMM, (offset >> 1) + 1));  
4838    }    }
4839  else if (opcode == OP_SBRA || opcode == OP_SCOND)  else if (opcode == OP_SBRA || opcode == OP_SCOND)
4840    {    {
# Line 4080  else if (has_alternatives) Line 4852  else if (has_alternatives)
4852    }    }
4853    
4854  /* Generating code for the first alternative. */  /* Generating code for the first alternative. */
 hotpath = ccbegin + 1 + LINK_SIZE;  
 if (offset != 0)  
   hotpath += 2;  
4855  if (opcode == OP_COND || opcode == OP_SCOND)