/[pcre]/code/branches/pcre16/pcre_jit_compile.c
ViewVC logotype

Diff of /code/branches/pcre16/pcre_jit_compile.c

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

code/trunk/pcre_jit_compile.c revision 715 by zherczeg, Sat Oct 1 06:42:38 2011 UTC code/branches/pcre16/pcre_jit_compile.c revision 763 by zherczeg, Tue Nov 22 21:46:22 2011 UTC
# 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) (pcre_malloc)(size)
56    #define SLJIT_FREE(ptr) (pcre_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    
# Line 149  typedef struct jit_arguments { Line 152  typedef struct jit_arguments {
152    PCRE_SPTR begin;    PCRE_SPTR begin;
153    PCRE_SPTR end;    PCRE_SPTR end;
154    int *offsets;    int *offsets;
155    uschar *ptr;    pcre_uchar *ptr;
156    /* Everything else after. */    /* Everything else after. */
157    int offsetcount;    int offsetcount;
158    int calllimit;    int calllimit;
159    uschar notbol;    pcre_uint8 notbol;
160    uschar noteol;    pcre_uint8 noteol;
161    uschar notempty;    pcre_uint8 notempty;
162    uschar notempty_atstart;    pcre_uint8 notempty_atstart;
163  } jit_arguments;  } jit_arguments;
164    
165  typedef struct executable_function {  typedef struct executable_function {
# Line 194  typedef struct fallback_common { Line 197  typedef struct fallback_common {
197    struct fallback_common *top;    struct fallback_common *top;
198    jump_list *topfallbacks;    jump_list *topfallbacks;
199    /* Opcode pointer. */    /* Opcode pointer. */
200    uschar *cc;    pcre_uchar *cc;
201  } fallback_common;  } fallback_common;
202    
203  typedef struct assert_fallback {  typedef struct assert_fallback {
# Line 265  typedef struct recurse_fallback { Line 268  typedef struct recurse_fallback {
268    
269  typedef struct compiler_common {  typedef struct compiler_common {
270    struct sljit_compiler *compiler;    struct sljit_compiler *compiler;
271    uschar *start;    pcre_uchar *start;
272    int localsize;    int localsize;
273    int *localptrs;    int *localptrs;
274    const uschar *fcc;    const pcre_uint8 *fcc;
275    sljit_w lcc;    sljit_w lcc;
276    int cbraptr;    int cbraptr;
277    int nltype;    int nltype;
# Line 276  typedef struct compiler_common { Line 279  typedef struct compiler_common {
279    int bsr_nltype;    int bsr_nltype;
280    int endonly;    int endonly;
281    sljit_w ctypes;    sljit_w ctypes;
282      sljit_uw name_table;
283      sljit_w name_count;
284      sljit_w name_entry_size;
285    struct sljit_label *acceptlabel;    struct sljit_label *acceptlabel;
286    stub_list *stubs;    stub_list *stubs;
287    recurse_entry *entries;    recurse_entry *entries;
# Line 352  enum { Line 358  enum {
358  /* Two local variables for possessive quantifiers (char1 cannot use them). */  /* Two local variables for possessive quantifiers (char1 cannot use them). */
359  #define POSSESSIVE0      (2 * sizeof(sljit_w))  #define POSSESSIVE0      (2 * sizeof(sljit_w))
360  #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))  
361  /* Head of the last recursion. */  /* Head of the last recursion. */
362  #define RECURSIVE_HEAD   (5 * sizeof(sljit_w))  #define RECURSIVE_HEAD   (4 * sizeof(sljit_w))
363  /* Max limit of recursions. */  /* Max limit of recursions. */
364  #define CALL_LIMIT       (7 * sizeof(sljit_w))  #define CALL_LIMIT       (5 * sizeof(sljit_w))
365  /* Last known position of the requested byte. */  /* Last known position of the requested byte. */
366  #define REQ_BYTE_PTR     (8 * sizeof(sljit_w))  #define REQ_BYTE_PTR     (6 * sizeof(sljit_w))
367  /* End pointer of the first line. */  /* End pointer of the first line. */
368  #define FIRSTLINE_END    (9 * sizeof(sljit_w))  #define FIRSTLINE_END    (7 * sizeof(sljit_w))
369  /* The output vector is stored on the stack, and contains pointers  /* The output vector is stored on the stack, and contains pointers
370  to characters. The vector data is divided into two groups: the first  to characters. The vector data is divided into two groups: the first
371  group contains the start / end character pointers, and the second is  group contains the start / end character pointers, and the second is
372  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. */
373  #define OVECTOR_START    (10 * sizeof(sljit_w))  #define OVECTOR_START    (8 * sizeof(sljit_w))
374  #define OVECTOR(i)       (OVECTOR_START + (i) * sizeof(sljit_w))  #define OVECTOR(i)       (OVECTOR_START + (i) * sizeof(sljit_w))
375  #define OVECTOR_PRIV(i)  (common->cbraptr + (i) * sizeof(sljit_w))  #define OVECTOR_PRIV(i)  (common->cbraptr + (i) * sizeof(sljit_w))
376  #define PRIV(cc)         (common->localptrs[(cc) - common->start])  #define PRIV(cc)         (common->localptrs[(cc) - common->start])
# Line 393  the start pointers when the end of the c Line 397  the start pointers when the end of the c
397  #define COND_VALUE(op, dst, dstw, type) \  #define COND_VALUE(op, dst, dstw, type) \
398    sljit_emit_cond_value(compiler, (op), (dst), (dstw), (type))    sljit_emit_cond_value(compiler, (op), (dst), (dstw), (type))
399    
400  static uschar* bracketend(uschar* cc)  static pcre_uchar* bracketend(pcre_uchar* cc)
401  {  {
402  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));
403  do cc += GET(cc, 1); while (*cc == OP_ALT);  do cc += GET(cc, 1); while (*cc == OP_ALT);
# Line 414  return cc; Line 418  return cc;
418   compile_fallbackpath   compile_fallbackpath
419  */  */
420    
421  static uschar *next_opcode(compiler_common *common, uschar *cc)  static pcre_uchar *next_opcode(compiler_common *common, pcre_uchar *cc)
422  {  {
423  SLJIT_UNUSED_ARG(common);  SLJIT_UNUSED_ARG(common);
424  switch(*cc)  switch(*cc)
# Line 469  switch(*cc) Line 473  switch(*cc)
473    case OP_SKIPZERO:    case OP_SKIPZERO:
474    return cc + 1;    return cc + 1;
475    
476      case OP_ANYBYTE:
477    #ifdef SUPPORT_UTF8
478      if (common->utf8) return NULL;
479    #endif
480      return cc + 1;
481    
482    case OP_CHAR:    case OP_CHAR:
483    case OP_CHARI:    case OP_CHARI:
484    case OP_NOT:    case OP_NOT:
# Line 547  switch(*cc) Line 557  switch(*cc)
557    case OP_REF:    case OP_REF:
558    case OP_REFI:    case OP_REFI:
559    case OP_CREF:    case OP_CREF:
560      case OP_NCREF:
561      case OP_RREF:
562      case OP_NRREF:
563    case OP_CLOSE:    case OP_CLOSE:
564    cc += 3;    cc += 3;
565    return cc;    return cc;
# Line 571  switch(*cc) Line 584  switch(*cc)
584    case OP_ASSERTBACK_NOT:    case OP_ASSERTBACK_NOT:
585    case OP_REVERSE:    case OP_REVERSE:
586    case OP_ONCE:    case OP_ONCE:
587      case OP_ONCE_NC:
588    case OP_BRA:    case OP_BRA:
589    case OP_BRAPOS:    case OP_BRAPOS:
590    case OP_COND:    case OP_COND:
# Line 595  switch(*cc) Line 609  switch(*cc)
609    }    }
610  }  }
611    
612  static int get_localspace(compiler_common *common, uschar *cc, uschar *ccend)  static int get_localspace(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend)
613  {  {
614  int localspace = 0;  int localspace = 0;
615  uschar *alternative;  pcre_uchar *alternative;
616  /* 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. */
617  while (cc < ccend)  while (cc < ccend)
618    {    {
# Line 609  while (cc < ccend) Line 623  while (cc < ccend)
623      case OP_ASSERTBACK:      case OP_ASSERTBACK:
624      case OP_ASSERTBACK_NOT:      case OP_ASSERTBACK_NOT:
625      case OP_ONCE:      case OP_ONCE:
626        case OP_ONCE_NC:
627      case OP_BRAPOS:      case OP_BRAPOS:
628      case OP_SBRA:      case OP_SBRA:
629      case OP_SBRAPOS:      case OP_SBRAPOS:
# Line 641  while (cc < ccend) Line 656  while (cc < ccend)
656  return localspace;  return localspace;
657  }  }
658    
659  static void set_localptrs(compiler_common *common, int localptr, uschar *ccend)  static void set_localptrs(compiler_common *common, int localptr, pcre_uchar *ccend)
660  {  {
661  uschar *cc = common->start;  pcre_uchar *cc = common->start;
662  uschar *alternative;  pcre_uchar *alternative;
663  while (cc < ccend)  while (cc < ccend)
664    {    {
665    switch(*cc)    switch(*cc)
# Line 654  while (cc < ccend) Line 669  while (cc < ccend)
669      case OP_ASSERTBACK:      case OP_ASSERTBACK:
670      case OP_ASSERTBACK_NOT:      case OP_ASSERTBACK_NOT:
671      case OP_ONCE:      case OP_ONCE:
672        case OP_ONCE_NC:
673      case OP_BRAPOS:      case OP_BRAPOS:
674      case OP_SBRA:      case OP_SBRA:
675      case OP_SBRAPOS:      case OP_SBRAPOS:
# Line 690  while (cc < ccend) Line 706  while (cc < ccend)
706  }  }
707    
708  /* Returns with -1 if no need for frame. */  /* Returns with -1 if no need for frame. */
709  static int get_framesize(compiler_common *common, uschar *cc, BOOL recursive)  static int get_framesize(compiler_common *common, pcre_uchar *cc, BOOL recursive)
710  {  {
711  uschar *ccend = bracketend(cc);  pcre_uchar *ccend = bracketend(cc);
 uschar *end;  
712  int length = 0;  int length = 0;
713  BOOL possessive = FALSE;  BOOL possessive = FALSE;
 BOOL needs_frame = FALSE;  
714  BOOL setsom_found = FALSE;  BOOL setsom_found = FALSE;
715    
716  if (!recursive && (*cc == OP_CBRAPOS || *cc == OP_SCBRAPOS))  if (!recursive && (*cc == OP_CBRAPOS || *cc == OP_SCBRAPOS))
# Line 720  while (cc < ccend) Line 734  while (cc < ccend)
734      cc += (*cc == OP_SET_SOM) ? 1 : 1 + LINK_SIZE;      cc += (*cc == OP_SET_SOM) ? 1 : 1 + LINK_SIZE;
735      break;      break;
736    
     case OP_ASSERT:  
     case OP_ASSERT_NOT:  
     case OP_ASSERTBACK:  
     case OP_ASSERTBACK_NOT:  
     case OP_ONCE:  
     if (needs_frame || length > 0)  
       {  
       cc = bracketend(cc);  
       break;  
       }  
     /* Check whether a frame must be created. */  
     end = bracketend(cc);  
     while (cc < end)  
       {  
       if (*cc == OP_SET_SOM || *cc == OP_CBRA || *cc == OP_CBRAPOS  
           || *cc == OP_SCBRA || *cc == OP_SCBRAPOS || *cc == OP_RECURSE)  
         needs_frame = TRUE;  
       cc = next_opcode(common, cc);  
       SLJIT_ASSERT(cc != NULL);  
       }  
     break;  
   
737      case OP_CBRA:      case OP_CBRA:
738      case OP_CBRAPOS:      case OP_CBRAPOS:
739      case OP_SCBRA:      case OP_SCBRA:
# Line 757  while (cc < ccend) Line 749  while (cc < ccend)
749      }      }
750    
751  /* Possessive quantifiers can use a special case. */  /* Possessive quantifiers can use a special case. */
752  if (SLJIT_UNLIKELY(possessive) && !needs_frame && length == 3 + 2)  if (SLJIT_UNLIKELY(possessive) && length == 3)
753    return -1;    return -1;
754    
755  if (length > 0)  if (length > 0)
756    return length + 2;    return length + 1;
757  return needs_frame ? 0 : -1;  return -1;
758  }  }
759    
760  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)
761  {  {
 /* TMP2 must contain STACK_TOP - (-STACK(stackpos)) */  
762  DEFINE_COMPILER;  DEFINE_COMPILER;
763  uschar *ccend = bracketend(cc);  pcre_uchar *ccend = bracketend(cc);
764  BOOL setsom_found = FALSE;  BOOL setsom_found = FALSE;
765  int offset;  int offset;
766    
767  if (stackpos < stacktop)  /* >= 1 + shortest item size (2) */
768    {  SLJIT_ASSERT(stackpos >= stacktop + 2);
   SLJIT_ASSERT(stackpos + 1 == stacktop);  
   return;  
   }  
769    
770  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);  
   
771  if (recursive || (*cc != OP_CBRAPOS && *cc != OP_SCBRAPOS))  if (recursive || (*cc != OP_CBRAPOS && *cc != OP_SCBRAPOS))
772    cc = next_opcode(common, cc);    cc = next_opcode(common, cc);
773  SLJIT_ASSERT(cc != NULL);  SLJIT_ASSERT(cc != NULL);
# Line 804  while (cc < ccend) Line 788  while (cc < ccend)
788      cc += (*cc == OP_SET_SOM) ? 1 : 1 + LINK_SIZE;      cc += (*cc == OP_SET_SOM) ? 1 : 1 + LINK_SIZE;
789      break;      break;
790    
     case OP_ASSERT:  
     case OP_ASSERT_NOT:  
     case OP_ASSERTBACK:  
     case OP_ASSERTBACK_NOT:  
     case OP_ONCE:  
     cc = bracketend(cc);  
     break;  
   
791      case OP_CBRA:      case OP_CBRA:
792      case OP_CBRAPOS:      case OP_CBRAPOS:
793      case OP_SCBRA:      case OP_SCBRA:
# Line 836  while (cc < ccend) Line 812  while (cc < ccend)
812      }      }
813    
814  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, frame_end);  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, frame_end);
815  SLJIT_ASSERT(stackpos == STACK(stacktop + 1));  SLJIT_ASSERT(stackpos == STACK(stacktop));
816  }  }
817    
818  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)
819  {  {
820  int localsize = 2;  int localsize = 2;
821  uschar *alternative;  pcre_uchar *alternative;
822  /* Calculate the sum of the local variables. */  /* Calculate the sum of the local variables. */
823  while (cc < ccend)  while (cc < ccend)
824    {    {
# Line 853  while (cc < ccend) Line 829  while (cc < ccend)
829      case OP_ASSERTBACK:      case OP_ASSERTBACK:
830      case OP_ASSERTBACK_NOT:      case OP_ASSERTBACK_NOT:
831      case OP_ONCE:      case OP_ONCE:
832        case OP_ONCE_NC:
833      case OP_BRAPOS:      case OP_BRAPOS:
834      case OP_SBRA:      case OP_SBRA:
835      case OP_SBRAPOS:      case OP_SBRAPOS:
# Line 891  SLJIT_ASSERT(cc == ccend); Line 868  SLJIT_ASSERT(cc == ccend);
868  return localsize;  return localsize;
869  }  }
870    
871  static void copy_locals(compiler_common *common, uschar *cc, uschar *ccend,  static void copy_locals(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend,
872    BOOL save, int stackptr, int stacktop)    BOOL save, int stackptr, int stacktop)
873  {  {
874  DEFINE_COMPILER;  DEFINE_COMPILER;
# Line 900  int count; Line 877  int count;
877  BOOL tmp1next = TRUE;  BOOL tmp1next = TRUE;
878  BOOL tmp1empty = TRUE;  BOOL tmp1empty = TRUE;
879  BOOL tmp2empty = TRUE;  BOOL tmp2empty = TRUE;
880  uschar *alternative;  pcre_uchar *alternative;
881  enum {  enum {
882    start,    start,
883    loop,    loop,
# Line 955  while (status != end) Line 932  while (status != end)
932        case OP_ASSERTBACK:        case OP_ASSERTBACK:
933        case OP_ASSERTBACK_NOT:        case OP_ASSERTBACK_NOT:
934        case OP_ONCE:        case OP_ONCE:
935          case OP_ONCE_NC:
936        case OP_BRAPOS:        case OP_BRAPOS:
937        case OP_SBRA:        case OP_SBRA:
938        case OP_SBRAPOS:        case OP_SBRAPOS:
# Line 1255  else Line 1233  else
1233    OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, 1);    OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, 1);
1234  }  }
1235    
1236  static SLJIT_INLINE BOOL char_has_othercase(compiler_common *common, uschar* cc)  static SLJIT_INLINE BOOL char_has_othercase(compiler_common *common, pcre_uchar* cc)
1237  {  {
1238  /* Detects if the character has an othercase. */  /* Detects if the character has an othercase. */
1239  unsigned int c;  unsigned int c;
# Line 1295  if (common->utf8 && c > 127) Line 1273  if (common->utf8 && c > 127)
1273  return common->fcc[c];  return common->fcc[c];
1274  }  }
1275    
1276  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)
1277  {  {
1278  /* Detects if the character and its othercase has only 1 bit difference. */  /* Detects if the character and its othercase has only 1 bit difference. */
1279  unsigned int c, oc, bit;  unsigned int c, oc, bit;
# Line 1373  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(ST Line 1351  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(ST
1351  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF8
1352  if (common->utf8)  if (common->utf8)
1353    {    {
1354    /* Should not found a value between 128 and 192 here. */    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);
   jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 192);  
1355    add_jump(compiler, &common->utf8readchar, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->utf8readchar, JUMP(SLJIT_FAST_CALL));
1356    JUMPHERE(jump);    JUMPHERE(jump);
1357    }    }
# Line 1395  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(ST Line 1372  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(ST
1372  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF8
1373  if (common->utf8)  if (common->utf8)
1374    {    {
1375    /* Should not found a value between 128 and 192 here. */    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);
   jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 192);  
1376    add_jump(compiler, &common->utf8readchar, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->utf8readchar, JUMP(SLJIT_FAST_CALL));
1377    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
1378    JUMPHERE(jump);    JUMPHERE(jump);
# Line 1420  if (common->utf8) Line 1396  if (common->utf8)
1396    /* This can be an extra read in some situations, but hopefully    /* This can be an extra read in some situations, but hopefully
1397    it is a clever early read in most cases. */    it is a clever early read in most cases. */
1398    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);
1399    /* Should not found a value between 128 and 192 here. */    jump = CMP(SLJIT_C_LESS, TMP2, 0, SLJIT_IMM, 0xc0);
   jump = CMP(SLJIT_C_LESS, TMP2, 0, SLJIT_IMM, 192);  
