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

Diff of /code/trunk/pcre_jit_compile.c

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

revision 726 by zherczeg, Sun Oct 9 18:53:25 2011 UTC revision 792 by ph10, Wed Dec 7 16:44:48 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 163  typedef struct executable_function { Line 166  typedef struct executable_function {
166    void *executable_func;    void *executable_func;
167    pcre_jit_callback callback;    pcre_jit_callback callback;
168    void *userdata;    void *userdata;
169      sljit_uw executable_size;
170  } executable_function;  } executable_function;
171    
172  typedef struct jump_list {  typedef struct jump_list {
# Line 276  typedef struct compiler_common { Line 280  typedef struct compiler_common {
280    int bsr_nltype;    int bsr_nltype;
281    int endonly;    int endonly;
282    sljit_w ctypes;    sljit_w ctypes;
283      sljit_uw name_table;
284      sljit_w name_count;
285      sljit_w name_entry_size;
286    struct sljit_label *acceptlabel;    struct sljit_label *acceptlabel;
287    stub_list *stubs;    stub_list *stubs;
288    recurse_entry *entries;    recurse_entry *entries;
# Line 467  switch(*cc) Line 474  switch(*cc)
474    case OP_SKIPZERO:    case OP_SKIPZERO:
475    return cc + 1;    return cc + 1;
476    
477      case OP_ANYBYTE:
478    #ifdef SUPPORT_UTF8
479      if (common->utf8) return NULL;
480    #endif
481      return cc + 1;
482    
483    case OP_CHAR:    case OP_CHAR:
484    case OP_CHARI:    case OP_CHARI:
485    case OP_NOT:    case OP_NOT:
# Line 545  switch(*cc) Line 558  switch(*cc)
558    case OP_REF:    case OP_REF:
559    case OP_REFI:    case OP_REFI:
560    case OP_CREF:    case OP_CREF:
561      case OP_NCREF:
562      case OP_RREF:
563      case OP_NRREF:
564    case OP_CLOSE:    case OP_CLOSE:
565    cc += 3;    cc += 3;
566    return cc;    return cc;
# Line 1336  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(ST Line 1352  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(ST
1352  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF8
1353  if (common->utf8)  if (common->utf8)
1354    {    {
1355    /* 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);  
1356    add_jump(compiler, &common->utf8readchar, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->utf8readchar, JUMP(SLJIT_FAST_CALL));
1357    JUMPHERE(jump);    JUMPHERE(jump);
1358    }    }
# Line 1358  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(ST Line 1373  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(ST
1373  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF8
1374  if (common->utf8)  if (common->utf8)
1375    {    {
1376    /* 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);  
1377    add_jump(compiler, &common->utf8readchar, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->utf8readchar, JUMP(SLJIT_FAST_CALL));
1378    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
1379    JUMPHERE(jump);    JUMPHERE(jump);
# Line 1383  if (common->utf8) Line 1397  if (common->utf8)
1397    /* This can be an extra read in some situations, but hopefully    /* This can be an extra read in some situations, but hopefully
1398    it is a clever early read in most cases. */    it is a clever early read in most cases. */
1399    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);
1400    /* 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);  
1401    add_jump(compiler, &common->utf8readtype8, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->utf8readtype8, JUMP(SLJIT_FAST_CALL));
1402    JUMPHERE(jump);    JUMPHERE(jump);
1403    return;    return;
# Line 1444  else Line 1457  else
1457  static void do_utf8readchar(compiler_common *common)  static void do_utf8readchar(compiler_common *common)
1458  {  {
1459  /* Fast decoding an utf8 character. TMP1 contains the first byte  /* Fast decoding an utf8 character. TMP1 contains the first byte
1460  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. */
1461  DEFINE_COMPILER;  DEFINE_COMPILER;
1462  struct sljit_jump *jump;  struct sljit_jump *jump;
1463    
# Line 1527  sljit_emit_fast_return(compiler, RETURN_ Line 1540  sljit_emit_fast_return(compiler, RETURN_
1540  static void do_utf8readtype8(compiler_common *common)  static void do_utf8readtype8(compiler_common *common)
1541  {  {
1542  /* Fast decoding an utf8 character type. TMP2 contains the first byte  /* Fast decoding an utf8 character type. TMP2 contains the first byte
1543  of the character (>= 192) and TMP1 is destroyed. Return value in TMP1. */  of the character (>= 0xc0) and TMP1 is destroyed. Return value in TMP1. */
1544  DEFINE_COMPILER;  DEFINE_COMPILER;
1545  struct sljit_jump *jump;  struct sljit_jump *jump;
1546  struct sljit_jump *compare;  struct sljit_jump *compare;
# Line 1553  sljit_emit_fast_return(compiler, RETURN_ Line 1566  sljit_emit_fast_return(compiler, RETURN_
1566  JUMPHERE(jump);  JUMPHERE(jump);
1567    
1568  /* We only have types for characters less than 256. */  /* We only have types for characters less than 256. */
1569  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);  
1570  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
1571  OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);  OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);
1572  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
# Line 1598  struct sljit_label *newlinelabel = NULL; Line 1610  struct sljit_label *newlinelabel = NULL;
1610  struct sljit_jump *start;  struct sljit_jump *start;
1611  struct sljit_jump *end = NULL;  struct sljit_jump *end = NULL;
1612  struct sljit_jump *nl = NULL;  struct sljit_jump *nl = NULL;
1613    #ifdef SUPPORT_UTF8
1614    struct sljit_jump *singlebyte;
1615    #endif
1616  jump_list *newline = NULL;  jump_list *newline = NULL;
1617  BOOL newlinecheck = FALSE;  BOOL newlinecheck = FALSE;
1618  BOOL readbyte = FALSE;  BOOL readbyte = FALSE;
# Line 1668  if (readbyte) Line 1683  if (readbyte)
1683  if (newlinecheck)  if (newlinecheck)
1684    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);
1685    
1686    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 1);
1687  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF8
1688  if (common->utf8)  if (common->utf8)
1689    {    {
1690    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);
1691      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)_pcre_utf8_char_sizes - 0xc0);
1692    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
1693      JUMPHERE(singlebyte);
1694    }    }
 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);  
