/[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 715 by zherczeg, Sat Oct 1 06:42:38 2011 UTC revision 736 by zherczeg, Sun Oct 16 15:48:03 2011 UTC
# Line 352  enum { Line 352  enum {
352  /* Two local variables for possessive quantifiers (char1 cannot use them). */  /* Two local variables for possessive quantifiers (char1 cannot use them). */
353  #define POSSESSIVE0      (2 * sizeof(sljit_w))  #define POSSESSIVE0      (2 * sizeof(sljit_w))
354  #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))  
355  /* Head of the last recursion. */  /* Head of the last recursion. */
356  #define RECURSIVE_HEAD   (5 * sizeof(sljit_w))  #define RECURSIVE_HEAD   (4 * sizeof(sljit_w))
357  /* Max limit of recursions. */  /* Max limit of recursions. */
358  #define CALL_LIMIT       (7 * sizeof(sljit_w))  #define CALL_LIMIT       (5 * sizeof(sljit_w))
359  /* Last known position of the requested byte. */  /* Last known position of the requested byte. */
360  #define REQ_BYTE_PTR     (8 * sizeof(sljit_w))  #define REQ_BYTE_PTR     (6 * sizeof(sljit_w))
361  /* End pointer of the first line. */  /* End pointer of the first line. */
362  #define FIRSTLINE_END    (9 * sizeof(sljit_w))  #define FIRSTLINE_END    (7 * sizeof(sljit_w))
363  /* The output vector is stored on the stack, and contains pointers  /* The output vector is stored on the stack, and contains pointers
364  to characters. The vector data is divided into two groups: the first  to characters. The vector data is divided into two groups: the first
365  group contains the start / end character pointers, and the second is  group contains the start / end character pointers, and the second is
366  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. */
367  #define OVECTOR_START    (10 * sizeof(sljit_w))  #define OVECTOR_START    (8 * sizeof(sljit_w))
368  #define OVECTOR(i)       (OVECTOR_START + (i) * sizeof(sljit_w))  #define OVECTOR(i)       (OVECTOR_START + (i) * sizeof(sljit_w))
369  #define OVECTOR_PRIV(i)  (common->cbraptr + (i) * sizeof(sljit_w))  #define OVECTOR_PRIV(i)  (common->cbraptr + (i) * sizeof(sljit_w))
370  #define PRIV(cc)         (common->localptrs[(cc) - common->start])  #define PRIV(cc)         (common->localptrs[(cc) - common->start])
# Line 469  switch(*cc) Line 467  switch(*cc)
467    case OP_SKIPZERO:    case OP_SKIPZERO:
468    return cc + 1;    return cc + 1;
469    
470      case OP_ANYBYTE:
471    #ifdef SUPPORT_UTF8
472      if (common->utf8) return NULL;
473    #endif
474      return cc + 1;
475    
476    case OP_CHAR:    case OP_CHAR:
477    case OP_CHARI:    case OP_CHARI:
478    case OP_NOT:    case OP_NOT:
# Line 571  switch(*cc) Line 575  switch(*cc)
575    case OP_ASSERTBACK_NOT:    case OP_ASSERTBACK_NOT:
576    case OP_REVERSE:    case OP_REVERSE:
577    case OP_ONCE:    case OP_ONCE:
578      case OP_ONCE_NC:
579    case OP_BRA:    case OP_BRA:
580    case OP_BRAPOS:    case OP_BRAPOS:
581    case OP_COND:    case OP_COND:
# Line 609  while (cc < ccend) Line 614  while (cc < ccend)
614      case OP_ASSERTBACK:      case OP_ASSERTBACK:
615      case OP_ASSERTBACK_NOT:      case OP_ASSERTBACK_NOT:
616      case OP_ONCE:      case OP_ONCE:
617        case OP_ONCE_NC:
618      case OP_BRAPOS:      case OP_BRAPOS:
619      case OP_SBRA:      case OP_SBRA:
620      case OP_SBRAPOS:      case OP_SBRAPOS:
# Line 654  while (cc < ccend) Line 660  while (cc < ccend)
660      case OP_ASSERTBACK:      case OP_ASSERTBACK:
661      case OP_ASSERTBACK_NOT:      case OP_ASSERTBACK_NOT:
662      case OP_ONCE:      case OP_ONCE:
663        case OP_ONCE_NC:
664      case OP_BRAPOS:      case OP_BRAPOS:
665      case OP_SBRA:      case OP_SBRA:
666      case OP_SBRAPOS:      case OP_SBRAPOS:
# Line 693  while (cc < ccend) Line 700  while (cc < ccend)
700  static int get_framesize(compiler_common *common, uschar *cc, BOOL recursive)  static int get_framesize(compiler_common *common, uschar *cc, BOOL recursive)
701  {  {
702  uschar *ccend = bracketend(cc);  uschar *ccend = bracketend(cc);
 uschar *end;  
703  int length = 0;  int length = 0;
704  BOOL possessive = FALSE;  BOOL possessive = FALSE;
 BOOL needs_frame = FALSE;  
705  BOOL setsom_found = FALSE;  BOOL setsom_found = FALSE;
706    
707  if (!recursive && (*cc == OP_CBRAPOS || *cc == OP_SCBRAPOS))  if (!recursive && (*cc == OP_CBRAPOS || *cc == OP_SCBRAPOS))
# Line 720  while (cc < ccend) Line 725  while (cc < ccend)
725      cc += (*cc == OP_SET_SOM) ? 1 : 1 + LINK_SIZE;      cc += (*cc == OP_SET_SOM) ? 1 : 1 + LINK_SIZE;
726      break;      break;
727    
     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;  
   
728      case OP_CBRA:      case OP_CBRA:
729      case OP_CBRAPOS:      case OP_CBRAPOS:
730      case OP_SCBRA:      case OP_SCBRA:
# Line 757  while (cc < ccend) Line 740  while (cc < ccend)
740      }      }
741    
742  /* Possessive quantifiers can use a special case. */  /* Possessive quantifiers can use a special case. */
743  if (SLJIT_UNLIKELY(possessive) && !needs_frame && length == 3 + 2)  if (SLJIT_UNLIKELY(possessive) && length == 3)
744    return -1;    return -1;
745    
746  if (length > 0)  if (length > 0)
747    return length + 2;    return length + 1;
748  return needs_frame ? 0 : -1;  return -1;
749  }  }
750    
751  static void init_frame(compiler_common *common, uschar *cc, int stackpos, int stacktop, BOOL recursive)  static void init_frame(compiler_common *common, uschar *cc, int stackpos, int stacktop, BOOL recursive)
752  {  {
 /* TMP2 must contain STACK_TOP - (-STACK(stackpos)) */  
753  DEFINE_COMPILER;  DEFINE_COMPILER;
754  uschar *ccend = bracketend(cc);  uschar *ccend = bracketend(cc);
755  BOOL setsom_found = FALSE;  BOOL setsom_found = FALSE;
756  int offset;  int offset;
757    
758  if (stackpos < stacktop)  /* >= 1 + shortest item size (2) */
759    {  SLJIT_ASSERT(stackpos >= stacktop + 2);
   SLJIT_ASSERT(stackpos + 1 == stacktop);  
   return;  
   }  
760    
761  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);  
   
762  if (recursive || (*cc != OP_CBRAPOS && *cc != OP_SCBRAPOS))  if (recursive || (*cc != OP_CBRAPOS && *cc != OP_SCBRAPOS))
763    cc = next_opcode(common, cc);    cc = next_opcode(common, cc);
764  SLJIT_ASSERT(cc != NULL);  SLJIT_ASSERT(cc != NULL);
# Line 804  while (cc < ccend) Line 779  while (cc < ccend)
779      cc += (*cc == OP_SET_SOM) ? 1 : 1 + LINK_SIZE;      cc += (*cc == OP_SET_SOM) ? 1 : 1 + LINK_SIZE;
780      break;      break;
781    
     case OP_ASSERT:  
     case OP_ASSERT_NOT:  
     case OP_ASSERTBACK:  
     case OP_ASSERTBACK_NOT:  
     case OP_ONCE:  
     cc = bracketend(cc);  
     break;  
   
782      case OP_CBRA:      case OP_CBRA:
783      case OP_CBRAPOS:      case OP_CBRAPOS:
784      case OP_SCBRA:      case OP_SCBRA:
# Line 836  while (cc < ccend) Line 803  while (cc < ccend)
803      }      }
804    
805  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, frame_end);  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, frame_end);
806  SLJIT_ASSERT(stackpos == STACK(stacktop + 1));  SLJIT_ASSERT(stackpos == STACK(stacktop));
807  }  }
808    
809  static SLJIT_INLINE int get_localsize(compiler_common *common, uschar *cc, uschar *ccend)  static SLJIT_INLINE int get_localsize(compiler_common *common, uschar *cc, uschar *ccend)
# Line 853  while (cc < ccend) Line 820  while (cc < ccend)
820      case OP_ASSERTBACK:      case OP_ASSERTBACK:
821      case OP_ASSERTBACK_NOT:      case OP_ASSERTBACK_NOT:
822      case OP_ONCE:      case OP_ONCE:
823        case OP_ONCE_NC:
824      case OP_BRAPOS:      case OP_BRAPOS:
825      case OP_SBRA:      case OP_SBRA:
826      case OP_SBRAPOS:      case OP_SBRAPOS:
# Line 955  while (status != end) Line 923  while (status != end)
923        case OP_ASSERTBACK:        case OP_ASSERTBACK:
924        case OP_ASSERTBACK_NOT:        case OP_ASSERTBACK_NOT:
925        case OP_ONCE:        case OP_ONCE:
926          case OP_ONCE_NC:
927        case OP_BRAPOS:        case OP_BRAPOS:
928        case OP_SBRA:        case OP_SBRA:
929        case OP_SBRAPOS:        case OP_SBRAPOS:
# Line 1373  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(ST Line 1342  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(ST
1342  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF8
1343  if (common->utf8)  if (common->utf8)
1344    {    {
1345    /* 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);  
1346    add_jump(compiler, &common->utf8readchar, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->utf8readchar, JUMP(SLJIT_FAST_CALL));
1347    JUMPHERE(jump);    JUMPHERE(jump);
1348    }    }
# Line 1395  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(ST Line 1363  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(ST
1363  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF8
1364  if (common->utf8)  if (common->utf8)
1365    {    {
1366    /* 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);  
1367    add_jump(compiler, &common->utf8readchar, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->utf8readchar, JUMP(SLJIT_FAST_CALL));
1368    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
1369    JUMPHERE(jump);    JUMPHERE(jump);
# Line 1420  if (common->utf8) Line 1387  if (common->utf8)
1387    /* This can be an extra read in some situations, but hopefully    /* This can be an extra read in some situations, but hopefully
1388    it is a clever early read in most cases. */    it is a clever early read in most cases. */
1389    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);
1390    /* 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);  
1391    add_jump(compiler, &common->utf8readtype8, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->utf8readtype8, JUMP(SLJIT_FAST_CALL));
1392    JUMPHERE(jump);    JUMPHERE(jump);
1393    return;    return;
# Line 1481  else Line 1447  else
1447  static void do_utf8readchar(compiler_common *common)  static void do_utf8readchar(compiler_common *common)
1448  {  {
1449  /* Fast decoding an utf8 character. TMP1 contains the first byte  /* Fast decoding an utf8 character. TMP1 contains the first byte
1450  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. */
1451  DEFINE_COMPILER;  DEFINE_COMPILER;
1452  struct sljit_jump *jump;  struct sljit_jump *jump;
1453    
# Line 1564  sljit_emit_fast_return(compiler, RETURN_ Line 1530  sljit_emit_fast_return(compiler, RETURN_
1530  static void do_utf8readtype8(compiler_common *common)  static void do_utf8readtype8(compiler_common *common)
1531  {  {
1532  /* Fast decoding an utf8 character type. TMP2 contains the first byte  /* Fast decoding an utf8 character type. TMP2 contains the first byte
1533  of the character (>= 192) and TMP1 is destroyed. Return value in TMP1. */  of the character (>= 0xc0) and TMP1 is destroyed. Return value in TMP1. */
1534  DEFINE_COMPILER;  DEFINE_COMPILER;
1535  struct sljit_jump *jump;  struct sljit_jump *jump;
1536  struct sljit_jump *compare;  struct sljit_jump *compare;
# Line 1590  sljit_emit_fast_return(compiler, RETURN_ Line 1556  sljit_emit_fast_return(compiler, RETURN_
1556  JUMPHERE(jump);  JUMPHERE(jump);
1557    
1558  /* We only have types for characters less than 256. */  /* We only have types for characters less than 256. */
1559  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_char_sizes - 0xc0);
 OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);  
1560  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
1561  OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);  OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);
1562  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
# Line 1635  struct sljit_label *newlinelabel = NULL; Line 1600  struct sljit_label *newlinelabel = NULL;
1600  struct sljit_jump *start;  struct sljit_jump *start;
1601  struct sljit_jump *end = NULL;  struct sljit_jump *end = NULL;
1602  struct sljit_jump *nl = NULL;  struct sljit_jump *nl = NULL;
1603    #ifdef SUPPORT_UTF8
1604    struct sljit_jump *singlebyte;
1605    #endif
1606  jump_list *newline = NULL;  jump_list *newline = NULL;
1607  BOOL newlinecheck = FALSE;  BOOL newlinecheck = FALSE;
1608  BOOL readbyte = FALSE;  BOOL readbyte = FALSE;
# Line 1705  if (readbyte) Line 1673  if (readbyte)
1673  if (newlinecheck)  if (newlinecheck)
1674    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);
1675    
1676    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 1);
1677  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF8
1678  if (common->utf8)  if (common->utf8)
1679    {    {
1680    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);
1681      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)_pcre_utf8_char_sizes - 0xc0);
1682    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
1683      JUMPHERE(singlebyte);
1684    }    }
 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);  