1400    add_jump(compiler, &common->utf8readtype8, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->utf8readtype8, JUMP(SLJIT_FAST_CALL));
1401    JUMPHERE(jump);    JUMPHERE(jump);
1402    return;    return;
# Line 1481  else Line 1456  else
1456  static void do_utf8readchar(compiler_common *common)  static void do_utf8readchar(compiler_common *common)
1457  {  {
1458  /* Fast decoding an utf8 character. TMP1 contains the first byte  /* Fast decoding an utf8 character. TMP1 contains the first byte
1459  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. */
1460  DEFINE_COMPILER;  DEFINE_COMPILER;
1461  struct sljit_jump *jump;  struct sljit_jump *jump;
1462    
# Line 1564  sljit_emit_fast_return(compiler, RETURN_ Line 1539  sljit_emit_fast_return(compiler, RETURN_
1539  static void do_utf8readtype8(compiler_common *common)  static void do_utf8readtype8(compiler_common *common)
1540  {  {
1541  /* Fast decoding an utf8 character type. TMP2 contains the first byte  /* Fast decoding an utf8 character type. TMP2 contains the first byte
1542  of the character (>= 192) and TMP1 is destroyed. Return value in TMP1. */  of the character (>= 0xc0) and TMP1 is destroyed. Return value in TMP1. */
1543  DEFINE_COMPILER;  DEFINE_COMPILER;
1544  struct sljit_jump *jump;  struct sljit_jump *jump;
1545  struct sljit_jump *compare;  struct sljit_jump *compare;
# Line 1590  sljit_emit_fast_return(compiler, RETURN_ Line 1565  sljit_emit_fast_return(compiler, RETURN_
1565  JUMPHERE(jump);  JUMPHERE(jump);
1566    
1567  /* We only have types for characters less than 256. */  /* We only have types for characters less than 256. */
1568  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)_pcre_utf8_table4 - 0xc0);
 OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);  
1569  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
1570  OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);  OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);
1571  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
# Line 1635  struct sljit_label *newlinelabel = NULL; Line 1609  struct sljit_label *newlinelabel = NULL;
1609  struct sljit_jump *start;  struct sljit_jump *start;
1610  struct sljit_jump *end = NULL;  struct sljit_jump *end = NULL;
1611  struct sljit_jump *nl = NULL;  struct sljit_jump *nl = NULL;
1612    #ifdef SUPPORT_UTF8
1613    struct sljit_jump *singlebyte;
1614    #endif
1615  jump_list *newline = NULL;  jump_list *newline = NULL;
1616  BOOL newlinecheck = FALSE;  BOOL newlinecheck = FALSE;
1617  BOOL readbyte = FALSE;  BOOL readbyte = FALSE;
# Line 1705  if (readbyte) Line 1682  if (readbyte)
1682  if (newlinecheck)  if (newlinecheck)
1683    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);
1684    
1685    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 1);
1686  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF8
1687  if (common->utf8)  if (common->utf8)
1688    {    {
1689    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)_pcre_utf8_char_sizes);    singlebyte = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);
1690      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)_pcre_utf8_table4 - 0xc0);
1691    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
1692      JUMPHERE(singlebyte);
1693    }    }
 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);  