1695  #endif  #endif
1696  JUMPHERE(start);  JUMPHERE(start);
1697    
# Line 1730  else Line 1744  else
1744      }      }
1745    }    }
1746    
1747    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 1);
1748  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF8
1749  if (common->utf8)  if (common->utf8)
1750    {    {
1751    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);
1752      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)_pcre_utf8_char_sizes - 0xc0);
1753    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
1754    }    }
 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);  
1755  #endif  #endif
1756  JUMPTO(SLJIT_JUMP, start);  JUMPTO(SLJIT_JUMP, start);
1757  JUMPHERE(found);  JUMPHERE(found);
# Line 1846  leave = CMP(SLJIT_C_GREATER_EQUAL, STR_P Line 1858  leave = CMP(SLJIT_C_GREATER_EQUAL, STR_P
1858  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
1859  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF8
1860  if (common->utf8)  if (common->utf8)
1861    OP1(SLJIT_MOV_UB, TMP3, 0, SLJIT_MEM1(TMP1), (sljit_w)_pcre_utf8_char_sizes);    OP1(SLJIT_MOV, TMP3, 0, TMP1, 0);
1862  #endif  #endif
1863  OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);  OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);
1864  OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);  OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);
# Line 1857  found = JUMP(SLJIT_C_NOT_ZERO); Line 1869  found = JUMP(SLJIT_C_NOT_ZERO);
1869    
1870  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF8
1871  if (common->utf8)  if (common->utf8)
1872    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP3, 0);    OP1(SLJIT_MOV, TMP1, 0, TMP3, 0);
1873  else  #endif
   OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 1);  
 #else  
