/[pcre]/code/tags/pcre-8.37/pcre_jit_compile.c
ViewVC logotype

Diff of /code/tags/pcre-8.37/pcre_jit_compile.c

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

revision 678 by ph10, Sun Aug 28 15:23:03 2011 UTC revision 929 by zherczeg, Fri Feb 24 11:07:47 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    int calllimit;    int calllimit;
160    uschar notbol;    pcre_uint8 notbol;
161    uschar noteol;    pcre_uint8 noteol;
162    uschar notempty;    pcre_uint8 notempty;
163    uschar notempty_atstart;    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 194  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 265  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 *acceptlabel;    struct sljit_label *acceptlabel;
311    stub_list *stubs;    stub_list *stubs;
312    recurse_entry *entries;    recurse_entry *entries;
313    recurse_entry *currententry;    recurse_entry *currententry;
314      jump_list *partialmatch;
315    jump_list *accept;    jump_list *accept;
316    jump_list *calllimit;    jump_list *calllimit;
317    jump_list *stackalloc;    jump_list *stackalloc;
# Line 291  typedef struct compiler_common { Line 323  typedef struct compiler_common {
323    jump_list *casefulcmp;    jump_list *casefulcmp;
324    jump_list *caselesscmp;    jump_list *caselesscmp;
325    BOOL jscript_compat;    BOOL jscript_compat;
326  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
327    BOOL utf8;    BOOL utf;
328  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
329    BOOL useucp;    BOOL use_ucp;
330  #endif  #endif
331    jump_list *utf8readchar;    jump_list *utfreadchar;
332    jump_list *utf8readtype8;  #ifdef COMPILE_PCRE8
333      jump_list *utfreadtype8;
334  #endif  #endif
335    #endif /* SUPPORT_UTF */
336  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
337    jump_list *getucd;    jump_list *getucd;
338  #endif  #endif
# Line 310  typedef struct compare_context { Line 344  typedef struct compare_context {
344    int length;    int length;
345    int sourcereg;    int sourcereg;
346  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
347    int byteptr;    int ucharptr;
348    union {    union {
349      int asint;      sljit_i asint;
350      short asshort;      sljit_uh asushort;
351    #ifdef COMPILE_PCRE8
352      sljit_ub asbyte;      sljit_ub asbyte;
353      sljit_ub asbytes[4];      sljit_ub asuchars[4];
354    #else
355    #ifdef COMPILE_PCRE16
356        sljit_uh asuchars[2];
357    #endif
358    #endif
359    } c;    } c;
360    union {    union {
361      int asint;      sljit_i asint;
362      short asshort;      sljit_uh asushort;
363    #ifdef COMPILE_PCRE8
364      sljit_ub asbyte;      sljit_ub asbyte;
365      sljit_ub asbytes[4];      sljit_ub asuchars[4];
366    #else
367    #ifdef COMPILE_PCRE16
368        sljit_uh asuchars[2];
369    #endif
370    #endif
371    } oc;    } oc;
372  #endif  #endif
373  } compare_context;  } compare_context;
374    
375  enum {  enum {
376    frame_end = 0,    frame_end = 0,
377    frame_setmaxindex = -1,    frame_setstrbegin = -1,
378    frame_setstrbegin = -2    frame_setmark = -2
379  };  };
380    
381    /* Undefine sljit macros. */
382    #undef CMP
383    
384  /* Used for accessing the elements of the stack. */  /* Used for accessing the elements of the stack. */
385  #define STACK(i)      ((-(i) - 1) * (int)sizeof(sljit_w))  #define STACK(i)      ((-(i) - 1) * (int)sizeof(sljit_w))
386    
387  #define TMP1          SLJIT_TEMPORARY_REG1  #define TMP1          SLJIT_TEMPORARY_REG1
388  #define TMP2          SLJIT_TEMPORARY_REG3  #define TMP2          SLJIT_TEMPORARY_REG3
389  #define TMP3          SLJIT_TEMPORARY_EREG2  #define TMP3          SLJIT_TEMPORARY_EREG2
390  #define STR_PTR       SLJIT_GENERAL_REG1  #define STR_PTR       SLJIT_SAVED_REG1
391  #define STR_END       SLJIT_GENERAL_REG2  #define STR_END       SLJIT_SAVED_REG2
392  #define STACK_TOP     SLJIT_TEMPORARY_REG2  #define STACK_TOP     SLJIT_TEMPORARY_REG2
393  #define STACK_LIMIT   SLJIT_GENERAL_REG3  #define STACK_LIMIT   SLJIT_SAVED_REG3
394  #define ARGUMENTS     SLJIT_GENERAL_EREG1  #define ARGUMENTS     SLJIT_SAVED_EREG1
395  #define MAX_INDEX     SLJIT_GENERAL_EREG2  #define CALL_COUNT    SLJIT_SAVED_EREG2
396  #define RETURN_ADDR   SLJIT_TEMPORARY_EREG1  #define RETURN_ADDR   SLJIT_TEMPORARY_EREG1
397    
398  /* Locals layout. */  /* Locals layout. */
# Line 353  enum { Line 402  enum {
402  /* Two local variables for possessive quantifiers (char1 cannot use them). */  /* Two local variables for possessive quantifiers (char1 cannot use them). */
403  #define POSSESSIVE0      (2 * sizeof(sljit_w))  #define POSSESSIVE0      (2 * sizeof(sljit_w))
404  #define POSSESSIVE1      (3 * sizeof(sljit_w))  #define POSSESSIVE1      (3 * sizeof(sljit_w))
 /* Head of the saved local variables */  
 #define LOCALS_HEAD      (4 * sizeof(sljit_w))  
 /* Head of the last recursion. */  
 #define RECURSIVE_HEAD   (5 * sizeof(sljit_w))  
 /* Number of recursions. */  
 #define CALL_COUNT       (6 * sizeof(sljit_w))  
405  /* Max limit of recursions. */  /* Max limit of recursions. */
406  #define CALL_LIMIT       (7 * sizeof(sljit_w))  #define CALL_LIMIT       (4 * sizeof(sljit_w))
 /* Last known position of the requested byte. */  
 #define REQ_BYTE_PTR     (8 * sizeof(sljit_w))  
 /* End pointer of the first line. */  
 #define FIRSTLINE_END    (9 * sizeof(sljit_w))  