1694  #endif  #endif
1695  JUMPHERE(start);  JUMPHERE(start);
1696    
# Line 1767  else Line 1743  else
1743      }      }
1744    }    }
1745    
1746    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 1);
1747  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF8
1748  if (common->utf8)  if (common->utf8)
1749    {    {
1750    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);
1751      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)_pcre_utf8_table4 - 0xc0);
1752    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
1753    }    }
 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);  
1754  #endif  #endif
1755  JUMPTO(SLJIT_JUMP, start);  JUMPTO(SLJIT_JUMP, start);
1756  JUMPHERE(found);  JUMPHERE(found);
# Line 1883  leave = CMP(SLJIT_C_GREATER_EQUAL, STR_P Line 1857  leave = CMP(SLJIT_C_GREATER_EQUAL, STR_P
1857  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
1858  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF8
1859  if (common->utf8)  if (common->utf8)
1860    OP1(SLJIT_MOV_UB, TMP3, 0, SLJIT_MEM1(TMP1), (sljit_w)_pcre_utf8_char_sizes);    OP1(SLJIT_MOV, TMP3, 0, TMP1, 0);
1861  #endif  #endif
1862  OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);  OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);
1863  OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);  OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);
# Line 1894  found = JUMP(SLJIT_C_NOT_ZERO); Line 1868  found = JUMP(SLJIT_C_NOT_ZERO);
1868    
1869  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF8
1870  if (common->utf8)  if (common->utf8)
1871    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP3, 0);    OP1(SLJIT_MOV, TMP1, 0, TMP3, 0);
1872  else  #endif
   OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 1);  
 #else  
1873  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 1);  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 1);
1874    #ifdef SUPPORT_UTF8
1875    if (common->utf8)
1876      {
1877      CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0, start);
1878      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)_pcre_utf8_table4 - 0xc0);
1879      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
1880      }
1881  #endif  #endif
1882  JUMPTO(SLJIT_JUMP, start);  JUMPTO(SLJIT_JUMP, start);
1883  JUMPHERE(found);  JUMPHERE(found);
# Line 1966  return notfound; Line 1945  return notfound;
1945  static void do_revertframes(compiler_common *common)  static void do_revertframes(compiler_common *common)
1946  {  {
1947  DEFINE_COMPILER;  DEFINE_COMPILER;
 struct sljit_jump *earlyexit;  
1948  struct sljit_jump *jump;  struct sljit_jump *jump;
1949  struct sljit_label *mainloop;  struct sljit_label *mainloop;
1950    
1951  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);
1952  OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS_HEAD);  OP1(SLJIT_MOV, TMP1, 0, STACK_TOP, 0);
1953    
1954  /* Drop frames until we reach STACK_TOP. */  /* Drop frames until we reach STACK_TOP. */
 earlyexit = CMP(SLJIT_C_LESS, TMP1, 0, STACK_TOP, 0);  
1955  mainloop = LABEL();  mainloop = LABEL();
1956  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), 0);  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), 0);
1957  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 1987  JUMPTO(SLJIT_JUMP, mainloop); Line 1964  JUMPTO(SLJIT_JUMP, mainloop);
1964  JUMPHERE(jump);  JUMPHERE(jump);
1965  jump = CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, frame_end);  jump = CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, frame_end);
1966  /* 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);  
1967  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
1968    
1969  JUMPHERE(jump);  JUMPHERE(jump);
# Line 2015  struct sljit_jump *beginend; Line 1988  struct sljit_jump *beginend;
1988  struct sljit_jump *jump;  struct sljit_jump *jump;
1989  #endif  #endif
1990    
1991  SLJIT_ASSERT(ctype_word == 0x10);  SLJIT_COMPILE_ASSERT(ctype_word == 0x10, ctype_word_must_be_16);
1992    
1993  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);
1994  /* Get type of the previous char, and put it to LOCALS1. */  /* Get type of the previous char, and put it to LOCALS1. */
# Line 2258  sljit_emit_fast_return(compiler, RETURN_ Line 2231  sljit_emit_fast_return(compiler, RETURN_
2231  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF8
2232  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
2233    
2234  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)
2235  {  {
2236  /* This function would be ineffective to do in JIT level. */  /* This function would be ineffective to do in JIT level. */
2237  int c1, c2;  int c1, c2;
2238  uschar *src2 = args->ptr;  const pcre_uchar *src2 = args->ptr;
2239  uschar *end2 = (uschar*)args->end;  const pcre_uchar *end2 = (pcre_uchar *)args->end;
2240    
2241  while (src1 < end1)  while (src1 < end1)
2242    {    {
# Line 2279  return src2; Line 2252  return src2;
2252  #endif  #endif
2253  #endif  #endif
2254    
2255  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,
2256      compare_context* context, jump_list **fallbacks)      compare_context* context, jump_list **fallbacks)
2257  {  {
2258  DEFINE_COMPILER;  DEFINE_COMPILER;
2259  unsigned int othercasebit = 0;  unsigned int othercasebit = 0;
2260  uschar *othercasebyte = NULL;  pcre_uint8 *othercasebyte = NULL;
2261  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF8
2262  int utf8length;  int utf8length;
2263  #endif  #endif
# Line 2422  return cc; Line 2395  return cc;
2395      } \      } \
2396    charoffset = (value);    charoffset = (value);
2397    
2398  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)
2399  {  {
2400  DEFINE_COMPILER;  DEFINE_COMPILER;
2401  jump_list *found = NULL;  jump_list *found = NULL;
# Line 2430  jump_list **list = (*cc & XCL_NOT) == 0 Line 2403  jump_list **list = (*cc & XCL_NOT) == 0
2403  unsigned int c;  unsigned int c;
2404  int compares;  int compares;
2405  struct sljit_jump *jump = NULL;  struct sljit_jump *jump = NULL;
2406  uschar *ccbegin;  pcre_uchar *ccbegin;
2407  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
2408  BOOL needstype = FALSE, needsscript = FALSE, needschar = FALSE;  BOOL needstype = FALSE, needsscript = FALSE, needschar = FALSE;
2409  BOOL charsaved = FALSE;  BOOL charsaved = FALSE;
# Line 2751  if (found != NULL) Line 2724  if (found != NULL)
2724    
2725  #endif  #endif
2726    
2727  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)
2728  {  {
2729  DEFINE_COMPILER;  DEFINE_COMPILER;
2730  int length;  int length;
# Line 2761  struct sljit_jump *jump[4]; Line 2734  struct sljit_jump *jump[4];
2734  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF8
2735  struct sljit_label *label;  struct sljit_label *label;
2736  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
2737  uschar propdata[5];  pcre_uchar propdata[5];
2738  #endif  #endif
2739  #endif  #endif
2740    
# Line 2831  switch(type) Line 2804  switch(type)
2804    if (common->utf8)    if (common->utf8)
2805      {      {
2806      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
2807      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, 1);
2808        jump[0] = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);
2809        OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)_pcre_utf8_table4 - 0xc0);
2810      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2811        JUMPHERE(jump[0]);
2812      return cc;      return cc;
2813      }      }
2814  #endif  #endif
2815    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 1);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 1);
2816    return cc;    return cc;
2817    
2818      case OP_ANYBYTE:
2819      check_input_end(common, fallbacks);
2820      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 1);
2821      return cc;
2822    
2823  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF8
2824  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
2825    case OP_NOTPROP:    case OP_NOTPROP:
# Line 3085  switch(type) Line 3066  switch(type)
3066      if (c <= 127)      if (c <= 127)
3067        {        {
3068        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);  
3069        if (type == OP_NOT || !char_has_othercase(common, cc))        if (type == OP_NOT || !char_has_othercase(common, cc))
3070          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));
3071        else        else
3072          {          {
3073          /* 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. */
3074          OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x20);          OP2(SLJIT_OR, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x20);
3075          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));
3076          }          }
3077        /* Skip the variable-length character. */        /* Skip the variable-length character. */
3078        OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0);        OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 1);
3079          jump[0] = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);
3080          OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)_pcre_utf8_table4 - 0xc0);
3081          OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
3082          JUMPHERE(jump[0]);
3083        return cc + length;        return cc + length;
3084        }        }
3085      else      else
# Line 3188  SLJIT_ASSERT_STOP(); Line 3172  SLJIT_ASSERT_STOP();
3172  return cc;  return cc;
3173  }  }
3174    
3175  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)
3176  {  {
3177  /* This function consumes at least one input character. */  /* This function consumes at least one input character. */
3178  /* 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. */
3179  DEFINE_COMPILER;  DEFINE_COMPILER;
3180  uschar *ccbegin = cc;  pcre_uchar *ccbegin = cc;
3181  compare_context context;  compare_context context;
3182  int size;  int size;
3183    
# Line 3254  if (context.length > 0) Line 3238  if (context.length > 0)
3238  return compile_char1_hotpath(common, *cc, cc + 1, fallbacks);  return compile_char1_hotpath(common, *cc, cc + 1, fallbacks);
3239  }  }
3240    
3241  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)
3242  {  {
3243  DEFINE_COMPILER;  DEFINE_COMPILER;
3244  int offset = GET2(cc, 1) << 1;  int offset = GET2(cc, 1) << 1;
# Line 3276  return CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT Line 3260  return CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT
3260  }  }
3261    
3262  /* Forward definitions. */  /* Forward definitions. */
3263  static void compile_hotpath(compiler_common *, uschar *, uschar *, fallback_common *);  static void compile_hotpath(compiler_common *, pcre_uchar *, pcre_uchar *, fallback_common *);
3264  static void compile_fallbackpath(compiler_common *, struct fallback_common *);  static void compile_fallbackpath(compiler_common *, struct fallback_common *);
3265    
3266  #define PUSH_FALLBACK(size, ccstart, error) \  #define PUSH_FALLBACK(size, ccstart, error) \
# Line 3307  static void compile_fallbackpath(compile Line 3291  static void compile_fallbackpath(compile
3291    
3292  #define FALLBACK_AS(type) ((type*)fallback)  #define FALLBACK_AS(type) ((type*)fallback)
3293    
3294  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)
3295  {  {
3296  DEFINE_COMPILER;  DEFINE_COMPILER;
3297  int offset = GET2(cc, 1) << 1;  int offset = GET2(cc, 1) << 1;
# Line 3330  if (common->utf8 && *cc == OP_REFI) Line 3314  if (common->utf8 && *cc == OP_REFI)
3314    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, STACK_TOP, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, STACK_TOP, 0);
3315    OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, ARGUMENTS, 0);    OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, ARGUMENTS, 0);
3316    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), SLJIT_OFFSETOF(jit_arguments, ptr), STR_PTR, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), SLJIT_OFFSETOF(jit_arguments, ptr), STR_PTR, 0);
3317    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));
3318    OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);    OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);
3319    add_jump(compiler, fallbacks, CMP(SLJIT_C_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 0));    add_jump(compiler, fallbacks, CMP(SLJIT_C_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 0));
3320    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_RETURN_REG, 0);    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_RETURN_REG, 0);
# Line 3359  if (jump != NULL) Line 3343  if (jump != NULL)
3343  return cc + 3;  return cc + 3;
3344  }  }
3345    
3346  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)
3347  {  {
3348  DEFINE_COMPILER;  DEFINE_COMPILER;
3349  fallback_common *fallback;  fallback_common *fallback;
3350  uschar type;  pcre_uchar type;
3351  struct sljit_label *label;  struct sljit_label *label;
3352  struct sljit_jump *zerolength;  struct sljit_jump *zerolength;
3353  struct sljit_jump *jump = NULL;  struct sljit_jump *jump = NULL;
3354  uschar *ccbegin = cc;  pcre_uchar *ccbegin = cc;
3355  int min = 0, max = 0;  int min = 0, max = 0;
3356  BOOL minimize;  BOOL minimize;
3357    
# Line 3503  decrease_call_count(common); Line 3487  decrease_call_count(common);
3487  return cc;  return cc;
3488  }  }
3489    
3490  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)
3491  {  {
3492  DEFINE_COMPILER;  DEFINE_COMPILER;
3493  fallback_common *fallback;  fallback_common *fallback;
# Line 3549  add_jump(compiler, &fallback->topfallbac Line 3533  add_jump(compiler, &fallback->topfallbac
3533  return cc + 1 + LINK_SIZE;  return cc + 1 + LINK_SIZE;
3534  }  }
3535    
3536  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)
3537  {  {
3538  DEFINE_COMPILER;  DEFINE_COMPILER;
3539  int framesize;  int framesize;
3540  int localptr;  int localptr;
3541  fallback_common altfallback;  fallback_common altfallback;
3542  uschar *ccbegin;  pcre_uchar *ccbegin;
3543  uschar opcode;  pcre_uchar opcode;
3544  uschar bra = OP_BRA;  pcre_uchar bra = OP_BRA;
3545  jump_list *tmp = NULL;  jump_list *tmp = NULL;
3546  jump_list **target = (conditional) ? &fallback->condfailed : &fallback->common.topfallbacks;  jump_list **target = (conditional) ? &fallback->condfailed : &fallback->common.topfallbacks;
3547  jump_list **found;  jump_list **found;
# Line 3632  while (1) Line 3616  while (1)
3616    if (common->accept != NULL)    if (common->accept != NULL)
3617      set_jumps(common->accept, common->acceptlabel);      set_jumps(common->accept, common->acceptlabel);
3618    
3619      /* Reset stack. */
3620    if (framesize < 0)    if (framesize < 0)
3621      OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);      OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
3622      else {
3623        if ((opcode != OP_ASSERT_NOT && opcode != OP_ASSERTBACK_NOT) || conditional)
3624          {
3625          /* We don't need to keep the STR_PTR, only the previous localptr. */
3626          OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_IMM, (framesize + 1) * sizeof(sljit_w));
3627          }
3628        else
3629          {
3630          OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
3631          add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
3632          }
3633      }
3634    
3635    if (opcode == OP_ASSERT_NOT || opcode == OP_ASSERTBACK_NOT)    if (opcode == OP_ASSERT_NOT || opcode == OP_ASSERTBACK_NOT)
3636      {      {
3637      /* 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. */
3638      if (conditional)      if (conditional)
3639        {        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));  
         }  
       }  