1685  #endif  #endif
1686  JUMPHERE(start);  JUMPHERE(start);
1687    
# Line 1767  else Line 1734  else
1734      }      }
1735    }    }
1736    
1737    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 1);
1738  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF8
1739  if (common->utf8)  if (common->utf8)
1740    {    {
1741    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);
1742      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)_pcre_utf8_char_sizes - 0xc0);
1743    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
1744    }    }
 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);  
1745  #endif  #endif
1746  JUMPTO(SLJIT_JUMP, start);  JUMPTO(SLJIT_JUMP, start);
1747  JUMPHERE(found);  JUMPHERE(found);
# Line 1883  leave = CMP(SLJIT_C_GREATER_EQUAL, STR_P Line 1848  leave = CMP(SLJIT_C_GREATER_EQUAL, STR_P
1848  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
1849  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF8
1850  if (common->utf8)  if (common->utf8)
1851    OP1(SLJIT_MOV_UB, TMP3, 0, SLJIT_MEM1(TMP1), (sljit_w)_pcre_utf8_char_sizes);    OP1(SLJIT_MOV, TMP3, 0, TMP1, 0);
1852  #endif  #endif
1853  OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);  OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);
1854  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 1859  found = JUMP(SLJIT_C_NOT_ZERO);
1859    
1860  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF8
1861  if (common->utf8)  if (common->utf8)
1862    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP3, 0);    OP1(SLJIT_MOV, TMP1, 0, TMP3, 0);
1863  else  #endif
   OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 1);  
 #else  