1874  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 1);  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 1);
1875    #ifdef SUPPORT_UTF8
1876    if (common->utf8)
1877      {
1878      CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0, start);
1879      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)_pcre_utf8_char_sizes - 0xc0);
1880      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
1881      }
1882  #endif  #endif
1883  JUMPTO(SLJIT_JUMP, start);  JUMPTO(SLJIT_JUMP, start);
1884  JUMPHERE(found);  JUMPHERE(found);
# Line 1972  struct sljit_jump *beginend; Line 1989  struct sljit_jump *beginend;
1989  struct sljit_jump *jump;  struct sljit_jump *jump;
1990  #endif  #endif
1991    
1992  SLJIT_ASSERT(ctype_word == 0x10);  SLJIT_COMPILE_ASSERT(ctype_word == 0x10, ctype_word_must_be_16);
1993    
1994  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);
1995  /* Get type of the previous char, and put it to LOCALS1. */  /* Get type of the previous char, and put it to LOCALS1. */
# Line 2788  switch(type) Line 2805  switch(type)
2805    if (common->utf8)    if (common->utf8)
2806      {      {
2807      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
2808      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);
2809        jump[0] = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);
2810        OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)_pcre_utf8_char_sizes - 0xc0);
2811      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2812        JUMPHERE(jump[0]);
2813      return cc;      return cc;
2814      }      }
2815  #endif  #endif
2816    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 1);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 1);
2817    return cc;    return cc;
2818    
2819      case OP_ANYBYTE:
2820      check_input_end(common, fallbacks);
2821      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 1);
2822      return cc;
2823    
2824  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF8
2825  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
2826    case OP_NOTPROP:    case OP_NOTPROP:
# Line 3042  switch(type) Line 3067  switch(type)
3067      if (c <= 127)      if (c <= 127)
3068        {        {
3069        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);  
3070        if (type == OP_NOT || !char_has_othercase(common, cc))        if (type == OP_NOT || !char_has_othercase(common, cc))
3071          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));
3072        else        else
3073          {          {
3074          /* 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. */
3075          OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x20);          OP2(SLJIT_OR, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x20);
3076          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));
3077          }          }
3078        /* Skip the variable-length character. */        /* Skip the variable-length character. */
3079        OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0);        OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 1);
3080          jump[0] = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);
3081          OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)_pcre_utf8_char_sizes - 0xc0);
3082          OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
3083          JUMPHERE(jump[0]);
3084        return cc + length;        return cc + length;
3085        }        }
3086      else      else
# Line 3776  common->accept = save_accept; Line 3804  common->accept = save_accept;
3804  return cc + 1 + LINK_SIZE;  return cc + 1 + LINK_SIZE;
3805  }  }
3806    
3807    static sljit_w SLJIT_CALL do_searchovector(sljit_w refno, sljit_w* locals, uschar *name_table)
3808    {
3809    int condition = FALSE;
3810    uschar *slotA = name_table;
3811    uschar *slotB;
3812    sljit_w name_count = locals[LOCALS0 / sizeof(sljit_w)];
3813    sljit_w name_entry_size = locals[LOCALS1 / sizeof(sljit_w)];
3814    sljit_w no_capture;
3815    int i;
3816    
3817    locals += OVECTOR_START / sizeof(sljit_w);
3818    no_capture = locals[1];
3819    
3820    for (i = 0; i < name_count; i++)
3821      {
3822      if (GET2(slotA, 0) == refno) break;
3823      slotA += name_entry_size;
3824      }
3825    
3826    if (i < name_count)
3827      {
3828      /* Found a name for the number - there can be only one; duplicate names
3829      for different numbers are allowed, but not vice versa. First scan down
3830      for duplicates. */
3831    
3832      slotB = slotA;
3833      while (slotB > name_table)
3834        {
3835        slotB -= name_entry_size;
3836        if (strcmp((char *)slotA + 2, (char *)slotB + 2) == 0)
3837          {
3838          condition = locals[GET2(slotB, 0) << 1] != no_capture;
3839          if (condition) break;
3840          }
3841        else break;
3842        }
3843    
3844      /* Scan up for duplicates */
3845      if (!condition)
3846        {
3847        slotB = slotA;
3848        for (i++; i < name_count; i++)
3849          {
3850          slotB += name_entry_size;
3851          if (strcmp((char *)slotA + 2, (char *)slotB + 2) == 0)
3852            {
3853            condition = locals[GET2(slotB, 0) << 1] != no_capture;
3854            if (condition) break;
3855            }
3856          else break;
3857          }
3858        }
3859      }
3860    return condition;
3861    }
3862    
3863    static sljit_w SLJIT_CALL do_searchgroups(sljit_w recno, sljit_w* locals, uschar *name_table)
3864    {
3865    int condition = FALSE;
3866    uschar *slotA = name_table;
3867    uschar *slotB;
3868    sljit_w name_count = locals[LOCALS0 / sizeof(sljit_w)];
3869    sljit_w name_entry_size = locals[LOCALS1 / sizeof(sljit_w)];
3870    sljit_w group_num = locals[POSSESSIVE0 / sizeof(sljit_w)];
3871    int i;
3872    
3873    for (i = 0; i < name_count; i++)
3874      {
3875      if (GET2(slotA, 0) == recno) break;
3876      slotA += name_entry_size;
3877      }
3878    
3879    if (i < name_count)
3880      {
3881      /* Found a name for the number - there can be only one; duplicate
3882      names for different numbers are allowed, but not vice versa. First
3883      scan down for duplicates. */
3884    
3885      slotB = slotA;
3886      while (slotB > name_table)
3887        {
3888        slotB -= name_entry_size;
3889        if (strcmp((char *)slotA + 2, (char *)slotB + 2) == 0)
3890          {
3891          condition = GET2(slotB, 0) == group_num;
3892          if (condition) break;
3893          }
3894        else break;
3895        }
3896    
3897      /* Scan up for duplicates */
3898      if (!condition)
3899        {
3900        slotB = slotA;
3901        for (i++; i < name_count; i++)
3902          {
3903          slotB += name_entry_size;
3904          if (strcmp((char *)slotA + 2, (char *)slotB + 2) == 0)
3905            {
3906            condition = GET2(slotB, 0) == group_num;
3907            if (condition) break;
3908            }
3909          else break;
3910          }
3911        }
3912      }
3913    return condition;
3914    }
3915    
3916  /*  /*
3917    Handling bracketed expressions is probably the most complex part.    Handling bracketed expressions is probably the most complex part.
3918    
# Line 3860  if (*cc == OP_BRAZERO || *cc == OP_BRAMI Line 3997  if (*cc == OP_BRAZERO || *cc == OP_BRAMI
3997    
3998  opcode = *cc;  opcode = *cc;
3999  ccbegin = cc;  ccbegin = cc;
4000    hotpath = ccbegin + 1 + LINK_SIZE;
4001    
4002  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)
4003    {    {
4004    /* Drop this bracket_fallback. */    /* Drop this bracket_fallback. */
# Line 3871  ket = *(bracketend(cc) - 1 - LINK_SIZE); Line 4010  ket = *(bracketend(cc) - 1 - LINK_SIZE);
4010  SLJIT_ASSERT(ket == OP_KET || ket == OP_KETRMAX || ket == OP_KETRMIN);  SLJIT_ASSERT(ket == OP_KET || ket == OP_KETRMAX || ket == OP_KETRMIN);
4011  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)));
4012  cc += GET(cc, 1);  cc += GET(cc, 1);
4013  has_alternatives = *cc == OP_ALT || opcode == OP_COND || opcode == OP_SCOND;  
4014    has_alternatives = *cc == OP_ALT;
4015    if (SLJIT_UNLIKELY(opcode == OP_COND) || SLJIT_UNLIKELY(opcode == OP_SCOND))
4016      {
4017      has_alternatives = (*hotpath == OP_RREF) ? FALSE : TRUE;
4018      if (*hotpath == OP_NRREF)
4019        {
4020        stacksize = GET2(hotpath, 1);
4021        if (common->currententry == NULL || stacksize == RREF_ANY)
4022          has_alternatives = FALSE;
4023        else if (common->currententry->start == 0)
4024          has_alternatives = stacksize != 0;
4025        else
4026          has_alternatives = stacksize != GET2(common->start, common->currententry->start + 1 + LINK_SIZE);
4027        }
4028      }
4029    
4030  if (SLJIT_UNLIKELY(opcode == OP_COND) && (*cc == OP_KETRMAX || *cc == OP_KETRMIN))  if (SLJIT_UNLIKELY(opcode == OP_COND) && (*cc == OP_KETRMAX || *cc == OP_KETRMIN))
4031    opcode = OP_SCOND;    opcode = OP_SCOND;
4032  if (SLJIT_UNLIKELY(opcode == OP_ONCE_NC))  if (SLJIT_UNLIKELY(opcode == OP_ONCE_NC))
# Line 3884  if (opcode == OP_CBRA || opcode == OP_SC Line 4039  if (opcode == OP_CBRA || opcode == OP_SC
4039    localptr = OVECTOR_PRIV(offset);    localptr = OVECTOR_PRIV(offset);
4040    offset <<= 1;    offset <<= 1;
4041    FALLBACK_AS(bracket_fallback)->localptr = localptr;    FALLBACK_AS(bracket_fallback)->localptr = localptr;
4042      hotpath += 2;
4043    }    }
4044  else if (opcode == OP_ONCE || opcode == OP_SBRA || opcode == OP_SCOND)  else if (opcode == OP_ONCE || opcode == OP_SBRA || opcode == OP_SCOND)
4045    {    {
# Line 4040  else if (has_alternatives) Line 4196  else if (has_alternatives)
4196    }    }
4197    
4198  /* Generating code for the first alternative. */  /* Generating code for the first alternative. */
 hotpath = ccbegin + 1 + LINK_SIZE;  
 if (offset != 0)  
   hotpath += 2;  