3640      else if (bra == OP_BRAZERO)      else if (bra == OP_BRAZERO)
3641        {        {
3642        if (framesize < 0)        if (framesize < 0)
3643          OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), 0);          OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), 0);
3644        else        else
3645          {          {
         OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);  
         add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));  
3646          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));
3647          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));
3648          OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP1, 0);          OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP1, 0);
# Line 3663  while (1) Line 3650  while (1)
3650        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));
3651        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
3652        }        }
3653      else if (bra == OP_BRAMINZERO)      else if (framesize >= 0)
3654        {        {
3655        if (framesize >= 0)        /* For OP_BRA and OP_BRAMINZERO. */
3656          {        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));  
         }  
3657        }        }
3658      }      }
3659    add_jump(compiler, found, JUMP(SLJIT_JUMP));    add_jump(compiler, found, JUMP(SLJIT_JUMP));
# Line 3697  if (opcode == OP_ASSERT || opcode == OP_ Line 3680  if (opcode == OP_ASSERT || opcode == OP_
3680    /* Assert is failed. */    /* Assert is failed. */
3681    if (conditional || bra == OP_BRAZERO)    if (conditional || bra == OP_BRAZERO)
3682      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
3683    
3684    if (framesize < 0)    if (framesize < 0)
3685      {      {
3686      /* The topmost item should be 0. */      /* The topmost item should be 0. */
# Line 3708  if (opcode == OP_ASSERT || opcode == OP_ Line 3692  if (opcode == OP_ASSERT || opcode == OP_
3692    else    else
3693      {      {
3694      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));  
3695      /* The topmost item should be 0. */      /* The topmost item should be 0. */
3696      if (bra == OP_BRAZERO)      if (bra == OP_BRAZERO)
3697        {        {
# Line 3719  if (opcode == OP_ASSERT || opcode == OP_ Line 3701  if (opcode == OP_ASSERT || opcode == OP_
3701      else      else
3702        free_stack(common, framesize + 2);        free_stack(common, framesize + 2);
3703      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);  
3704      }      }
3705    jump = JUMP(SLJIT_JUMP);    jump = JUMP(SLJIT_JUMP);
3706    if (bra != OP_BRAZERO)    if (bra != OP_BRAZERO)
# Line 3743  if (opcode == OP_ASSERT || opcode == OP_ Line 3723  if (opcode == OP_ASSERT || opcode == OP_
3723      }      }
3724    else    else
3725      {      {
3726      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)  
3727        {        {
3728        allocate_stack(common, 1);        /* We don't need to keep the STR_PTR, only the previous localptr. */
3729        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));
3730          OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), 0);
3731        }        }
3732      else if (bra == OP_BRAMINZERO)      else
3733        {        {
3734        allocate_stack(common, 1);        /* We don't need to keep the STR_PTR, only the previous localptr. */
3735        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));
3736          OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
3737          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), bra == OP_BRAZERO ? STR_PTR : SLJIT_IMM, 0);
3738        }        }
3739      }      }
3740    
# Line 3790  else Line 3771  else
3771      {      {
3772      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
3773      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));  
3774      /* The topmost item should be 0. */      /* The topmost item should be 0. */
3775      if (bra != OP_BRA)      if (bra != OP_BRA)
3776        {        {
# Line 3801  else Line 3780  else
3780      else      else
3781        free_stack(common, framesize + 2);        free_stack(common, framesize + 2);
3782      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);  
3783      }      }
3784    
3785    if (bra == OP_BRAZERO)    if (bra == OP_BRAZERO)
# Line 3826  common->accept = save_accept; Line 3803  common->accept = save_accept;
3803  return cc + 1 + LINK_SIZE;  return cc + 1 + LINK_SIZE;
3804  }  }
3805    
3806    static sljit_w SLJIT_CALL do_searchovector(sljit_w refno, sljit_w* locals, pcre_uchar *name_table)
3807    {
3808    int condition = FALSE;
3809    pcre_uchar *slotA = name_table;
3810    pcre_uchar *slotB;
3811    sljit_w name_count = locals[LOCALS0 / sizeof(sljit_w)];
3812    sljit_w name_entry_size = locals[LOCALS1 / sizeof(sljit_w)];
3813    sljit_w no_capture;
3814    int i;
3815    
3816    locals += OVECTOR_START / sizeof(sljit_w);
3817    no_capture = locals[1];
3818    
3819    for (i = 0; i < name_count; i++)
3820      {
3821      if (GET2(slotA, 0) == refno) break;
3822      slotA += name_entry_size;
3823      }
3824    
3825    if (i < name_count)
3826      {
3827      /* Found a name for the number - there can be only one; duplicate names
3828      for different numbers are allowed, but not vice versa. First scan down
3829      for duplicates. */
3830    
3831      slotB = slotA;
3832      while (slotB > name_table)
3833        {
3834        slotB -= name_entry_size;
3835        if (STRCMP_UC_UC(slotA + IMM2_SIZE, slotB + IMM2_SIZE) == 0)
3836          {
3837          condition = locals[GET2(slotB, 0) << 1] != no_capture;
3838          if (condition) break;
3839          }
3840        else break;
3841        }
3842    
3843      /* Scan up for duplicates */
3844      if (!condition)
3845        {
3846        slotB = slotA;
3847        for (i++; i < name_count; i++)
3848          {
3849          slotB += name_entry_size;
3850          if (STRCMP_UC_UC(slotA + IMM2_SIZE, slotB + IMM2_SIZE) == 0)
3851            {
3852            condition = locals[GET2(slotB, 0) << 1] != no_capture;
3853            if (condition) break;
3854            }
3855          else break;
3856          }
3857        }
3858      }
3859    return condition;
3860    }
3861    
3862    static sljit_w SLJIT_CALL do_searchgroups(sljit_w recno, sljit_w* locals, pcre_uchar *name_table)
3863    {
3864    int condition = FALSE;
3865    pcre_uchar *slotA = name_table;
3866    pcre_uchar *slotB;
3867    sljit_w name_count = locals[LOCALS0 / sizeof(sljit_w)];
3868    sljit_w name_entry_size = locals[LOCALS1 / sizeof(sljit_w)];
3869    sljit_w group_num = locals[POSSESSIVE0 / sizeof(sljit_w)];
3870    int i;
3871    
3872    for (i = 0; i < name_count; i++)
3873      {
3874      if (GET2(slotA, 0) == recno) break;
3875      slotA += name_entry_size;
3876      }
3877    
3878    if (i < name_count)
3879      {
3880      /* Found a name for the number - there can be only one; duplicate
3881      names for different numbers are allowed, but not vice versa. First
3882      scan down for duplicates. */
3883    
3884      slotB = slotA;
3885      while (slotB > name_table)
3886        {
3887        slotB -= name_entry_size;
3888        if (STRCMP_UC_UC(slotA + IMM2_SIZE, slotB + IMM2_SIZE) == 0)
3889          {
3890          condition = GET2(slotB, 0) == group_num;
3891          if (condition) break;
3892          }
3893        else break;
3894        }
3895    
3896      /* Scan up for duplicates */
3897      if (!condition)
3898        {
3899        slotB = slotA;
3900        for (i++; i < name_count; i++)
3901          {
3902          slotB += name_entry_size;
3903          if (STRCMP_UC_UC(slotA + IMM2_SIZE, slotB + IMM2_SIZE) == 0)
3904            {
3905            condition = GET2(slotB, 0) == group_num;
3906            if (condition) break;
3907            }
3908          else break;
3909          }
3910        }
3911      }
3912    return condition;
3913    }
3914    
3915  /*  /*
3916    Handling bracketed expressions is probably the most complex part.    Handling bracketed expressions is probably the most complex part.
3917    
# Line 3873  return cc + 1 + LINK_SIZE; Line 3959  return cc + 1 + LINK_SIZE;
3959      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.
3960    
3961    The next list shows the possible content of a bracket:    The next list shows the possible content of a bracket:
3962    (|)     OP_*BRA  | OP_ALT ...         M A    (|)     OP_*BRA    | OP_ALT ...         M A
3963    (?()|)  OP_*COND | OP_ALT             M A    (?()|)  OP_*COND   | OP_ALT             M A
3964    (?>|)   OP_ONCE  | OP_ALT ...         [stack trace] M A    (?>|)   OP_ONCE    | OP_ALT ...         [stack trace] M A
3965                                          Or nothing, if trace is unnecessary    (?>|)   OP_ONCE_NC | OP_ALT ...         [stack trace] M A
3966                                              Or nothing, if trace is unnecessary
3967  */  */
3968    
3969  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)
3970  {  {
3971  DEFINE_COMPILER;  DEFINE_COMPILER;
3972  fallback_common *fallback;  fallback_common *fallback;
3973  uschar opcode;  pcre_uchar opcode;
3974  int localptr = 0;  int localptr = 0;
3975  int offset = 0;  int offset = 0;
3976  int stacksize;  int stacksize;
3977  uschar *ccbegin;  pcre_uchar *ccbegin;
3978  uschar *hotpath;  pcre_uchar *hotpath;
3979  uschar bra = OP_BRA;  pcre_uchar bra = OP_BRA;
3980  uschar ket;  pcre_uchar ket;
3981  assert_fallback *assert;  assert_fallback *assert;
3982  BOOL has_alternatives;  BOOL has_alternatives;
3983  struct sljit_jump *jump;  struct sljit_jump *jump;
# Line 3909  if (*cc == OP_BRAZERO || *cc == OP_BRAMI Line 3996  if (*cc == OP_BRAZERO || *cc == OP_BRAMI
3996    
3997  opcode = *cc;  opcode = *cc;
3998  ccbegin = cc;  ccbegin = cc;
3999    hotpath = ccbegin + 1 + LINK_SIZE;
4000    
4001  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)
4002    {    {
4003    /* Drop this bracket_fallback. */    /* Drop this bracket_fallback. */
# Line 3920  ket = *(bracketend(cc) - 1 - LINK_SIZE); Line 4009  ket = *(bracketend(cc) - 1 - LINK_SIZE);
4009  SLJIT_ASSERT(ket == OP_KET || ket == OP_KETRMAX || ket == OP_KETRMIN);  SLJIT_ASSERT(ket == OP_KET || ket == OP_KETRMAX || ket == OP_KETRMIN);
4010  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)));
4011  cc += GET(cc, 1);  cc += GET(cc, 1);
4012  has_alternatives = *cc == OP_ALT || opcode == OP_COND || opcode == OP_SCOND;  
4013    has_alternatives = *cc == OP_ALT;
4014    if (SLJIT_UNLIKELY(opcode == OP_COND) || SLJIT_UNLIKELY(opcode == OP_SCOND))
4015      {
4016      has_alternatives = (*hotpath == OP_RREF) ? FALSE : TRUE;
4017      if (*hotpath == OP_NRREF)
4018        {
4019        stacksize = GET2(hotpath, 1);
4020        if (common->currententry == NULL || stacksize == RREF_ANY)
4021          has_alternatives = FALSE;
4022        else if (common->currententry->start == 0)
4023          has_alternatives = stacksize != 0;
4024        else
4025          has_alternatives = stacksize != GET2(common->start, common->currententry->start + 1 + LINK_SIZE);
4026        }
4027      }
4028    
4029  if (SLJIT_UNLIKELY(opcode == OP_COND) && (*cc == OP_KETRMAX || *cc == OP_KETRMIN))  if (SLJIT_UNLIKELY(opcode == OP_COND) && (*cc == OP_KETRMAX || *cc == OP_KETRMIN))
4030    opcode = OP_SCOND;    opcode = OP_SCOND;
4031    if (SLJIT_UNLIKELY(opcode == OP_ONCE_NC))
4032      opcode = OP_ONCE;
4033    
4034  if (opcode == OP_CBRA || opcode == OP_SCBRA)  if (opcode == OP_CBRA || opcode == OP_SCBRA)
4035    {    {
# Line 3931  if (opcode == OP_CBRA || opcode == OP_SC Line 4038  if (opcode == OP_CBRA || opcode == OP_SC
4038    localptr = OVECTOR_PRIV(offset);    localptr = OVECTOR_PRIV(offset);
4039    offset <<= 1;    offset <<= 1;
4040    FALLBACK_AS(bracket_fallback)->localptr = localptr;    FALLBACK_AS(bracket_fallback)->localptr = localptr;
4041      hotpath += 2;
4042    }    }
4043  else if (opcode == OP_ONCE || opcode == OP_SBRA || opcode == OP_SCOND)  else if (opcode == OP_ONCE || opcode == OP_SBRA || opcode == OP_SCOND)
4044    {    {
# Line 4087  else if (has_alternatives) Line 4195  else if (has_alternatives)
4195    }    }
4196    
4197  /* Generating code for the first alternative. */  /* Generating code for the first alternative. */
 hotpath = ccbegin + 1 + LINK_SIZE;  
 if (offset != 0)  
   hotpath += 2;  