407  /* The output vector is stored on the stack, and contains pointers  /* The output vector is stored on the stack, and contains pointers
408  to characters. The vector data is divided into two groups: the first  to characters. The vector data is divided into two groups: the first
409  group contains the start / end character pointers, and the second is  group contains the start / end character pointers, and the second is
410  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. */
411  #define OVECTOR_START    (10 * sizeof(sljit_w))  #define OVECTOR_START    (common->ovector_start)
412  #define OVECTOR(i)       (OVECTOR_START + (i) * sizeof(sljit_w))  #define OVECTOR(i)       (OVECTOR_START + (i) * sizeof(sljit_w))
413  #define OVECTOR_PRIV(i)  (common->cbraptr + (i) * sizeof(sljit_w))  #define OVECTOR_PRIV(i)  (common->cbraptr + (i) * sizeof(sljit_w))
414  #define PRIV(cc)         (common->localptrs[(cc) - common->start])  #define PRIV_DATA(cc)    (common->localptrs[(cc) - common->start])
415    
416    #ifdef COMPILE_PCRE8
417    #define MOV_UCHAR  SLJIT_MOV_UB
418    #define MOVU_UCHAR SLJIT_MOVU_UB
419    #else
420    #ifdef COMPILE_PCRE16
421    #define MOV_UCHAR  SLJIT_MOV_UH
422    #define MOVU_UCHAR SLJIT_MOVU_UH
423    #else
424    #error Unsupported compiling mode
425    #endif
426    #endif
427    
428  /* Shortcuts. */  /* Shortcuts. */
429  #define DEFINE_COMPILER \  #define DEFINE_COMPILER \
# Line 396  the start pointers when the end of the c Line 447  the start pointers when the end of the c
447  #define COND_VALUE(op, dst, dstw, type) \  #define COND_VALUE(op, dst, dstw, type) \
448    sljit_emit_cond_value(compiler, (op), (dst), (dstw), (type))    sljit_emit_cond_value(compiler, (op), (dst), (dstw), (type))
449    
450  static uschar* bracketend(uschar* cc)  static pcre_uchar* bracketend(pcre_uchar* cc)
451  {  {
452  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));
453  do cc += GET(cc, 1); while (*cc == OP_ALT);  do cc += GET(cc, 1); while (*cc == OP_ALT);
# Line 405  cc += 1 + LINK_SIZE; Line 456  cc += 1 + LINK_SIZE;
456  return cc;  return cc;
457  }  }
458    
459  /* Functions whose might need modification for all new supported opcodes:  /* Functions whose might need modification for all new supported opcodes:
460   next_opcode   next_opcode
461   get_localspace   get_localspace
462   set_localptrs   set_localptrs
# Line 417  return cc; Line 468  return cc;
468   compile_fallbackpath   compile_fallbackpath
469  */  */
470    
471  static uschar *next_opcode(compiler_common *common, uschar *cc)  static pcre_uchar *next_opcode(compiler_common *common, pcre_uchar *cc)
472  {  {
473  SLJIT_UNUSED_ARG(common);  SLJIT_UNUSED_ARG(common);
474  switch(*cc)  switch(*cc)
# Line 472  switch(*cc) Line 523  switch(*cc)
523    case OP_SKIPZERO:    case OP_SKIPZERO:
524    return cc + 1;    return cc + 1;
525    
526      case OP_ANYBYTE:
527    #ifdef SUPPORT_UTF
528      if (common->utf) return NULL;
529    #endif
530      return cc + 1;
531    
532    case OP_CHAR:    case OP_CHAR:
533    case OP_CHARI:    case OP_CHARI:
534    case OP_NOT:    case OP_NOT:
535    case OP_NOTI:    case OP_NOTI:
   
536    case OP_STAR:    case OP_STAR:
537    case OP_MINSTAR:    case OP_MINSTAR:
538    case OP_PLUS:    case OP_PLUS:
# Line 514  switch(*cc) Line 570  switch(*cc)
570    case OP_NOTPOSPLUSI:    case OP_NOTPOSPLUSI:
571    case OP_NOTPOSQUERYI:    case OP_NOTPOSQUERYI:
572    cc += 2;    cc += 2;
573  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
574    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]);
575  #endif  #endif
576    return cc;    return cc;
577    
# Line 535  switch(*cc) Line 591  switch(*cc)
591    case OP_NOTMINUPTOI:    case OP_NOTMINUPTOI:
592    case OP_NOTEXACTI:    case OP_NOTEXACTI:
593    case OP_NOTPOSUPTOI:    case OP_NOTPOSUPTOI:
594    cc += 4;    cc += 2 + IMM2_SIZE;
595  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
596    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]);
597  #endif  #endif
598    return cc;    return cc;
599    
600    case OP_NOTPROP:    case OP_NOTPROP:
601    case OP_PROP:    case OP_PROP:
602      return cc + 1 + 2;
603    
604    case OP_TYPEUPTO:    case OP_TYPEUPTO:
605    case OP_TYPEMINUPTO:    case OP_TYPEMINUPTO:
606    case OP_TYPEEXACT:    case OP_TYPEEXACT:
# Line 550  switch(*cc) Line 608  switch(*cc)
608    case OP_REF:    case OP_REF:
609    case OP_REFI:    case OP_REFI:
610    case OP_CREF:    case OP_CREF:
611      case OP_NCREF:
612      case OP_RREF:
613      case OP_NRREF:
614    case OP_CLOSE:    case OP_CLOSE:
615    cc += 3;    cc += 1 + IMM2_SIZE;
616    return cc;    return cc;
617    
618    case OP_CRRANGE:    case OP_CRRANGE:
619    case OP_CRMINRANGE:    case OP_CRMINRANGE:
620    return cc + 5;    return cc + 1 + 2 * IMM2_SIZE;
621    
622    case OP_CLASS:    case OP_CLASS:
623    case OP_NCLASS:    case OP_NCLASS:
624    return cc + 33;    return cc + 1 + 32 / sizeof(pcre_uchar);
625    
626  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
627    case OP_XCLASS:    case OP_XCLASS:
628    return cc + GET(cc, 1);    return cc + GET(cc, 1);
629  #endif  #endif
# Line 574  switch(*cc) Line 635  switch(*cc)
635    case OP_ASSERTBACK_NOT:    case OP_ASSERTBACK_NOT:
636    case OP_REVERSE:    case OP_REVERSE:
637    case OP_ONCE:    case OP_ONCE:
638      case OP_ONCE_NC:
639    case OP_BRA:    case OP_BRA:
640    case OP_BRAPOS:    case OP_BRAPOS:
641    case OP_COND:    case OP_COND:
# Line 591  switch(*cc) Line 653  switch(*cc)
653    case OP_CBRAPOS:    case OP_CBRAPOS:
654    case OP_SCBRA:    case OP_SCBRA:
655    case OP_SCBRAPOS:    case OP_SCBRAPOS:
656    return cc + 1 + LINK_SIZE + 2;    return cc + 1 + LINK_SIZE + IMM2_SIZE;
657    
658      case OP_MARK:
659      return cc + 1 + 2 + cc[1];
660    
661    default:    default:
662    return NULL;    return NULL;
663    }    }
664  }  }
665    
666  static int get_localspace(compiler_common *common, uschar *cc, uschar *ccend)  static int get_localspace(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend)
667  {  {
668  int localspace = 0;  int localspace = 0;
669  uschar *alternative;  pcre_uchar *alternative;
670  /* 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. */
671  while (cc < ccend)  while (cc < ccend)
672    {    {
673    switch(*cc)    switch(*cc)
674      {      {
675        case OP_SET_SOM:
676        common->has_set_som = TRUE;
677        cc += 1;
678        break;
679    
680      case OP_ASSERT:      case OP_ASSERT:
681      case OP_ASSERT_NOT:      case OP_ASSERT_NOT:
682      case OP_ASSERTBACK:      case OP_ASSERTBACK:
683      case OP_ASSERTBACK_NOT:      case OP_ASSERTBACK_NOT:
684      case OP_ONCE:      case OP_ONCE:
685        case OP_ONCE_NC:
686      case OP_BRAPOS:      case OP_BRAPOS:
687      case OP_SBRA:      case OP_SBRA:
688      case OP_SBRAPOS:      case OP_SBRAPOS:
# Line 623  while (cc < ccend) Line 694  while (cc < ccend)
694      case OP_CBRAPOS:      case OP_CBRAPOS:
695      case OP_SCBRAPOS:      case OP_SCBRAPOS:
696      localspace += sizeof(sljit_w);      localspace += sizeof(sljit_w);
697      cc += 1 + LINK_SIZE + 2;      cc += 1 + LINK_SIZE + IMM2_SIZE;
698      break;      break;
699    
700      case OP_COND:      case OP_COND:
# Line 634  while (cc < ccend) Line 705  while (cc < ccend)
705      cc += 1 + LINK_SIZE;      cc += 1 + LINK_SIZE;
706      break;      break;
707    
708        case OP_RECURSE:
709        /* Set its value only once. */
710        if (common->recursive_head == 0)
711          {
712          common->recursive_head = common->ovector_start;
713          common->ovector_start += sizeof(sljit_w);
714          }
715        cc += 1 + LINK_SIZE;
716        break;
717    
718        case OP_MARK:
719        if (common->mark_ptr == 0)
720          {
721          common->mark_ptr = common->ovector_start;
722          common->ovector_start += sizeof(sljit_w);
723          }
724        cc += 1 + 2 + cc[1];
725        break;
726    
727      default:      default:
728      cc = next_opcode(common, cc);      cc = next_opcode(common, cc);
729      if (cc == NULL)      if (cc == NULL)
# Line 644  while (cc < ccend) Line 734  while (cc < ccend)
734  return localspace;  return localspace;
735  }  }
736    
737  static void set_localptrs(compiler_common *common, int localptr, uschar *ccend)  static void set_localptrs(compiler_common *common, int localptr, pcre_uchar *ccend)
738  {  {
739  uschar *cc = common->start;  pcre_uchar *cc = common->start;
740  uschar *alternative;  pcre_uchar *alternative;
741  while (cc < ccend)  while (cc < ccend)
742    {    {
743    switch(*cc)    switch(*cc)
# Line 657  while (cc < ccend) Line 747  while (cc < ccend)
747      case OP_ASSERTBACK:      case OP_ASSERTBACK:
748      case OP_ASSERTBACK_NOT:      case OP_ASSERTBACK_NOT:
749      case OP_ONCE:      case OP_ONCE:
750        case OP_ONCE_NC:
751      case OP_BRAPOS:      case OP_BRAPOS:
752      case OP_SBRA:      case OP_SBRA:
753      case OP_SBRAPOS:      case OP_SBRAPOS:
# Line 670  while (cc < ccend) Line 761  while (cc < ccend)
761      case OP_SCBRAPOS:      case OP_SCBRAPOS:
762      common->localptrs[cc - common->start] = localptr;      common->localptrs[cc - common->start] = localptr;
763      localptr += sizeof(sljit_w);      localptr += sizeof(sljit_w);
764      cc += 1 + LINK_SIZE + 2;      cc += 1 + LINK_SIZE + IMM2_SIZE;
765      break;      break;
766    
767      case OP_COND:      case OP_COND:
# Line 693  while (cc < ccend) Line 784  while (cc < ccend)
784  }  }
785    
786  /* Returns with -1 if no need for frame. */  /* Returns with -1 if no need for frame. */
787  static int get_framesize(compiler_common *common, uschar *cc, BOOL recursive)  static int get_framesize(compiler_common *common, pcre_uchar *cc, BOOL recursive)
788  {  {
789  uschar *ccend = bracketend(cc);  pcre_uchar *ccend = bracketend(cc);
 uschar *end;  
790  int length = 0;  int length = 0;
791  BOOL possessive = FALSE;  BOOL possessive = FALSE;
792  BOOL needs_frame = FALSE;  BOOL setsom_found = recursive;
793  BOOL needs_maxindex = FALSE;  BOOL setmark_found = recursive;
 BOOL setsom_found = FALSE;  
794    
795  if (!recursive && (*cc == OP_CBRAPOS || *cc == OP_SCBRAPOS))  if (!recursive && (*cc == OP_CBRAPOS || *cc == OP_SCBRAPOS))
796    {    {
797    length = 3 + 2;    length = 3;
   needs_maxindex = TRUE;  
798    possessive = TRUE;    possessive = TRUE;
799    }    }
800    
# Line 716  while (cc < ccend) Line 804  while (cc < ccend)
804    switch(*cc)    switch(*cc)
805      {      {
806      case OP_SET_SOM:      case OP_SET_SOM:
807      case OP_RECURSE:      SLJIT_ASSERT(common->has_set_som);
808      if (!setsom_found)      if (!setsom_found)
809        {        {
810        length += 2;        length += 2;
811        setsom_found = TRUE;        setsom_found = TRUE;
812        }        }
813      cc += (*cc == OP_SET_SOM) ? 1 : 1 + LINK_SIZE;      cc += 1;
814      break;      break;
815    
816      case OP_ASSERT:      case OP_MARK:
817      case OP_ASSERT_NOT:      SLJIT_ASSERT(common->mark_ptr != 0);
818      case OP_ASSERTBACK:      if (!setmark_found)
     case OP_ASSERTBACK_NOT:  
     case OP_ONCE:  
     if (needs_frame || length > 0)  
819        {        {
820        cc = bracketend(cc);        length += 2;
821        break;        setmark_found = TRUE;
822        }        }
823      /* Check whether a frame must be created. */      cc += 1 + 2 + cc[1];
824      end = bracketend(cc);      break;
825      while (cc < end)  
826        {      case OP_RECURSE:
827        if (*cc == OP_SET_SOM || *cc == OP_CBRA || *cc == OP_CBRAPOS      if (common->has_set_som && !setsom_found)
828            || *cc == OP_SCBRA || *cc == OP_SCBRAPOS || *cc == OP_RECURSE)        {
829          needs_frame = TRUE;        length += 2;
830        cc = next_opcode(common, cc);        setsom_found = TRUE;
       SLJIT_ASSERT(cc != NULL);  
831        }        }
832        if (common->mark_ptr != 0 && !setmark_found)
833          {
834          length += 2;
835          setmark_found = TRUE;
836          }
837        cc += 1 + LINK_SIZE;
838      break;      break;
839    
840      case OP_CBRA:      case OP_CBRA:
841      case OP_CBRAPOS:      case OP_CBRAPOS:
842      case OP_SCBRA:      case OP_SCBRA:
843      case OP_SCBRAPOS:      case OP_SCBRAPOS:
     if (!needs_maxindex)  
       {  
       needs_maxindex = TRUE;  
       length += 2;  
       }  
844      length += 3;      length += 3;
845      cc += 1 + LINK_SIZE + 2;      cc += 1 + LINK_SIZE + IMM2_SIZE;
846      break;      break;
847    
848      default:      default:
# Line 767  while (cc < ccend) Line 852  while (cc < ccend)
852      }      }
853    
854  /* Possessive quantifiers can use a special case. */  /* Possessive quantifiers can use a special case. */
855  if (SLJIT_UNLIKELY(possessive) && !needs_frame && length == 3 + 2)  if (SLJIT_UNLIKELY(possessive) && length == 3)
856    return -1;    return -1;
857    
858  if (length > 0)  if (length > 0)
859    return length + 2;    return length + 1;
860  return needs_frame ? 0 : -1;  return -1;
861  }  }
862    
863  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)
864  {  {
 /* TMP2 must contain STACK_TOP - (-STACK(stackpos)) */  
865  DEFINE_COMPILER;  DEFINE_COMPILER;
866  uschar *ccend = bracketend(cc);  pcre_uchar *ccend = bracketend(cc);
867  BOOL needs_maxindex = FALSE;  BOOL setsom_found = recursive;
868  BOOL setsom_found = FALSE;  BOOL setmark_found = recursive;
869  int offset;  int offset;
870    
871  if (stackpos < stacktop)  /* >= 1 + shortest item size (2) */
872    {  SLJIT_UNUSED_ARG(stacktop);
873    SLJIT_ASSERT(stackpos + 1 == stacktop);  SLJIT_ASSERT(stackpos >= stacktop + 2);
   return;  
   }  
874    
875  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);  
   
876  if (recursive || (*cc != OP_CBRAPOS && *cc != OP_SCBRAPOS))  if (recursive || (*cc != OP_CBRAPOS && *cc != OP_SCBRAPOS))
877    cc = next_opcode(common, cc);    cc = next_opcode(common, cc);
878  SLJIT_ASSERT(cc != NULL);  SLJIT_ASSERT(cc != NULL);
# Line 802  while (cc < ccend) Line 880  while (cc < ccend)
880    switch(*cc)    switch(*cc)
881      {      {
882      case OP_SET_SOM:      case OP_SET_SOM:
883      case OP_RECURSE:      SLJIT_ASSERT(common->has_set_som);
884      if (!setsom_found)      if (!setsom_found)
885        {        {
886        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 812  while (cc < ccend) Line 890  while (cc < ccend)
890        stackpos += (int)sizeof(sljit_w);        stackpos += (int)sizeof(sljit_w);
891        setsom_found = TRUE;        setsom_found = TRUE;
892        }        }
893      cc += (*cc == OP_SET_SOM) ? 1 : 1 + LINK_SIZE;      cc += 1;
894      break;      break;
895    
896      case OP_ASSERT:      case OP_MARK:
897      case OP_ASSERT_NOT:      SLJIT_ASSERT(common->mark_ptr != 0);
898      case OP_ASSERTBACK:      if (!setmark_found)
899      case OP_ASSERTBACK_NOT:        {
900      case OP_ONCE:        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr);
901      cc = bracketend(cc);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, frame_setmark);
902          stackpos += (int)sizeof(sljit_w);
903          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);
904          stackpos += (int)sizeof(sljit_w);
905          setmark_found = TRUE;
906          }
907        cc += 1 + 2 + cc[1];
908      break;      break;
909    
910      case OP_CBRA:      case OP_RECURSE:
911      case OP_CBRAPOS:      if (common->has_set_som && !setsom_found)
     case OP_SCBRA:  
     case OP_SCBRAPOS:  
     if (!needs_maxindex)  
912        {        {
913        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, frame_setmaxindex);        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0));
914          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, frame_setstrbegin);
915        stackpos += (int)sizeof(sljit_w);        stackpos += (int)sizeof(sljit_w);
916        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, MAX_INDEX, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);
917        stackpos += (int)sizeof(sljit_w);        stackpos += (int)sizeof(sljit_w);
918        needs_maxindex = TRUE;        setsom_found = TRUE;
919        }        }
920        if (common->mark_ptr != 0 && !setmark_found)
921          {
922          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr);
923          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, frame_setmark);
924          stackpos += (int)sizeof(sljit_w);
925          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);
926          stackpos += (int)sizeof(sljit_w);
927          setmark_found = TRUE;
928          }
929        cc += 1 + LINK_SIZE;
930        break;
931    
932        case OP_CBRA:
933        case OP_CBRAPOS:
934        case OP_SCBRA:
935        case OP_SCBRAPOS:
936      offset = (GET2(cc, 1 + LINK_SIZE)) << 1;      offset = (GET2(cc, 1 + LINK_SIZE)) << 1;
937      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, OVECTOR(offset));      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, OVECTOR(offset));
938      stackpos += (int)sizeof(sljit_w);      stackpos += (int)sizeof(sljit_w);
# Line 845  while (cc < ccend) Line 943  while (cc < ccend)
943      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP2, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP2, 0);
944      stackpos += (int)sizeof(sljit_w);      stackpos += (int)sizeof(sljit_w);
945    
946      cc += 1 + LINK_SIZE + 2;      cc += 1 + LINK_SIZE + IMM2_SIZE;
947      break;      break;
948    
949      default:      default:
# Line 855  while (cc < ccend) Line 953  while (cc < ccend)
953      }      }
954    
955  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, frame_end);  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, frame_end);
956  SLJIT_ASSERT(stackpos == STACK(stacktop + 1));  SLJIT_ASSERT(stackpos == STACK(stacktop));
957  }  }
958    
959  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)
960  {  {
961  int localsize = 2;  int localsize = 2;
962  uschar *alternative;  pcre_uchar *alternative;
963  /* Calculate the sum of the local variables. */  /* Calculate the sum of the local variables. */
964  while (cc < ccend)  while (cc < ccend)
965    {    {
# Line 872  while (cc < ccend) Line 970  while (cc < ccend)
970      case OP_ASSERTBACK:      case OP_ASSERTBACK:
971      case OP_ASSERTBACK_NOT:      case OP_ASSERTBACK_NOT:
972      case OP_ONCE:      case OP_ONCE:
973        case OP_ONCE_NC:
974      case OP_BRAPOS:      case OP_BRAPOS:
975      case OP_SBRA:      case OP_SBRA:
976      case OP_SBRAPOS:      case OP_SBRAPOS:
# Line 883  while (cc < ccend) Line 982  while (cc < ccend)
982      case OP_CBRA:      case OP_CBRA:
983      case OP_SCBRA:      case OP_SCBRA:
984      localsize++;      localsize++;
985      cc += 1 + LINK_SIZE + 2;      cc += 1 + LINK_SIZE + IMM2_SIZE;
986      break;      break;
987    
988      case OP_CBRAPOS:      case OP_CBRAPOS:
989      case OP_SCBRAPOS:      case OP_SCBRAPOS:
990      localsize += 2;      localsize += 2;
991      cc += 1 + LINK_SIZE + 2;      cc += 1 + LINK_SIZE + IMM2_SIZE;
992      break;      break;
993    
994      case OP_COND:      case OP_COND:
# Line 910  SLJIT_ASSERT(cc == ccend); Line 1009  SLJIT_ASSERT(cc == ccend);
1009  return localsize;  return localsize;
1010  }  }
1011    
1012  static void copy_locals(compiler_common *common, uschar *cc, uschar *ccend,  static void copy_locals(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend,
1013    BOOL save, int stackptr, int stacktop)    BOOL save, int stackptr, int stacktop)
1014  {  {
1015  DEFINE_COMPILER;  DEFINE_COMPILER;
# Line 919  int count; Line 1018  int count;
1018  BOOL tmp1next = TRUE;  BOOL tmp1next = TRUE;
1019  BOOL tmp1empty = TRUE;  BOOL tmp1empty = TRUE;
1020  BOOL tmp2empty = TRUE;  BOOL tmp2empty = TRUE;
1021  uschar *alternative;  pcre_uchar *alternative;
1022  enum {  enum {
1023    start,    start,
1024    loop,    loop,
# Line 954  while (status != end) Line 1053  while (status != end)
1053    switch(status)    switch(status)
1054      {      {
1055      case start:      case start:
1056      SLJIT_ASSERT(save);      SLJIT_ASSERT(save && common->recursive_head != 0);
1057      count = 1;      count = 1;
1058      srcw[0] = RECURSIVE_HEAD;      srcw[0] = common->recursive_head;
1059      status = loop;      status = loop;
1060      break;      break;
1061    
# Line 974  while (status != end) Line 1073  while (status != end)
1073        case OP_ASSERTBACK:        case OP_ASSERTBACK:
1074        case OP_ASSERTBACK_NOT:        case OP_ASSERTBACK_NOT:
1075        case OP_ONCE:        case OP_ONCE:
1076          case OP_ONCE_NC:
1077        case OP_BRAPOS:        case OP_BRAPOS:
1078        case OP_SBRA:        case OP_SBRA:
1079        case OP_SBRAPOS:        case OP_SBRAPOS:
1080        case OP_SCOND:        case OP_SCOND:
1081        count = 1;        count = 1;
1082        srcw[0] = PRIV(cc);        srcw[0] = PRIV_DATA(cc);
1083        SLJIT_ASSERT(srcw[0] != 0);        SLJIT_ASSERT(srcw[0] != 0);
1084        cc += 1 + LINK_SIZE;        cc += 1 + LINK_SIZE;
1085        break;        break;
# Line 988  while (status != end) Line 1088  while (status != end)
1088        case OP_SCBRA:        case OP_SCBRA:
1089        count = 1;        count = 1;
1090        srcw[0] = OVECTOR_PRIV(GET2(cc, 1 + LINK_SIZE));        srcw[0] = OVECTOR_PRIV(GET2(cc, 1 + LINK_SIZE));
1091        cc += 1 + LINK_SIZE + 2;        cc += 1 + LINK_SIZE + IMM2_SIZE;
1092        break;        break;
1093    
1094        case OP_CBRAPOS:        case OP_CBRAPOS:
1095        case OP_SCBRAPOS:        case OP_SCBRAPOS:
1096        count = 2;        count = 2;
1097        srcw[1] = OVECTOR_PRIV(GET2(cc, 1 + LINK_SIZE));        srcw[1] = OVECTOR_PRIV(GET2(cc, 1 + LINK_SIZE));
1098        srcw[0] = PRIV(cc);        srcw[0] = PRIV_DATA(cc);
1099        SLJIT_ASSERT(srcw[0] != 0);        SLJIT_ASSERT(srcw[0] != 0);
1100        cc += 1 + LINK_SIZE + 2;        cc += 1 + LINK_SIZE + IMM2_SIZE;
1101        break;        break;
1102    
1103        case OP_COND:        case OP_COND:
# Line 1006  while (status != end) Line 1106  while (status != end)
1106        if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)        if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)
1107          {          {
1108          count = 1;          count = 1;
1109          srcw[0] = PRIV(cc);          srcw[0] = PRIV_DATA(cc);
1110          SLJIT_ASSERT(srcw[0] != 0);          SLJIT_ASSERT(srcw[0] != 0);
1111          }          }
1112        cc += 1 + LINK_SIZE;        cc += 1 + LINK_SIZE;
# Line 1170  while (list_item) Line 1270  while (list_item)
1270      case stack_alloc:      case stack_alloc:
1271      add_jump(compiler, &common->stackalloc, JUMP(SLJIT_FAST_CALL));      add_jump(compiler, &common->stackalloc, JUMP(SLJIT_FAST_CALL));
1272      break;      break;
   
     case max_index:  
     OP1(SLJIT_MOV, MAX_INDEX, 0, SLJIT_IMM, list_item->data);  
     break;  
1273      }      }
1274    JUMPTO(SLJIT_JUMP, list_item->leave);    JUMPTO(SLJIT_JUMP, list_item->leave);
1275    list_item = list_item->next;    list_item = list_item->next;
# Line 1185  static SLJIT_INLINE void decrease_call_c Line 1281  static SLJIT_INLINE void decrease_call_c
1281  {  {
1282  DEFINE_COMPILER;  DEFINE_COMPILER;
1283    
1284  OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_MEM1(SLJIT_LOCALS_REG), CALL_COUNT, SLJIT_MEM1(SLJIT_LOCALS_REG), CALL_COUNT, SLJIT_IMM, 1);  OP2(SLJIT_SUB | SLJIT_SET_E, CALL_COUNT, 0, CALL_COUNT, 0, SLJIT_IMM, 1);
1285  add_jump(compiler, &common->calllimit, JUMP(SLJIT_C_ZERO));  add_jump(compiler, &common->calllimit, JUMP(SLJIT_C_ZERO));
1286  }  }
1287    
# Line 1218  struct sljit_label *loop; Line 1314  struct sljit_label *loop;
1314  int i;  int i;
1315  /* At this point we can freely use all temporary registers. */  /* At this point we can freely use all temporary registers. */
1316  /* TMP1 returns with begin - 1. */  /* TMP1 returns with begin - 1. */
1317  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);  
1318  if (length < 8)  if (length < 8)
1319    {    {
1320    for (i = 0; i < length; i++)    for (i = 0; i < length; i++)
# Line 1236  else Line 1331  else
1331    }    }
1332  }  }
1333    
1334  static SLJIT_INLINE void copy_ovector(compiler_common *common)  static SLJIT_INLINE void copy_ovector(compiler_common *common, int topbracket)
1335  {  {
1336  DEFINE_COMPILER;  DEFINE_COMPILER;
1337  struct sljit_label *loop;  struct sljit_label *loop;
1338  struct sljit_jump *earlyexit;  struct sljit_jump *earlyexit;
1339    
1340  /* At this point we can freely use all registers. */  /* At this point we can freely use all registers. */
1341    OP1(SLJIT_MOV, SLJIT_SAVED_REG3, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1));
1342    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1), STR_PTR, 0);
1343    
1344  OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG1, 0, ARGUMENTS, 0);  OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG1, 0, ARGUMENTS, 0);
1345    if (common->mark_ptr != 0)
1346      OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG3, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr);
1347  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));
1348    if (common->mark_ptr != 0)
1349      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_TEMPORARY_REG1), SLJIT_OFFSETOF(jit_arguments, mark_ptr), SLJIT_TEMPORARY_REG3, 0);
1350  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));
1351  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));
1352  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);
1353  /* Unlikely, but possible */  /* Unlikely, but possible */
1354  earlyexit = CMP(SLJIT_C_EQUAL, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, 0);  earlyexit = CMP(SLJIT_C_EQUAL, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, 0);
1355  loop = LABEL();  loop = LABEL();
1356  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);
1357  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));
1358  /* Copy the integer value to the output buffer */  /* Copy the integer value to the output buffer */
1359  OP1(SLJIT_MOVU_SI, SLJIT_MEM1(SLJIT_TEMPORARY_REG3), sizeof(int), SLJIT_GENERAL_REG2, 0);  #ifdef COMPILE_PCRE16
1360    OP2(SLJIT_ASHR, SLJIT_SAVED_REG2, 0, SLJIT_SAVED_REG2, 0, SLJIT_IMM, 1);
1361    #endif
1362    OP1(SLJIT_MOVU_SI, SLJIT_MEM1(SLJIT_TEMPORARY_REG3), sizeof(int), SLJIT_SAVED_REG2, 0);
1363  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);
1364  JUMPTO(SLJIT_C_NOT_ZERO, loop);  JUMPTO(SLJIT_C_NOT_ZERO, loop);
1365  JUMPHERE(earlyexit);  JUMPHERE(earlyexit);
1366    
1367    /* Calculate the return value, which is the maximum ovector value. */
1368    if (topbracket > 1)
1369      {
1370      OP2(SLJIT_ADD, SLJIT_TEMPORARY_REG1, 0, SLJIT_LOCALS_REG, 0, SLJIT_IMM, OVECTOR_START + topbracket * 2 * sizeof(sljit_w));
1371      OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, topbracket + 1);
1372    
1373      /* OVECTOR(0) is never equal to SLJIT_SAVED_REG3. */
1374      loop = LABEL();
1375      OP1(SLJIT_MOVU, SLJIT_TEMPORARY_REG3, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG1), -(2 * (sljit_w)sizeof(sljit_w)));
1376      OP2(SLJIT_SUB, SLJIT_TEMPORARY_REG2, 0, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, 1);
1377      CMPTO(SLJIT_C_EQUAL, SLJIT_TEMPORARY_REG3, 0, SLJIT_SAVED_REG3, 0, loop);
1378      OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_TEMPORARY_REG2, 0);
1379      }
1380    else
1381      OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, 1);
1382    }
1383    
1384    static SLJIT_INLINE void return_with_partial_match(compiler_common *common, struct sljit_label *leave)
1385    {
1386    DEFINE_COMPILER;
1387    
1388    SLJIT_COMPILE_ASSERT(STR_END == SLJIT_SAVED_REG2, str_end_must_be_saved_reg2);
1389    SLJIT_ASSERT(common->start_used_ptr != 0 && (common->mode == JIT_PARTIAL_SOFT_COMPILE ? common->hit_start != 0 : common->hit_start == 0));
1390    
1391    OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, ARGUMENTS, 0);
1392    OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_PARTIAL);
1393    OP1(SLJIT_MOV_SI, SLJIT_TEMPORARY_REG3, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), SLJIT_OFFSETOF(jit_arguments, offsetcount));
1394    CMPTO(SLJIT_C_LESS, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, 2, leave);
1395    
1396    /* Store match begin and end. */
1397    OP1(SLJIT_MOV, SLJIT_SAVED_REG1, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), SLJIT_OFFSETOF(jit_arguments, begin));
1398    OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), SLJIT_OFFSETOF(jit_arguments, offsets));
1399    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);
1400    OP2(SLJIT_SUB, SLJIT_SAVED_REG2, 0, STR_END, 0, SLJIT_SAVED_REG1, 0);
1401    #ifdef COMPILE_PCRE16
1402    OP2(SLJIT_ASHR, SLJIT_SAVED_REG2, 0, SLJIT_SAVED_REG2, 0, SLJIT_IMM, 1);
1403    #endif
1404    OP1(SLJIT_MOV_SI, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), sizeof(int), SLJIT_SAVED_REG2, 0);
1405    
1406    OP2(SLJIT_SUB, SLJIT_TEMPORARY_REG3, 0, SLJIT_TEMPORARY_REG3, 0, SLJIT_SAVED_REG1, 0);
1407    #ifdef COMPILE_PCRE16
1408    OP2(SLJIT_ASHR, SLJIT_TEMPORARY_REG3, 0, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, 1);
1409    #endif
1410    OP1(SLJIT_MOV_SI, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), 0, SLJIT_TEMPORARY_REG3, 0);
1411    
1412    JUMPTO(SLJIT_JUMP, leave);
1413  }  }
1414    
1415  static SLJIT_INLINE BOOL char_has_othercase(compiler_common *common, uschar* cc)  static SLJIT_INLINE void check_start_used_ptr(compiler_common *common)
1416    {
1417    /* May destroy TMP1. */
1418    DEFINE_COMPILER;
1419    struct sljit_jump *jump;
1420    
1421    if (common->mode == JIT_PARTIAL_SOFT_COMPILE)
1422      {
1423      /* The value of -1 must be kept for start_used_ptr! */
1424      OP2(SLJIT_ADD, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, SLJIT_IMM, 1);
1425      /* Jumps if start_used_ptr < STR_PTR, or start_used_ptr == -1. Although overwriting
1426      is not necessary if start_used_ptr == STR_PTR, it does not hurt as well. */
1427      jump = CMP(SLJIT_C_LESS_EQUAL, TMP1, 0, STR_PTR, 0);
1428      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0);
1429      JUMPHERE(jump);
1430      }
1431    else if (common->mode == JIT_PARTIAL_HARD_COMPILE)
1432      {
1433      jump = CMP(SLJIT_C_LESS_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0);
1434      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0);
1435      JUMPHERE(jump);
1436      }
1437    }
1438    
1439    static SLJIT_INLINE BOOL char_has_othercase(compiler_common *common, pcre_uchar* cc)
1440  {  {
1441  /* Detects if the character has an othercase. */  /* Detects if the character has an othercase. */
1442  unsigned int c;  unsigned int c;
1443    
1444  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
1445  if (common->utf8)  if (common->utf)
1446    {    {
1447    GETCHAR(c, cc);    GETCHAR(c, cc);
1448    if (c > 127)    if (c > 127)
# Line 1277  if (common->utf8) Line 1453  if (common->utf8)
1453      return FALSE;      return FALSE;
1454  #endif  #endif
1455      }      }
1456    #ifndef COMPILE_PCRE8
1457      return common->fcc[c] != c;
1458    #endif
1459    }    }
1460  else  else
1461  #endif  #endif
1462    c = *cc;    c = *cc;
1463  return common->fcc[c] != c;  return MAX_255(c) ? common->fcc[c] != c : FALSE;
1464  }  }
1465    
1466  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)
1467  {  {
1468  /* Returns with the othercase. */  /* Returns with the othercase. */
1469  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
1470  if (common->utf8 && c > 127)  if (common->utf && c > 127)
1471    {    {
1472  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
1473    return UCD_OTHERCASE(c);    return UCD_OTHERCASE(c);
# Line 1297  if (common->utf8 && c > 127) Line 1476  if (common->utf8 && c > 127)
1476  #endif  #endif
1477    }    }
1478  #endif  #endif
1479  return common->fcc[c];  return TABLE_GET(c, common->fcc, c);
1480  }  }
1481    
1482  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)
1483  {  {
1484  /* Detects if the character and its othercase has only 1 bit difference. */  /* Detects if the character and its othercase has only 1 bit difference. */
1485  unsigned int c, oc, bit;  unsigned int c, oc, bit;
1486  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF && defined COMPILE_PCRE8
1487  int n;  int n;
1488  #endif  #endif
1489    
1490  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
1491  if (common->utf8)  if (common->utf)
1492    {    {
1493    GETCHAR(c, cc);    GETCHAR(c, cc);
1494    if (c <= 127)    if (c <= 127)
# Line 1326  if (common->utf8) Line 1505  if (common->utf8)
1505  else  else
1506    {    {
1507    c = *cc;    c = *cc;
1508    oc = common->fcc[c];    oc = TABLE_GET(c, common->fcc, c);
1509    }    }
1510  #else  #else
1511  c = *cc;  c = *cc;
1512  oc = common->fcc[c];  oc = TABLE_GET(c, common->fcc, c);
1513  #endif  #endif
1514    
1515  SLJIT_ASSERT(c != oc);  SLJIT_ASSERT(c != oc);
# Line 1344  if (c <= 127 && bit == 0x20) Line 1523  if (c <= 127 && bit == 0x20)
1523  if (!ispowerof2(bit))  if (!ispowerof2(bit))
1524    return 0;    return 0;
1525    
1526  #ifdef SUPPORT_UTF8  #ifdef COMPILE_PCRE8
1527  if (common->utf8 && c > 127)  
1528    #ifdef SUPPORT_UTF
1529    if (common->utf && c > 127)
1530    {    {
1531    n = _pcre_utf8_table4[*cc & 0x3f];    n = GET_EXTRALEN(*cc);
1532    while ((bit & 0x3f) == 0)    while ((bit & 0x3f) == 0)
1533      {      {
1534      n--;      n--;
# Line 1355  if (common->utf8 && c > 127) Line 1536  if (common->utf8 && c > 127)
1536      }      }
1537    return (n << 8) | bit;    return (n << 8) | bit;
1538    }    }
1539  #endif  #endif /* SUPPORT_UTF */
1540  return (0 << 8) | bit;  return (0 << 8) | bit;
1541    
1542    #else /* COMPILE_PCRE8 */
1543    
1544    #ifdef COMPILE_PCRE16
1545    #ifdef SUPPORT_UTF
1546    if (common->utf && c > 65535)
1547      {
1548      if (bit >= (1 << 10))
1549        bit >>= 10;
1550      else
1551        return (bit < 256) ? ((2 << 8) | bit) : ((3 << 8) | (bit >> 8));
1552      }
1553    #endif /* SUPPORT_UTF */
1554    return (bit < 256) ? ((0 << 8) | bit) : ((1 << 8) | (bit >> 8));
1555    #endif /* COMPILE_PCRE16 */
1556    
1557    #endif /* COMPILE_PCRE8 */
1558    }
1559    
1560    static void check_partial(compiler_common *common, BOOL force)
1561    {
1562    /* Checks whether a partial matching is occured. Does not modify registers. */
1563    DEFINE_COMPILER;
1564    struct sljit_jump *jump = NULL;
1565    
1566    SLJIT_ASSERT(!force || common->mode != JIT_COMPILE);
1567    
1568    if (common->mode == JIT_COMPILE)
1569      return;
1570    
1571    if (!force)
1572      jump = CMP(SLJIT_C_GREATER_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0);
1573    else if (common->mode == JIT_PARTIAL_SOFT_COMPILE)
1574      jump = CMP(SLJIT_C_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, SLJIT_IMM, -1);
1575    
1576    if (common->mode == JIT_PARTIAL_SOFT_COMPILE)
1577      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, -1);
1578    else
1579      {
1580      if (common->partialmatchlabel != NULL)
1581        JUMPTO(SLJIT_JUMP, common->partialmatchlabel);
1582      else
1583        add_jump(compiler, &common->partialmatch, JUMP(SLJIT_JUMP));
1584      }
1585    
1586    if (jump != NULL)
1587      JUMPHERE(jump);
1588  }  }
1589    
1590  static SLJIT_INLINE void check_input_end(compiler_common *common, jump_list **fallbacks)  static struct sljit_jump *check_str_end(compiler_common *common)
1591  {  {
1592    /* Does not affect registers. Usually used in a tight spot. */
1593  DEFINE_COMPILER;  DEFINE_COMPILER;
1594  add_jump(compiler, fallbacks, CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0));  struct sljit_jump *jump;
1595    struct sljit_jump *nohit;
1596    struct sljit_jump *return_value;
1597    
1598    if (common->mode == JIT_COMPILE)
1599      return CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
1600    
1601    jump = CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0);
1602    if (common->mode == JIT_PARTIAL_SOFT_COMPILE)
1603      {
1604      nohit = CMP(SLJIT_C_GREATER_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0);
1605      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, -1);
1606      JUMPHERE(nohit);
1607      return_value = JUMP(SLJIT_JUMP);
1608      }
1609    else
1610      {
1611      return_value = CMP(SLJIT_C_GREATER_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0);
1612      if (common->partialmatchlabel != NULL)
1613        JUMPTO(SLJIT_JUMP, common->partialmatchlabel);
1614      else
1615        add_jump(compiler, &common->partialmatch, JUMP(SLJIT_JUMP));
1616      }
1617    JUMPHERE(jump);
1618    return return_value;
1619    }
1620    
1621    static void fallback_at_str_end(compiler_common *common, jump_list **fallbacks)
1622    {
1623    DEFINE_COMPILER;
1624    struct sljit_jump *jump;
1625    
1626    if (common->mode == JIT_COMPILE)
1627      {
1628      add_jump(compiler, fallbacks, CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0));
1629      return;
1630      }
1631    
1632    /* Partial matching mode. */
1633    jump = CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0);
1634    add_jump(compiler, fallbacks, CMP(SLJIT_C_GREATER_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0));
1635    if (common->mode == JIT_PARTIAL_SOFT_COMPILE)
1636      {
1637      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, -1);
1638      add_jump(compiler, fallbacks, JUMP(SLJIT_JUMP));
1639      }
1640    else
1641      {
1642      if (common->partialmatchlabel != NULL)
1643        JUMPTO(SLJIT_JUMP, common->partialmatchlabel);
1644      else
1645        add_jump(compiler, &common->partialmatch, JUMP(SLJIT_JUMP));
1646      }
1647    JUMPHERE(jump);
1648  }  }
1649    
1650  static void read_char(compiler_common *common)  static void read_char(compiler_common *common)
# Line 1370  static void read_char(compiler_common *c Line 1652  static void read_char(compiler_common *c
1652  /* Reads the character into TMP1, updates STR_PTR.  /* Reads the character into TMP1, updates STR_PTR.
1653  Does not check STR_END. TMP2 Destroyed. */  Does not check STR_END. TMP2 Destroyed. */
1654  DEFINE_COMPILER;  DEFINE_COMPILER;
1655  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
1656  struct sljit_jump *jump;  struct sljit_jump *jump;
1657  #endif  #endif
1658    
1659  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
1660  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
1661  if (common->utf8)  if (common->utf)
1662    {    {
1663    /* Should not found a value between 128 and 192 here. */  #ifdef COMPILE_PCRE8
1664    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 192);    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);
1665    add_jump(compiler, &common->utf8readchar, JUMP(SLJIT_FAST_CALL));  #else
1666    #ifdef COMPILE_PCRE16
1667      jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800);
1668    #endif
1669    #endif /* COMPILE_PCRE8 */
1670      add_jump(compiler, &common->utfreadchar, JUMP(SLJIT_FAST_CALL));
1671    JUMPHERE(jump);    JUMPHERE(jump);
1672    }    }
1673  #endif  #endif
1674  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));
1675  }  }
1676    
1677  static void peek_char(compiler_common *common)  static void peek_char(compiler_common *common)
# Line 1392  static void peek_char(compiler_common *c Line 1679  static void peek_char(compiler_common *c
1679  /* Reads the character into TMP1, keeps STR_PTR.  /* Reads the character into TMP1, keeps STR_PTR.
1680  Does not check STR_END. TMP2 Destroyed. */  Does not check STR_END. TMP2 Destroyed. */
1681  DEFINE_COMPILER;  DEFINE_COMPILER;
1682  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
1683  struct sljit_jump *jump;  struct sljit_jump *jump;
1684  #endif  #endif
1685    
1686  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
1687  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
1688  if (common->utf8)  if (common->utf)
1689    {    {
1690    /* Should not found a value between 128 and 192 here. */  #ifdef COMPILE_PCRE8
1691    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 192);    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);
1692    add_jump(compiler, &common->utf8readchar, JUMP(SLJIT_FAST_CALL));  #else
1693    #ifdef COMPILE_PCRE16
1694      jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800);
1695    #endif
1696    #endif /* COMPILE_PCRE8 */
1697      add_jump(compiler, &common->utfreadchar, JUMP(SLJIT_FAST_CALL));
1698    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
1699    JUMPHERE(jump);    JUMPHERE(jump);
1700    }    }
# Line 1413  static void read_char8_type(compiler_com Line 1705  static void read_char8_type(compiler_com
1705  {  {
1706  /* 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. */
1707  DEFINE_COMPILER;  DEFINE_COMPILER;
1708  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF || defined COMPILE_PCRE16
1709  struct sljit_jump *jump;  struct sljit_jump *jump;
1710  #endif  #endif
1711    
1712  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
1713  if (common->utf8)  if (common->utf)
1714    {    {
1715    OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), 0);    OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), 0);
1716    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));
1717    #ifdef COMPILE_PCRE8
1718    /* This can be an extra read in some situations, but hopefully    /* This can be an extra read in some situations, but hopefully
1719    it is a clever early read in most cases. */    it is needed in most cases. */
1720    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);
1721    /* Should not found a value between 128 and 192 here. */    jump = CMP(SLJIT_C_LESS, TMP2, 0, SLJIT_IMM, 0xc0);
1722    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));  
1723    JUMPHERE(jump);    JUMPHERE(jump);
1724    #else
1725    #ifdef COMPILE_PCRE16
1726      OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);
1727      jump = CMP(SLJIT_C_GREATER, TMP2, 0, SLJIT_IMM, 255);
1728      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);
1729      JUMPHERE(jump);
1730      /* Skip low surrogate if necessary. */
1731      OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0xfc00);
1732      OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, 0xd800);
1733      COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);
1734      OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 1);
1735      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
1736    #endif
1737    #endif /* COMPILE_PCRE8 */
1738    return;    return;
1739    }    }
1740  #endif  #endif
1741  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);  OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), 0);
1742  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 1);  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
1743  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), common->ctypes);  #ifdef COMPILE_PCRE16
1744    /* The ctypes array contains only 256 values. */
1745    OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);
1746    jump = CMP(SLJIT_C_GREATER, TMP2, 0, SLJIT_IMM, 255);
1747    #endif
1748    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);
1749    #ifdef COMPILE_PCRE16
1750    JUMPHERE(jump);
1751    #endif
1752  }  }
1753    
1754  static void skip_char_back(compiler_common *common)  static void skip_char_back(compiler_common *common)
1755  {  {
1756  /* 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. */
1757  DEFINE_COMPILER;  DEFINE_COMPILER;
1758  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF && defined COMPILE_PCRE8
1759  struct sljit_label *label;  struct sljit_label *label;
1760    
1761  if (common->utf8)  if (common->utf)
1762    {    {
1763    label = LABEL();    label = LABEL();
1764    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 1);    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), -IN_UCHARS(1));
1765    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));
1766    OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xc0);    OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xc0);
1767    CMPTO(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, 0x80, label);    CMPTO(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, 0x80, label);
1768    return;    return;
1769    }    }
1770  #endif  #endif
1771  OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 1);  #if defined SUPPORT_UTF && defined COMPILE_PCRE16
1772    if (common->utf)
1773      {
1774      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), -IN_UCHARS(1));
1775      OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
1776      /* Skip low surrogate if necessary. */
1777      OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);
1778      OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xdc00);
1779      COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);
1780      OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
1781      OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
1782      return;
1783      }
1784    #endif
1785    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
1786  }  }
1787    
1788  static void check_newlinechar(compiler_common *common, int nltype, jump_list **fallbacks, BOOL jumpiftrue)  static void check_newlinechar(compiler_common *common, int nltype, jump_list **fallbacks, BOOL jumpiftrue)
# Line 1477  else if (nltype == NLTYPE_ANYCRLF) Line 1805  else if (nltype == NLTYPE_ANYCRLF)
1805    }    }
1806  else  else
1807    {    {
1808    SLJIT_ASSERT(nltype == NLTYPE_FIXED && common->newline <= 255);    SLJIT_ASSERT(nltype == NLTYPE_FIXED && common->newline < 256);
1809    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));
1810    }    }
1811  }  }
1812    
1813  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
1814  static void do_utf8readchar(compiler_common *common)  
1815    #ifdef COMPILE_PCRE8
1816    static void do_utfreadchar(compiler_common *common)
1817  {  {
1818  /* Fast decoding an utf8 character. TMP1 contains the first byte  /* Fast decoding a UTF-8 character. TMP1 contains the first byte
1819  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. */
1820  DEFINE_COMPILER;  DEFINE_COMPILER;
1821  struct sljit_jump *jump;  struct sljit_jump *jump;
1822    
# Line 1494  sljit_emit_fast_enter(compiler, RETURN_A Line 1824  sljit_emit_fast_enter(compiler, RETURN_A
1824  /* Searching for the first zero. */  /* Searching for the first zero. */
1825  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);
1826  jump = JUMP(SLJIT_C_NOT_ZERO);  jump = JUMP(SLJIT_C_NOT_ZERO);
1827  /* 2 byte sequence */  /* Two byte sequence. */
1828  OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), 1);  OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
1829  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));
1830  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x1f);  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x1f);
1831  OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 6);  OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 6);
1832  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
1833  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
1834  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 1);  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, IN_UCHARS(1));
1835  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
1836  JUMPHERE(jump);  JUMPHERE(jump);
1837    
1838  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);
1839  jump = JUMP(SLJIT_C_NOT_ZERO);  jump = JUMP(SLJIT_C_NOT_ZERO);
1840  /* 3 byte sequence */  /* Three byte sequence. */
1841  OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), 1);  OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
1842  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x0f);  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x0f);
1843  OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 12);  OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 12);
1844  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
1845  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6);  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6);
1846  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
1847  OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), 2);  OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(2));
1848  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));
1849  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
1850  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
1851  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 2);  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, IN_UCHARS(2));
1852  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
1853  JUMPHERE(jump);  JUMPHERE(jump);
1854    
1855  OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x08);  /* Four byte sequence. */
1856  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);  
1857  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x07);  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x07);
1858  OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 18);  OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 18);
1859  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
1860  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 12);  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 12);
1861  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
1862  OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), 2);  OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(2));
 OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);  
 OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6);  
 OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);  
 OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), 3);  
 OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 3);  
 OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);  
 OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);  
 OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 3);  
 sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  
 JUMPHERE(jump);  
   
 /* 5 byte sequence */  
 OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), 1);  
 OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x03);  
 OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 24);  
 OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);  
 OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 18);  
 OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);  
 OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), 2);  
 OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);  
 OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 12);  
 OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);  
 OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), 3);  