1864  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 1);  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 1);
1865    #ifdef SUPPORT_UTF8
1866    if (common->utf8)
1867      {
1868      CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0, start);
1869      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)_pcre_utf8_char_sizes - 0xc0);
1870      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
1871      }
1872  #endif  #endif
1873  JUMPTO(SLJIT_JUMP, start);  JUMPTO(SLJIT_JUMP, start);
1874  JUMPHERE(found);  JUMPHERE(found);
# Line 1966  return notfound; Line 1936  return notfound;
1936  static void do_revertframes(compiler_common *common)  static void do_revertframes(compiler_common *common)
1937  {  {
1938  DEFINE_COMPILER;  DEFINE_COMPILER;
 struct sljit_jump *earlyexit;  
1939  struct sljit_jump *jump;  struct sljit_jump *jump;
1940  struct sljit_label *mainloop;  struct sljit_label *mainloop;
1941    
1942  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);
1943  OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS_HEAD);  OP1(SLJIT_MOV, TMP1, 0, STACK_TOP, 0);
1944    
1945  /* Drop frames until we reach STACK_TOP. */  /* Drop frames until we reach STACK_TOP. */
 earlyexit = CMP(SLJIT_C_LESS, TMP1, 0, STACK_TOP, 0);  
1946  mainloop = LABEL();  mainloop = LABEL();
1947  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), 0);  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), 0);
1948  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 1955  JUMPTO(SLJIT_JUMP, mainloop);
1955  JUMPHERE(jump);  JUMPHERE(jump);
1956  jump = CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, frame_end);  jump = CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, frame_end);
1957  /* 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);  
1958  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
1959    
1960  JUMPHERE(jump);  JUMPHERE(jump);
# Line 2831  switch(type) Line 2795  switch(type)
2795    if (common->utf8)    if (common->utf8)
2796      {      {
2797      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
2798      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);
2799        jump[0] = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);
2800        OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)_pcre_utf8_char_sizes - 0xc0);
2801      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2802        JUMPHERE(jump[0]);
2803      return cc;      return cc;
2804      }      }
2805  #endif  #endif
2806    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 1);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 1);
2807    return cc;    return cc;
2808    
2809      case OP_ANYBYTE:
2810      check_input_end(common, fallbacks);
2811      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 1);
2812      return cc;
2813    
2814  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF8
2815  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
2816    case OP_NOTPROP:    case OP_NOTPROP:
# Line 3085  switch(type) Line 3057  switch(type)
3057      if (c <= 127)      if (c <= 127)
3058        {        {
3059        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);  
3060        if (type == OP_NOT || !char_has_othercase(common, cc))        if (type == OP_NOT || !char_has_othercase(common, cc))
3061          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));
3062        else        else
3063          {          {
3064          /* 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. */
3065          OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x20);          OP2(SLJIT_OR, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x20);
3066          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));
3067          }          }
3068        /* Skip the variable-length character. */        /* Skip the variable-length character. */
3069        OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0);        OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 1);
3070          jump[0] = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);
3071          OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)_pcre_utf8_char_sizes - 0xc0);
3072          OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
3073          JUMPHERE(jump[0]);
3074        return cc + length;        return cc + length;
3075        }        }
3076      else      else
# Line 3632  while (1) Line 3607  while (1)
3607    if (common->accept != NULL)    if (common->accept != NULL)
3608      set_jumps(common->accept, common->acceptlabel);      set_jumps(common->accept, common->acceptlabel);
3609    
3610      /* Reset stack. */
3611    if (framesize < 0)    if (framesize < 0)
3612      OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);      OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
3613      else {
3614        if ((opcode != OP_ASSERT_NOT && opcode != OP_ASSERTBACK_NOT) || conditional)
3615          {
3616          /* We don't need to keep the STR_PTR, only the previous localptr. */
3617          OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_IMM, (framesize + 1) * sizeof(sljit_w));
3618          }
3619        else
3620          {
3621          OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
3622          add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
3623          }
3624      }
3625    
3626    if (opcode == OP_ASSERT_NOT || opcode == OP_ASSERTBACK_NOT)    if (opcode == OP_ASSERT_NOT || opcode == OP_ASSERTBACK_NOT)
3627      {      {
3628      /* 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. */
3629      if (conditional)      if (conditional)
3630        {        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));  
         }  
       }  