4198  if (opcode == OP_COND || opcode == OP_SCOND)  if (opcode == OP_COND || opcode == OP_SCOND)
4199    {    {
4200    if (*hotpath == OP_CREF)    if (*hotpath == OP_CREF)
4201      {      {
4202        SLJIT_ASSERT(has_alternatives);
4203      add_jump(compiler, &(FALLBACK_AS(bracket_fallback)->u.condfailed),      add_jump(compiler, &(FALLBACK_AS(bracket_fallback)->u.condfailed),
4204        CMP(SLJIT_C_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR((GET2(hotpath, 1) << 1)), SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1)));        CMP(SLJIT_C_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(GET2(hotpath, 1) << 1), SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1)));
4205      hotpath += 3;      hotpath += 3;
4206      }      }
4207      else if (*hotpath == OP_NCREF)
4208        {
4209        SLJIT_ASSERT(has_alternatives);
4210        stacksize = GET2(hotpath, 1);
4211        jump = CMP(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(stacksize << 1), SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1));
4212    
4213        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STACK_TOP, 0);
4214        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, SLJIT_IMM, common->name_count);
4215        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, SLJIT_IMM, common->name_entry_size);
4216        OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG1, 0, SLJIT_IMM, stacksize);
4217        OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, SLJIT_LOCALS_REG, 0);
4218        OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, common->name_table);
4219        sljit_emit_ijump(compiler, SLJIT_CALL3, SLJIT_IMM, SLJIT_FUNC_OFFSET(do_searchovector));
4220        OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1);
4221        add_jump(compiler, &(FALLBACK_AS(bracket_fallback)->u.condfailed), CMP(SLJIT_C_EQUAL, SLJIT_TEMPORARY_REG1, 0, SLJIT_IMM, 0));
4222    
4223        JUMPHERE(jump);
4224        hotpath += 3;
4225        }
4226      else if (*hotpath == OP_RREF || *hotpath == OP_NRREF)
4227        {
4228        /* Never has other case. */
4229        FALLBACK_AS(bracket_fallback)->u.condfailed = NULL;
4230    
4231        stacksize = GET2(hotpath, 1);
4232        if (common->currententry == NULL)
4233          stacksize = 0;
4234        else if (stacksize == RREF_ANY)
4235          stacksize = 1;
4236        else if (common->currententry->start == 0)
4237          stacksize = stacksize == 0;
4238        else
4239          stacksize = stacksize == GET2(common->start, common->currententry->start + 1 + LINK_SIZE);
4240    
4241        if (*hotpath == OP_RREF || stacksize || common->currententry == NULL)
4242          {
4243          SLJIT_ASSERT(!has_alternatives);
4244          if (stacksize != 0)
4245            hotpath += 3;
4246          else
4247            {
4248            if (*cc == OP_ALT)
4249              {
4250              hotpath = cc + 1 + LINK_SIZE;
4251              cc += GET(cc, 1);
4252              }
4253            else
4254              hotpath = cc;
4255            }
4256          }
4257        else
4258          {
4259          SLJIT_ASSERT(has_alternatives);
4260    
4261          stacksize = GET2(hotpath, 1);
4262          OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STACK_TOP, 0);
4263          OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, SLJIT_IMM, common->name_count);
4264          OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, SLJIT_IMM, common->name_entry_size);
4265          OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, GET2(common->start, common->currententry->start + 1 + LINK_SIZE));
4266          OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG1, 0, SLJIT_IMM, stacksize);
4267          OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, SLJIT_LOCALS_REG, 0);
4268          OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, common->name_table);
4269          sljit_emit_ijump(compiler, SLJIT_CALL3, SLJIT_IMM, SLJIT_FUNC_OFFSET(do_searchgroups));
4270          OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1);
4271          add_jump(compiler, &(FALLBACK_AS(bracket_fallback)->u.condfailed), CMP(SLJIT_C_EQUAL, SLJIT_TEMPORARY_REG1, 0, SLJIT_IMM, 0));
4272          hotpath += 3;
4273          }
4274        }
4275    else    else
4276      {      {
4277      SLJIT_ASSERT(*hotpath >= OP_ASSERT && *hotpath <= OP_ASSERTBACK_NOT);      SLJIT_ASSERT(has_alternatives && *hotpath >= OP_ASSERT && *hotpath <= OP_ASSERTBACK_NOT);
4278      /* Similar code as PUSH_FALLBACK macro. */      /* Similar code as PUSH_FALLBACK macro. */
4279      assert = sljit_alloc_memory(compiler, sizeof(assert_fallback));      assert = sljit_alloc_memory(compiler, sizeof(assert_fallback));
4280      if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))      if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
# Line 4130  if (opcode == OP_ONCE) Line 4304  if (opcode == OP_ONCE)
4304        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_MEM1(STACK_TOP), 0);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_MEM1(STACK_TOP), 0);
4305        }        }
4306      }      }
4307    else if (ket == OP_KETRMAX)    else
4308      {      {
4309      /* TMP2 which is set here used by OP_KETRMAX below. */      stacksize = (ket == OP_KETRMIN || ket == OP_KETRMAX || has_alternatives) ? 2 : 1;
4310      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);      OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_IMM, (FALLBACK_AS(bracket_fallback)->u.framesize + stacksize) * sizeof(sljit_w));
4311      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP2), (FALLBACK_AS(bracket_fallback)->u.framesize + 1) * sizeof(sljit_w));      if (ket == OP_KETRMAX)
4312          {
4313          /* TMP2 which is set here used by OP_KETRMAX below. */
4314          OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
4315          }
4316      }      }
4317    }    }
4318    
# Line 4227  cc += 1 + LINK_SIZE; Line 4405  cc += 1 + LINK_SIZE;
4405  return cc;  return cc;
4406  }  }
4407    
4408  static uschar *compile_bracketpos_hotpath(compiler_common *common, uschar *cc, fallback_common *parent)  static pcre_uchar *compile_bracketpos_hotpath(compiler_common *common, pcre_uchar *cc, fallback_common *parent)
4409  {  {
4410  DEFINE_COMPILER;  DEFINE_COMPILER;
4411  fallback_common *fallback;  fallback_common *fallback;
4412  uschar opcode;  pcre_uchar opcode;
4413  int localptr;  int localptr;
4414  int cbraprivptr = 0;  int cbraprivptr = 0;
4415  int framesize;  int framesize;
4416  int stacksize;  int stacksize;
4417  int offset = 0;  int offset = 0;
4418  BOOL zero = FALSE;  BOOL zero = FALSE;
4419  uschar *ccbegin = NULL;  pcre_uchar *ccbegin = NULL;
4420  int stack;  int stack;
4421  struct sljit_label *loop = NULL;  struct sljit_label *loop = NULL;
4422  struct jump_list *emptymatch = NULL;  struct jump_list *emptymatch = NULL;
# Line 4368  while (*cc != OP_KETRPOS) Line 4546  while (*cc != OP_KETRPOS)
4546      {      {
4547      if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS)      if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS)
4548        {        {
4549          OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_IMM, stacksize * sizeof(sljit_w));
4550        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr);        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr);
       if (!zero)  
         OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);  