1863  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
1864  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6);  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6);
1865  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
1866  OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), 4);  OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(3));
1867  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 4);  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(3));
1868  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
1869  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
1870  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 4);  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, IN_UCHARS(3));
1871  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
1872  }  }
1873    
1874  static void do_utf8readtype8(compiler_common *common)  static void do_utfreadtype8(compiler_common *common)
1875  {  {
1876  /* Fast decoding an utf8 character type. TMP2 contains the first byte  /* Fast decoding a UTF-8 character type. TMP2 contains the first byte
1877  of the character (>= 192) and TMP1 is destroyed. Return value in TMP1. */  of the character (>= 0xc0). Return value in TMP1. */
1878  DEFINE_COMPILER;  DEFINE_COMPILER;
1879  struct sljit_jump *jump;  struct sljit_jump *jump;
1880  struct sljit_jump *compare;  struct sljit_jump *compare;
# Line 1578  sljit_emit_fast_enter(compiler, RETURN_A Line 1883  sljit_emit_fast_enter(compiler, RETURN_A
1883    
1884  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);
1885  jump = JUMP(SLJIT_C_NOT_ZERO);  jump = JUMP(SLJIT_C_NOT_ZERO);
1886  /* 2 byte sequence */  /* Two byte sequence. */
1887  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
1888  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));
1889  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x1f);  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x1f);
1890  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6);  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6);
1891  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x3f);  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x3f);
# Line 1595  sljit_emit_fast_return(compiler, RETURN_ Line 1900  sljit_emit_fast_return(compiler, RETURN_
1900  JUMPHERE(jump);  JUMPHERE(jump);
1901    
1902  /* We only have types for characters less than 256. */  /* We only have types for characters less than 256. */
1903  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);  
1904  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
1905  OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);  OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);
1906  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
1907  }  }
1908    
1909  #endif  #else /* COMPILE_PCRE8 */
1910    
1911    #ifdef COMPILE_PCRE16
1912    static void do_utfreadchar(compiler_common *common)
1913    {
1914    /* Fast decoding a UTF-16 character. TMP1 contains the first 16 bit char
1915    of the character (>= 0xd800). Return char value in TMP1, length - 1 in TMP2. */
1916    DEFINE_COMPILER;
1917    struct sljit_jump *jump;
1918    
1919    sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize);
1920    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xdc00);
1921    /* Do nothing, only return. */
1922    sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
1923    
1924    JUMPHERE(jump);
1925    /* Combine two 16 bit characters. */
1926    OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
1927    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
1928    OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x3ff);
1929    OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 10);
1930    OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3ff);
1931    OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
1932    OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, IN_UCHARS(1));
1933    OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x10000);
1934    sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
1935    }
1936    #endif /* COMPILE_PCRE16 */
1937    
1938    #endif /* COMPILE_PCRE8 */
1939    
1940    #endif /* SUPPORT_UTF */
1941    
1942  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
1943    
# Line 1620  SLJIT_ASSERT(UCD_BLOCK_SIZE == 128 && si Line 1955  SLJIT_ASSERT(UCD_BLOCK_SIZE == 128 && si
1955    
1956  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);
1957  OP2(SLJIT_LSHR, TMP2, 0, TMP1, 0, SLJIT_IMM, UCD_BLOCK_SHIFT);  OP2(SLJIT_LSHR, TMP2, 0, TMP1, 0, SLJIT_IMM, UCD_BLOCK_SHIFT);
1958  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));
1959  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, UCD_BLOCK_MASK);  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, UCD_BLOCK_MASK);
1960  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, UCD_BLOCK_SHIFT);  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, UCD_BLOCK_SHIFT);
1961  OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, TMP2, 0);  OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, TMP2, 0);
1962  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, (sljit_w)_pcre_ucd_stage2);  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, (sljit_w)PRIV(ucd_stage2));
1963  OP1(SLJIT_MOV_UH, TMP2, 0, SLJIT_MEM2(TMP2, TMP1), 1);  OP1(SLJIT_MOV_UH, TMP2, 0, SLJIT_MEM2(TMP2, TMP1), 1);
1964  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));
1965  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM2(TMP1, TMP2), 3);  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM2(TMP1, TMP2), 3);
1966  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
1967  }  }
# Line 1640  struct sljit_label *newlinelabel = NULL; Line 1975  struct sljit_label *newlinelabel = NULL;
1975  struct sljit_jump *start;  struct sljit_jump *start;
1976  struct sljit_jump *end = NULL;  struct sljit_jump *end = NULL;
1977  struct sljit_jump *nl = NULL;  struct sljit_jump *nl = NULL;
1978    #ifdef SUPPORT_UTF
1979    struct sljit_jump *singlechar;
1980    #endif
1981  jump_list *newline = NULL;  jump_list *newline = NULL;
1982  BOOL newlinecheck = FALSE;  BOOL newlinecheck = FALSE;
1983  BOOL readbyte = FALSE;  BOOL readuchar = FALSE;
1984    
1985  if (!(hascrorlf || firstline) && (common->nltype == NLTYPE_ANY ||  if (!(hascrorlf || firstline) && (common->nltype == NLTYPE_ANY ||
1986      common->nltype == NLTYPE_ANYCRLF || common->newline > 255))      common->nltype == NLTYPE_ANYCRLF || common->newline > 255))
# Line 1651  if (!(hascrorlf || firstline) && (common Line 1989  if (!(hascrorlf || firstline) && (common
1989  if (firstline)  if (firstline)
1990    {    {
1991    /* Search for the end of the first line. */    /* Search for the end of the first line. */
1992      SLJIT_ASSERT(common->first_line_end != 0);
1993    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, STR_PTR, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, STR_PTR, 0);
1994    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);
1995    
1996    if (common->nltype == NLTYPE_FIXED && common->newline > 255)    if (common->nltype == NLTYPE_FIXED && common->newline > 255)
1997      {      {
1998      mainloop = LABEL();      mainloop = LABEL();
1999      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));
2000      end = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);      end = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
2001      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), -1);      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-1));
2002      OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), 0);      OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
2003      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);
2004      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);
2005      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));
2006      }      }
2007    else    else
2008      {      {
2009      end = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);      end = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
2010      mainloop = LABEL();      mainloop = LABEL();
2011      /* Continual stores does not cause data dependency. */      /* Continual stores does not cause data dependency. */
2012      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);
2013      read_char(common);      read_char(common);
2014      check_newlinechar(common, common->nltype, &newline, TRUE);      check_newlinechar(common, common->nltype, &newline, TRUE);
2015      CMPTO(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0, mainloop);      CMPTO(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0, mainloop);
2016      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);
2017      set_jumps(newline, LABEL());      set_jumps(newline, LABEL());
2018      }      }
2019    
# Line 1687  start = JUMP(SLJIT_JUMP); Line 2026  start = JUMP(SLJIT_JUMP);
2026  if (newlinecheck)  if (newlinecheck)
2027    {    {
2028    newlinelabel = LABEL();    newlinelabel = LABEL();
2029    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));
2030    end = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);    end = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
2031    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
2032    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);
2033    COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);    COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);
2034    #ifdef COMPILE_PCRE16
2035      OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
2036    #endif
2037    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2038    nl = JUMP(SLJIT_JUMP);    nl = JUMP(SLJIT_JUMP);
2039    }    }
# Line 1699  if (newlinecheck) Line 2041  if (newlinecheck)
2041  mainloop = LABEL();  mainloop = LABEL();
2042    
2043  /* 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. */
2044  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
2045  if (common->utf8) readbyte = TRUE;  if (common->utf) readuchar = TRUE;
2046  #endif  #endif
2047  if (newlinecheck) readbyte = TRUE;  if (newlinecheck) readuchar = TRUE;
2048    
2049  if (readbyte)  if (readuchar)
2050    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
2051    
2052  if (newlinecheck)  if (newlinecheck)
2053    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);
2054    
2055  #ifdef SUPPORT_UTF8  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2056  if (common->utf8)  #if defined SUPPORT_UTF && defined COMPILE_PCRE8
2057    if (common->utf)
2058    {    {
2059    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);
2060      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)PRIV(utf8_table4) - 0xc0);
2061    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2062      JUMPHERE(singlechar);
2063      }
2064    #endif
2065    #if defined SUPPORT_UTF && defined COMPILE_PCRE16
2066    if (common->utf)
2067      {
2068      singlechar = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800);
2069      OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);
2070      OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xd800);
2071      COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);
2072      OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
2073      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2074      JUMPHERE(singlechar);
2075    }    }
 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);  