4199  if (opcode == OP_COND || opcode == OP_SCOND)  if (opcode == OP_COND || opcode == OP_SCOND)
4200    {    {
4201    if (*hotpath == OP_CREF)    if (*hotpath == OP_CREF)
4202      {      {
4203        SLJIT_ASSERT(has_alternatives);
4204      add_jump(compiler, &(FALLBACK_AS(bracket_fallback)->u.condfailed),      add_jump(compiler, &(FALLBACK_AS(bracket_fallback)->u.condfailed),
4205        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)));
4206      hotpath += 3;      hotpath += 3;
4207      }      }
4208      else if (*hotpath == OP_NCREF)
4209        {
4210        SLJIT_ASSERT(has_alternatives);
4211        stacksize = GET2(hotpath, 1);
4212        jump = CMP(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(stacksize << 1), SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1));
4213    
4214        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STACK_TOP, 0);
4215        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, SLJIT_IMM, common->name_count);
4216        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, SLJIT_IMM, common->name_entry_size);
4217        OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG1, 0, SLJIT_IMM, stacksize);
4218        OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, SLJIT_LOCALS_REG, 0);
4219        OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, common->name_table);
4220        sljit_emit_ijump(compiler, SLJIT_CALL3, SLJIT_IMM, SLJIT_FUNC_OFFSET(do_searchovector));
4221        OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1);
4222        add_jump(compiler, &(FALLBACK_AS(bracket_fallback)->u.condfailed), CMP(SLJIT_C_EQUAL, SLJIT_TEMPORARY_REG1, 0, SLJIT_IMM, 0));
4223    
4224        JUMPHERE(jump);
4225        hotpath += 3;
4226        }
4227      else if (*hotpath == OP_RREF || *hotpath == OP_NRREF)
4228        {
4229        /* Never has other case. */
4230        FALLBACK_AS(bracket_fallback)->u.condfailed = NULL;
4231    
4232        stacksize = GET2(hotpath, 1);
4233        if (common->currententry == NULL)
4234          stacksize = 0;
4235        else if (stacksize == RREF_ANY)
4236          stacksize = 1;
4237        else if (common->currententry->start == 0)
4238          stacksize = stacksize == 0;
4239        else
4240          stacksize = stacksize == GET2(common->start, common->currententry->start + 1 + LINK_SIZE);
4241    
4242        if (*hotpath == OP_RREF || stacksize || common->currententry == NULL)
4243          {
4244          SLJIT_ASSERT(!has_alternatives);
4245          if (stacksize != 0)
4246            hotpath += 3;
4247          else
4248            {
4249            if (*cc == OP_ALT)
4250              {
4251              hotpath = cc + 1 + LINK_SIZE;
4252              cc += GET(cc, 1);
4253              }
4254            else
4255              hotpath = cc;
4256            }
4257          }
4258        else
4259          {
4260          SLJIT_ASSERT(has_alternatives);
4261    
4262          stacksize = GET2(hotpath, 1);
4263          OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STACK_TOP, 0);
4264          OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, SLJIT_IMM, common->name_count);
4265          OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, SLJIT_IMM, common->name_entry_size);
4266          OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, GET2(common->start, common->currententry->start + 1 + LINK_SIZE));
4267          OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG1, 0, SLJIT_IMM, stacksize);
4268          OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, SLJIT_LOCALS_REG, 0);
4269          OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, common->name_table);
4270          sljit_emit_ijump(compiler, SLJIT_CALL3, SLJIT_IMM, SLJIT_FUNC_OFFSET(do_searchgroups));
4271          OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1);
4272          add_jump(compiler, &(FALLBACK_AS(bracket_fallback)->u.condfailed), CMP(SLJIT_C_EQUAL, SLJIT_TEMPORARY_REG1, 0, SLJIT_IMM, 0));
4273          hotpath += 3;
4274          }
4275        }
4276    else    else
4277      {      {
4278      SLJIT_ASSERT(*hotpath >= OP_ASSERT && *hotpath <= OP_ASSERTBACK_NOT);      SLJIT_ASSERT(has_alternatives && *hotpath >= OP_ASSERT && *hotpath <= OP_ASSERTBACK_NOT);
4279      /* Similar code as PUSH_FALLBACK macro. */      /* Similar code as PUSH_FALLBACK macro. */
4280      assert = sljit_alloc_memory(compiler, sizeof(assert_fallback));      assert = sljit_alloc_memory(compiler, sizeof(assert_fallback));
4281      if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))      if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
# Line 4744  while (cc < ccend) Line 4966  while (cc < ccend)
4966      case OP_WORDCHAR:      case OP_WORDCHAR:
4967      case OP_ANY:      case OP_ANY:
4968      case OP_ALLANY:      case OP_ALLANY:
4969        case OP_ANYBYTE:
4970      case OP_NOTPROP:      case OP_NOTPROP:
4971      case OP_PROP:      case OP_PROP:
4972      case OP_ANYNL:      case OP_ANYNL:
# Line 5212  jump_list *jumplistitem = NULL; Line 5435  jump_list *jumplistitem = NULL;
5435  uschar bra = OP_BRA;  uschar bra = OP_BRA;
5436  uschar ket;  uschar ket;
5437  assert_fallback *assert;  assert_fallback *assert;
5438    BOOL has_alternatives;
5439  struct sljit_jump *brazero = NULL;  struct sljit_jump *brazero = NULL;
5440  struct sljit_jump *once = NULL;  struct sljit_jump *once = NULL;
5441  struct sljit_jump *cond = NULL;  struct sljit_jump *cond = NULL;
# Line 5227  opcode = *cc; Line 5451  opcode = *cc;
5451  ccbegin = cc;  ccbegin = cc;
5452  ket = *(bracketend(ccbegin) - 1 - LINK_SIZE);  ket = *(bracketend(ccbegin) - 1 - LINK_SIZE);
5453  cc += GET(cc, 1);  cc += GET(cc, 1);
5454    has_alternatives = *cc == OP_ALT;
5455    if (SLJIT_UNLIKELY(opcode == OP_COND) || SLJIT_UNLIKELY(opcode == OP_SCOND))
5456      has_alternatives = (ccbegin[1 + LINK_SIZE] >= OP_ASSERT && ccbegin[1 + LINK_SIZE] <= OP_ASSERTBACK_NOT) || CURRENT_AS(bracket_fallback)->u.condfailed != NULL;
5457  if (opcode == OP_CBRA || opcode == OP_SCBRA)  if (opcode == OP_CBRA || opcode == OP_SCBRA)
5458    offset = (GET2(ccbegin, 1 + LINK_SIZE)) << 1;    offset = (GET2(ccbegin, 1 + LINK_SIZE)) << 1;
5459  if (SLJIT_UNLIKELY(opcode == OP_COND) && (*cc == OP_KETRMAX || *cc == OP_KETRMIN))  if (SLJIT_UNLIKELY(opcode == OP_COND) && (*cc == OP_KETRMAX || *cc == OP_KETRMIN))
# Line 5275  else if (bra == OP_BRAZERO) Line 5502  else if (bra == OP_BRAZERO)
5502    brazero = CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, 0);    brazero = CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, 0);
5503    }    }
5504    
5505  if (opcode == OP_ONCE)  if (SLJIT_UNLIKELY(opcode == OP_ONCE))
5506    {    {
5507    if (CURRENT_AS(bracket_fallback)->u.framesize >= 0)    if (CURRENT_AS(bracket_fallback)->u.framesize >= 0)
5508      {      {
# Line 5284  if (opcode == OP_ONCE) Line 5511  if (opcode == OP_ONCE)
5511      }      }
5512    once = JUMP(SLJIT_JUMP);    once = JUMP(SLJIT_JUMP);
5513    }    }
5514    else if (SLJIT_UNLIKELY(opcode == OP_COND) || SLJIT_UNLIKELY(opcode == OP_SCOND))
5515      {
5516      if (has_alternatives)
5517        {
5518        /* Always exactly one alternative. */
5519        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
5520        free_stack(common, 1);
5521    
5522        jumplistitem = sljit_alloc_memory(compiler, sizeof(jump_list));
5523        if (SLJIT_UNLIKELY(!jumplistitem))
5524          return;
5525        jumplist = jumplistitem;
5526        jumplistitem->next = NULL;
5527        jumplistitem->jump = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, 1);
5528        }
5529      }
5530  else if (*cc == OP_ALT)  else if (*cc == OP_ALT)
5531    {    {
5532    /* Build a jump list. Get the last successfully matched branch index. */    /* Build a jump list. Get the last successfully matched branch index. */
# Line 5315  else if (*cc == OP_ALT) Line 5558  else if (*cc == OP_ALT)
5558    
5559    cc = ccbegin + GET(ccbegin, 1);    cc = ccbegin + GET(ccbegin, 1);
5560    }    }
 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);  
   }  