4551        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), STR_PTR, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), STR_PTR, 0);
4552        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr, STR_PTR, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr, STR_PTR, 0);
4553        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);
# Line 4378  while (*cc != OP_KETRPOS) Line 4555  while (*cc != OP_KETRPOS)
4555      else      else
4556        {        {
4557        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
4558          OP2(SLJIT_ADD, STACK_TOP, 0, TMP2, 0, SLJIT_IMM, stacksize * sizeof(sljit_w));
4559        if (opcode == OP_SBRAPOS)        if (opcode == OP_SBRAPOS)
4560          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), (framesize + 1) * sizeof(sljit_w));          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), (framesize + 1) * sizeof(sljit_w));
4561        OP1(SLJIT_MOV, SLJIT_MEM1(TMP2), (framesize + 1) * sizeof(sljit_w), STR_PTR, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(TMP2), (framesize + 1) * sizeof(sljit_w), STR_PTR, 0);
# Line 4386  while (*cc != OP_KETRPOS) Line 4564  while (*cc != OP_KETRPOS)
4564      if (opcode == OP_SBRAPOS || opcode == OP_SCBRAPOS)      if (opcode == OP_SBRAPOS || opcode == OP_SCBRAPOS)
4565        add_jump(compiler, &emptymatch, CMP(SLJIT_C_EQUAL, TMP1, 0, STR_PTR, 0));        add_jump(compiler, &emptymatch, CMP(SLJIT_C_EQUAL, TMP1, 0, STR_PTR, 0));
4566    
     /* TMP2 must be set above. */  
4567      if (!zero)      if (!zero)
4568        {        {
4569        if (framesize < 0)        if (framesize < 0)
4570          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize - 1), SLJIT_IMM, 0);          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize - 1), SLJIT_IMM, 0);
4571        else        else
4572          OP1(SLJIT_MOV, SLJIT_MEM1(TMP2), (stacksize - 1) * sizeof(sljit_w), SLJIT_IMM, 0);          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
4573        }        }
4574      }      }
4575    JUMPTO(SLJIT_JUMP, loop);    JUMPTO(SLJIT_JUMP, loop);
# Line 4414  while (*cc != OP_KETRPOS) Line 4591  while (*cc != OP_KETRPOS)
4591      {      {
4592      if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS)      if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS)
4593        {        {
4594          /* Last alternative. */
4595        if (*cc == OP_KETRPOS)        if (*cc == OP_KETRPOS)
4596          OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);          OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
4597        OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr);        OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr);
# Line 4445  decrease_call_count(common); Line 4623  decrease_call_count(common);
4623  return cc + 1 + LINK_SIZE;  return cc + 1 + LINK_SIZE;
4624  }  }
4625    
4626  static SLJIT_INLINE uschar *get_iterator_parameters(compiler_common *common, uschar *cc, uschar *opcode, uschar *type, int *arg1, int *arg2, uschar **end)  static SLJIT_INLINE pcre_uchar *get_iterator_parameters(compiler_common *common, pcre_uchar *cc, pcre_uchar *opcode, pcre_uchar *type, int *arg1, int *arg2, pcre_uchar **end)
4627  {  {
4628  int class_len;  int class_len;
4629    
# Line 4537  if (end != NULL) Line 4715  if (end != NULL)
4715  return cc;  return cc;
4716  }  }
4717    
4718  static uschar *compile_iterator_hotpath(compiler_common *common, uschar *cc, fallback_common *parent)  static pcre_uchar *compile_iterator_hotpath(compiler_common *common, pcre_uchar *cc, fallback_common *parent)
4719  {  {
4720  DEFINE_COMPILER;  DEFINE_COMPILER;
4721  fallback_common *fallback;  fallback_common *fallback;
4722  uschar opcode;  pcre_uchar opcode;
4723  uschar type;  pcre_uchar type;
4724  int arg1 = -1, arg2 = -1;  int arg1 = -1, arg2 = -1;
4725  uschar* end;  pcre_uchar* end;
4726  jump_list *nomatch = NULL;  jump_list *nomatch = NULL;
4727  struct sljit_jump *jump = NULL;  struct sljit_jump *jump = NULL;
4728  struct sljit_label *label;  struct sljit_label *label;
# Line 4706  decrease_call_count(common); Line 4884  decrease_call_count(common);
4884  return end;  return end;
4885  }  }
4886    
4887  static SLJIT_INLINE uschar *compile_fail_accept_hotpath(compiler_common *common, uschar *cc, fallback_common *parent)  static SLJIT_INLINE pcre_uchar *compile_fail_accept_hotpath(compiler_common *common, pcre_uchar *cc, fallback_common *parent)
4888  {  {
4889  DEFINE_COMPILER;  DEFINE_COMPILER;
4890  fallback_common *fallback;  fallback_common *fallback;
# Line 4750  add_jump(compiler, &fallback->topfallbac Line 4928  add_jump(compiler, &fallback->topfallbac
4928  return cc + 1;  return cc + 1;
4929  }  }
4930    
4931  static SLJIT_INLINE uschar *compile_close_hotpath(compiler_common *common, uschar *cc)  static SLJIT_INLINE pcre_uchar *compile_close_hotpath(compiler_common *common, pcre_uchar *cc)
4932  {  {
4933  DEFINE_COMPILER;  DEFINE_COMPILER;
4934  int offset = GET2(cc, 1);  int offset = GET2(cc, 1);
# Line 4766  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_R Line 4944  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_R
4944  return cc + 3;  return cc + 3;
4945  }  }
4946    
4947  static void compile_hotpath(compiler_common *common, uschar *cc, uschar *ccend, fallback_common *parent)  static void compile_hotpath(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend, fallback_common *parent)
4948  {  {
4949  DEFINE_COMPILER;  DEFINE_COMPILER;
4950  fallback_common *fallback;  fallback_common *fallback;
# Line 4787  while (cc < ccend) Line 4965  while (cc < ccend)
4965      case OP_WORDCHAR:      case OP_WORDCHAR:
4966      case OP_ANY:      case OP_ANY:
4967      case OP_ALLANY:      case OP_ALLANY:
4968        case OP_ANYBYTE:
4969      case OP_NOTPROP:      case OP_NOTPROP:
4970      case OP_PROP:      case OP_PROP:
4971      case OP_ANYNL:      case OP_ANYNL:
# Line 4946  while (cc < ccend) Line 5125  while (cc < ccend)
5125      break;      break;
5126    
5127      case OP_ONCE:      case OP_ONCE:
5128        case OP_ONCE_NC:
5129      case OP_BRA:      case OP_BRA:
5130      case OP_CBRA:      case OP_CBRA:
5131      case OP_COND:      case OP_COND:
# Line 5015  SLJIT_ASSERT(cc == ccend); Line 5195  SLJIT_ASSERT(cc == ccend);
5195  static void compile_iterator_fallbackpath(compiler_common *common, struct fallback_common *current)  static void compile_iterator_fallbackpath(compiler_common *common, struct fallback_common *current)
5196  {  {
5197  DEFINE_COMPILER;  DEFINE_COMPILER;
5198  uschar *cc = current->cc;  pcre_uchar *cc = current->cc;
5199  uschar opcode;  pcre_uchar opcode;
5200  uschar type;  pcre_uchar type;
5201  int arg1 = -1, arg2 = -1;  int arg1 = -1, arg2 = -1;
5202  struct sljit_label *label = NULL;  struct sljit_label *label = NULL;
5203  struct sljit_jump *jump = NULL;  struct sljit_jump *jump = NULL;
# Line 5142  switch(opcode) Line 5322  switch(opcode)
5322  static void compile_ref_iterator_fallbackpath(compiler_common *common, struct fallback_common *current)  static void compile_ref_iterator_fallbackpath(compiler_common *common, struct fallback_common *current)
5323  {  {
5324  DEFINE_COMPILER;  DEFINE_COMPILER;
5325  uschar *cc = current->cc;  pcre_uchar *cc = current->cc;
5326  uschar type;  pcre_uchar type;
5327    
5328  type = cc[3];  type = cc[3];
5329  if ((type & 0x1) == 0)  if ((type & 0x1) == 0)
# Line 5174  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_R Line 5354  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_R
5354  static void compile_assert_fallbackpath(compiler_common *common, struct fallback_common *current)  static void compile_assert_fallbackpath(compiler_common *common, struct fallback_common *current)
5355  {  {
5356  DEFINE_COMPILER;  DEFINE_COMPILER;
5357  uschar *cc = current->cc;  pcre_uchar *cc = current->cc;
5358  uschar bra = OP_BRA;  pcre_uchar bra = OP_BRA;
 struct sljit_jump *jump;  
5359  struct sljit_jump *brajump = NULL;  struct sljit_jump *brajump = NULL;
5360    
5361  SLJIT_ASSERT(*cc != OP_BRAMINZERO);  SLJIT_ASSERT(*cc != OP_BRAMINZERO);
# Line 5222  if (*cc == OP_ASSERT || *cc == OP_ASSERT Line 5401  if (*cc == OP_ASSERT || *cc == OP_ASSERT
5401    {    {
5402    OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), CURRENT_AS(assert_fallback)->localptr);    OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), CURRENT_AS(assert_fallback)->localptr);
5403    add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
5404      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), CURRENT_AS(assert_fallback)->localptr, SLJIT_MEM1(STACK_TOP), CURRENT_AS(assert_fallback)->framesize * sizeof(sljit_w));
5405    
5406    set_jumps(current->topfallbacks, LABEL());    set_jumps(current->topfallbacks, LABEL());
5407    }    }
5408  else  else
   {  
   jump = JUMP(SLJIT_JUMP);  
   
5409    set_jumps(current->topfallbacks, LABEL());    set_jumps(current->topfallbacks, LABEL());
   OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), CURRENT_AS(assert_fallback)->localptr);  
   add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));  
   JUMPHERE(jump);  
   }  
 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), CURRENT_AS(assert_fallback)->localptr, SLJIT_MEM1(STACK_TOP), CURRENT_AS(assert_fallback)->framesize * sizeof(sljit_w));  