2076  #endif  #endif
2077  JUMPHERE(start);  JUMPHERE(start);
2078    
# Line 1732  if (newlinecheck) Line 2085  if (newlinecheck)
2085  return mainloop;  return mainloop;
2086  }  }
2087    
2088  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)
2089  {  {
2090  DEFINE_COMPILER;  DEFINE_COMPILER;
2091  struct sljit_label *start;  struct sljit_label *start;
2092  struct sljit_jump *leave;  struct sljit_jump *leave;
2093  struct sljit_jump *found;  struct sljit_jump *found;
2094  pcre_uint16 oc, bit;  pcre_uchar oc, bit;
2095    
2096  if (firstline)  if (firstline)
2097    {    {
2098    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, STR_END, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, STR_END, 0);
2099    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);
2100    }    }
2101    
2102  start = LABEL();  start = LABEL();
2103  leave = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);  leave = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
2104  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
2105    
2106  if ((firstbyte & REQ_CASELESS) == 0)  oc = first_char;
2107    found = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, firstbyte & 0xff);  if (caseless)
2108      {
2109      oc = TABLE_GET(first_char, common->fcc, first_char);
2110    #if defined SUPPORT_UCP && !(defined COMPILE_PCRE8)
2111      if (first_char > 127 && common->utf)
2112        oc = UCD_OTHERCASE(first_char);
2113    #endif
2114      }
2115    if (first_char == oc)
2116      found = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, first_char);
2117  else  else
2118    {    {
2119    firstbyte &= 0xff;    bit = first_char ^ oc;
   oc = common->fcc[firstbyte];  
   bit = firstbyte ^ oc;  
2120    if (ispowerof2(bit))    if (ispowerof2(bit))
2121      {      {
2122      OP2(SLJIT_OR, TMP2, 0, TMP1, 0, SLJIT_IMM, bit);      OP2(SLJIT_OR, TMP2, 0, TMP1, 0, SLJIT_IMM, bit);
2123      found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, firstbyte | bit);      found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, first_char | bit);
2124      }      }
2125    else    else
2126      {      {
2127      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);
2128      COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);      COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);
2129      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);
2130      COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);      COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);
# Line 1772  else Line 2132  else
2132      }      }
2133    }    }
2134    
2135  #ifdef SUPPORT_UTF8  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2136  if (common->utf8)  #if defined SUPPORT_UTF && defined COMPILE_PCRE8
2137    if (common->utf)
2138    {    {
2139    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);
2140      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)PRIV(utf8_table4) - 0xc0);
2141      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2142      }
2143    #endif
2144    #if defined SUPPORT_UTF && defined COMPILE_PCRE16
2145    if (common->utf)
2146      {
2147      CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800, start);
2148      OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);
2149      OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xd800);
2150      COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);
2151      OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
2152    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2153    }    }
 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);  
2154  #endif  #endif
2155  JUMPTO(SLJIT_JUMP, start);  JUMPTO(SLJIT_JUMP, start);
2156  JUMPHERE(found);  JUMPHERE(found);
# Line 1805  jump_list *newline = NULL; Line 2174  jump_list *newline = NULL;
2174  if (firstline)  if (firstline)
2175    {    {
2176    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, STR_END, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, STR_END, 0);
2177    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);
2178    }    }
2179    
2180  if (common->nltype == NLTYPE_FIXED && common->newline > 255)  if (common->nltype == NLTYPE_FIXED && common->newline > 255)
# Line 1816  if (common->nltype == NLTYPE_FIXED && co Line 2185  if (common->nltype == NLTYPE_FIXED && co
2185    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));
2186    firstchar = CMP(SLJIT_C_LESS_EQUAL, STR_PTR, 0, TMP2, 0);    firstchar = CMP(SLJIT_C_LESS_EQUAL, STR_PTR, 0, TMP2, 0);
2187    
2188    OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 2);    OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(2));
2189    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);
2190    COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_GREATER_EQUAL);    COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_GREATER_EQUAL);
2191    #ifdef COMPILE_PCRE16
2192      OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 1);
2193    #endif
2194    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
2195    
2196    loop = LABEL();    loop = LABEL();
2197    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));
2198    leave = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);    leave = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
2199    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), -2);    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-2));
2200    OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), -1);    OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-1));
2201    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);
2202    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);
2203    
# Line 1856  if (common->nltype == NLTYPE_ANY || comm Line 2228  if (common->nltype == NLTYPE_ANY || comm
2228    leave = JUMP(SLJIT_JUMP);    leave = JUMP(SLJIT_JUMP);
2229    JUMPHERE(foundcr);    JUMPHERE(foundcr);
2230    notfoundnl = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);    notfoundnl = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
2231    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
2232    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);
2233    COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);    COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);
2234    #ifdef COMPILE_PCRE16
2235      OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
2236    #endif
2237    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2238    JUMPHERE(notfoundnl);    JUMPHERE(notfoundnl);
2239    JUMPHERE(leave);    JUMPHERE(leave);
# Line 1876  DEFINE_COMPILER; Line 2251  DEFINE_COMPILER;
2251  struct sljit_label *start;  struct sljit_label *start;
2252  struct sljit_jump *leave;  struct sljit_jump *leave;
2253  struct sljit_jump *found;  struct sljit_jump *found;
2254    #ifndef COMPILE_PCRE8
2255    struct sljit_jump *jump;
2256    #endif
2257    
2258  if (firstline)  if (firstline)
2259    {    {
2260    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, STR_END, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, STR_END, 0);
2261    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);
2262    }    }
2263    
2264  start = LABEL();  start = LABEL();
2265  leave = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);  leave = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
2266  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
2267  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
2268  if (common->utf8)  if (common->utf)
2269    OP1(SLJIT_MOV_UB, TMP3, 0, SLJIT_MEM1(TMP1), (sljit_w)_pcre_utf8_char_sizes);    OP1(SLJIT_MOV, TMP3, 0, TMP1, 0);
2270    #endif
2271    #ifndef COMPILE_PCRE8
2272    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 255);
2273    OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 255);
2274    JUMPHERE(jump);
2275  #endif  #endif
2276  OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);  OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);
2277  OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);  OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);
# Line 1897  OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TM Line 2280  OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TM
2280  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);
2281  found = JUMP(SLJIT_C_NOT_ZERO);  found = JUMP(SLJIT_C_NOT_ZERO);
2282    
2283  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
2284  if (common->utf8)  if (common->utf)
2285    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP3, 0);    OP1(SLJIT_MOV, TMP1, 0, TMP3, 0);
2286  else  #endif
2287    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));
2288  #else  #if defined SUPPORT_UTF && defined COMPILE_PCRE8
2289  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 1);  if (common->utf)
2290      {
2291      CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0, start);
2292      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)PRIV(utf8_table4) - 0xc0);
2293      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2294      }
2295    #endif
2296    #if defined SUPPORT_UTF && defined COMPILE_PCRE16
2297    if (common->utf)
2298      {
2299      CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800, start);
2300      OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);
2301      OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xd800);
2302      COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);
2303      OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
2304      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2305      }
2306  #endif  #endif
2307  JUMPTO(SLJIT_JUMP, start);  JUMPTO(SLJIT_JUMP, start);
2308  JUMPHERE(found);  JUMPHERE(found);
# Line 1913  if (firstline) Line 2312  if (firstline)
2312    OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0);    OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0);
2313  }  }
2314    
2315  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)
2316  {  {
2317  DEFINE_COMPILER;  DEFINE_COMPILER;
2318  struct sljit_label *loop;  struct sljit_label *loop;
# Line 1922  struct sljit_jump *alreadyfound; Line 2321  struct sljit_jump *alreadyfound;
2321  struct sljit_jump *found;  struct sljit_jump *found;
2322  struct sljit_jump *foundoc = NULL;  struct sljit_jump *foundoc = NULL;
2323  struct sljit_jump *notfound;  struct sljit_jump *notfound;
2324  pcre_uint16 oc, bit;  pcre_uchar oc, bit;
2325    
2326  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), REQ_BYTE_PTR);  SLJIT_ASSERT(common->req_char_ptr != 0);
2327    OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->req_char_ptr);
2328  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);
2329  toolong = CMP(SLJIT_C_LESS, TMP1, 0, STR_END, 0);  toolong = CMP(SLJIT_C_LESS, TMP1, 0, STR_END, 0);
2330  alreadyfound = CMP(SLJIT_C_LESS, STR_PTR, 0, TMP2, 0);  alreadyfound = CMP(SLJIT_C_LESS, STR_PTR, 0, TMP2, 0);
2331    
2332  if (has_firstbyte)  if (has_firstchar)
2333    OP2(SLJIT_ADD, TMP1, 0, STR_PTR, 0, SLJIT_IMM, 1);    OP2(SLJIT_ADD, TMP1, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2334  else  else
2335    OP1(SLJIT_MOV, TMP1, 0, STR_PTR, 0);    OP1(SLJIT_MOV, TMP1, 0, STR_PTR, 0);
2336    
2337  loop = LABEL();  loop = LABEL();
2338  notfound = CMP(SLJIT_C_GREATER_EQUAL, TMP1, 0, STR_END, 0);  notfound = CMP(SLJIT_C_GREATER_EQUAL, TMP1, 0, STR_END, 0);
2339    
2340  OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP1), 0);  OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(TMP1), 0);
2341  if ((reqbyte & REQ_CASELESS) == 0)  oc = req_char;
2342    found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, reqbyte & 0xff);  if (caseless)
2343      {
2344      oc = TABLE_GET(req_char, common->fcc, req_char);
2345    #if defined SUPPORT_UCP && !(defined COMPILE_PCRE8)
2346      if (req_char > 127 && common->utf)
2347        oc = UCD_OTHERCASE(req_char);
2348    #endif
2349      }
2350    if (req_char == oc)
2351      found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, req_char);
2352  else  else
2353    {    {
2354    reqbyte &= 0xff;    bit = req_char ^ oc;
   oc = common->fcc[reqbyte];  
   bit = reqbyte ^ oc;  
2355    if (ispowerof2(bit))    if (ispowerof2(bit))
2356      {      {
2357      OP2(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_IMM, bit);      OP2(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_IMM, bit);
2358      found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, reqbyte | bit);      found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, req_char | bit);
2359      }      }
2360    else    else
2361      {      {
2362      found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, reqbyte);      found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, req_char);
2363      foundoc = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, oc);      foundoc = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, oc);
2364      }      }
2365    }    }
2366  OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);  OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(1));
2367  JUMPTO(SLJIT_JUMP, loop);  JUMPTO(SLJIT_JUMP, loop);
2368    
2369  JUMPHERE(found);  JUMPHERE(found);
2370  if (foundoc)  if (foundoc)
2371    JUMPHERE(foundoc);    JUMPHERE(foundoc);
2372  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);
2373  JUMPHERE(alreadyfound);  JUMPHERE(alreadyfound);
2374  JUMPHERE(toolong);  JUMPHERE(toolong);
2375  return notfound;  return notfound;
# Line 1971  return notfound; Line 2378  return notfound;
2378  static void do_revertframes(compiler_common *common)  static void do_revertframes(compiler_common *common)
2379  {  {
2380  DEFINE_COMPILER;  DEFINE_COMPILER;
 struct sljit_jump *earlyexit;  
2381  struct sljit_jump *jump;  struct sljit_jump *jump;
2382  struct sljit_label *mainloop;  struct sljit_label *mainloop;
2383    
2384  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);
2385  OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS_HEAD);  OP1(SLJIT_MOV, TMP1, 0, STACK_TOP, 0);
2386    
2387  /* Drop frames until we reach STACK_TOP. */  /* Drop frames until we reach STACK_TOP. */
 earlyexit = CMP(SLJIT_C_LESS, TMP1, 0, STACK_TOP, 0);  