3631      else if (bra == OP_BRAZERO)      else if (bra == OP_BRAZERO)
3632        {        {
3633        if (framesize < 0)        if (framesize < 0)
3634          OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), 0);          OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), 0);
3635        else        else
3636          {          {
         OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);  
         add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));  
3637          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));
3638          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));
3639          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 3641  while (1)
3641        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));
3642        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
3643        }        }
3644      else if (bra == OP_BRAMINZERO)      else if (framesize >= 0)
3645        {        {
3646        if (framesize >= 0)        /* For OP_BRA and OP_BRAMINZERO. */
3647          {        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));  
         }  
3648        }        }
3649      }      }
3650    add_jump(compiler, found, JUMP(SLJIT_JUMP));    add_jump(compiler, found, JUMP(SLJIT_JUMP));
# Line 3697  if (opcode == OP_ASSERT || opcode == OP_ Line 3671  if (opcode == OP_ASSERT || opcode == OP_
3671    /* Assert is failed. */    /* Assert is failed. */
3672    if (conditional || bra == OP_BRAZERO)    if (conditional || bra == OP_BRAZERO)
3673      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
3674    
3675    if (framesize < 0)    if (framesize < 0)
3676      {      {
3677      /* The topmost item should be 0. */      /* The topmost item should be 0. */
# Line 3708  if (opcode == OP_ASSERT || opcode == OP_ Line 3683  if (opcode == OP_ASSERT || opcode == OP_
3683    else    else
3684      {      {
3685      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));  
3686      /* The topmost item should be 0. */      /* The topmost item should be 0. */
3687      if (bra == OP_BRAZERO)      if (bra == OP_BRAZERO)
3688        {        {
# Line 3719  if (opcode == OP_ASSERT || opcode == OP_ Line 3692  if (opcode == OP_ASSERT || opcode == OP_
3692      else      else
3693        free_stack(common, framesize + 2);        free_stack(common, framesize + 2);
3694      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);  
3695      }      }
3696    jump = JUMP(SLJIT_JUMP);    jump = JUMP(SLJIT_JUMP);
3697    if (bra != OP_BRAZERO)    if (bra != OP_BRAZERO)
# Line 3743  if (opcode == OP_ASSERT || opcode == OP_ Line 3714  if (opcode == OP_ASSERT || opcode == OP_
3714      }      }
3715    else    else
3716      {      {
3717      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)  
3718        {        {
3719        allocate_stack(common, 1);        /* We don't need to keep the STR_PTR, only the previous localptr. */
3720        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));
3721          OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), 0);
3722        }        }
3723      else if (bra == OP_BRAMINZERO)      else
3724        {        {
3725        allocate_stack(common, 1);        /* We don't need to keep the STR_PTR, only the previous localptr. */
3726        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));
3727          OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
3728          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), bra == OP_BRAZERO ? STR_PTR : SLJIT_IMM, 0);
3729        }        }
3730      }      }
3731    
# Line 3790  else Line 3762  else
3762      {      {
3763      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
3764      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));  
3765      /* The topmost item should be 0. */      /* The topmost item should be 0. */
3766      if (bra != OP_BRA)      if (bra != OP_BRA)
3767        {        {
# Line 3801  else Line 3771  else
3771      else      else
3772        free_stack(common, framesize + 2);        free_stack(common, framesize + 2);
3773      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);  
3774      }      }
3775    
3776    if (bra == OP_BRAZERO)    if (bra == OP_BRAZERO)
# Line 3873  return cc + 1 + LINK_SIZE; Line 3841  return cc + 1 + LINK_SIZE;
3841      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.
3842    
3843    The next list shows the possible content of a bracket:    The next list shows the possible content of a bracket:
3844    (|)     OP_*BRA  | OP_ALT ...         M A    (|)     OP_*BRA    | OP_ALT ...         M A
3845    (?()|)  OP_*COND | OP_ALT             M A    (?()|)  OP_*COND   | OP_ALT             M A
3846    (?>|)   OP_ONCE  | OP_ALT ...         [stack trace] M A    (?>|)   OP_ONCE    | OP_ALT ...         [stack trace] M A
3847                                          Or nothing, if trace is unnecessary    (?>|)   OP_ONCE_NC | OP_ALT ...         [stack trace] M A
3848                                              Or nothing, if trace is unnecessary
3849  */  */
3850    
3851  static uschar *compile_bracket_hotpath(compiler_common *common, uschar *cc, fallback_common *parent)  static uschar *compile_bracket_hotpath(compiler_common *common, uschar *cc, fallback_common *parent)
# Line 3923  cc += GET(cc, 1); Line 3892  cc += GET(cc, 1);
3892  has_alternatives = *cc == OP_ALT || opcode == OP_COND || opcode == OP_SCOND;  has_alternatives = *cc == OP_ALT || opcode == OP_COND || opcode == OP_SCOND;
3893  if (SLJIT_UNLIKELY(opcode == OP_COND) && (*cc == OP_KETRMAX || *cc == OP_KETRMIN))  if (SLJIT_UNLIKELY(opcode == OP_COND) && (*cc == OP_KETRMAX || *cc == OP_KETRMIN))
3894    opcode = OP_SCOND;    opcode = OP_SCOND;
3895    if (SLJIT_UNLIKELY(opcode == OP_ONCE_NC))
3896      opcode = OP_ONCE;
3897    
3898  if (opcode == OP_CBRA || opcode == OP_SCBRA)  if (opcode == OP_CBRA || opcode == OP_SCBRA)
3899    {    {
# Line 4130  if (opcode == OP_ONCE) Line 4101  if (opcode == OP_ONCE)
4101        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);
4102        }        }
4103      }      }
4104    else if (ket == OP_KETRMAX)    else
4105      {      {
4106      /* TMP2 which is set here used by OP_KETRMAX below. */      stacksize = (ket == OP_KETRMIN || ket == OP_KETRMAX || has_alternatives) ? 2 : 1;
4107      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));
4108      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP2), (FALLBACK_AS(bracket_fallback)->u.framesize + 1) * sizeof(sljit_w));      if (ket == OP_KETRMAX)
4109          {
4110          /* TMP2 which is set here used by OP_KETRMAX below. */
4111          OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
4112          }
4113      }      }
4114    }    }
4115    
# Line 4368  while (*cc != OP_KETRPOS) Line 4343  while (*cc != OP_KETRPOS)
4343      {      {
4344      if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS)      if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS)
4345        {        {
4346          OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_IMM, stacksize * sizeof(sljit_w));
4347        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);  
4348        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);
4349        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr, STR_PTR, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr, STR_PTR, 0);
4350        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 4352  while (*cc != OP_KETRPOS)
4352      else      else
4353        {        {
4354        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
4355          OP2(SLJIT_ADD, STACK_TOP, 0, TMP2, 0, SLJIT_IMM, stacksize * sizeof(sljit_w));
4356        if (opcode == OP_SBRAPOS)        if (opcode == OP_SBRAPOS)
4357          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));
4358        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 4361  while (*cc != OP_KETRPOS)
4361      if (opcode == OP_SBRAPOS || opcode == OP_SCBRAPOS)      if (opcode == OP_SBRAPOS || opcode == OP_SCBRAPOS)
4362        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));
4363    
     /* TMP2 must be set above. */  