5410    
5411  if (bra == OP_BRAZERO)  if (bra == OP_BRAZERO)
5412    {    {
# Line 5254  int offset = 0; Line 5426  int offset = 0;
5426  int localptr = CURRENT_AS(bracket_fallback)->localptr;  int localptr = CURRENT_AS(bracket_fallback)->localptr;
5427  int stacksize;  int stacksize;
5428  int count;  int count;
5429  uschar *cc = current->cc;  pcre_uchar *cc = current->cc;
5430  uschar *ccbegin;  pcre_uchar *ccbegin;
5431  uschar *ccprev;  pcre_uchar *ccprev;
5432  jump_list *jumplist = NULL;  jump_list *jumplist = NULL;
5433  jump_list *jumplistitem = NULL;  jump_list *jumplistitem = NULL;
5434  uschar bra = OP_BRA;  pcre_uchar bra = OP_BRA;
5435  uschar ket;  pcre_uchar ket;
5436  assert_fallback *assert;  assert_fallback *assert;
5437    BOOL has_alternatives;
5438  struct sljit_jump *brazero = NULL;  struct sljit_jump *brazero = NULL;
5439  struct sljit_jump *once = NULL;  struct sljit_jump *once = NULL;
5440  struct sljit_jump *cond = NULL;  struct sljit_jump *cond = NULL;
# Line 5277  opcode = *cc; Line 5450  opcode = *cc;
5450  ccbegin = cc;  ccbegin = cc;
5451  ket = *(bracketend(ccbegin) - 1 - LINK_SIZE);  ket = *(bracketend(ccbegin) - 1 - LINK_SIZE);
5452  cc += GET(cc, 1);  cc += GET(cc, 1);
5453    has_alternatives = *cc == OP_ALT;
5454    if (SLJIT_UNLIKELY(opcode == OP_COND) || SLJIT_UNLIKELY(opcode == OP_SCOND))
5455      has_alternatives = (ccbegin[1 + LINK_SIZE] >= OP_ASSERT && ccbegin[1 + LINK_SIZE] <= OP_ASSERTBACK_NOT) || CURRENT_AS(bracket_fallback)->u.condfailed != NULL;
5456  if (opcode == OP_CBRA || opcode == OP_SCBRA)  if (opcode == OP_CBRA || opcode == OP_SCBRA)
5457    offset = (GET2(ccbegin, 1 + LINK_SIZE)) << 1;    offset = (GET2(ccbegin, 1 + LINK_SIZE)) << 1;
5458  if (SLJIT_UNLIKELY(opcode == OP_COND) && (*cc == OP_KETRMAX || *cc == OP_KETRMIN))  if (SLJIT_UNLIKELY(opcode == OP_COND) && (*cc == OP_KETRMAX || *cc == OP_KETRMIN))
5459    opcode = OP_SCOND;    opcode = OP_SCOND;
5460    if (SLJIT_UNLIKELY(opcode == OP_ONCE_NC))
5461      opcode = OP_ONCE;
5462    
5463  if (ket == OP_KETRMAX)  if (ket == OP_KETRMAX)
5464    {    {
# Line 5323  else if (bra == OP_BRAZERO) Line 5501  else if (bra == OP_BRAZERO)
5501    brazero = CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, 0);    brazero = CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, 0);
5502    }    }
5503    
5504  if (opcode == OP_ONCE)  if (SLJIT_UNLIKELY(opcode == OP_ONCE))
5505    {    {
5506    if (CURRENT_AS(bracket_fallback)->u.framesize >= 0)    if (CURRENT_AS(bracket_fallback)->u.framesize >= 0)
5507      {      {
# Line 5332  if (opcode == OP_ONCE) Line 5510  if (opcode == OP_ONCE)
5510      }      }
5511    once = JUMP(SLJIT_JUMP);    once = JUMP(SLJIT_JUMP);
5512    }    }
5513    else if (SLJIT_UNLIKELY(opcode == OP_COND) || SLJIT_UNLIKELY(opcode == OP_SCOND))
5514      {
5515      if (has_alternatives)
5516        {
5517        /* Always exactly one alternative. */
5518        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
5519        free_stack(common, 1);
5520    
5521        jumplistitem = sljit_alloc_memory(compiler, sizeof(jump_list));
5522        if (SLJIT_UNLIKELY(!jumplistitem))
5523          return;
5524        jumplist = jumplistitem;
5525        jumplistitem->next = NULL;
5526        jumplistitem->jump = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, 1);
5527        }
5528      }
5529  else if (*cc == OP_ALT)  else if (*cc == OP_ALT)
5530    {    {
5531    /* Build a jump list. Get the last successfully matched branch index. */    /* Build a jump list. Get the last successfully matched branch index. */
# Line 5363  else if (*cc == OP_ALT) Line 5557  else if (*cc == OP_ALT)
5557    
5558    cc = ccbegin + GET(ccbegin, 1);    cc = ccbegin + GET(ccbegin, 1);
5559    }    }
 else if (opcode == OP_COND || opcode == OP_SCOND)  
   {  
   /* Always one. */  
   OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));  
   free_stack(common, 1);  
   
   jumplistitem = sljit_alloc_memory(compiler, sizeof(jump_list));  
   if (SLJIT_UNLIKELY(!jumplistitem))  
     return;  
   jumplist = jumplistitem;  
   jumplistitem->next = NULL;  
   jumplistitem->jump = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, 1);  
   }  
5560    
5561  COMPILE_FALLBACKPATH(current->top);  COMPILE_FALLBACKPATH(current->top);
5562  if (current->topfallbacks)  if (current->topfallbacks)
5563    set_jumps(current->topfallbacks, LABEL());    set_jumps(current->topfallbacks, LABEL());
5564    
5565  if (opcode == OP_COND || opcode == OP_SCOND)  if (SLJIT_UNLIKELY(opcode == OP_COND) || SLJIT_UNLIKELY(opcode == OP_SCOND))
5566    {    {
5567    /* Conditional block always has at most one alternative. */    /* Conditional block always has at most one alternative. */
5568    if (ccbegin[1 + LINK_SIZE] >= OP_ASSERT && ccbegin[1 + LINK_SIZE] <= OP_ASSERTBACK_NOT)    if (ccbegin[1 + LINK_SIZE] >= OP_ASSERT && ccbegin[1 + LINK_SIZE] <= OP_ASSERTBACK_NOT)
5569      {      {
5570        SLJIT_ASSERT(has_alternatives);
5571      assert = CURRENT_AS(bracket_fallback)->u.assert;      assert = CURRENT_AS(bracket_fallback)->u.assert;
5572      if (assert->framesize >= 0 && (ccbegin[1 + LINK_SIZE] == OP_ASSERT || ccbegin[1 + LINK_SIZE] == OP_ASSERTBACK))      if (assert->framesize >= 0 && (ccbegin[1 + LINK_SIZE] == OP_ASSERT || ccbegin[1 + LINK_SIZE] == OP_ASSERTBACK))
5573        {        {
# Line 5396  if (opcode == OP_COND || opcode == OP_SC Line 5578  if (opcode == OP_COND || opcode == OP_SC
5578      cond = JUMP(SLJIT_JUMP);      cond = JUMP(SLJIT_JUMP);
5579      set_jumps(CURRENT_AS(bracket_fallback)->u.assert->condfailed, LABEL());      set_jumps(CURRENT_AS(bracket_fallback)->u.assert->condfailed, LABEL());
5580      }      }
5581    else    else if (CURRENT_AS(bracket_fallback)->u.condfailed != NULL)
5582      {      {
5583        SLJIT_ASSERT(has_alternatives);
5584      cond = JUMP(SLJIT_JUMP);      cond = JUMP(SLJIT_JUMP);
5585      set_jumps(CURRENT_AS(bracket_fallback)->u.condfailed, LABEL());      set_jumps(CURRENT_AS(bracket_fallback)->u.condfailed, LABEL());
5586      }      }
5587      else
5588        SLJIT_ASSERT(!has_alternatives);
5589    }    }
5590    
5591  if (*cc == OP_ALT || opcode == OP_COND || opcode == OP_SCOND)  if (has_alternatives)
5592    {    {
5593    count = 1;    count = 1;
5594    do    do
# Line 5431  if (*cc == OP_ALT || opcode == OP_COND | Line 5616  if (*cc == OP_ALT || opcode == OP_COND |
5616      /* There is a similar code in compile_bracket_hotpath. */      /* There is a similar code in compile_bracket_hotpath. */
5617      if (opcode == OP_ONCE)      if (opcode == OP_ONCE)
5618        {        {
5619        if (CURRENT_AS(bracket_fallback)->u.framesize >= 0)        if (CURRENT_AS(bracket_fallback)->u.framesize < 0)
5620          {          {
5621            OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
5622            /* TMP2 which is set here used by OP_KETRMAX below. */
5623          if (ket == OP_KETRMAX)          if (ket == OP_KETRMAX)
5624              OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), 0);
5625            else if (ket == OP_KETRMIN)
5626            {            {
5627            OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);            /* Move the STR_PTR to the localptr. */
5628            OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP2), (CURRENT_AS(bracket_fallback)->u.framesize + 1) * sizeof(sljit_w));            OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_MEM1(STACK_TOP), 0);
5629            }            }
5630          }          }
5631        else        else
5632          {          {
5633          OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);          OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_IMM, (CURRENT_AS(bracket_fallback)->u.framesize + 2) * sizeof(sljit_w));
         /* The register which is set here used by OP_KETRMAX below. */  