2388  mainloop = LABEL();  mainloop = LABEL();
2389  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), 0);  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), 0);
2390  jump = CMP(SLJIT_C_SIG_LESS_EQUAL, TMP2, 0, SLJIT_IMM, frame_end);  jump = CMP(SLJIT_C_SIG_LESS_EQUAL, TMP2, 0, SLJIT_IMM, frame_end);
# Line 1992  JUMPTO(SLJIT_JUMP, mainloop); Line 2397  JUMPTO(SLJIT_JUMP, mainloop);
2397  JUMPHERE(jump);  JUMPHERE(jump);
2398  jump = CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, frame_end);  jump = CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, frame_end);
2399  /* 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);  
2400  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
2401    
2402  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);  
2403  jump = CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, frame_setstrbegin);  jump = CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, frame_setstrbegin);
2404  /* Set max index. */  /* Set string begin. */
2405  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), sizeof(sljit_w));  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), sizeof(sljit_w));
2406  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));
2407  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0), TMP2, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0), TMP2, 0);
2408  JUMPTO(SLJIT_JUMP, mainloop);  JUMPTO(SLJIT_JUMP, mainloop);
2409    
2410  JUMPHERE(jump);  JUMPHERE(jump);
2411    if (common->mark_ptr != 0)
2412      {
2413      jump = CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, frame_setmark);
2414      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), sizeof(sljit_w));
2415      OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 2 * sizeof(sljit_w));
2416      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr, TMP2, 0);
2417      JUMPTO(SLJIT_JUMP, mainloop);
2418    
2419      JUMPHERE(jump);
2420      }
2421    
2422  /* Unknown command. */  /* Unknown command. */
2423  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));
2424  JUMPTO(SLJIT_JUMP, mainloop);  JUMPTO(SLJIT_JUMP, mainloop);
# Line 2022  JUMPTO(SLJIT_JUMP, mainloop); Line 2427  JUMPTO(SLJIT_JUMP, mainloop);
2427  static void check_wordboundary(compiler_common *common)  static void check_wordboundary(compiler_common *common)
2428  {  {
2429  DEFINE_COMPILER;  DEFINE_COMPILER;
2430  struct sljit_jump *beginend;  struct sljit_jump *skipread;
2431  #ifdef SUPPORT_UTF8  #if !(defined COMPILE_PCRE8) || defined SUPPORT_UTF
2432  struct sljit_jump *jump;  struct sljit_jump *jump;
2433  #endif  #endif
2434    
2435  SLJIT_ASSERT(ctype_word == 0x10);  SLJIT_COMPILE_ASSERT(ctype_word == 0x10, ctype_word_must_be_16);
2436    
2437  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);
2438  /* Get type of the previous char, and put it to LOCALS1. */  /* Get type of the previous char, and put it to LOCALS1. */
2439  OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);  OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
2440  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));
2441  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, SLJIT_IMM, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, SLJIT_IMM, 0);
2442  beginend = CMP(SLJIT_C_LESS_EQUAL, STR_PTR, 0, TMP1, 0);  skipread = CMP(SLJIT_C_LESS_EQUAL, STR_PTR, 0, TMP1, 0);
2443  skip_char_back(common);  skip_char_back(common);
2444    check_start_used_ptr(common);
2445  read_char(common);  read_char(common);
2446    
2447  /* Testing char type. */  /* Testing char type. */
2448  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
2449  if (common->useucp)  if (common->use_ucp)
2450    {    {
2451    OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 1);    OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 1);
2452    jump = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_UNDERSCORE);    jump = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_UNDERSCORE);
# Line 2057  if (common->useucp) Line 2463  if (common->useucp)
2463  else  else
2464  #endif  #endif
2465    {    {
2466  #ifdef SUPPORT_UTF8  #ifndef COMPILE_PCRE8
2467      jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);
2468    #elif defined SUPPORT_UTF
2469    /* Here LOCALS1 has already been zeroed. */    /* Here LOCALS1 has already been zeroed. */
2470    jump = NULL;    jump = NULL;
2471    if (common->utf8)    if (common->utf)
2472      jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);      jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);
2473  #endif  #endif /* COMPILE_PCRE8 */
2474    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), common->ctypes);    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), common->ctypes);
2475    OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 4 /* ctype_word */);    OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 4 /* ctype_word */);
2476    OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);    OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
2477    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, TMP1, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, TMP1, 0);
2478  #ifdef SUPPORT_UTF8  #ifndef COMPILE_PCRE8
2479      JUMPHERE(jump);
2480    #elif defined SUPPORT_UTF
2481    if (jump != NULL)    if (jump != NULL)
2482      JUMPHERE(jump);      JUMPHERE(jump);
2483  #endif  #endif /* COMPILE_PCRE8 */
2484    }    }
2485  JUMPHERE(beginend);  JUMPHERE(skipread);
2486    
2487  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0);  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0);
2488  beginend = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);  skipread = check_str_end(common);
2489  peek_char(common);  peek_char(common);
2490    
2491  /* Testing char type. This is a code duplication. */  /* Testing char type. This is a code duplication. */
2492  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
2493  if (common->useucp)  if (common->use_ucp)
2494    {    {
2495    OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 1);    OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 1);
2496    jump = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_UNDERSCORE);    jump = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_UNDERSCORE);
# Line 2096  if (common->useucp) Line 2506  if (common->useucp)
2506  else  else
2507  #endif  #endif
2508    {    {
2509  #ifdef SUPPORT_UTF8  #ifndef COMPILE_PCRE8
2510      /* TMP2 may be destroyed by peek_char. */
2511      OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0);
2512      jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);
2513    #elif defined SUPPORT_UTF
2514    OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0);    OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0);
2515    jump = NULL;    jump = NULL;
2516    if (common->utf8)    if (common->utf)
2517      jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);      jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);
2518  #endif  #endif
2519    OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP1), common->ctypes);    OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP1), common->ctypes);
2520    OP2(SLJIT_LSHR, TMP2, 0, TMP2, 0, SLJIT_IMM, 4 /* ctype_word */);    OP2(SLJIT_LSHR, TMP2, 0, TMP2, 0, SLJIT_IMM, 4 /* ctype_word */);
2521    OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 1);    OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 1);
2522  #ifdef SUPPORT_UTF8  #ifndef COMPILE_PCRE8
2523      JUMPHERE(jump);
2524    #elif defined SUPPORT_UTF
2525    if (jump != NULL)    if (jump != NULL)
2526      JUMPHERE(jump);      JUMPHERE(jump);
2527  #endif  #endif /* COMPILE_PCRE8 */
2528    }    }
2529  JUMPHERE(beginend);  JUMPHERE(skipread);
2530    
2531  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);
2532  sljit_emit_fast_return(compiler, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);  sljit_emit_fast_return(compiler, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);
# Line 2127  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_I Line 2543  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_I
2543  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);
2544  COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS_EQUAL);  COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS_EQUAL);
2545  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);
2546  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF || defined COMPILE_PCRE16
2547  if (common->utf8)  #ifdef COMPILE_PCRE8
2548    if (common->utf)
2549    {    {
2550    #endif
2551    COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);    COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);
2552    OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x1);    OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x1);
2553    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);
2554    #ifdef COMPILE_PCRE8
2555    }    }
2556  #endif  #endif
2557    #endif /* SUPPORT_UTF || COMPILE_PCRE16 */
2558  COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);  COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);
2559  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
2560  }  }
# Line 2151  COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_E Line 2571  COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_E
2571  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);
2572  COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);  COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);
2573  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);
2574  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF || defined COMPILE_PCRE16
2575  if (common->utf8)  #ifdef COMPILE_PCRE8
2576    if (common->utf)
2577    {    {
2578    #endif
2579    COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);    COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);
2580    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);
2581    COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);    COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);
# Line 2167  if (common->utf8) Line 2589  if (common->utf8)
2589    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);
2590    COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);    COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);
2591    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);
2592    #ifdef COMPILE_PCRE8
2593    }    }
2594  #endif  #endif
2595    #endif /* SUPPORT_UTF || COMPILE_PCRE16 */
2596  COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);  COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);
2597    
2598  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
# Line 2185  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_I Line 2609  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_I
2609  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);
2610  COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS_EQUAL);  COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS_EQUAL);
2611  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);
2612  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF || defined COMPILE_PCRE16
2613  if (common->utf8)  #ifdef COMPILE_PCRE8
2614    if (common->utf)
2615    {    {
2616    #endif
2617    COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);    COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);
2618    OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x1);    OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x1);
2619    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);
2620    #ifdef COMPILE_PCRE8
2621    }    }
2622  #endif  #endif
2623    #endif /* SUPPORT_UTF || COMPILE_PCRE16 */
2624  COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);  COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);
2625    
2626  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
# Line 2211  sljit_emit_fast_enter(compiler, RETURN_A Line 2639  sljit_emit_fast_enter(compiler, RETURN_A
2639  OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);  OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
2640  OP1(SLJIT_MOV, TMP3, 0, CHAR1, 0);  OP1(SLJIT_MOV, TMP3, 0, CHAR1, 0);
2641  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, CHAR2, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, CHAR2, 0);
2642  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(1));
2643  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));
2644    
2645  label = LABEL();  label = LABEL();
2646  OP1(SLJIT_MOVU_UB, CHAR1, 0, SLJIT_MEM1(TMP1), 1);  OP1(MOVU_UCHAR, CHAR1, 0, SLJIT_MEM1(TMP1), IN_UCHARS(1));
2647  OP1(SLJIT_MOVU_UB, CHAR2, 0, SLJIT_MEM1(STR_PTR), 1);  OP1(MOVU_UCHAR, CHAR2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
2648  jump = CMP(SLJIT_C_NOT_EQUAL, CHAR1, 0, CHAR2, 0);  jump = CMP(SLJIT_C_NOT_EQUAL, CHAR1, 0, CHAR2, 0);
2649  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));
2650  JUMPTO(SLJIT_C_NOT_ZERO, label);  JUMPTO(SLJIT_C_NOT_ZERO, label);
2651    
2652  JUMPHERE(jump);  JUMPHERE(jump);
2653  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));
2654  OP1(SLJIT_MOV, CHAR1, 0, TMP3, 0);  OP1(SLJIT_MOV, CHAR1, 0, TMP3, 0);
2655  OP1(SLJIT_MOV, CHAR2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);  OP1(SLJIT_MOV, CHAR2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);
2656  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
# Line 2243  OP1(SLJIT_MOV, TMP3, 0, LCC_TABLE, 0); Line 2671  OP1(SLJIT_MOV, TMP3, 0, LCC_TABLE, 0);
2671  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, CHAR1, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, CHAR1, 0);
2672  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, CHAR2, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, CHAR2, 0);
2673  OP1(SLJIT_MOV, LCC_TABLE, 0, SLJIT_IMM, common->lcc);  OP1(SLJIT_MOV, LCC_TABLE, 0, SLJIT_IMM, common->lcc);
2674  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(1));
2675  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));
2676    
2677  label = LABEL();  label = LABEL();
2678  OP1(SLJIT_MOVU_UB, CHAR1, 0, SLJIT_MEM1(TMP1), 1);  OP1(MOVU_UCHAR, CHAR1, 0, SLJIT_MEM1(TMP1), IN_UCHARS(1));
2679  OP1(SLJIT_MOVU_UB, CHAR2, 0, SLJIT_MEM1(STR_PTR), 1);  OP1(MOVU_UCHAR, CHAR2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
2680    #ifndef COMPILE_PCRE8
2681    jump = CMP(SLJIT_C_GREATER, CHAR1, 0, SLJIT_IMM, 255);
2682    #endif
2683  OP1(SLJIT_MOV_UB, CHAR1, 0, SLJIT_MEM2(LCC_TABLE, CHAR1), 0);  OP1(SLJIT_MOV_UB, CHAR1, 0, SLJIT_MEM2(LCC_TABLE, CHAR1), 0);
2684    #ifndef COMPILE_PCRE8
2685    JUMPHERE(jump);
2686    jump = CMP(SLJIT_C_GREATER, CHAR2, 0, SLJIT_IMM, 255);
2687    #endif
2688  OP1(SLJIT_MOV_UB, CHAR2, 0, SLJIT_MEM2(LCC_TABLE, CHAR2), 0);  OP1(SLJIT_MOV_UB, CHAR2, 0, SLJIT_MEM2(LCC_TABLE, CHAR2), 0);
2689    #ifndef COMPILE_PCRE8
2690    JUMPHERE(jump);
2691    #endif
2692  jump = CMP(SLJIT_C_NOT_EQUAL, CHAR1, 0, CHAR2, 0);  jump = CMP(SLJIT_C_NOT_EQUAL, CHAR1, 0, CHAR2, 0);
2693  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));
2694  JUMPTO(SLJIT_C_NOT_ZERO, label);  JUMPTO(SLJIT_C_NOT_ZERO, label);
2695    
2696  JUMPHERE(jump);  JUMPHERE(jump);
2697  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));
2698  OP1(SLJIT_MOV, LCC_TABLE, 0, TMP3, 0);  OP1(SLJIT_MOV, LCC_TABLE, 0, TMP3, 0);
2699  OP1(SLJIT_MOV, CHAR1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);  OP1(SLJIT_MOV, CHAR1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);
2700  OP1(SLJIT_MOV, CHAR2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1);  OP1(SLJIT_MOV, CHAR2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1);
# Line 2267  sljit_emit_fast_return(compiler, RETURN_ Line 2705  sljit_emit_fast_return(compiler, RETURN_
2705  #undef CHAR1  #undef CHAR1
2706  #undef CHAR2  #undef CHAR2
2707    
2708  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF && defined SUPPORT_UCP
 #ifdef SUPPORT_UCP  
2709    
2710  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)
2711  {  {
2712  /* This function would be ineffective to do in JIT level. */  /* This function would be ineffective to do in JIT level. */
2713  int c1, c2;  int c1, c2;
2714  uschar *src2 = args->ptr;  const pcre_uchar *src2 = args->uchar_ptr;
2715  uschar *end2 = (uschar*)args->end;  const pcre_uchar *end2 = args->end;
2716    
2717  while (src1 < end1)  while (src1 < end1)
2718    {    {
2719    if (src2 >= end2)    if (src2 >= end2)
2720      return 0;      return (pcre_uchar*)1;
2721    GETCHARINC(c1, src1);    GETCHARINC(c1, src1);
2722    GETCHARINC(c2, src2);    GETCHARINC(c2, src2);
2723    if (c1 != c2 && c1 != UCD_OTHERCASE(c2)) return 0;    if (c1 != c2 && c1 != UCD_OTHERCASE(c2)) return NULL;
2724    }    }
2725  return src2;  return src2;
2726  }  }
2727    
2728  #endif  #endif /* SUPPORT_UTF && SUPPORT_UCP */
 #endif  