5561    
5562  COMPILE_FALLBACKPATH(current->top);  COMPILE_FALLBACKPATH(current->top);
5563  if (current->topfallbacks)  if (current->topfallbacks)
5564    set_jumps(current->topfallbacks, LABEL());    set_jumps(current->topfallbacks, LABEL());
5565    
5566  if (opcode == OP_COND || opcode == OP_SCOND)  if (SLJIT_UNLIKELY(opcode == OP_COND) || SLJIT_UNLIKELY(opcode == OP_SCOND))
5567    {    {
5568    /* Conditional block always has at most one alternative. */    /* Conditional block always has at most one alternative. */
5569    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)
5570      {      {
5571        SLJIT_ASSERT(has_alternatives);
5572      assert = CURRENT_AS(bracket_fallback)->u.assert;      assert = CURRENT_AS(bracket_fallback)->u.assert;
5573      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))
5574        {        {
# Line 5348  if (opcode == OP_COND || opcode == OP_SC Line 5579  if (opcode == OP_COND || opcode == OP_SC
5579      cond = JUMP(SLJIT_JUMP);      cond = JUMP(SLJIT_JUMP);
5580      set_jumps(CURRENT_AS(bracket_fallback)->u.assert->condfailed, LABEL());      set_jumps(CURRENT_AS(bracket_fallback)->u.assert->condfailed, LABEL());
5581      }      }
5582    else    else if (CURRENT_AS(bracket_fallback)->u.condfailed != NULL)
5583      {      {
5584        SLJIT_ASSERT(has_alternatives);
5585      cond = JUMP(SLJIT_JUMP);      cond = JUMP(SLJIT_JUMP);
5586      set_jumps(CURRENT_AS(bracket_fallback)->u.condfailed, LABEL());      set_jumps(CURRENT_AS(bracket_fallback)->u.condfailed, LABEL());
5587      }      }
5588      else
5589        SLJIT_ASSERT(!has_alternatives);
5590    }    }
5591    
5592  if (*cc == OP_ALT || opcode == OP_COND || opcode == OP_SCOND)  if (has_alternatives)
5593    {    {
5594    count = 1;    count = 1;
5595    do    do
# Line 5464  if (*cc == OP_ALT || opcode == OP_COND | Line 5698  if (*cc == OP_ALT || opcode == OP_COND |
5698      {      {
5699      SLJIT_ASSERT(opcode == OP_COND || opcode == OP_SCOND);      SLJIT_ASSERT(opcode == OP_COND || opcode == OP_SCOND);
5700      assert = CURRENT_AS(bracket_fallback)->u.assert;      assert = CURRENT_AS(bracket_fallback)->u.assert;
5701      if (assert->framesize >= 0 && (ccbegin[1 + LINK_SIZE] == OP_ASSERT_NOT || ccbegin[1 + LINK_SIZE] == OP_ASSERTBACK_NOT))      if ((ccbegin[1 + LINK_SIZE] == OP_ASSERT_NOT || ccbegin[1 + LINK_SIZE] == OP_ASSERTBACK_NOT) && assert->framesize >= 0)
5702    
5703        {        {
5704        OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), assert->localptr);        OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), assert->localptr);
5705        add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));        add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
# Line 5861  struct sljit_compiler *compiler; Line 6096  struct sljit_compiler *compiler;
6096  fallback_common rootfallback;  fallback_common rootfallback;
6097  compiler_common common_data;  compiler_common common_data;
6098  compiler_common *common = &common_data;  compiler_common *common = &common_data;
6099  const unsigned char *tables = re->tables;  const uschar *tables = re->tables;
6100  pcre_study_data *study;  pcre_study_data *study;
6101  uschar *ccend;  uschar *ccend;
6102  executable_function *function;  executable_function *function;
6103  void *executable_func;  void *executable_func;
6104    sljit_uw executable_size;
6105  struct sljit_label *leave;  struct sljit_label *leave;
6106  struct sljit_label *mainloop = NULL;  struct sljit_label *mainloop = NULL;
6107  struct sljit_label *empty_match_found;  struct sljit_label *empty_match_found;
# Line 5922  else Line 6158  else
6158    }    }
6159  common->endonly = (re->options & PCRE_DOLLAR_ENDONLY) != 0;  common->endonly = (re->options & PCRE_DOLLAR_ENDONLY) != 0;
6160  common->ctypes = (sljit_w)(tables + ctypes_offset);  common->ctypes = (sljit_w)(tables + ctypes_offset);
6161    common->name_table = (sljit_w)re + re->name_table_offset;
6162    common->name_count = re->name_count;
6163    common->name_entry_size = re->name_entry_size;
6164  common->acceptlabel = NULL;  common->acceptlabel = NULL;
6165  common->stubs = NULL;  common->stubs = NULL;
6166  common->entries = NULL;  common->entries = NULL;
# Line 6192  if (common->getucd != NULL) Line 6431  if (common->getucd != NULL)
6431    
6432  SLJIT_FREE(common->localptrs);  SLJIT_FREE(common->localptrs);
6433  executable_func = sljit_generate_code(compiler);  executable_func = sljit_generate_code(compiler);
6434    executable_size = sljit_get_generated_code_size(compiler);
6435  sljit_free_compiler(compiler);  sljit_free_compiler(compiler);
6436  if (executable_func == NULL)  if (executable_func == NULL)
6437    return;    return;
# Line 6206  if (function == NULL) Line 6446  if (function == NULL)
6446    }    }
6447    
6448  function->executable_func = executable_func;  function->executable_func = executable_func;
6449    function->executable_size = executable_size;
6450  function->callback = NULL;  function->callback = NULL;
6451  function->userdata = NULL;  function->userdata = NULL;
6452  extra->executable_jit = function;  extra->executable_jit = function;
# Line 6294  sljit_free_code(function->executable_fun Line 6535  sljit_free_code(function->executable_fun
6535  SLJIT_FREE(function);  SLJIT_FREE(function);
6536  }  }
6537    
6538    int
6539    _pcre_jit_get_size(void *executable_func)
6540    {
6541    return ((executable_function*)executable_func)->executable_size;
6542    }
6543    
6544  PCRE_EXP_DECL pcre_jit_stack *  PCRE_EXP_DECL pcre_jit_stack *
6545  pcre_jit_stack_alloc(int startsize, int maxsize)  pcre_jit_stack_alloc(int startsize, int maxsize)
6546  {  {

Legend:
Removed from v.726  
changed lines
  Added in v.792

  ViewVC Help
Powered by ViewVC 1.1.5