5634          if (ket == OP_KETRMAX)          if (ket == OP_KETRMAX)
5635            OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), 0);            {
5636          else if (ket == OP_KETRMIN)            /* TMP2 which is set here used by OP_KETRMAX below. */
5637            OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_MEM1(STACK_TOP), 0);            OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
5638              }
5639          }          }
5640        }        }
5641    
# Line 5544  else if (opcode == OP_ONCE) Line 5733  else if (opcode == OP_ONCE)
5733      {      {
5734      /* Reset head and drop saved frame. */      /* Reset head and drop saved frame. */
5735      stacksize = (ket == OP_KETRMAX || ket == OP_KETRMIN || *cc == OP_ALT) ? 2 : 1;      stacksize = (ket == OP_KETRMAX || ket == OP_KETRMIN || *cc == OP_ALT) ? 2 : 1;
     if (CURRENT_AS(bracket_fallback)->u.framesize > 0)  
       OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(stacksize));  
5736      free_stack(common, CURRENT_AS(bracket_fallback)->u.framesize + stacksize);      free_stack(common, CURRENT_AS(bracket_fallback)->u.framesize + stacksize);
     if (CURRENT_AS(bracket_fallback)->u.framesize > 0)  
       OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS_HEAD, TMP1, 0);  
5737      }      }
5738    else if (ket == OP_KETRMAX || (*cc == OP_ALT && ket != OP_KETRMIN))    else if (ket == OP_KETRMAX || (*cc == OP_ALT && ket != OP_KETRMIN))
5739      {      {
# Line 5632  if (current->topfallbacks) Line 5817  if (current->topfallbacks)
5817    {    {
5818    jump = JUMP(SLJIT_JUMP);    jump = JUMP(SLJIT_JUMP);
5819    set_jumps(current->topfallbacks, LABEL());    set_jumps(current->topfallbacks, LABEL());
5820    /* Drop the stack frame and restore LOCALS_HEAD. */    /* Drop the stack frame. */
   OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(CURRENT_AS(bracketpos_fallback)->stacksize - CURRENT_AS(bracketpos_fallback)->framesize));  
5821    free_stack(common, CURRENT_AS(bracketpos_fallback)->stacksize);    free_stack(common, CURRENT_AS(bracketpos_fallback)->stacksize);
   OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS_HEAD, TMP1, 0);  
5822    JUMPHERE(jump);    JUMPHERE(jump);
5823    }    }
5824  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), CURRENT_AS(bracketpos_fallback)->localptr, SLJIT_MEM1(STACK_TOP), CURRENT_AS(bracketpos_fallback)->framesize * sizeof(sljit_w));  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), CURRENT_AS(bracketpos_fallback)->localptr, SLJIT_MEM1(STACK_TOP), CURRENT_AS(bracketpos_fallback)->framesize * sizeof(sljit_w));
# Line 5769  while (current) Line 5952  while (current)
5952      break;      break;
5953    
5954      case OP_ONCE:      case OP_ONCE:
5955        case OP_ONCE_NC:
5956      case OP_BRA:      case OP_BRA:
5957      case OP_CBRA:      case OP_CBRA:
5958      case OP_COND:      case OP_COND:
# Line 5814  while (current) Line 5998  while (current)
5998  static SLJIT_INLINE void compile_recurse(compiler_common *common)  static SLJIT_INLINE void compile_recurse(compiler_common *common)
5999  {  {
6000  DEFINE_COMPILER;  DEFINE_COMPILER;
6001  uschar *cc = common->start + common->currententry->start;  pcre_uchar *cc = common->start + common->currententry->start;
6002  uschar *ccbegin = cc + 1 + LINK_SIZE + (*cc == OP_BRA ? 0 : 2);  pcre_uchar *ccbegin = cc + 1 + LINK_SIZE + (*cc == OP_BRA ? 0 : 2);
6003  uschar *ccend = bracketend(cc);  pcre_uchar *ccend = bracketend(cc);
6004  int localsize = get_localsize(common, ccbegin, ccend);  int localsize = get_localsize(common, ccbegin, ccend);
6005  int framesize = get_framesize(common, cc, TRUE);  int framesize = get_framesize(common, cc, TRUE);
6006  int alternativesize;  int alternativesize;
# Line 5840  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), ST Line 6024  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), ST
6024  copy_locals(common, ccbegin, ccend, TRUE, localsize + framesize + alternativesize, framesize + alternativesize);  copy_locals(common, ccbegin, ccend, TRUE, localsize + framesize + alternativesize, framesize + alternativesize);
6025  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), RECURSIVE_HEAD, STACK_TOP, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), RECURSIVE_HEAD, STACK_TOP, 0);
6026  if (needsframe)  if (needsframe)
   {  
   OP2(SLJIT_SUB, TMP2, 0, STACK_TOP, 0, SLJIT_IMM, -STACK(framesize + alternativesize - 1));  
6027    init_frame(common, cc, framesize + alternativesize - 1, alternativesize, FALSE);    init_frame(common, cc, framesize + alternativesize - 1, alternativesize, FALSE);
   }  
6028    
6029  if (alternativesize > 0)  if (alternativesize > 0)
6030    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
# Line 5880  while (1) Line 6061  while (1)
6061    }    }
6062  /* None of them matched. */  /* None of them matched. */
6063  OP1(SLJIT_MOV, TMP3, 0, SLJIT_IMM, 0);  OP1(SLJIT_MOV, TMP3, 0, SLJIT_IMM, 0);
 if (needsframe)  
   OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS_HEAD, SLJIT_MEM1(STACK_TOP), STACK(alternativesize));  
6064  jump = JUMP(SLJIT_JUMP);  jump = JUMP(SLJIT_JUMP);
6065    
6066  set_jumps(common->accept, LABEL());  set_jumps(common->accept, LABEL());
# Line 5889  OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1( Line 6068  OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(
6068  if (needsframe)  if (needsframe)
6069    {    {
6070    OP1(SLJIT_MOV, TMP3, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0));    OP1(SLJIT_MOV, TMP3, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0));
6071    OP2(SLJIT_SUB, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, (localsize + framesize + alternativesize) * sizeof(sljit_w));    OP2(SLJIT_SUB, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, (framesize + alternativesize) * sizeof(sljit_w));
6072    add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
6073    OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, (localsize + framesize + alternativesize) * sizeof(sljit_w));    OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, (framesize + alternativesize) * sizeof(sljit_w));
6074    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0), TMP3, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0), TMP3, 0);
6075    }    }
6076  OP1(SLJIT_MOV, TMP3, 0, SLJIT_IMM, 1);  OP1(SLJIT_MOV, TMP3, 0, SLJIT_IMM, 1);
# Line 5915  struct sljit_compiler *compiler; Line 6094  struct sljit_compiler *compiler;
6094  fallback_common rootfallback;  fallback_common rootfallback;
6095  compiler_common common_data;  compiler_common common_data;
6096  compiler_common *common = &common_data;  compiler_common *common = &common_data;
6097  const unsigned char *tables = re->tables;  const pcre_uint8 *tables = re->tables;
6098  pcre_study_data *study;  pcre_study_data *study;
6099  uschar *ccend;  pcre_uchar *ccend;
6100  executable_function *function;  executable_function *function;
6101  void *executable_func;  void *executable_func;
6102  struct sljit_label *leave;  struct sljit_label *leave;
# Line 5935  if (!tables) Line 6114  if (!tables)
6114    tables = _pcre_default_tables;    tables = _pcre_default_tables;
6115    
6116  memset(&rootfallback, 0, sizeof(fallback_common));  memset(&rootfallback, 0, sizeof(fallback_common));
6117  rootfallback.cc = (uschar *)re + re->name_table_offset + re->name_count * re->name_entry_size;  rootfallback.cc = (pcre_uchar *)re + re->name_table_offset + re->name_count * re->name_entry_size;
6118    
6119  common->compiler = NULL;  common->compiler = NULL;
6120  common->start = rootfallback.cc;  common->start = rootfallback.cc;
# Line 5976  else Line 6155  else
6155    }    }
6156  common->endonly = (re->options & PCRE_DOLLAR_ENDONLY) != 0;  common->endonly = (re->options & PCRE_DOLLAR_ENDONLY) != 0;
6157  common->ctypes = (sljit_w)(tables + ctypes_offset);  common->ctypes = (sljit_w)(tables + ctypes_offset);
6158    common->name_table = (sljit_w)re + re->name_table_offset;
6159    common->name_count = re->name_count;
6160    common->name_entry_size = re->name_entry_size;
6161  common->acceptlabel = NULL;  common->acceptlabel = NULL;
6162  common->stubs = NULL;  common->stubs = NULL;
6163  common->entries = NULL;  common->entries = NULL;
# Line 6031  sljit_emit_enter(compiler, 1, 5, 5, comm Line 6213  sljit_emit_enter(compiler, 1, 5, 5, comm
6213  reset_ovector(common, (re->top_bracket + 1) * 2);  reset_ovector(common, (re->top_bracket + 1) * 2);
6214  if ((re->flags & PCRE_REQCHSET) != 0)  if ((re->flags & PCRE_REQCHSET) != 0)
6215    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), REQ_BYTE_PTR, SLJIT_TEMPORARY_REG1, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), REQ_BYTE_PTR, SLJIT_TEMPORARY_REG1, 0);
 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS_HEAD, SLJIT_IMM, 0);  
6216    
6217  OP1(SLJIT_MOV, ARGUMENTS, 0, SLJIT_GENERAL_REG1, 0);  OP1(SLJIT_MOV, ARGUMENTS, 0, SLJIT_GENERAL_REG1, 0);
6218  OP1(SLJIT_MOV, TMP1, 0, SLJIT_GENERAL_REG1, 0);  OP1(SLJIT_MOV, TMP1, 0, SLJIT_GENERAL_REG1, 0);
# Line 6273  union { Line 6454  union {
6454     void* executable_func;     void* executable_func;
6455     jit_function call_executable_func;     jit_function call_executable_func;
6456  } convert_executable_func;  } convert_executable_func;
6457  uschar local_area[LOCAL_SPACE_SIZE];  pcre_uint8 local_area[LOCAL_SPACE_SIZE];
6458  struct sljit_stack local_stack;  struct sljit_stack local_stack;
6459    
6460  local_stack.top = (sljit_w)&local_area;  local_stack.top = (sljit_w)&local_area;

Legend:
Removed from v.715  
changed lines
  Added in v.763

  ViewVC Help
Powered by ViewVC 1.1.5