2729    
2730  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,
2731      compare_context* context, jump_list **fallbacks)      compare_context* context, jump_list **fallbacks)
2732  {  {
2733  DEFINE_COMPILER;  DEFINE_COMPILER;
2734  unsigned int othercasebit = 0;  unsigned int othercasebit = 0;
2735  uschar *othercasebyte = NULL;  pcre_uchar *othercasechar = NULL;
2736  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
2737  int utf8length;  int utflength;
2738  #endif  #endif
2739    
2740  if (caseless && char_has_othercase(common, cc))  if (caseless && char_has_othercase(common, cc))
# Line 2306  if (caseless && char_has_othercase(commo Line 2742  if (caseless && char_has_othercase(commo
2742    othercasebit = char_get_othercase_bit(common, cc);    othercasebit = char_get_othercase_bit(common, cc);
2743    SLJIT_ASSERT(othercasebit);    SLJIT_ASSERT(othercasebit);
2744    /* Extracting bit difference info. */    /* Extracting bit difference info. */
2745    othercasebyte = cc + (othercasebit >> 8);  #ifdef COMPILE_PCRE8
2746      othercasechar = cc + (othercasebit >> 8);
2747    othercasebit &= 0xff;    othercasebit &= 0xff;
2748    #else
2749    #ifdef COMPILE_PCRE16
2750      othercasechar = cc + (othercasebit >> 9);
2751      if ((othercasebit & 0x100) != 0)
2752        othercasebit = (othercasebit & 0xff) << 8;
2753      else
2754        othercasebit &= 0xff;
2755    #endif
2756    #endif
2757    }    }
2758    
2759  if (context->sourcereg == -1)  if (context->sourcereg == -1)
2760    {    {
2761    #ifdef COMPILE_PCRE8
2762  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
2763    if (context->length >= 4)    if (context->length >= 4)
2764      OP1(SLJIT_MOV_SI, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);      OP1(SLJIT_MOV_SI, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);
2765    else if (context->length >= 2)    else if (context->length >= 2)
2766      OP1(SLJIT_MOV_SH, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);      OP1(SLJIT_MOV_UH, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);
2767    else    else
2768  #endif  #endif
2769      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);
2770    #else
2771    #ifdef COMPILE_PCRE16
2772    #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
2773      if (context->length >= 4)
2774        OP1(SLJIT_MOV_SI, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);
2775      else
2776    #endif
2777        OP1(SLJIT_MOV_UH, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);
2778    #endif
2779    #endif /* COMPILE_PCRE8 */
2780    context->sourcereg = TMP2;    context->sourcereg = TMP2;
2781    }    }
2782    
2783  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
2784  utf8length = 1;  utflength = 1;
2785  if (common->utf8 && *cc >= 0xc0)  if (common->utf && HAS_EXTRALEN(*cc))
2786    utf8length += _pcre_utf8_table4[*cc & 0x3f];    utflength += GET_EXTRALEN(*cc);
2787    
2788  do  do
2789    {    {
2790  #endif  #endif
2791    
2792    context->length--;    context->length -= IN_UCHARS(1);
2793  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
2794    
2795    /* Unaligned read is supported. */    /* Unaligned read is supported. */
2796    if (othercasebit != 0 && othercasebyte == cc)    if (othercasebit != 0 && othercasechar == cc)
2797      {      {
2798      context->c.asbytes[context->byteptr] = *cc | othercasebit;      context->c.asuchars[context->ucharptr] = *cc | othercasebit;
2799      context->oc.asbytes[context->byteptr] = othercasebit;      context->oc.asuchars[context->ucharptr] = othercasebit;
2800      }      }
2801    else    else
2802      {      {
2803      context->c.asbytes[context->byteptr] = *cc;      context->c.asuchars[context->ucharptr] = *cc;
2804      context->oc.asbytes[context->byteptr] = 0;      context->oc.asuchars[context->ucharptr] = 0;
2805      }      }
2806    context->byteptr++;    context->ucharptr++;
2807    
2808    if (context->byteptr >= 4 || context->length == 0 || (context->byteptr == 2 && context->length == 1))  #ifdef COMPILE_PCRE8
2809      if (context->ucharptr >= 4 || context->length == 0 || (context->ucharptr == 2 && context->length == 1))
2810    #else
2811      if (context->ucharptr >= 2 || context->length == 0)
2812    #endif
2813      {      {
2814      if (context->length >= 4)      if (context->length >= 4)
2815        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);
2816    #ifdef COMPILE_PCRE8
2817      else if (context->length >= 2)      else if (context->length >= 2)
2818        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);
2819      else if (context->length >= 1)      else if (context->length >= 1)
2820        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);
2821    #else
2822        else if (context->length >= 2)
2823          OP1(SLJIT_MOV_UH, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);
2824    #endif
2825      context->sourcereg = context->sourcereg == TMP1 ? TMP2 : TMP1;      context->sourcereg = context->sourcereg == TMP1 ? TMP2 : TMP1;
2826    
2827      switch(context->byteptr)      switch(context->ucharptr)
2828        {        {
2829        case 4:        case 4 / sizeof(pcre_uchar):
2830        if (context->oc.asint != 0)        if (context->oc.asint != 0)
2831          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);
2832        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));
2833        break;        break;
2834    
2835        case 2:        case 2 / sizeof(pcre_uchar):
2836        if (context->oc.asshort != 0)        if (context->oc.asushort != 0)
2837          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);
2838        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));
2839        break;        break;
2840    
2841    #ifdef COMPILE_PCRE8
2842        case 1:        case 1:
2843        if (context->oc.asbyte != 0)        if (context->oc.asbyte != 0)
2844          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);
2845        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));
2846        break;        break;
2847    #endif
2848    
2849        default:        default:
2850        SLJIT_ASSERT_STOP();        SLJIT_ASSERT_STOP();
2851        break;        break;
2852        }        }
2853      context->byteptr = 0;      context->ucharptr = 0;
2854      }      }
2855    
2856  #else  #else
2857    
2858    /* Unaligned read is unsupported. */    /* Unaligned read is unsupported. */
2859    #ifdef COMPILE_PCRE8
2860    if (context->length > 0)    if (context->length > 0)
2861      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);
2862    #else
2863      if (context->length > 0)
2864        OP1(SLJIT_MOV_UH, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);
2865    #endif
2866    context->sourcereg = context->sourcereg == TMP1 ? TMP2 : TMP1;    context->sourcereg = context->sourcereg == TMP1 ? TMP2 : TMP1;
2867    
2868    if (othercasebit != 0 && othercasebyte == cc)    if (othercasebit != 0 && othercasechar == cc)
2869      {      {
2870      OP2(SLJIT_OR, context->sourcereg, 0, context->sourcereg, 0, SLJIT_IMM, othercasebit);      OP2(SLJIT_OR, context->sourcereg, 0, context->sourcereg, 0, SLJIT_IMM, othercasebit);
2871      add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, context->sourcereg, 0, SLJIT_IMM, *cc | othercasebit));      add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, context->sourcereg, 0, SLJIT_IMM, *cc | othercasebit));
# Line 2403  do Line 2876  do
2876  #endif  #endif
2877    
2878    cc++;    cc++;
2879  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
2880    utf8length--;    utflength--;
2881    }    }
2882  while (utf8length > 0);  while (utflength > 0);
2883  #endif  #endif
2884    
2885  return cc;  return cc;
2886  }  }
2887    
2888  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
2889    
2890  #define SET_TYPE_OFFSET(value) \  #define SET_TYPE_OFFSET(value) \
2891    if ((value) != typeoffset) \    if ((value) != typeoffset) \
# Line 2434  return cc; Line 2907  return cc;
2907      } \      } \
2908    charoffset = (value);    charoffset = (value);
2909    
2910  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)
2911  {  {
2912  DEFINE_COMPILER;  DEFINE_COMPILER;
2913  jump_list *found = NULL;  jump_list *found = NULL;
# Line 2442  jump_list **list = (*cc & XCL_NOT) == 0 Line 2915  jump_list **list = (*cc & XCL_NOT) == 0
2915  unsigned int c;  unsigned int c;
2916  int compares;  int compares;
2917  struct sljit_jump *jump = NULL;  struct sljit_jump *jump = NULL;
2918  uschar *ccbegin;  pcre_uchar *ccbegin;
2919  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
2920  BOOL needstype = FALSE, needsscript = FALSE, needschar = FALSE;  BOOL needstype = FALSE, needsscript = FALSE, needschar = FALSE;
2921  BOOL charsaved = FALSE;  BOOL charsaved = FALSE;
2922  int typereg = TMP1, scriptreg = TMP1, typeoffset;  int typereg = TMP1, scriptreg = TMP1;
2923    unsigned int typeoffset;
2924  #endif  #endif
2925  int charoffset, invertcmp, numberofcmps;  int invertcmp, numberofcmps;
2926    unsigned int charoffset;
2927    
2928  /* 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. */
2929  check_input_end(common, fallbacks);  fallback_at_str_end(common, fallbacks);
2930  read_char(common);  read_char(common);
2931    
2932  if ((*cc++ & XCL_MAP) != 0)  if ((*cc++ & XCL_MAP) != 0)
2933    {    {
2934    OP1(SLJIT_MOV, TMP3, 0, TMP1, 0);    OP1(SLJIT_MOV, TMP3, 0, TMP1, 0);
2935    if (common->utf8)  #ifndef COMPILE_PCRE8
2936      jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);
2937    #elif defined SUPPORT_UTF
2938      if (common->utf)
2939      jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);      jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);
2940    #endif
2941    
2942    OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);    OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);
2943    OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);    OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);
# Line 2467  if ((*cc++ & XCL_MAP) != 0) Line 2946  if ((*cc++ & XCL_MAP) != 0)
2946    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);
2947    add_jump(compiler, list, JUMP(SLJIT_C_NOT_ZERO));    add_jump(compiler, list, JUMP(SLJIT_C_NOT_ZERO));
2948    
2949    if (common->utf8)  #ifndef COMPILE_PCRE8
2950      JUMPHERE(jump);
2951    #elif defined SUPPORT_UTF
2952      if (common->utf)
2953      JUMPHERE(jump);      JUMPHERE(jump);
2954    #endif
2955    OP1(SLJIT_MOV, TMP1, 0, TMP3, 0);    OP1(SLJIT_MOV, TMP1, 0, TMP3, 0);
2956  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
2957    charsaved = TRUE;    charsaved = TRUE;
2958  #endif  #endif
2959    cc += 32;    cc += 32 / sizeof(pcre_uchar);
2960    }    }
2961    
2962  /* Scanning the necessary info. */  /* Scanning the necessary info. */
# Line 2485  while (*cc != XCL_END) Line 2968  while (*cc != XCL_END)
2968    if (*cc == XCL_SINGLE)    if (*cc == XCL_SINGLE)
2969      {      {
2970      cc += 2;      cc += 2;
2971  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
2972      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]);
2973  #endif  #endif
2974  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
2975      needschar = TRUE;      needschar = TRUE;
# Line 2495  while (*cc != XCL_END) Line 2978  while (*cc != XCL_END)
2978    else if (*cc == XCL_RANGE)    else if (*cc == XCL_RANGE)
2979      {      {
2980      cc += 2;      cc += 2;
2981  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
2982      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]);
2983  #endif  #endif
2984      cc++;      cc++;
2985  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
2986      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]);
2987  #endif  #endif
2988  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
2989      needschar = TRUE;      needschar = TRUE;
# Line 2570  if (needstype || needsscript) Line 3053  if (needstype || needsscript)
3053      {      {
3054      if (scriptreg == TMP1)      if (scriptreg == TMP1)
3055        {        {
3056        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));
3057        OP1(SLJIT_MOV_UB, scriptreg, 0, SLJIT_MEM2(scriptreg, TMP2), 3);        OP1(SLJIT_MOV_UB, scriptreg, 0, SLJIT_MEM2(scriptreg, TMP2), 3);
3058        }        }
3059      else      else
3060        {        {
3061        OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 3);        OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 3);
3062        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));
3063        OP1(SLJIT_MOV_UB, scriptreg, 0, SLJIT_MEM1(TMP2), 0);        OP1(SLJIT_MOV_UB, scriptreg, 0, SLJIT_MEM1(TMP2), 0);
3064        }        }
3065      }      }
# Line 2600  while (*cc != XCL_END) Line 3083  while (*cc != XCL_END)
3083    if (*cc == XCL_SINGLE)    if (*cc == XCL_SINGLE)
3084      {      {
3085      cc ++;      cc ++;
3086  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3087      if (common->utf8)      if (common->utf)
3088        {        {
3089        GETCHARINC(c, cc);        GETCHARINC(c, cc);
3090        }        }
# Line 2631  while (*cc != XCL_END) Line 3114  while (*cc != XCL_END)
3114    else if (*cc == XCL_RANGE)    else if (*cc == XCL_RANGE)
3115      {      {
3116      cc ++;      cc ++;
3117  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3118      if (common->utf8)      if (common->utf)
3119        {        {
3120        GETCHARINC(c, cc);        GETCHARINC(c, cc);
3121        }        }
# Line 2640  while (*cc != XCL_END) Line 3123  while (*cc != XCL_END)
3123  #endif  #endif
3124        c = *cc++;        c = *cc++;
3125      SET_CHAR_OFFSET(c);      SET_CHAR_OFFSET(c);
3126  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3127      if (common->utf8)      if (common->utf)
3128        {        {
3129        GETCHARINC(c, cc);        GETCHARINC(c, cc);
3130        }        }
# Line 2697  while (*cc != XCL_END) Line 3180  while (*cc != XCL_END)
3180        break;        break;
3181    
3182        case PT_GC:        case PT_GC:
3183        c = _pcre_ucp_typerange[(int)cc[1] * 2];        c = PRIV(ucp_typerange)[(int)cc[1] * 2];
3184        SET_TYPE_OFFSET(c);        SET_TYPE_OFFSET(c);
3185        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);
3186        break;        break;
3187    
3188        case PT_PC:        case PT_PC:
# Line 2761  if (found != NULL) Line 3244  if (found != NULL)
3244    
3245  #endif  #endif
3246    
3247  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)
3248  {  {
3249  DEFINE_COMPILER;  DEFINE_COMPILER;
3250  int length;  int length;
3251  unsigned int c, oc, bit;  unsigned int c, oc, bit;
3252  compare_context context;  compare_context context;
3253  struct sljit_jump *jump[4];  struct sljit_jump *jump[4];
3254  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3255  struct sljit_label *label;  struct sljit_label *label;
3256  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
3257  uschar propdata[5];  pcre_uchar propdata[5];
3258  #endif  #endif
3259  #endif  #endif
3260    
# Line 2797  switch(type) Line 3280  switch(type)
3280    
3281    case OP_NOT_DIGIT:    case OP_NOT_DIGIT:
3282    case OP_DIGIT:    case OP_DIGIT:
3283    check_input_end(common, fallbacks);    fallback_at_str_end(common, fallbacks);
3284    read_char8_type(common);    read_char8_type(common);
3285    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);
3286    add_jump(compiler, fallbacks, JUMP(type == OP_DIGIT ? SLJIT_C_ZERO : SLJIT_C_NOT_ZERO));    add_jump(compiler, fallbacks, JUMP(type == OP_DIGIT ? SLJIT_C_ZERO : SLJIT_C_NOT_ZERO));
# Line 2805  switch(type) Line 3288  switch(type)
3288    
3289    case OP_NOT_WHITESPACE:    case OP_NOT_WHITESPACE:
3290    case OP_WHITESPACE:    case OP_WHITESPACE:
3291    check_input_end(common, fallbacks);    fallback_at_str_end(common, fallbacks);
3292    read_char8_type(common);    read_char8_type(common);
3293    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);
3294    add_jump(compiler, fallbacks, JUMP(type == OP_WHITESPACE ? SLJIT_C_ZERO : SLJIT_C_NOT_ZERO));    add_jump(compiler, fallbacks, JUMP(type == OP_WHITESPACE ? SLJIT_C_ZERO : SLJIT_C_NOT_ZERO));
# Line 2813  switch(type) Line 3296  switch(type)
3296    
3297    case OP_NOT_WORDCHAR:    case OP_NOT_WORDCHAR:
3298    case OP_WORDCHAR:    case OP_WORDCHAR:
3299    check_input_end(common, fallbacks);    fallback_at_str_end(common, fallbacks);
3300    read_char8_type(common);    read_char8_type(common);
3301    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);
3302    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));
3303    return cc;    return cc;
3304    
3305    case OP_ANY:    case OP_ANY:
3306    check_input_end(common, fallbacks);    fallback_at_str_end(common, fallbacks);
3307    read_char(common);    read_char(common);
3308    if (common->nltype == NLTYPE_FIXED && common->newline > 255)    if (common->nltype == NLTYPE_FIXED && common->newline > 255)
3309      {      {
3310      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);
3311      jump[1] = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);      if (common->mode != JIT_PARTIAL_HARD_COMPILE)
3312      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);        jump[1] = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
3313        else
3314          jump[1] = check_str_end(common);
3315    
3316        OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
3317      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));
3318      JUMPHERE(jump[1]);      if (jump[1] != NULL)
3319          JUMPHERE(jump[1]);
3320      JUMPHERE(jump[0]);      JUMPHERE(jump[0]);
3321      }      }
3322    else    else
# Line 2836  switch(type) Line 3324  switch(type)
3324    return cc;    return cc;
3325    
3326    case OP_ALLANY:    case OP_ALLANY:
3327    check_input_end(common, fallbacks);    fallback_at_str_end(common, fallbacks);
3328  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3329    if (common->utf8)    if (common->utf)
3330      {      {
3331      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
3332      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));
3333    #ifdef COMPILE_PCRE8
3334        jump[0] = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);
3335        OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)PRIV(utf8_table4) - 0xc0);
3336      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
3337    #else /* COMPILE_PCRE8 */
3338    #ifdef COMPILE_PCRE16
3339        jump[0] = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800);
3340        OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);
3341        OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xd800);
3342        COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);
3343        OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
3344        OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
3345    #endif /* COMPILE_PCRE16 */
3346    #endif /* COMPILE_PCRE8 */
3347        JUMPHERE(jump[0]);
3348      return cc;      return cc;
3349      }      }
3350  #endif  #endif
3351    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));
3352    return cc;    return cc;
3353    
3354  #ifdef SUPPORT_UTF8    case OP_ANYBYTE:
3355      fallback_at_str_end(common, fallbacks);
3356      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
3357      return cc;
3358    
3359    #ifdef SUPPORT_UTF
3360  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
3361    case OP_NOTPROP:    case OP_NOTPROP:
3362    case OP_PROP:    case OP_PROP:
# Line 2864  switch(type) Line 3371  switch(type)
3371  #endif  #endif
3372    
3373    case OP_ANYNL:    case OP_ANYNL:
3374    check_input_end(common, fallbacks);    fallback_at_str_end(common, fallbacks);
3375    read_char(common);    read_char(common);
3376    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);
3377    jump[1] = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);    /* We don't need to handle soft partial matching case. */
3378    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);    if (common->mode != JIT_PARTIAL_HARD_COMPILE)
3379        jump[1] = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
3380      else
3381        jump[1] = check_str_end(common);
3382      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
3383    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);
3384    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));
3385    jump[3] = JUMP(SLJIT_JUMP);    jump[3] = JUMP(SLJIT_JUMP);
3386    JUMPHERE(jump[0]);    JUMPHERE(jump[0]);
3387    check_newlinechar(common, common->bsr_nltype, fallbacks, FALSE);    check_newlinechar(common, common->bsr_nltype, fallbacks, FALSE);
# Line 2881  switch(type) Line 3392  switch(type)
3392    
3393    case OP_NOT_HSPACE:    case OP_NOT_HSPACE:
3394    case OP_HSPACE:    case OP_HSPACE:
3395    check_input_end(common, fallbacks);    fallback_at_str_end(common, fallbacks);
3396    read_char(common);    read_char(common);
3397    add_jump(compiler, &common->hspace, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->hspace, JUMP(SLJIT_FAST_CALL));
3398    add_jump(compiler, fallbacks, JUMP(type == OP_NOT_HSPACE ? SLJIT_C_NOT_ZERO : SLJIT_C_ZERO));    add_jump(compiler, fallbacks, JUMP(type == OP_NOT_HSPACE ? SLJIT_C_NOT_ZERO : SLJIT_C_ZERO));
# Line 2889  switch(type) Line 3400  switch(type)
3400    
3401    case OP_NOT_VSPACE:    case OP_NOT_VSPACE:
3402    case OP_VSPACE:    case OP_VSPACE:
3403    check_input_end(common, fallbacks);    fallback_at_str_end(common, fallbacks);
3404    read_char(common);    read_char(common);
3405    add_jump(compiler, &common->vspace, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->vspace, JUMP(SLJIT_FAST_CALL));
3406    add_jump(compiler, fallbacks, JUMP(type == OP_NOT_VSPACE ? SLJIT_C_NOT_ZERO : SLJIT_C_ZERO));    add_jump(compiler, fallbacks, JUMP(type == OP_NOT_VSPACE ? SLJIT_C_NOT_ZERO : SLJIT_C_ZERO));
# Line 2897  switch(type) Line 3408  switch(type)
3408    
3409  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
3410    case OP_EXTUNI:    case OP_EXTUNI:
3411    check_input_end(common, fallbacks);    fallback_at_str_end(common, fallbacks);
3412    read_char(common);    read_char(common);
3413    add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL));
3414    OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Mc);    OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Mc);
# Line 2913  switch(type) Line 3424  switch(type)
3424    
3425    OP1(SLJIT_MOV, STR_PTR, 0, TMP3, 0);    OP1(SLJIT_MOV, STR_PTR, 0, TMP3, 0);
3426    JUMPHERE(jump[0]);    JUMPHERE(jump[0]);
3427      if (common->mode == JIT_PARTIAL_HARD_COMPILE)
3428        {
3429        jump[0] = CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0);
3430        /* Since we successfully read a char above, partial matching must occure. */
3431        check_partial(common, TRUE);
3432        JUMPHERE(jump[0]);
3433        }
3434    return cc;    return cc;
3435  #endif  #endif
3436    
3437    case OP_EODN:    case OP_EODN:
3438      /* Requires rather complex checks. */
3439    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);
3440    if (common->nltype == NLTYPE_FIXED && common->newline > 255)    if (common->nltype == NLTYPE_FIXED && common->newline > 255)
3441      {      {
3442      OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, 2);      OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2));
3443      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
3444      add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, STR_END, 0));      if (common->mode == JIT_COMPILE)
3445      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));
3446        else
3447          {
3448          jump[1] = CMP(SLJIT_C_EQUAL, TMP2, 0, STR_END, 0);
3449          OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP2, 0, STR_END, 0);
3450          COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS);
3451          OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff);
3452          COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_NOT_EQUAL);
3453          add_jump(compiler, fallbacks, JUMP(SLJIT_C_NOT_EQUAL));
3454          check_partial(common, TRUE);
3455          add_jump(compiler, fallbacks, JUMP(SLJIT_JUMP));
3456          JUMPHERE(jump[1]);
3457          }
3458        OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
3459      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));
3460      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));
3461      }      }
3462    else if (common->nltype == NLTYPE_FIXED)    else if (common->nltype == NLTYPE_FIXED)
3463      {      {
3464      OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, 1);      OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
3465      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
3466      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));
3467      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));
3468      }      }
3469    else    else
3470      {      {
3471      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
3472      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);
3473      OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, 2);      OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2));
3474      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);
3475      jump[2] = JUMP(SLJIT_C_GREATER);      jump[2] = JUMP(SLJIT_C_GREATER);
3476      add_jump(compiler, fallbacks, JUMP(SLJIT_C_LESS));      add_jump(compiler, fallbacks, JUMP(SLJIT_C_LESS));
3477      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 1);      /* Equal. */
3478        OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
3479      jump[3] = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_NL);      jump[3] = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_NL);
3480      add_jump(compiler, fallbacks, JUMP(SLJIT_JUMP));      add_jump(compiler, fallbacks, JUMP(SLJIT_JUMP));
3481    
3482      JUMPHERE(jump[1]);      JUMPHERE(jump[1]);
3483      if (common->nltype == NLTYPE_ANYCRLF)      if (common->nltype == NLTYPE_ANYCRLF)
3484        {        {
3485        OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, 1);        OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
3486        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));
3487        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));
3488        }        }
# Line 2966  switch(type) Line 3499  switch(type)
3499      JUMPHERE(jump[3]);      JUMPHERE(jump[3]);
3500      }      }
3501    JUMPHERE(jump[0]);    JUMPHERE(jump[0]);
3502      check_partial(common, FALSE);
3503    return cc;    return cc;
3504    
3505    case OP_EOD:    case OP_EOD:
3506    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));
3507      check_partial(common, FALSE);
3508    return cc;    return cc;
3509    
3510    case OP_CIRC:    case OP_CIRC:
# Line 2989  switch(type) Line 3524  switch(type)
3524    jump[0] = JUMP(SLJIT_JUMP);    jump[0] = JUMP(SLJIT_JUMP);
3525    JUMPHERE(jump[1]);    JUMPHERE(jump[1]);
3526    
3527    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));  
   