4364      if (!zero)      if (!zero)
4365        {        {
4366        if (framesize < 0)        if (framesize < 0)
4367          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);
4368        else        else
4369          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);
4370        }        }
4371      }      }
4372    JUMPTO(SLJIT_JUMP, loop);    JUMPTO(SLJIT_JUMP, loop);
# Line 4414  while (*cc != OP_KETRPOS) Line 4388  while (*cc != OP_KETRPOS)
4388      {      {
4389      if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS)      if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS)
4390        {        {
4391          /* Last alternative. */
4392        if (*cc == OP_KETRPOS)        if (*cc == OP_KETRPOS)
4393          OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);          OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
4394        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 4787  while (cc < ccend) Line 4762  while (cc < ccend)
4762      case OP_WORDCHAR:      case OP_WORDCHAR:
4763      case OP_ANY:      case OP_ANY:
4764      case OP_ALLANY:      case OP_ALLANY:
4765        case OP_ANYBYTE:
4766      case OP_NOTPROP:      case OP_NOTPROP:
4767      case OP_PROP:      case OP_PROP:
4768      case OP_ANYNL:      case OP_ANYNL:
# Line 4946  while (cc < ccend) Line 4922  while (cc < ccend)
4922      break;      break;
4923    
4924      case OP_ONCE:      case OP_ONCE:
4925        case OP_ONCE_NC:
4926      case OP_BRA:      case OP_BRA:
4927      case OP_CBRA:      case OP_CBRA:
4928      case OP_COND:      case OP_COND:
# Line 5176  static void compile_assert_fallbackpath( Line 5153  static void compile_assert_fallbackpath(
5153  DEFINE_COMPILER;  DEFINE_COMPILER;
5154  uschar *cc = current->cc;  uschar *cc = current->cc;
5155  uschar bra = OP_BRA;  uschar bra = OP_BRA;
 struct sljit_jump *jump;  
5156  struct sljit_jump *brajump = NULL;  struct sljit_jump *brajump = NULL;
5157    
5158  SLJIT_ASSERT(*cc != OP_BRAMINZERO);  SLJIT_ASSERT(*cc != OP_BRAMINZERO);
# Line 5222  if (*cc == OP_ASSERT || *cc == OP_ASSERT Line 5198  if (*cc == OP_ASSERT || *cc == OP_ASSERT
5198    {    {
5199    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);
5200    add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
5201      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));
5202    
5203    set_jumps(current->topfallbacks, LABEL());    set_jumps(current->topfallbacks, LABEL());
5204    }    }
5205  else  else
   {  
   jump = JUMP(SLJIT_JUMP);  
   
5206    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));  
5207    
5208  if (bra == OP_BRAZERO)  if (bra == OP_BRAZERO)
5209    {    {
# Line 5281  if (opcode == OP_CBRA || opcode == OP_SC Line 5250  if (opcode == OP_CBRA || opcode == OP_SC
5250    offset = (GET2(ccbegin, 1 + LINK_SIZE)) << 1;    offset = (GET2(ccbegin, 1 + LINK_SIZE)) << 1;
5251  if (SLJIT_UNLIKELY(opcode == OP_COND) && (*cc == OP_KETRMAX || *cc == OP_KETRMIN))  if (SLJIT_UNLIKELY(opcode == OP_COND) && (*cc == OP_KETRMAX || *cc == OP_KETRMIN))
5252    opcode = OP_SCOND;    opcode = OP_SCOND;
5253    if (SLJIT_UNLIKELY(opcode == OP_ONCE_NC))
5254      opcode = OP_ONCE;
5255    
5256  if (ket == OP_KETRMAX)  if (ket == OP_KETRMAX)
5257    {    {
# Line 5431  if (*cc == OP_ALT || opcode == OP_COND | Line 5402  if (*cc == OP_ALT || opcode == OP_COND |
5402      /* There is a similar code in compile_bracket_hotpath. */      /* There is a similar code in compile_bracket_hotpath. */
5403      if (opcode == OP_ONCE)      if (opcode == OP_ONCE)
5404        {        {
5405        if (CURRENT_AS(bracket_fallback)->u.framesize >= 0)        if (CURRENT_AS(bracket_fallback)->u.framesize < 0)
5406          {          {
5407            OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
5408            /* TMP2 which is set here used by OP_KETRMAX below. */
5409          if (ket == OP_KETRMAX)          if (ket == OP_KETRMAX)
5410              OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), 0);
5411            else if (ket == OP_KETRMIN)
5412            {            {
5413            OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);            /* Move the STR_PTR to the localptr. */
5414            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);
5415            }            }
5416          }          }
5417        else        else
5418          {          {
5419          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. */  
5420          if (ket == OP_KETRMAX)          if (ket == OP_KETRMAX)
5421            OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), 0);            {
5422          else if (ket == OP_KETRMIN)            /* TMP2 which is set here used by OP_KETRMAX below. */
5423            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));
5424              }
5425          }          }
5426        }        }
5427    
# Line 5544  else if (opcode == OP_ONCE) Line 5519  else if (opcode == OP_ONCE)
5519      {      {
5520      /* Reset head and drop saved frame. */      /* Reset head and drop saved frame. */
5521      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));  
5522      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);  
5523      }      }
5524    else if (ket == OP_KETRMAX || (*cc == OP_ALT && ket != OP_KETRMIN))    else if (ket == OP_KETRMAX || (*cc == OP_ALT && ket != OP_KETRMIN))
5525      {      {
# Line 5632  if (current->topfallbacks) Line 5603  if (current->topfallbacks)
5603    {    {
5604    jump = JUMP(SLJIT_JUMP);    jump = JUMP(SLJIT_JUMP);
5605    set_jumps(current->topfallbacks, LABEL());    set_jumps(current->topfallbacks, LABEL());
5606    /* 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));  
5607    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);  
5608    JUMPHERE(jump);    JUMPHERE(jump);
5609    }    }
5610  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 5738  while (current)
5738      break;      break;
5739    
5740      case OP_ONCE:      case OP_ONCE:
5741        case OP_ONCE_NC:
5742      case OP_BRA:      case OP_BRA:
5743      case OP_CBRA:      case OP_CBRA:
5744      case OP_COND:      case OP_COND:
# Line 5840  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), ST Line 5810  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), ST
5810  copy_locals(common, ccbegin, ccend, TRUE, localsize + framesize + alternativesize, framesize + alternativesize);  copy_locals(common, ccbegin, ccend, TRUE, localsize + framesize + alternativesize, framesize + alternativesize);
5811  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);
5812  if (needsframe)  if (needsframe)
   {  
   OP2(SLJIT_SUB, TMP2, 0, STACK_TOP, 0, SLJIT_IMM, -STACK(framesize + alternativesize - 1));  
5813    init_frame(common, cc, framesize + alternativesize - 1, alternativesize, FALSE);    init_frame(common, cc, framesize + alternativesize - 1, alternativesize, FALSE);
   }  
5814    
5815  if (alternativesize > 0)  if (alternativesize > 0)
5816    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 5847  while (1)
5847    }    }
5848  /* None of them matched. */  /* None of them matched. */
5849  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));  
5850  jump = JUMP(SLJIT_JUMP);  jump = JUMP(SLJIT_JUMP);
5851    
5852  set_jumps(common->accept, LABEL());  set_jumps(common->accept, LABEL());
# Line 5889  OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1( Line 5854  OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(
5854  if (needsframe)  if (needsframe)
5855    {    {
5856    OP1(SLJIT_MOV, TMP3, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0));    OP1(SLJIT_MOV, TMP3, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0));
5857    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));
5858    add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
5859    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));
5860    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0), TMP3, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0), TMP3, 0);
5861    }    }
5862  OP1(SLJIT_MOV, TMP3, 0, SLJIT_IMM, 1);  OP1(SLJIT_MOV, TMP3, 0, SLJIT_IMM, 1);
# Line 6031  sljit_emit_enter(compiler, 1, 5, 5, comm Line 5996  sljit_emit_enter(compiler, 1, 5, 5, comm
5996  reset_ovector(common, (re->top_bracket + 1) * 2);  reset_ovector(common, (re->top_bracket + 1) * 2);
5997  if ((re->flags & PCRE_REQCHSET) != 0)  if ((re->flags & PCRE_REQCHSET) != 0)
5998    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);  
5999    
6000  OP1(SLJIT_MOV, ARGUMENTS, 0, SLJIT_GENERAL_REG1, 0);  OP1(SLJIT_MOV, ARGUMENTS, 0, SLJIT_GENERAL_REG1, 0);
6001  OP1(SLJIT_MOV, TMP1, 0, SLJIT_GENERAL_REG1, 0);  OP1(SLJIT_MOV, TMP1, 0, SLJIT_GENERAL_REG1, 0);

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

  ViewVC Help
Powered by ViewVC 1.1.5