3528    if (common->nltype == NLTYPE_FIXED && common->newline > 255)    if (common->nltype == NLTYPE_FIXED && common->newline > 255)
3529      {      {
3530      OP2(SLJIT_SUB, TMP2, 0, STR_PTR, 0, SLJIT_IMM, 2);      OP2(SLJIT_SUB, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2));
3531      add_jump(compiler, fallbacks, CMP(SLJIT_C_LESS, TMP2, 0, TMP1, 0));      add_jump(compiler, fallbacks, CMP(SLJIT_C_LESS, TMP2, 0, TMP1, 0));
3532      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), -2);      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-2));
3533      OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), -1);      OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-1));
3534      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));
3535      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));
3536      }      }
# Line 3018  switch(type) Line 3551  switch(type)
3551    if (!common->endonly)    if (!common->endonly)
3552      compile_char1_hotpath(common, OP_EODN, cc, fallbacks);      compile_char1_hotpath(common, OP_EODN, cc, fallbacks);
3553    else    else
3554        {
3555      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));
3556        check_partial(common, FALSE);
3557        }
3558    return cc;    return cc;
3559    
3560    case OP_DOLLM:    case OP_DOLLM:
# Line 3026  switch(type) Line 3562  switch(type)
3562    OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0);    OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0);
3563    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));
3564    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));
3565      check_partial(common, FALSE);
3566    jump[0] = JUMP(SLJIT_JUMP);    jump[0] = JUMP(SLJIT_JUMP);
3567    JUMPHERE(jump[1]);    JUMPHERE(jump[1]);
3568    
3569    if (common->nltype == NLTYPE_FIXED && common->newline > 255)    if (common->nltype == NLTYPE_FIXED && common->newline > 255)
3570      {      {
3571      OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, 2);      OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2));
3572      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));
3573      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);      if (common->mode == JIT_COMPILE)
3574      OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), 1);        add_jump(compiler, fallbacks, CMP(SLJIT_C_GREATER, TMP2, 0, STR_END, 0));
3575        else
3576          {
3577          jump[1] = CMP(SLJIT_C_LESS_EQUAL, TMP2, 0, STR_END, 0);
3578          /* STR_PTR = STR_END - IN_UCHARS(1) */
3579          add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff));
3580          check_partial(common, TRUE);
3581          add_jump(compiler, fallbacks, JUMP(SLJIT_JUMP));
3582          JUMPHERE(jump[1]);
3583          }
3584    
3585        OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
3586      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));
3587      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));
3588      }      }
# Line 3049  switch(type) Line 3597  switch(type)
3597    case OP_CHAR:    case OP_CHAR:
3598    case OP_CHARI:    case OP_CHARI:
3599    length = 1;    length = 1;
3600  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3601    if (common->utf8 && *cc >= 0xc0) length += _pcre_utf8_table4[*cc & 0x3f];    if (common->utf && HAS_EXTRALEN(*cc)) length += GET_EXTRALEN(*cc);
3602  #endif  #endif
3603    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))
3604      {      {
3605      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));
3606      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));
3607    
3608      context.length = length;      context.length = IN_UCHARS(length);
3609      context.sourcereg = -1;      context.sourcereg = -1;
3610  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
3611      context.byteptr = 0;      context.ucharptr = 0;
3612  #endif  #endif
3613      return byte_sequence_compare(common, type == OP_CHARI, cc, &context, fallbacks);      return byte_sequence_compare(common, type == OP_CHARI, cc, &context, fallbacks);
3614      }      }
3615    add_jump(compiler, fallbacks, CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0));    fallback_at_str_end(common, fallbacks);
3616    read_char(common);    read_char(common);
3617  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3618    if (common->utf8)    if (common->utf)
3619      {      {
3620      GETCHAR(c, cc);      GETCHAR(c, cc);
3621      }      }
3622    else    else
3623  #endif  #endif
3624      c = *cc;      c = *cc;
3625      if (type == OP_CHAR || !char_has_othercase(common, cc))
3626        {
3627        add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, c));
3628        return cc + length;
3629        }
3630      oc = char_othercase(common, c);
3631      bit = c ^ oc;
3632      if (ispowerof2(bit))
3633        {
3634        OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, bit);
3635        add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, c | bit));
3636        return cc + length;
3637        }
3638    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);
3639    COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);    COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);
3640    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, char_othercase(common, c));    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, char_othercase(common, c));
# Line 3083  switch(type) Line 3644  switch(type)
3644    
3645    case OP_NOT:    case OP_NOT:
3646    case OP_NOTI:    case OP_NOTI:
3647      fallback_at_str_end(common, fallbacks);
3648    length = 1;    length = 1;
3649  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3650    if (common->utf8)    if (common->utf)
3651      {      {
3652      if (*cc >= 0xc0) length += _pcre_utf8_table4[*cc & 0x3f];  #ifdef COMPILE_PCRE8
3653        c = *cc;
3654      check_input_end(common, fallbacks);      if (c < 128)
     GETCHAR(c, cc);  
   
     if (c <= 127)  
3655        {        {
3656        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);  
3657        if (type == OP_NOT || !char_has_othercase(common, cc))        if (type == OP_NOT || !char_has_othercase(common, cc))
3658          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));
3659        else        else
3660          {          {
3661          /* 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. */
3662          OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x20);          OP2(SLJIT_OR, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x20);
3663          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));
3664          }          }
3665        /* Skip the variable-length character. */        /* Skip the variable-length character. */
3666        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));
3667        return cc + length;        jump[0] = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);
3668          OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)PRIV(utf8_table4) - 0xc0);
3669          OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
3670          JUMPHERE(jump[0]);
3671          return cc + 1;
3672        }        }
3673      else      else
3674    #endif /* COMPILE_PCRE8 */
3675          {
3676          GETCHARLEN(c, cc, length);
3677        read_char(common);        read_char(common);
3678          }
3679      }      }
3680    else    else
3681  #endif  #endif /* SUPPORT_UTF */
3682      {      {
3683      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);  
3684      c = *cc;      c = *cc;
3685      }      }
3686    
# Line 3141  switch(type) Line 3705  switch(type)
3705    
3706    case OP_CLASS:    case OP_CLASS:
3707    case OP_NCLASS:    case OP_NCLASS:
3708    check_input_end(common, fallbacks);    fallback_at_str_end(common, fallbacks);
3709    read_char(common);    read_char(common);
3710  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
3711    jump[0] = NULL;    jump[0] = NULL;
3712    if (common->utf8)  #ifdef COMPILE_PCRE8
3713      /* This check only affects 8 bit mode. In other modes, we
3714      always need to compare the value with 255. */
3715      if (common->utf)
3716    #endif /* COMPILE_PCRE8 */
3717      {      {
3718      jump[0] = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);      jump[0] = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);
3719      if (type == OP_CLASS)      if (type == OP_CLASS)
# Line 3154  switch(type) Line 3722  switch(type)
3722        jump[0] = NULL;        jump[0] = NULL;
3723        }        }
3724      }      }
3725  #endif  #endif /* SUPPORT_UTF || !COMPILE_PCRE8 */
3726    OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);    OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);
3727    OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);    OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);
3728    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)cc);    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)cc);
3729    OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0);    OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0);
3730    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);
3731    add_jump(compiler, fallbacks, JUMP(SLJIT_C_ZERO));    add_jump(compiler, fallbacks, JUMP(SLJIT_C_ZERO));
3732  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
3733    if (jump[0] != NULL)    if (jump[0] != NULL)
3734      JUMPHERE(jump[0]);      JUMPHERE(jump[0]);
3735  #endif  #endif /* SUPPORT_UTF || !COMPILE_PCRE8 */
3736    return cc + 32;    return cc + 32 / sizeof(pcre_uchar);
3737    
3738  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF || defined COMPILE_PCRE16
3739    case OP_XCLASS:    case OP_XCLASS:
3740    compile_xclass_hotpath(common, cc + LINK_SIZE, fallbacks);    compile_xclass_hotpath(common, cc + LINK_SIZE, fallbacks);
3741    return cc + GET(cc, 0) - 1;    return cc + GET(cc, 0) - 1;
# Line 3177  switch(type) Line 3745  switch(type)
3745    length = GET(cc, 0);    length = GET(cc, 0);
3746    SLJIT_ASSERT(length > 0);    SLJIT_ASSERT(length > 0);
3747    OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);    OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
3748    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin));  #ifdef SUPPORT_UTF
3749  #ifdef SUPPORT_UTF8    if (common->utf)
   if (common->utf8)  
3750      {      {
3751        OP1(SLJIT_MOV, TMP3, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin));
3752      OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, length);      OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, length);
3753      label = LABEL();      label = LABEL();
3754      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));
3755      skip_char_back(common);      skip_char_back(common);
3756      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);
3757      JUMPTO(SLJIT_C_NOT_ZERO, label);      JUMPTO(SLJIT_C_NOT_ZERO, label);
     return cc + LINK_SIZE;  
3758      }      }
3759      else
3760  #endif  #endif
3761    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, length);      {
3762    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));
3763        OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(length));
3764        add_jump(compiler, fallbacks, CMP(SLJIT_C_LESS, STR_PTR, 0, TMP1, 0));
3765        }
3766      check_start_used_ptr(common);
3767    return cc + LINK_SIZE;    return cc + LINK_SIZE;
3768    }    }
3769  SLJIT_ASSERT_STOP();  SLJIT_ASSERT_STOP();
3770  return cc;  return cc;
3771  }  }
3772    
3773  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)
3774  {  {
3775  /* This function consumes at least one input character. */  /* This function consumes at least one input character. */
3776  /* 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. */
3777  DEFINE_COMPILER;  DEFINE_COMPILER;
3778  uschar *ccbegin = cc;  pcre_uchar *ccbegin = cc;
3779  compare_context context;  compare_context context;
3780  int size;  int size;
3781    
# Line 3216  do Line 3788  do
3788    if (*cc == OP_CHAR)    if (*cc == OP_CHAR)
3789      {      {
3790      size = 1;      size = 1;
3791  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3792      if (common->utf8 && cc[1] >= 0xc0)      if (common->utf && HAS_EXTRALEN(cc[1]))
3793        size += _pcre_utf8_table4[cc[1] & 0x3f];        size += GET_EXTRALEN(cc[1]);
3794  #endif  #endif
3795      }      }
3796    else if (*cc == OP_CHARI)    else if (*cc == OP_CHARI)
3797      {      {
3798      size = 1;      size = 1;
3799  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3800      if (common->utf8)      if (common->utf)
3801        {        {
3802        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)
3803          size = 0;          size = 0;
3804        else if (cc[1] >= 0xc0)        else if (HAS_EXTRALEN(cc[1]))
3805          size += _pcre_utf8_table4[cc[1] & 0x3f];          size += GET_EXTRALEN(cc[1]);
3806        }        }
3807      else      else
3808  #endif  #endif
3809      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)
3810        size = 0;        size = 0;
# Line 3241  do Line 3813  do
3813      size = 0;      size = 0;
3814    
3815    cc += 1 + size;    cc += 1 + size;
3816    context.length += size;    context.length += IN_UCHARS(size);
3817    }    }
3818  while (size > 0 && context.length <= 128);  while (size > 0 && context.length <= 128);
3819    
# Line 3254  if (context.length > 0) Line 3826  if (context.length > 0)
3826    
3827    context.sourcereg = -1;    context.sourcereg = -1;
3828  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
3829    context.byteptr = 0;    context.ucharptr = 0;
3830  #endif  #endif
3831    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);
3832    return cc;    return cc;
# Line 3264  if (context.length > 0) Line 3836  if (context.length > 0)
3836  return compile_char1_hotpath(common, *cc, cc + 1, fallbacks);  return compile_char1_hotpath(common, *cc, cc + 1, fallbacks);
3837  }  }
3838    
3839  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)
3840  {  {
3841  DEFINE_COMPILER;  DEFINE_COMPILER;
3842  int offset = GET2(cc, 1) << 1;  int offset = GET2(cc, 1) << 1;
# Line 3274  if (!common->jscript_compat) Line 3846  if (!common->jscript_compat)
3846    {    {
3847    if (fallbacks == NULL)    if (fallbacks == NULL)
3848      {      {
3849        /* OVECTOR(1) contains the "string begin - 1" constant. */
3850      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));
3851      COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);      COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);
3852      OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1));      OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1));
# Line 3286  return CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT Line 3859  return CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT
3859  }  }
3860    
3861  /* Forward definitions. */  /* Forward definitions. */
3862  static void compile_hotpath(compiler_common *, uschar *, uschar *, fallback_common *);  static void compile_hotpath(compiler_common *, pcre_uchar *, pcre_uchar *, fallback_common *);
3863  static void compile_fallbackpath(compiler_common *, struct fallback_common *);  static void compile_fallbackpath(compiler_common *, struct fallback_common *);
3864    
3865  #define PUSH_FALLBACK(size, ccstart, error) \  #define PUSH_FALLBACK(size, ccstart, error) \
# Line 3315  static void compile_fallbackpath(compile Line 3888  static void compile_fallbackpath(compile
3888      } \      } \
3889    while (0)    while (0)
3890    
3891  #define FALLBACK_AS(type) ((type*)fallback)  #define FALLBACK_AS(type) ((type *)fallback)
3892    
3893  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)
3894  {  {
3895  DEFINE_COMPILER;  DEFINE_COMPILER;
3896  int offset = GET2(cc, 1) << 1;  int offset = GET2(cc, 1) << 1;
3897  struct sljit_jump *jump = NULL;  struct sljit_jump *jump = NULL;
3898    struct sljit_jump *partial;
3899    struct sljit_jump *nopartial;
3900    
3901  OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));  OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));
3902    /* OVECTOR(1) contains the "string begin - 1" constant. */
3903  if (withchecks && !common->jscript_compat)  if (withchecks && !common->jscript_compat)
3904    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)));
3905    
3906  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF && defined SUPPORT_UCP
3907  #ifdef SUPPORT_UCP  if (common->utf && *cc == OP_REFI)
 if (common->utf8 && *cc == OP_REFI)  
3908    {    {
3909    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);
3910    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 3339  if (common->utf8 && *cc == OP_REFI) Line 3914  if (common->utf8 && *cc == OP_REFI)
3914    /* Needed to save important temporary registers. */    /* Needed to save important temporary registers. */
3915    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, STACK_TOP, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, STACK_TOP, 0);
3916    OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, ARGUMENTS, 0);    OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, ARGUMENTS, 0);
3917    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);
3918    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));
3919    OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);    OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);
3920    add_jump(compiler, fallbacks, CMP(SLJIT_C_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 0));    if (common->mode == JIT_COMPILE)
3921        add_jump(compiler, fallbacks, CMP(SLJIT_C_LESS_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 1));
3922      else
3923        {
3924        add_jump(compiler, fallbacks, CMP(SLJIT_C_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 0));
3925        nopartial = CMP(SLJIT_C_NOT_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 1);
3926        check_partial(common, FALSE);
3927        add_jump(compiler, fallbacks, JUMP(SLJIT_JUMP));
3928        JUMPHERE(nopartial);
3929        }
3930    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_RETURN_REG, 0);    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_RETURN_REG, 0);
3931    }    }
3932  else  else
3933  #endif  #endif /* SUPPORT_UTF && SUPPORT_UCP */
 #endif  
3934    {    {
3935    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);
3936    if (withchecks)    if (withchecks)
3937      jump = JUMP(SLJIT_C_ZERO);      jump = JUMP(SLJIT_C_ZERO);
3938    
3939    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
3940      partial = CMP(SLJIT_C_GREATER, STR_PTR, 0, STR_END, 0);
3941      if (common->mode == JIT_COMPILE)
3942        add_jump(compiler, fallbacks, partial);
3943    
   add_jump(compiler, fallbacks, CMP(SLJIT_C_GREATER, STR_PTR, 0, STR_END, 0));  
3944    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));
3945    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));
3946    
3947      if (common->mode != JIT_COMPILE)
3948        {
3949        nopartial = JUMP(SLJIT_JUMP);
3950        JUMPHERE(partial);
3951        /* TMP2 -= STR_END - STR_PTR */
3952        OP2(SLJIT_SUB, TMP2, 0, TMP2, 0, STR_PTR, 0);
3953        OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, STR_END, 0);
3954        partial = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, 0);
3955        OP1(SLJIT_MOV, STR_PTR, 0, STR_END, 0);
3956        add_jump(compiler, *cc == OP_REF ? &common->casefulcmp : &common->caselesscmp, JUMP(SLJIT_FAST_CALL));
3957        add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0));
3958        JUMPHERE(partial);
3959        check_partial(common, FALSE);
3960        add_jump(compiler, fallbacks, JUMP(SLJIT_JUMP));
3961        JUMPHERE(nopartial);
3962        }
3963    }    }
3964    
3965  if (jump != NULL)  if (jump != NULL)
# Line 3366  if (jump != NULL) Line 3969  if (jump != NULL)
3969    else    else
3970      JUMPHERE(jump);      JUMPHERE(jump);
3971    }    }
3972  return cc + 3;  return cc + 1 + IMM2_SIZE;
3973  }  }
3974    
3975  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)
3976  {  {
3977  DEFINE_COMPILER;  DEFINE_COMPILER;
3978  fallback_common *fallback;  fallback_common *fallback;
3979  uschar type;  pcre_uchar type;
3980  struct sljit_label *label;  struct sljit_label *label;
3981  struct sljit_jump *zerolength;  struct sljit_jump *zerolength;
3982  struct sljit_jump *jump = NULL;  struct sljit_jump *jump = NULL;
3983  uschar *ccbegin = cc;  pcre_uchar *ccbegin = cc;
3984  int min = 0, max = 0;  int min = 0, max = 0;
3985  BOOL minimize;  BOOL minimize;
3986    
3987  PUSH_FALLBACK(sizeof(iterator_fallback), cc, NULL);  PUSH_FALLBACK(sizeof(iterator_fallback), cc, NULL);
3988    
3989  type = cc[3];  type = cc[1 + IMM2_SIZE];
3990  minimize = (type & 0x1) != 0;  minimize = (type & 0x1) != 0;
3991  switch(type)  switch(type)
3992    {    {
# Line 3391  switch(type) Line 3994  switch(type)
3994    case OP_CRMINSTAR:    case OP_CRMINSTAR:
3995    min = 0;    min = 0;
3996    max = 0;    max = 0;
3997    cc += 4;    cc += 1 + IMM2_SIZE + 1;
3998    break;    break;
3999    case OP_CRPLUS:    case OP_CRPLUS:
4000    case OP_CRMINPLUS:    case OP_CRMINPLUS:
4001    min = 1;    min = 1;
4002    max = 0;    max = 0;
4003    cc += 4;    cc += 1 + IMM2_SIZE + 1;
4004    break;    break;
4005    case OP_CRQUERY:    case OP_CRQUERY:
4006    case OP_CRMINQUERY:    case OP_CRMINQUERY:
4007    min = 0;    min = 0;
4008    max = 1;    max = 1;
4009    cc += 4;    cc += 1 + IMM2_SIZE + 1;
4010    break;    break;
4011    case OP_CRRANGE:    case OP_CRRANGE:
4012    case OP_CRMINRANGE:    case OP_CRMINRANGE:
4013    min = GET2(cc, 3 + 1);    min = GET2(cc, 1 + IMM2_SIZE + 1);
4014    max = GET2(cc, 3 + 3);    max = GET2(cc, 1 + IMM2_SIZE + 1 + IMM2_SIZE);
4015    cc += 8;    cc += 1 + IMM2_SIZE + 1 + 2 * IMM2_SIZE;
4016    break;    break;
4017    default:    default:
4018    SLJIT_ASSERT_STOP();    SLJIT_ASSERT_STOP();
# Line 3513  decrease_call_count(common); Line 4116  decrease_call_count(common);
4116  return cc;  return cc;
4117  }  }
4118    
4119  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)
4120  {  {
4121  DEFINE_COMPILER;  DEFINE_COMPILER;
4122  fallback_common *fallback;  fallback_common *fallback;
# Line 3546  if (entry == NULL) Line 4149  if (entry == NULL)
4149      common->entries = entry;      common->entries = entry;
4150    }    }
4151    
4152  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0));  if (common->has_set_som && common->mark_ptr != 0)
4153  allocate_stack(common, 1);    {
4154  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0);    OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0));
4155      allocate_stack(common, 2);
4156      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr);
4157      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0);
4158      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);
4159      }
4160    else if (common->has_set_som || common->mark_ptr != 0)
4161      {
4162      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->has_set_som ? (OVECTOR(0)) : common->mark_ptr);
4163      allocate_stack(common, 1);
4164      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0);
4165      }
4166    
4167  if (entry->entry == NULL)  if (entry->entry == NULL)
4168    add_jump(compiler, &entry->calls, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &entry->calls, JUMP(SLJIT_FAST_CALL));
# Line 3559  add_jump(compiler, &fallback->topfallbac Line 4173  add_jump(compiler, &fallback->topfallbac
4173  return cc + 1 + LINK_SIZE;  return cc + 1 + LINK_SIZE;
4174  }  }
4175    
4176  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)
4177  {  {
4178  DEFINE_COMPILER;  DEFINE_COMPILER;
4179  int framesize;  int framesize;
4180  int localptr;  int localptr;
4181  fallback_common altfallback;  fallback_common altfallback;
4182  uschar *ccbegin;  pcre_uchar *ccbegin;
4183  uschar opcode;  pcre_uchar opcode;
4184  uschar bra = OP_BRA;  pcre_uchar bra = OP_BRA;
4185  jump_list *tmp = NULL;  jump_list *tmp = NULL;
4186  jump_list **target = (conditional) ? &fallback->condfailed : &fallback->common.topfallbacks;  jump_list **target = (conditional) ? &fallback->condfailed : &fallback->common.topfallbacks;
4187  jump_list **found;  jump_list **found;
# Line 3583  if (*cc == OP_BRAZERO || *cc == OP_BRAMI Line 4197  if (*cc == OP_BRAZERO || *cc == OP_BRAMI
4197    bra = *cc;    bra = *cc;
4198    cc++;    cc++;
4199    }    }
4200  localptr = PRIV(cc);  localptr = PRIV_DATA(cc);
4201  SLJIT_ASSERT(localptr != 0);  SLJIT_ASSERT(localptr != 0);
4202  framesize = get_framesize(common, cc, FALSE);  framesize = get_framesize(common, cc, FALSE);
4203  fallback->framesize = framesize;  fallback->framesize = framesize;
# Line 3642  while (1) Line 4256  while (1)
4256    if (common->accept != NULL)    if (common->accept != NULL)
4257      set_jumps(common->accept, common->acceptlabel);      set_jumps(common->accept, common->acceptlabel);
4258    
4259      /* Reset stack. */
4260    if (framesize < 0)    if (framesize < 0)
4261      OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);      OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
4262      else {
4263        if ((opcode != OP_ASSERT_NOT && opcode != OP_ASSERTBACK_NOT) || conditional)
4264          {
4265          /* We don't need to keep the STR_PTR, only the previous localptr. */
4266          OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_IMM, (framesize + 1) * sizeof(sljit_w));
4267          }
4268        else
4269          {
4270          OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
4271          add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
4272          }
4273      }
4274    
4275    if (opcode == OP_ASSERT_NOT || opcode == OP_ASSERTBACK_NOT)    if (opcode == OP_ASSERT_NOT || opcode == OP_ASSERTBACK_NOT)
4276      {      {
4277      /* 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. */
4278      if (conditional)      if (conditional)
4279        {        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));  
         }  
       }  
4280      else if (bra == OP_BRAZERO)      else if (bra == OP_BRAZERO)
4281        {        {
4282        if (framesize < 0)        if (framesize < 0)
4283          OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), 0);          OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), 0);
4284        else        else
4285          {          {
         OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);  
         add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));  
4286          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));
4287          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));
4288          OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP1, 0);          OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP1, 0);
# Line 3673  while (1) Line 4290  while (1)
4290        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));
4291        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
4292        }        }
4293      else if (bra == OP_BRAMINZERO)      else if (framesize >= 0)
4294        {        {
4295        if (framesize >= 0)        /* For OP_BRA and OP_BRAMINZERO. */
4296          {        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));  
         }  
4297        }        }
4298      }      }
4299    add_jump(compiler, found, JUMP(SLJIT_JUMP));    add_jump(compiler, found, JUMP(SLJIT_JUMP));
# Line 3707  if (opcode == OP_ASSERT || opcode == OP_ Line 4320  if (opcode == OP_ASSERT || opcode == OP_
4320    /* Assert is failed. */    /* Assert is failed. */
4321    if (conditional || bra == OP_BRAZERO)    if (conditional || bra == OP_BRAZERO)
4322      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
4323    
4324    if (framesize < 0)    if (framesize < 0)
4325      {      {
4326      /* The topmost item should be 0. */      /* The topmost item should be 0. */
# Line 3718  if (opcode == OP_ASSERT || opcode == OP_ Line 4332  if (opcode == OP_ASSERT || opcode == OP_
4332    else    else
4333      {      {
4334      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));  
4335      /* The topmost item should be 0. */      /* The topmost item should be 0. */
4336      if (bra == OP_BRAZERO)      if (bra == OP_BRAZERO)
4337        {        {
# Line 3729  if (opcode == OP_ASSERT || opcode == OP_ Line 4341  if (opcode == OP_ASSERT || opcode == OP_
4341      else      else
4342        free_stack(common, framesize + 2);        free_stack(common, framesize + 2);
4343      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);  
4344      }      }
4345    jump = JUMP(SLJIT_JUMP);    jump = JUMP(SLJIT_JUMP);
4346    if (bra != OP_BRAZERO)    if (bra != OP_BRAZERO)
# Line 3753  if (opcode == OP_ASSERT || opcode == OP_ Line 4363  if (opcode == OP_ASSERT || opcode == OP_
4363      }      }
4364    else    else
4365      {      {
4366      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);      if (bra == OP_BRA)
     OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(TMP1), (framesize + 1) * sizeof(sljit_w));  
     if (bra == OP_BRAZERO)  
4367        {        {
4368        allocate_stack(common, 1);        /* We don't need to keep the STR_PTR, only the previous localptr. */
4369        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);        OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_IMM, (framesize + 1) * sizeof(sljit_w));
4370          OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), 0);
4371        }        }
4372      else if (bra == OP_BRAMINZERO)      else
4373        {        {
4374        allocate_stack(common, 1);        /* We don't need to keep the STR_PTR, only the previous localptr. */
4375        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));
4376          OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
4377          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), bra == OP_BRAZERO ? STR_PTR : SLJIT_IMM, 0);
4378        }        }
4379      }      }
4380    
# Line 3800  else Line 4411  else
4411      {      {
4412      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
4413      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));  
4414      /* The topmost item should be 0. */      /* The topmost item should be 0. */
4415      if (bra != OP_BRA)      if (bra != OP_BRA)
4416        {        {
# Line 3811  else Line 4420  else
4420      else      else
4421        free_stack(common, framesize + 2);        free_stack(common, framesize + 2);
4422      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);  
4423      }      }
4424    
4425    if (bra == OP_BRAZERO)    if (bra == OP_BRAZERO)
# Line 3836  common->accept = save_accept; Line 4443  common->accept = save_accept;
4443  return cc + 1 + LINK_SIZE;  return cc + 1 + LINK_SIZE;
4444  }  }
4445    
4446    static sljit_w SLJIT_CALL do_searchovector(sljit_w refno, sljit_w* locals, pcre_uchar *name_table)
4447    {
4448    int condition = FALSE;
4449    pcre_uchar *slotA = name_table;
4450    pcre_uchar *slotB;
4451    sljit_w name_count = locals[LOCALS0 / sizeof(sljit_w)];
4452    sljit_w name_entry_size = locals[LOCALS1 / sizeof(sljit_w)];
4453    sljit_w no_capture;
4454    int i;
4455    
4456    locals += refno & 0xff;
4457    refno >>= 8;
4458    no_capture = locals[1];
4459    
4460    for (i = 0; i < name_count; i++)
4461      {
4462      if (GET2(slotA, 0) == refno) break;
4463      slotA += name_entry_size;
4464      }
4465    
4466    if (i < name_count)
4467      {
4468      /* Found a name for the number - there can be only one; duplicate names
4469      for different numbers are allowed, but not vice versa. First scan down
4470      for duplicates. */
4471    
4472      slotB = slotA;
4473      while (slotB > name_table)
4474        {
4475        slotB -= name_entry_size;
4476        if (STRCMP_UC_UC(slotA + IMM2_SIZE, slotB + IMM2_SIZE) == 0)
4477          {
4478          condition = locals[GET2(slotB, 0) << 1] != no_capture;
4479          if (condition) break;
4480          }
4481        else break;
4482        }
4483    
4484      /* Scan up for duplicates */
4485      if (!condition)
4486        {
4487        slotB = slotA;
4488        for (i++; i < name_count; i++)
4489          {
4490          slotB += name_entry_size;
4491          if (STRCMP_UC_UC(slotA + IMM2_SIZE, slotB + IMM2_SIZE) == 0)
4492            {
4493            condition = locals[GET2(slotB, 0) << 1] != no_capture;
4494            if (condition) break;
4495            }
4496          else break;
4497          }
4498        }
4499      }
4500    return condition;
4501    }
4502    
4503    static sljit_w SLJIT_CALL do_searchgroups(sljit_w recno, sljit_w* locals, pcre_uchar *name_table)
4504    {
4505    int condition = FALSE;
4506    pcre_uchar *slotA = name_table;
4507    pcre_uchar *slotB;
4508    sljit_w name_count = locals[LOCALS0 / sizeof(sljit_w)];
4509    sljit_w name_entry_size = locals[LOCALS1 / sizeof(sljit_w)];
4510    sljit_w group_num = locals[POSSESSIVE0 / sizeof(sljit_w)];
4511    int i;
4512    
4513    for (i = 0; i < name_count; i++)
4514      {
4515      if (GET2(slotA, 0) == recno) break;
4516      slotA += name_entry_size;
4517      }
4518    
4519    if (i < name_count)
4520      {
4521      /* Found a name for the number - there can be only one; duplicate
4522      names for different numbers are allowed, but not vice versa. First
4523      scan down for duplicates. */
4524    
4525      slotB = slotA;
4526      while (slotB > name_table)
4527        {
4528        slotB -= name_entry_size;
4529        if (STRCMP_UC_UC(slotA + IMM2_SIZE, slotB + IMM2_SIZE) == 0)
4530          {
4531          condition = GET2(slotB, 0) == group_num;
4532          if (condition) break;
4533          }
4534        else break;
4535        }
4536    
4537      /* Scan up for duplicates */
4538      if (!condition)
4539        {
4540        slotB = slotA;
4541        for (i++; i < name_count; i++)
4542          {
4543          slotB += name_entry_size;
4544          if (STRCMP_UC_UC(slotA + IMM2_SIZE, slotB + IMM2_SIZE) == 0)
4545            {
4546            condition = GET2(slotB, 0) == group_num;
4547            if (condition) break;
4548            }
4549          else break;
4550          }
4551        }
4552      }
4553    return condition;
4554    }
4555    
4556  /*  /*
4557    Handling bracketed expressions is probably the most complex part.    Handling bracketed expressions is probably the most complex part.
4558    
# Line 3845  return cc + 1 + LINK_SIZE; Line 4562  return cc + 1 + LINK_SIZE;
4562      A - Push the current STR_PTR. Needed for restoring the STR_PTR      A - Push the current STR_PTR. Needed for restoring the STR_PTR
4563          before the next alternative. Not pushed if there are no alternatives.          before the next alternative. Not pushed if there are no alternatives.
4564      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.
4565      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.
4566      L - Push the previous local (pointed by localptr) to the stack      L - Push the previous local (pointed by localptr) to the stack
4567     () - opional values stored on the stack     () - opional values stored on the stack
4568    ()* - optonal, can be stored multiple times    ()* - optonal, can be stored multiple times
# Line 3883  return cc + 1 + LINK_SIZE; Line 4600  return cc + 1 + LINK_SIZE;
4600      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.
4601    
4602    The next list shows the possible content of a bracket:    The next list shows the possible content of a bracket:
4603    (|)     OP_*BRA  | OP_ALT ...         M A    (|)     OP_*BRA    | OP_ALT ...         M A
4604    (?()|)  OP_*COND | OP_ALT             M A    (?()|)  OP_*COND   | OP_ALT             M A
4605    (?>|)   OP_ONCE  | OP_ALT ...         [stack trace] M A    (?>|)   OP_ONCE    | OP_ALT ...         [stack trace] M A
4606                                          Or nothing, if trace is unnecessary    (?>|)   OP_ONCE_NC | OP_ALT ...         [stack trace] M A
4607                                              Or nothing, if trace is unnecessary
4608  */  */
4609    
4610  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)
4611  {  {
4612  DEFINE_COMPILER;  DEFINE_COMPILER;
4613  fallback_common *fallback;  fallback_common *fallback;
4614  uschar opcode;  pcre_uchar opcode;
4615  int localptr = 0;  int localptr = 0;
4616  int offset = 0;  int offset = 0;
4617  int stacksize;  int stacksize;
4618  uschar *ccbegin;  pcre_uchar *ccbegin;
4619  uschar *hotpath;  pcre_uchar *hotpath;
4620  uschar bra = OP_BRA;  pcre_uchar bra = OP_BRA;
4621  uschar ket;  pcre_uchar ket;
4622  assert_fallback *assert;  assert_fallback *assert;
4623  BOOL has_alternatives;  BOOL has_alternatives;
4624  struct sljit_jump *jump;  struct sljit_jump *jump;
# Line 3919  if (*cc == OP_BRAZERO || *cc == OP_BRAMI Line 4637  if (*cc == OP_BRAZERO || *cc == OP_BRAMI
4637    
4638  opcode = *cc;  opcode = *cc;
4639  ccbegin = cc;  ccbegin = cc;
4640    hotpath = ccbegin + 1 + LINK_SIZE;
4641    
4642  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)
4643    {    {
4644    /* Drop this bracket_fallback. */    /* Drop this bracket_fallback. */
# Line 3930  ket = *(bracketend(cc) - 1 - LINK_SIZE); Line 4650  ket = *(bracketend(cc) - 1 - LINK_SIZE);
4650  SLJIT_ASSERT(ket == OP_KET || ket == OP_KETRMAX || ket == OP_KETRMIN);  SLJIT_ASSERT(ket == OP_KET || ket == OP_KETRMAX || ket == OP_KETRMIN);
4651  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)));
4652  cc += GET(cc, 1);  cc += GET(cc, 1);
4653  has_alternatives = *cc == OP_ALT || opcode == OP_COND || opcode == OP_SCOND;  
4654    has_alternatives = *cc == OP_ALT;
4655    if (SLJIT_UNLIKELY(opcode == OP_COND) || SLJIT_UNLIKELY(opcode == OP_SCOND))
4656      {
4657      has_alternatives = (*hotpath == OP_RREF) ? FALSE : TRUE;
4658      if (*hotpath == OP_NRREF)
4659        {
4660        stacksize = GET2(hotpath, 1);
4661        if (common->currententry == NULL || stacksize == RREF_ANY)
4662          has_alternatives = FALSE;
4663        else if (common->currententry->start == 0)
4664          has_alternatives = stacksize != 0;
4665        else
4666          has_alternatives = stacksize != GET2(common->start, common->currententry->start + 1 + LINK_SIZE);
4667        }
4668      }
4669    
4670  if (SLJIT_UNLIKELY(opcode == OP_COND) && (*cc == OP_KETRMAX || *cc == OP_KETRMIN))  if (SLJIT_UNLIKELY(opcode == OP_COND) && (*cc == OP_KETRMAX || *cc == OP_KETRMIN))
4671    opcode = OP_SCOND;    opcode = OP_SCOND;
4672    if (SLJIT_UNLIKELY(opcode == OP_ONCE_NC))
4673      opcode = OP_ONCE;
4674    
4675  if (opcode == OP_CBRA || opcode == OP_SCBRA)  if (opcode == OP_CBRA || opcode == OP_SCBRA)
4676    {    {
# Line 3941  if (opcode == OP_CBRA || opcode == OP_SC Line 4679  if (opcode == OP_CBRA || opcode == OP_SC
4679    localptr = OVECTOR_PRIV(offset);    localptr = OVECTOR_PRIV(offset);
4680    offset <<= 1;    offset <<= 1;
4681    FALLBACK_AS(bracket_fallback)->localptr = localptr;    FALLBACK_AS(bracket_fallback)->localptr = localptr;
4682      hotpath += IMM2_SIZE;
4683    }    }
4684  else if (opcode == OP_ONCE || opcode == OP_SBRA || opcode == OP_SCOND)  else if (opcode == OP_ONCE || opcode == OP_SBRA || opcode == OP_SCOND)
4685    {    {
4686    /* Other brackets simply allocate the next entry. */    /* Other brackets simply allocate the next entry. */
4687    localptr = PRIV(ccbegin);    localptr = PRIV_DATA(ccbegin);
4688    SLJIT_ASSERT(localptr != 0);    SLJIT_ASSERT(localptr != 0);
4689    FALLBACK_AS(bracket_fallback)->localptr = localptr;    FALLBACK_AS(bracket_fallback)->localptr = localptr;
4690    if (opcode == OP_ONCE)    if (opcode == OP_ONCE)
# Line 4072  if (opcode == OP_ONCE) Line 4811  if (opcode == OP_ONCE)
4811  else if (opcode == OP_CBRA || opcode == OP_SCBRA)  else if (opcode == OP_CBRA || opcode == OP_SCBRA)
4812    {    {
4813    /* Saving the previous values. */    /* Saving the previous values. */
4814    allocate_stack(common, 4);    allocate_stack(common, 3);
4815    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));
4816    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));
4817    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0);
4818    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0);
4819    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);  
4820    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, STR_PTR, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, STR_PTR, 0);
4821    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));  
4822    }    }
4823  else if (opcode == OP_SBRA || opcode == OP_SCOND)  else if (opcode == OP_SBRA || opcode == OP_SCOND)
4824    {    {
# Line 4100  else if (has_alternatives) Line 4836  else if (has_alternatives)
4836    }    }
4837    
4838  /* Generating code for the first alternative. */  /* Generating code for the first alternative. */
 hotpath = ccbegin + 1 + LINK_SIZE;  
 if (offset != 0)  
   hotpath += 2;  
4839  if (opcode == OP_COND || opcode == OP_SCOND)  if (opcode == OP_COND || opcode == OP_SCOND)
4840    {    {
4841    if (*hotpath == OP_CREF)    if (*hotpath == OP_CREF)