/[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 1002 by zherczeg, Tue Aug 14 09:31:00 2012 UTC revision 1084 by chpe, Tue Oct 16 15:55:28 2012 UTC
# Line 46  POSSIBILITY OF SUCH DAMAGE. Line 46  POSSIBILITY OF SUCH DAMAGE.
46    
47  #include "pcre_internal.h"  #include "pcre_internal.h"
48    
49  #ifdef SUPPORT_JIT  #if defined SUPPORT_JIT
50    
51  /* All-in-one: Since we use the JIT compiler only from here,  /* All-in-one: Since we use the JIT compiler only from here,
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
# Line 279  typedef struct compiler_common { Line 279  typedef struct compiler_common {
279    
280    /* Maps private data offset to each opcode. */    /* Maps private data offset to each opcode. */
281    int *private_data_ptrs;    int *private_data_ptrs;
282      /* Tells whether the capturing bracket is optimized. */
283      pcre_uint8 *optimized_cbracket;
284      /* Starting offset of private data for capturing brackets. */
285    int cbraptr;    int cbraptr;
286    /* OVector starting point. Must be divisible by 2. */    /* OVector starting point. Must be divisible by 2. */
287    int ovector_start;    int ovector_start;
# Line 340  typedef struct compiler_common { Line 343  typedef struct compiler_common {
343  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
344    BOOL use_ucp;    BOOL use_ucp;
345  #endif  #endif
346    #ifndef COMPILE_PCRE32
347    jump_list *utfreadchar;    jump_list *utfreadchar;
348    #endif
349  #ifdef COMPILE_PCRE8  #ifdef COMPILE_PCRE8
350    jump_list *utfreadtype8;    jump_list *utfreadtype8;
351  #endif  #endif
# Line 360  typedef struct compare_context { Line 365  typedef struct compare_context {
365    union {    union {
366      sljit_i asint;      sljit_i asint;
367      sljit_uh asushort;      sljit_uh asushort;
368  #ifdef COMPILE_PCRE8  #if defined COMPILE_PCRE8
369      sljit_ub asbyte;      sljit_ub asbyte;
370      sljit_ub asuchars[4];      sljit_ub asuchars[4];
371  #else  #elif defined COMPILE_PCRE16
 #ifdef COMPILE_PCRE16  
372      sljit_uh asuchars[2];      sljit_uh asuchars[2];
373  #endif  #elif defined COMPILE_PCRE32
374        sljit_ui asuchars[1];
375  #endif  #endif
376    } c;    } c;
377    union {    union {
378      sljit_i asint;      sljit_i asint;
379      sljit_uh asushort;      sljit_uh asushort;
380  #ifdef COMPILE_PCRE8  #if defined COMPILE_PCRE8
381      sljit_ub asbyte;      sljit_ub asbyte;
382      sljit_ub asuchars[4];      sljit_ub asuchars[4];
383  #else  #elif defined COMPILE_PCRE16
 #ifdef COMPILE_PCRE16  
384      sljit_uh asuchars[2];      sljit_uh asuchars[2];
385  #endif  #elif defined COMPILE_PCRE32
386        sljit_ui asuchars[1];
387  #endif  #endif
388    } oc;    } oc;
389  #endif  #endif
# Line 425  the start pointers when the end of the c Line 430  the start pointers when the end of the c
430  #define OVECTOR_PRIV(i)  (common->cbraptr + (i) * sizeof(sljit_w))  #define OVECTOR_PRIV(i)  (common->cbraptr + (i) * sizeof(sljit_w))
431  #define PRIVATE_DATA(cc) (common->private_data_ptrs[(cc) - common->start])  #define PRIVATE_DATA(cc) (common->private_data_ptrs[(cc) - common->start])
432    
433  #ifdef COMPILE_PCRE8  #if defined COMPILE_PCRE8
434  #define MOV_UCHAR  SLJIT_MOV_UB  #define MOV_UCHAR  SLJIT_MOV_UB
435  #define MOVU_UCHAR SLJIT_MOVU_UB  #define MOVU_UCHAR SLJIT_MOVU_UB
436  #else  #elif defined COMPILE_PCRE16
 #ifdef COMPILE_PCRE16  
437  #define MOV_UCHAR  SLJIT_MOV_UH  #define MOV_UCHAR  SLJIT_MOV_UH
438  #define MOVU_UCHAR SLJIT_MOVU_UH  #define MOVU_UCHAR SLJIT_MOVU_UH
439    #elif defined COMPILE_PCRE32
440    #define MOV_UCHAR  SLJIT_MOV_UI
441    #define MOVU_UCHAR SLJIT_MOVU_UI
442  #else  #else
443  #error Unsupported compiling mode  #error Unsupported compiling mode
444  #endif  #endif
 #endif  
445    
446  /* Shortcuts. */  /* Shortcuts. */
447  #define DEFINE_COMPILER \  #define DEFINE_COMPILER \
# Line 585  switch(*cc) Line 591  switch(*cc)
591    case OP_NOTPOSPLUSI:    case OP_NOTPOSPLUSI:
592    case OP_NOTPOSQUERYI:    case OP_NOTPOSQUERYI:
593    cc += 2;    cc += 2;
594  #ifdef SUPPORT_UTF  #if defined SUPPORT_UTF && !defined COMPILE_PCRE32
595    if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);    if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
596  #endif  #endif
597    return cc;    return cc;
# Line 607  switch(*cc) Line 613  switch(*cc)
613    case OP_NOTEXACTI:    case OP_NOTEXACTI:
614    case OP_NOTPOSUPTOI:    case OP_NOTPOSUPTOI:
615    cc += 2 + IMM2_SIZE;    cc += 2 + IMM2_SIZE;
616  #ifdef SUPPORT_UTF  #if defined SUPPORT_UTF && !defined COMPILE_PCRE32
617    if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);    if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
618  #endif  #endif
619    return cc;    return cc;
# Line 759  static int get_private_data_length(compi Line 765  static int get_private_data_length(compi
765  {  {
766  int private_data_length = 0;  int private_data_length = 0;
767  pcre_uchar *alternative;  pcre_uchar *alternative;
768    pcre_uchar *name;
769  pcre_uchar *end = NULL;  pcre_uchar *end = NULL;
770  int space, size, bracketlen;  int space, size, bracketlen, i;
771    
772  /* 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. */
773  while (cc < ccend)  while (cc < ccend)
# Line 775  while (cc < ccend) Line 782  while (cc < ccend)
782      cc += 1;      cc += 1;
783      break;      break;
784    
785        case OP_REF:
786        case OP_REFI:
787        common->optimized_cbracket[GET2(cc, 1)] = 0;
788        cc += 1 + IMM2_SIZE;
789        break;
790    
791      case OP_ASSERT:      case OP_ASSERT:
792      case OP_ASSERT_NOT:      case OP_ASSERT_NOT:
793      case OP_ASSERTBACK:      case OP_ASSERTBACK:
# Line 784  while (cc < ccend) Line 797  while (cc < ccend)
797      case OP_BRAPOS:      case OP_BRAPOS:
798      case OP_SBRA:      case OP_SBRA:
799      case OP_SBRAPOS:      case OP_SBRAPOS:
     case OP_SCOND:  
800      private_data_length += sizeof(sljit_w);      private_data_length += sizeof(sljit_w);
801      bracketlen = 1 + LINK_SIZE;      bracketlen = 1 + LINK_SIZE;
802      break;      break;
# Line 792  while (cc < ccend) Line 804  while (cc < ccend)
804      case OP_CBRAPOS:      case OP_CBRAPOS:
805      case OP_SCBRAPOS:      case OP_SCBRAPOS:
806      private_data_length += sizeof(sljit_w);      private_data_length += sizeof(sljit_w);
807        common->optimized_cbracket[GET2(cc, 1 + LINK_SIZE)] = 0;
808      bracketlen = 1 + LINK_SIZE + IMM2_SIZE;      bracketlen = 1 + LINK_SIZE + IMM2_SIZE;
809      break;      break;
810    
811      case OP_COND:      case OP_COND:
812      /* Might be a hidden SCOND. */      case OP_SCOND:
813      alternative = cc + GET(cc, 1);      bracketlen = cc[1 + LINK_SIZE];
814      if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)      if (bracketlen == OP_CREF)
815          {
816          bracketlen = GET2(cc, 1 + LINK_SIZE + 1);
817          common->optimized_cbracket[bracketlen] = 0;
818          }
819        else if (bracketlen == OP_NCREF)
820          {
821          bracketlen = GET2(cc, 1 + LINK_SIZE + 1);
822          name = (pcre_uchar *)common->name_table;
823          alternative = name;
824          for (i = 0; i < common->name_count; i++)
825            {
826            if (GET2(name, 0) == bracketlen) break;
827            name += common->name_entry_size;
828            }
829          SLJIT_ASSERT(i != common->name_count);
830    
831          for (i = 0; i < common->name_count; i++)
832            {
833            if (STRCMP_UC_UC(alternative + IMM2_SIZE, name + IMM2_SIZE) == 0)
834              common->optimized_cbracket[GET2(alternative, 0)] = 0;
835            alternative += common->name_entry_size;
836            }
837          }
838    
839        if (*cc == OP_COND)
840          {
841          /* Might be a hidden SCOND. */
842          alternative = cc + GET(cc, 1);
843          if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)
844            private_data_length += sizeof(sljit_w);
845          }
846        else
847        private_data_length += sizeof(sljit_w);        private_data_length += sizeof(sljit_w);
848      bracketlen = 1 + LINK_SIZE;      bracketlen = 1 + LINK_SIZE;
849      break;      break;
# Line 891  while (cc < ccend) Line 936  while (cc < ccend)
936      if (size < 0)      if (size < 0)
937        {        {
938        cc += -size;        cc += -size;
939  #ifdef SUPPORT_UTF  #if defined SUPPORT_UTF && !defined COMPILE_PCRE32
940        if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);        if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
941  #endif  #endif
942        }        }
# Line 1031  while (cc < ccend) Line 1076  while (cc < ccend)
1076      if (size < 0)      if (size < 0)
1077        {        {
1078        cc += -size;        cc += -size;
1079  #ifdef SUPPORT_UTF  #if defined SUPPORT_UTF && !defined COMPILE_PCRE32
1080        if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);        if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
1081  #endif  #endif
1082        }        }
# Line 1252  while (cc < ccend) Line 1297  while (cc < ccend)
1297    
1298      case OP_CBRA:      case OP_CBRA:
1299      case OP_SCBRA:      case OP_SCBRA:
1300      private_data_length++;      if (common->optimized_cbracket[GET2(cc, 1 + LINK_SIZE)] == 0)
1301          private_data_length++;
1302      cc += 1 + LINK_SIZE + IMM2_SIZE;      cc += 1 + LINK_SIZE + IMM2_SIZE;
1303      break;      break;
1304    
# Line 1274  while (cc < ccend) Line 1320  while (cc < ccend)
1320      if (PRIVATE_DATA(cc))      if (PRIVATE_DATA(cc))
1321        private_data_length++;        private_data_length++;
1322      cc += 2;      cc += 2;
1323  #ifdef SUPPORT_UTF  #if defined SUPPORT_UTF && !defined COMPILE_PCRE32
1324      if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);      if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
1325  #endif  #endif
1326      break;      break;
# Line 1283  while (cc < ccend) Line 1329  while (cc < ccend)
1329      if (PRIVATE_DATA(cc))      if (PRIVATE_DATA(cc))
1330        private_data_length += 2;        private_data_length += 2;
1331      cc += 2;      cc += 2;
1332  #ifdef SUPPORT_UTF  #if defined SUPPORT_UTF && !defined COMPILE_PCRE32
1333      if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);      if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
1334  #endif  #endif
1335      break;      break;
# Line 1292  while (cc < ccend) Line 1338  while (cc < ccend)
1338      if (PRIVATE_DATA(cc))      if (PRIVATE_DATA(cc))
1339        private_data_length += 2;        private_data_length += 2;
1340      cc += 2 + IMM2_SIZE;      cc += 2 + IMM2_SIZE;
1341  #ifdef SUPPORT_UTF  #if defined SUPPORT_UTF && !defined COMPILE_PCRE32
1342      if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);      if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
1343  #endif  #endif
1344      break;      break;
# Line 1415  while (status != end) Line 1461  while (status != end)
1461    
1462        case OP_CBRA:        case OP_CBRA:
1463        case OP_SCBRA:        case OP_SCBRA:
1464        count = 1;        if (common->optimized_cbracket[GET2(cc, 1 + LINK_SIZE)] == 0)
1465        srcw[0] = OVECTOR_PRIV(GET2(cc, 1 + LINK_SIZE));          {
1466            count = 1;
1467            srcw[0] = OVECTOR_PRIV(GET2(cc, 1 + LINK_SIZE));
1468            }
1469        cc += 1 + LINK_SIZE + IMM2_SIZE;        cc += 1 + LINK_SIZE + IMM2_SIZE;
1470        break;        break;
1471    
1472        case OP_CBRAPOS:        case OP_CBRAPOS:
1473        case OP_SCBRAPOS:        case OP_SCBRAPOS:
1474        count = 2;        count = 2;
1475        srcw[0] = OVECTOR_PRIV(GET2(cc, 1 + LINK_SIZE));        srcw[0] = PRIVATE_DATA(cc);
1476        srcw[1] = PRIVATE_DATA(cc);        srcw[1] = OVECTOR_PRIV(GET2(cc, 1 + LINK_SIZE));
1477        SLJIT_ASSERT(srcw[0] != 0);        SLJIT_ASSERT(srcw[0] != 0 && srcw[1] != 0);
1478        cc += 1 + LINK_SIZE + IMM2_SIZE;        cc += 1 + LINK_SIZE + IMM2_SIZE;
1479        break;        break;
1480    
# Line 1448  while (status != end) Line 1497  while (status != end)
1497          srcw[0] = PRIVATE_DATA(cc);          srcw[0] = PRIVATE_DATA(cc);
1498          }          }
1499        cc += 2;        cc += 2;
1500  #ifdef SUPPORT_UTF  #if defined SUPPORT_UTF && !defined COMPILE_PCRE32
1501        if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);        if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
1502  #endif  #endif
1503        break;        break;
# Line 1461  while (status != end) Line 1510  while (status != end)
1510          srcw[1] = PRIVATE_DATA(cc) + sizeof(sljit_w);          srcw[1] = PRIVATE_DATA(cc) + sizeof(sljit_w);
1511          }          }
1512        cc += 2;        cc += 2;
1513  #ifdef SUPPORT_UTF  #if defined SUPPORT_UTF && !defined COMPILE_PCRE32
1514        if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);        if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
1515  #endif  #endif
1516        break;        break;
# Line 1474  while (status != end) Line 1523  while (status != end)
1523          srcw[1] = PRIVATE_DATA(cc) + sizeof(sljit_w);          srcw[1] = PRIVATE_DATA(cc) + sizeof(sljit_w);
1524          }          }
1525        cc += 2 + IMM2_SIZE;        cc += 2 + IMM2_SIZE;
1526  #ifdef SUPPORT_UTF  #if defined SUPPORT_UTF && !defined COMPILE_PCRE32
1527        if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);        if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
1528  #endif  #endif
1529        break;        break;
# Line 1646  SLJIT_ASSERT(cc == ccend && stackptr == Line 1695  SLJIT_ASSERT(cc == ccend && stackptr ==
1695  #undef CASE_ITERATOR_TYPE_PRIVATE_DATA_2A  #undef CASE_ITERATOR_TYPE_PRIVATE_DATA_2A
1696  #undef CASE_ITERATOR_TYPE_PRIVATE_DATA_2B  #undef CASE_ITERATOR_TYPE_PRIVATE_DATA_2B
1697    
1698  static SLJIT_INLINE BOOL ispowerof2(unsigned int value)  static SLJIT_INLINE BOOL is_powerof2(unsigned int value)
1699  {  {
1700  return (value & (value - 1)) == 0;  return (value & (value - 1)) == 0;
1701  }  }
# Line 1788  loop = LABEL(); Line 1837  loop = LABEL();
1837  OP2(SLJIT_SUB, SLJIT_SAVED_REG2, 0, SLJIT_MEM1(SLJIT_SAVED_REG1), 0, SLJIT_TEMPORARY_REG1, 0);  OP2(SLJIT_SUB, SLJIT_SAVED_REG2, 0, SLJIT_MEM1(SLJIT_SAVED_REG1), 0, SLJIT_TEMPORARY_REG1, 0);
1838  OP2(SLJIT_ADD, SLJIT_SAVED_REG1, 0, SLJIT_SAVED_REG1, 0, SLJIT_IMM, sizeof(sljit_w));  OP2(SLJIT_ADD, SLJIT_SAVED_REG1, 0, SLJIT_SAVED_REG1, 0, SLJIT_IMM, sizeof(sljit_w));
1839  /* Copy the integer value to the output buffer */  /* Copy the integer value to the output buffer */
1840  #ifdef COMPILE_PCRE16  #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
1841  OP2(SLJIT_ASHR, SLJIT_SAVED_REG2, 0, SLJIT_SAVED_REG2, 0, SLJIT_IMM, 1);  OP2(SLJIT_ASHR, SLJIT_SAVED_REG2, 0, SLJIT_SAVED_REG2, 0, SLJIT_IMM, UCHAR_SHIFT);
1842  #endif  #endif
1843  OP1(SLJIT_MOVU_SI, SLJIT_MEM1(SLJIT_TEMPORARY_REG3), sizeof(int), SLJIT_SAVED_REG2, 0);  OP1(SLJIT_MOVU_SI, SLJIT_MEM1(SLJIT_TEMPORARY_REG3), sizeof(int), SLJIT_SAVED_REG2, 0);
1844  OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_TEMPORARY_REG2, 0, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, 1);  OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_TEMPORARY_REG2, 0, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, 1);
# Line 1830  OP1(SLJIT_MOV, SLJIT_SAVED_REG1, 0, SLJI Line 1879  OP1(SLJIT_MOV, SLJIT_SAVED_REG1, 0, SLJI
1879  OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), SLJIT_OFFSETOF(jit_arguments, offsets));  OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), SLJIT_OFFSETOF(jit_arguments, offsets));
1880  OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG3, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mode == JIT_PARTIAL_HARD_COMPILE ? common->start_used_ptr : common->hit_start);  OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG3, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mode == JIT_PARTIAL_HARD_COMPILE ? common->start_used_ptr : common->hit_start);
1881  OP2(SLJIT_SUB, SLJIT_SAVED_REG2, 0, STR_END, 0, SLJIT_SAVED_REG1, 0);  OP2(SLJIT_SUB, SLJIT_SAVED_REG2, 0, STR_END, 0, SLJIT_SAVED_REG1, 0);
1882  #ifdef COMPILE_PCRE16  #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
1883  OP2(SLJIT_ASHR, SLJIT_SAVED_REG2, 0, SLJIT_SAVED_REG2, 0, SLJIT_IMM, 1);  OP2(SLJIT_ASHR, SLJIT_SAVED_REG2, 0, SLJIT_SAVED_REG2, 0, SLJIT_IMM, UCHAR_SHIFT);
1884  #endif  #endif
1885  OP1(SLJIT_MOV_SI, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), sizeof(int), SLJIT_SAVED_REG2, 0);  OP1(SLJIT_MOV_SI, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), sizeof(int), SLJIT_SAVED_REG2, 0);
1886    
1887  OP2(SLJIT_SUB, SLJIT_TEMPORARY_REG3, 0, SLJIT_TEMPORARY_REG3, 0, SLJIT_SAVED_REG1, 0);  OP2(SLJIT_SUB, SLJIT_TEMPORARY_REG3, 0, SLJIT_TEMPORARY_REG3, 0, SLJIT_SAVED_REG1, 0);
1888  #ifdef COMPILE_PCRE16  #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
1889  OP2(SLJIT_ASHR, SLJIT_TEMPORARY_REG3, 0, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, 1);  OP2(SLJIT_ASHR, SLJIT_TEMPORARY_REG3, 0, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, UCHAR_SHIFT);
1890  #endif  #endif
1891  OP1(SLJIT_MOV_SI, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), 0, SLJIT_TEMPORARY_REG3, 0);  OP1(SLJIT_MOV_SI, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), 0, SLJIT_TEMPORARY_REG3, 0);
1892    
# Line 1952  if (c <= 127 && bit == 0x20) Line 2001  if (c <= 127 && bit == 0x20)
2001    return (0 << 8) | 0x20;    return (0 << 8) | 0x20;
2002    
2003  /* Since c != oc, they must have at least 1 bit difference. */  /* Since c != oc, they must have at least 1 bit difference. */
2004  if (!ispowerof2(bit))  if (!is_powerof2(bit))
2005    return 0;    return 0;
2006    
2007  #ifdef COMPILE_PCRE8  #if defined COMPILE_PCRE8
2008    
2009  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
2010  if (common->utf && c > 127)  if (common->utf && c > 127)
# Line 1971  if (common->utf && c > 127) Line 2020  if (common->utf && c > 127)
2020  #endif /* SUPPORT_UTF */  #endif /* SUPPORT_UTF */
2021  return (0 << 8) | bit;  return (0 << 8) | bit;
2022    
2023  #else /* COMPILE_PCRE8 */  #elif defined COMPILE_PCRE16 || defined COMPILE_PCRE32
2024    
 #ifdef COMPILE_PCRE16  
2025  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
2026  if (common->utf && c > 65535)  if (common->utf && c > 65535)
2027    {    {
# Line 1984  if (common->utf && c > 65535) Line 2032  if (common->utf && c > 65535)
2032    }    }
2033  #endif /* SUPPORT_UTF */  #endif /* SUPPORT_UTF */
2034  return (bit < 256) ? ((0 << 8) | bit) : ((1 << 8) | (bit >> 8));  return (bit < 256) ? ((0 << 8) | bit) : ((1 << 8) | (bit >> 8));
 #endif /* COMPILE_PCRE16 */  
2035    
2036  #endif /* COMPILE_PCRE8 */  #endif /* COMPILE_PCRE[8|16|32] */
2037  }  }
2038    
2039  static void check_partial(compiler_common *common, BOOL force)  static void check_partial(compiler_common *common, BOOL force)
# Line 2084  static void read_char(compiler_common *c Line 2131  static void read_char(compiler_common *c
2131  /* Reads the character into TMP1, updates STR_PTR.  /* Reads the character into TMP1, updates STR_PTR.
2132  Does not check STR_END. TMP2 Destroyed. */  Does not check STR_END. TMP2 Destroyed. */
2133  DEFINE_COMPILER;  DEFINE_COMPILER;
2134  #ifdef SUPPORT_UTF  #if defined SUPPORT_UTF && !defined COMPILE_PCRE32
2135  struct sljit_jump *jump;  struct sljit_jump *jump;
2136  #endif  #endif
2137    
2138  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
2139  #ifdef SUPPORT_UTF  #if defined SUPPORT_UTF && !defined COMPILE_PCRE32
2140  if (common->utf)  if (common->utf)
2141    {    {
2142  #ifdef COMPILE_PCRE8  #if defined COMPILE_PCRE8
2143    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);
2144  #else  #elif defined COMPILE_PCRE16
 #ifdef COMPILE_PCRE16  
2145    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800);    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800);
2146  #endif  #endif /* COMPILE_PCRE[8|16] */
 #endif /* COMPILE_PCRE8 */  
2147    add_jump(compiler, &common->utfreadchar, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->utfreadchar, JUMP(SLJIT_FAST_CALL));
2148    JUMPHERE(jump);    JUMPHERE(jump);
2149    }    }
2150  #endif  #endif /* SUPPORT_UTF && !COMPILE_PCRE32 */
2151  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2152  }  }
2153    
# Line 2111  static void peek_char(compiler_common *c Line 2156  static void peek_char(compiler_common *c
2156  /* Reads the character into TMP1, keeps STR_PTR.  /* Reads the character into TMP1, keeps STR_PTR.
2157  Does not check STR_END. TMP2 Destroyed. */  Does not check STR_END. TMP2 Destroyed. */
2158  DEFINE_COMPILER;  DEFINE_COMPILER;
2159  #ifdef SUPPORT_UTF  #if defined SUPPORT_UTF && !defined COMPILE_PCRE32
2160  struct sljit_jump *jump;  struct sljit_jump *jump;
2161  #endif  #endif
2162    
2163  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
2164  #ifdef SUPPORT_UTF  #if defined SUPPORT_UTF && !defined COMPILE_PCRE32
2165  if (common->utf)  if (common->utf)
2166    {    {
2167  #ifdef COMPILE_PCRE8  #if defined COMPILE_PCRE8
2168    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);
2169  #else  #elif defined COMPILE_PCRE16
 #ifdef COMPILE_PCRE16  
2170    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800);    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800);
2171  #endif  #endif /* COMPILE_PCRE[8|16] */
 #endif /* COMPILE_PCRE8 */  
2172    add_jump(compiler, &common->utfreadchar, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->utfreadchar, JUMP(SLJIT_FAST_CALL));
2173    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
2174    JUMPHERE(jump);    JUMPHERE(jump);
2175    }    }
2176  #endif  #endif /* SUPPORT_UTF && !COMPILE_PCRE32 */
2177  }  }
2178    
2179  static void read_char8_type(compiler_common *common)  static void read_char8_type(compiler_common *common)
2180  {  {
2181  /* Reads the character type into TMP1, updates STR_PTR. Does not check STR_END. */  /* Reads the character type into TMP1, updates STR_PTR. Does not check STR_END. */
2182  DEFINE_COMPILER;  DEFINE_COMPILER;
2183  #if defined SUPPORT_UTF || defined COMPILE_PCRE16  #if defined SUPPORT_UTF || defined COMPILE_PCRE16 || defined COMPILE_PCRE32
2184  struct sljit_jump *jump;  struct sljit_jump *jump;
2185  #endif  #endif
2186    
# Line 2146  if (common->utf) Line 2189  if (common->utf)
2189    {    {
2190    OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), 0);    OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), 0);
2191    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2192  #ifdef COMPILE_PCRE8  #if defined COMPILE_PCRE8
2193    /* This can be an extra read in some situations, but hopefully    /* This can be an extra read in some situations, but hopefully
2194    it is needed in most cases. */    it is needed in most cases. */
2195    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);
2196    jump = CMP(SLJIT_C_LESS, TMP2, 0, SLJIT_IMM, 0xc0);    jump = CMP(SLJIT_C_LESS, TMP2, 0, SLJIT_IMM, 0xc0);
2197    add_jump(compiler, &common->utfreadtype8, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->utfreadtype8, JUMP(SLJIT_FAST_CALL));
2198    JUMPHERE(jump);    JUMPHERE(jump);
2199  #else  #elif defined COMPILE_PCRE16
 #ifdef COMPILE_PCRE16  
2200    OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);    OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);
2201    jump = CMP(SLJIT_C_GREATER, TMP2, 0, SLJIT_IMM, 255);    jump = CMP(SLJIT_C_GREATER, TMP2, 0, SLJIT_IMM, 255);
2202    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);
# Line 2165  if (common->utf) Line 2207  if (common->utf)
2207    COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);    COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);
2208    OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 1);    OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 1);
2209    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
2210  #endif  #elif defined COMPILE_PCRE32
2211  #endif /* COMPILE_PCRE8 */    OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);
2212      jump = CMP(SLJIT_C_GREATER, TMP2, 0, SLJIT_IMM, 255);
2213      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);
2214      JUMPHERE(jump);
2215    #endif /* COMPILE_PCRE[8|16|32] */
2216    return;    return;
2217    }    }
2218  #endif  #endif /* SUPPORT_UTF */
2219  OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), 0);  OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), 0);
2220  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2221  #ifdef COMPILE_PCRE16  #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
2222  /* The ctypes array contains only 256 values. */  /* The ctypes array contains only 256 values. */
2223  OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);  OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);
2224  jump = CMP(SLJIT_C_GREATER, TMP2, 0, SLJIT_IMM, 255);  jump = CMP(SLJIT_C_GREATER, TMP2, 0, SLJIT_IMM, 255);
2225  #endif  #endif
2226  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);
2227  #ifdef COMPILE_PCRE16  #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
2228  JUMPHERE(jump);  JUMPHERE(jump);
2229  #endif  #endif
2230  }  }
# Line 2187  static void skip_char_back(compiler_comm Line 2233  static void skip_char_back(compiler_comm
2233  {  {
2234  /* Goes one character back. Affects STR_PTR and TMP1. Does not check begin. */  /* Goes one character back. Affects STR_PTR and TMP1. Does not check begin. */
2235  DEFINE_COMPILER;  DEFINE_COMPILER;
2236  #if defined SUPPORT_UTF && defined COMPILE_PCRE8  #if defined SUPPORT_UTF && !defined COMPILE_PCRE32
2237    #if defined COMPILE_PCRE8
2238  struct sljit_label *label;  struct sljit_label *label;
2239    
2240  if (common->utf)  if (common->utf)
# Line 2199  if (common->utf) Line 2246  if (common->utf)
2246    CMPTO(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, 0x80, label);    CMPTO(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, 0x80, label);
2247    return;    return;
2248    }    }
2249  #endif  #elif defined COMPILE_PCRE16
 #if defined SUPPORT_UTF && defined COMPILE_PCRE16  
2250  if (common->utf)  if (common->utf)
2251    {    {
2252    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), -IN_UCHARS(1));    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), -IN_UCHARS(1));
# Line 2213  if (common->utf) Line 2259  if (common->utf)
2259    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP1, 0);    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2260    return;    return;
2261    }    }
2262  #endif  #endif /* COMPILE_PCRE[8|16] */
2263    #endif /* SUPPORT_UTF && !COMPILE_PCRE32 */
2264  OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));  OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2265  }  }
2266    
# Line 2244  else Line 2291  else
2291    
2292  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
2293    
2294  #ifdef COMPILE_PCRE8  #if defined COMPILE_PCRE8
2295  static void do_utfreadchar(compiler_common *common)  static void do_utfreadchar(compiler_common *common)
2296  {  {
2297  /* Fast decoding a UTF-8 character. TMP1 contains the first byte  /* Fast decoding a UTF-8 character. TMP1 contains the first byte
# Line 2338  OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0); Line 2385  OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);
2385  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
2386  }  }
2387    
2388  #else /* COMPILE_PCRE8 */  #elif defined COMPILE_PCRE16
2389    
 #ifdef COMPILE_PCRE16  
2390  static void do_utfreadchar(compiler_common *common)  static void do_utfreadchar(compiler_common *common)
2391  {  {
2392  /* Fast decoding a UTF-16 character. TMP1 contains the first 16 bit char  /* Fast decoding a UTF-16 character. TMP1 contains the first 16 bit char
# Line 2365  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, IN_UC Line 2411  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, IN_UC
2411  OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x10000);  OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x10000);
2412  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
2413  }  }
 #endif /* COMPILE_PCRE16 */  
2414    
2415  #endif /* COMPILE_PCRE8 */  #endif /* COMPILE_PCRE[8|16] */
2416    
2417  #endif /* SUPPORT_UTF */  #endif /* SUPPORT_UTF */
2418    
# Line 2463  if (newlinecheck) Line 2508  if (newlinecheck)
2508    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
2509    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, common->newline & 0xff);    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, common->newline & 0xff);
2510    COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);    COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);
2511  #ifdef COMPILE_PCRE16  #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
2512    OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);    OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, UCHAR_SHIFT);
2513  #endif  #endif
2514    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2515    nl = JUMP(SLJIT_JUMP);    nl = JUMP(SLJIT_JUMP);
# Line 2485  if (newlinecheck) Line 2530  if (newlinecheck)
2530    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);
2531    
2532  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2533  #if defined SUPPORT_UTF && defined COMPILE_PCRE8  #if defined SUPPORT_UTF && !defined COMPILE_PCRE32
2534    #if defined COMPILE_PCRE8
2535  if (common->utf)  if (common->utf)
2536    {    {
2537    singlechar = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);    singlechar = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);
# Line 2493  if (common->utf) Line 2539  if (common->utf)
2539    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2540    JUMPHERE(singlechar);    JUMPHERE(singlechar);
2541    }    }
2542  #endif  #elif defined COMPILE_PCRE16
 #if defined SUPPORT_UTF && defined COMPILE_PCRE16  
2543  if (common->utf)  if (common->utf)
2544    {    {
2545    singlechar = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800);    singlechar = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800);
# Line 2505  if (common->utf) Line 2550  if (common->utf)
2550    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2551    JUMPHERE(singlechar);    JUMPHERE(singlechar);
2552    }    }
2553  #endif  #endif /* COMPILE_PCRE[8|16] */
2554    #endif /* SUPPORT_UTF && !COMPILE_PCRE32 */
2555  JUMPHERE(start);  JUMPHERE(start);
2556    
2557  if (newlinecheck)  if (newlinecheck)
# Line 2517  if (newlinecheck) Line 2563  if (newlinecheck)
2563  return mainloop;  return mainloop;
2564  }  }
2565    
2566  static SLJIT_INLINE BOOL fast_forward_first_two_chars(compiler_common *common, BOOL firstline)  #define MAX_N_CHARS 3
2567    
2568    static SLJIT_INLINE BOOL fast_forward_first_n_chars(compiler_common *common, BOOL firstline)
2569  {  {
2570  DEFINE_COMPILER;  DEFINE_COMPILER;
2571  struct sljit_label *start;  struct sljit_label *start;
2572  struct sljit_jump *quit;  struct sljit_jump *quit;
2573  struct sljit_jump *found;  pcre_uint32 chars[MAX_N_CHARS * 2];
 pcre_int32 chars[4];  
2574  pcre_uchar *cc = common->start + 1 + IMM2_SIZE;  pcre_uchar *cc = common->start + 1 + IMM2_SIZE;
2575  int location = 0;  int location = 0;
2576  pcre_int32 len, c, bit, caseless;  pcre_int32 len, c, bit, caseless;
2577  BOOL must_end;  int must_stop;
   
 #ifdef COMPILE_PCRE8  
 union {  
     sljit_uh ascombined;  
     sljit_ub asuchars[2];  
 } pair;  
 #else  
 union {  
     sljit_ui ascombined;  
     sljit_uh asuchars[2];  
 } pair;  
 #endif  
2578    
2579    /* We do not support alternatives now. */
2580  if (*(common->start + GET(common->start, 1)) == OP_ALT)  if (*(common->start + GET(common->start, 1)) == OP_ALT)
2581    return FALSE;    return FALSE;
2582    
2583  while (TRUE)  while (TRUE)
2584    {    {
2585    caseless = 0;    caseless = 0;
2586    must_end = TRUE;    must_stop = 1;
2587    switch(*cc)    switch(*cc)
2588      {      {
2589      case OP_CHAR:      case OP_CHAR:
2590      must_end = FALSE;      must_stop = 0;
2591      cc++;      cc++;
2592      break;      break;
2593    
2594      case OP_CHARI:      case OP_CHARI:
2595      caseless = 1;      caseless = 1;
2596      must_end = FALSE;      must_stop = 0;
2597      cc++;      cc++;
2598      break;      break;
2599    
# Line 2599  while (TRUE) Line 2635  while (TRUE)
2635      break;      break;
2636    
2637      default:      default:
2638      return FALSE;      must_stop = 2;
2639        break;
2640      }      }
2641    
2642      if (must_stop == 2)
2643          break;
2644    
2645    len = 1;    len = 1;
2646  #ifdef SUPPORT_UTF  #if defined SUPPORT_UTF && !defined COMPILE_PCRE32
2647    if (common->utf && HAS_EXTRALEN(cc[0])) len += GET_EXTRALEN(cc[0]);    if (common->utf && HAS_EXTRALEN(cc[0])) len += GET_EXTRALEN(cc[0]);
2648  #endif  #endif
2649    
# Line 2624  while (TRUE) Line 2664  while (TRUE)
2664    else    else
2665      caseless = 0;      caseless = 0;
2666    
2667    while (len > 0 && location < 2 * 2)    while (len > 0 && location < MAX_N_CHARS * 2)
2668      {      {
2669      c = *cc;      c = *cc;
2670      bit = 0;      bit = 0;
# Line 2642  while (TRUE) Line 2682  while (TRUE)
2682      cc++;      cc++;
2683      }      }
2684    
2685    if (location == 2 * 2)    if (location >= MAX_N_CHARS * 2 || must_stop != 0)
2686      break;      break;
   else if (must_end)  
     return FALSE;  
2687    }    }
2688    
2689    /* At least two characters are required. */
2690    if (location < 2 * 2)
2691        return FALSE;
2692    
2693  if (firstline)  if (firstline)
2694    {    {
2695    SLJIT_ASSERT(common->first_line_end != 0);    SLJIT_ASSERT(common->first_line_end != 0);
2696    OP1(SLJIT_MOV, TMP3, 0, STR_END, 0);    OP1(SLJIT_MOV, TMP3, 0, STR_END, 0);
2697    OP2(SLJIT_SUB, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end, SLJIT_IMM, 1);    OP2(SLJIT_SUB, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end, SLJIT_IMM, (location >> 1) - 1);
2698    }    }
2699  else  else
2700    OP2(SLJIT_SUB, STR_END, 0, STR_END, 0, SLJIT_IMM, 1);    OP2(SLJIT_SUB, STR_END, 0, STR_END, 0, SLJIT_IMM, (location >> 1) - 1);
2701    
2702  start = LABEL();  start = LABEL();
2703  quit = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);  quit = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
 #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED  
 #ifdef COMPILE_PCRE8  
 OP1(SLJIT_MOV_UH, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);  
 #else /* COMPILE_PCRE8 */  
 OP1(SLJIT_MOV_UI, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);  
 #endif  
   
 #else /* SLJIT_UNALIGNED */  
2704    
2705  #if defined SLJIT_BIG_ENDIAN && SLJIT_BIG_ENDIAN  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
 OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), 0);  
 OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));  
 #else /* SLJIT_BIG_ENDIAN */  
2706  OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));  OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
2707  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2708  #endif /* SLJIT_BIG_ENDIAN */  if (chars[1] != 0)
2709      OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, chars[1]);
2710  #ifdef COMPILE_PCRE8  CMPTO(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, chars[0], start);
2711  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 8);  if (location > 2 * 2)
2712  #else /* COMPILE_PCRE8 */    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
2713  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 16);  if (chars[3] != 0)
2714  #endif    OP2(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_IMM, chars[3]);
2715  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);  CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, chars[2], start);
2716    if (location > 2 * 2)
2717  #endif    {
2718      if (chars[5] != 0)
2719  if (chars[1] != 0 || chars[3] != 0)      OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, chars[5]);
2720    {    CMPTO(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, chars[4], start);
   pair.asuchars[0] = chars[1];  
   pair.asuchars[1] = chars[3];  
   OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, pair.ascombined);  
2721    }    }
2722    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2723    
 pair.asuchars[0] = chars[0];  
 pair.asuchars[1] = chars[2];  
 found = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, pair.ascombined);  
   
 OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));  
 JUMPTO(SLJIT_JUMP, start);  
 JUMPHERE(found);  
2724  JUMPHERE(quit);  JUMPHERE(quit);
2725    
2726  if (firstline)  if (firstline)
2727    OP1(SLJIT_MOV, STR_END, 0, TMP3, 0);    OP1(SLJIT_MOV, STR_END, 0, TMP3, 0);
2728  else  else
2729    OP2(SLJIT_ADD, STR_END, 0, STR_END, 0, SLJIT_IMM, 1);    OP2(SLJIT_ADD, STR_END, 0, STR_END, 0, SLJIT_IMM, (location >> 1) - 1);
2730  return TRUE;  return TRUE;
2731  }  }
2732    
2733    #undef MAX_N_CHARS
2734    
2735  static SLJIT_INLINE void fast_forward_first_char(compiler_common *common, pcre_uchar first_char, BOOL caseless, BOOL firstline)  static SLJIT_INLINE void fast_forward_first_char(compiler_common *common, pcre_uchar first_char, BOOL caseless, BOOL firstline)
2736  {  {
2737  DEFINE_COMPILER;  DEFINE_COMPILER;
# Line 2741  if (first_char == oc) Line 2765  if (first_char == oc)
2765  else  else
2766    {    {
2767    bit = first_char ^ oc;    bit = first_char ^ oc;
2768    if (ispowerof2(bit))    if (is_powerof2(bit))
2769      {      {
2770      OP2(SLJIT_OR, TMP2, 0, TMP1, 0, SLJIT_IMM, bit);      OP2(SLJIT_OR, TMP2, 0, TMP1, 0, SLJIT_IMM, bit);
2771      found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, first_char | bit);      found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, first_char | bit);
# Line 2794  if (common->nltype == NLTYPE_FIXED && co Line 2818  if (common->nltype == NLTYPE_FIXED && co
2818    OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(2));    OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(2));
2819    OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, STR_PTR, 0, TMP1, 0);    OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, STR_PTR, 0, TMP1, 0);
2820    COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_GREATER_EQUAL);    COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_GREATER_EQUAL);
2821  #ifdef COMPILE_PCRE16  #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
2822    OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 1);    OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, UCHAR_SHIFT);
2823  #endif  #endif
2824    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
2825    
# Line 2837  if (common->nltype == NLTYPE_ANY || comm Line 2861  if (common->nltype == NLTYPE_ANY || comm
2861    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
2862    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, CHAR_NL);    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, CHAR_NL);
2863    COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);    COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);
2864  #ifdef COMPILE_PCRE16  #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
2865    OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);    OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, UCHAR_SHIFT);
2866  #endif  #endif
2867    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2868    JUMPHERE(notfoundnl);    JUMPHERE(notfoundnl);
# Line 2892  if (common->utf) Line 2916  if (common->utf)
2916    OP1(SLJIT_MOV, TMP1, 0, TMP3, 0);    OP1(SLJIT_MOV, TMP1, 0, TMP3, 0);
2917  #endif  #endif
2918  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2919  #if defined SUPPORT_UTF && defined COMPILE_PCRE8  #ifdef SUPPORT_UTF
2920    #if defined COMPILE_PCRE8
2921  if (common->utf)  if (common->utf)
2922    {    {
2923    CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0, start);    CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0, start);
2924    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)PRIV(utf8_table4) - 0xc0);    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)PRIV(utf8_table4) - 0xc0);
2925    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2926    }    }
2927  #endif  #elif defined COMPILE_PCRE16
 #if defined SUPPORT_UTF && defined COMPILE_PCRE16  
2928  if (common->utf)  if (common->utf)
2929    {    {
2930    CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800, start);    CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800, start);
# Line 2910  if (common->utf) Line 2934  if (common->utf)
2934    OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);    OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
2935    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2936    }    }
2937  #endif  #endif /* COMPILE_PCRE[8|16] */
2938    #endif /* SUPPORT_UTF */
2939  JUMPTO(SLJIT_JUMP, start);  JUMPTO(SLJIT_JUMP, start);
2940  JUMPHERE(found);  JUMPHERE(found);
2941  JUMPHERE(quit);  JUMPHERE(quit);
# Line 2928  struct sljit_jump *alreadyfound; Line 2953  struct sljit_jump *alreadyfound;
2953  struct sljit_jump *found;  struct sljit_jump *found;
2954  struct sljit_jump *foundoc = NULL;  struct sljit_jump *foundoc = NULL;
2955  struct sljit_jump *notfound;  struct sljit_jump *notfound;
2956  pcre_uchar oc, bit;  pcre_uint32 oc, bit;
2957    
2958  SLJIT_ASSERT(common->req_char_ptr != 0);  SLJIT_ASSERT(common->req_char_ptr != 0);
2959  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->req_char_ptr);  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->req_char_ptr);
# Line 2959  if (req_char == oc) Line 2984  if (req_char == oc)
2984  else  else
2985    {    {
2986    bit = req_char ^ oc;    bit = req_char ^ oc;
2987    if (ispowerof2(bit))    if (is_powerof2(bit))
2988      {      {
2989      OP2(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_IMM, bit);      OP2(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_IMM, bit);
2990      found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, req_char | bit);      found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, req_char | bit);
# Line 3189  switch(ranges[0]) Line 3214  switch(ranges[0])
3214        }        }
3215      return TRUE;      return TRUE;
3216      }      }
3217    if ((ranges[3] - ranges[2]) == (ranges[5] - ranges[4]) && ispowerof2(ranges[4] - ranges[2]))    if ((ranges[3] - ranges[2]) == (ranges[5] - ranges[4]) && is_powerof2(ranges[4] - ranges[2]))
3218      {      {
3219      if (readch)      if (readch)
3220        read_char(common);        read_char(common);
# Line 3290  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_I Line 3315  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_I
3315  OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x0d - 0x0a);  OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x0d - 0x0a);
3316  COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS_EQUAL);  COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS_EQUAL);
3317  OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x85 - 0x0a);  OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x85 - 0x0a);
3318  #if defined SUPPORT_UTF || defined COMPILE_PCRE16  #if defined SUPPORT_UTF || defined COMPILE_PCRE16 || defined COMPILE_PCRE32
3319  #ifdef COMPILE_PCRE8  #ifdef COMPILE_PCRE8
3320  if (common->utf)  if (common->utf)
3321    {    {
# Line 3301  if (common->utf) Line 3326  if (common->utf)
3326  #ifdef COMPILE_PCRE8  #ifdef COMPILE_PCRE8
3327    }    }
3328  #endif  #endif
3329  #endif /* SUPPORT_UTF || COMPILE_PCRE16 */  #endif /* SUPPORT_UTF || COMPILE_PCRE16 || COMPILE_PCRE32 */
3330  COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);  COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);
3331  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
3332  }  }
# Line 3318  COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_E Line 3343  COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_E
3343  OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x20);  OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x20);
3344  COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);  COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);
3345  OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xa0);  OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xa0);
3346  #if defined SUPPORT_UTF || defined COMPILE_PCRE16  #if defined SUPPORT_UTF || defined COMPILE_PCRE16 || defined COMPILE_PCRE32
3347  #ifdef COMPILE_PCRE8  #ifdef COMPILE_PCRE8
3348  if (common->utf)  if (common->utf)
3349    {    {
# Line 3339  if (common->utf) Line 3364  if (common->utf)
3364  #ifdef COMPILE_PCRE8  #ifdef COMPILE_PCRE8
3365    }    }
3366  #endif  #endif
3367  #endif /* SUPPORT_UTF || COMPILE_PCRE16 */  #endif /* SUPPORT_UTF || COMPILE_PCRE16 || COMPILE_PCRE32 */
3368  COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);  COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);
3369    
3370  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
# Line 3356  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_I Line 3381  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_I
3381  OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x0d - 0x0a);  OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x0d - 0x0a);
3382  COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS_EQUAL);  COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS_EQUAL);
3383  OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x85 - 0x0a);  OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x85 - 0x0a);
3384  #if defined SUPPORT_UTF || defined COMPILE_PCRE16  #if defined SUPPORT_UTF || defined COMPILE_PCRE16 || defined COMPILE_PCRE32
3385  #ifdef COMPILE_PCRE8  #ifdef COMPILE_PCRE8
3386  if (common->utf)  if (common->utf)
3387    {    {
# Line 3367  if (common->utf) Line 3392  if (common->utf)
3392  #ifdef COMPILE_PCRE8  #ifdef COMPILE_PCRE8
3393    }    }
3394  #endif  #endif
3395  #endif /* SUPPORT_UTF || COMPILE_PCRE16 */  #endif /* SUPPORT_UTF || COMPILE_PCRE16 || COMPILE_PCRE32 */
3396  COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);  COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);
3397    
3398  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
# Line 3457  sljit_emit_fast_return(compiler, RETURN_ Line 3482  sljit_emit_fast_return(compiler, RETURN_
3482  static const pcre_uchar *SLJIT_CALL do_utf_caselesscmp(pcre_uchar *src1, jit_arguments *args, pcre_uchar *end1)  static const pcre_uchar *SLJIT_CALL do_utf_caselesscmp(pcre_uchar *src1, jit_arguments *args, pcre_uchar *end1)
3483  {  {
3484  /* This function would be ineffective to do in JIT level. */  /* This function would be ineffective to do in JIT level. */
3485  int c1, c2;  pcre_uint32 c1, c2;
3486  const pcre_uchar *src2 = args->uchar_ptr;  const pcre_uchar *src2 = args->uchar_ptr;
3487  const pcre_uchar *end2 = args->end;  const pcre_uchar *end2 = args->end;
3488    const ucd_record *ur;
3489    const pcre_uint32 *pp;
3490    
3491  while (src1 < end1)  while (src1 < end1)
3492    {    {
# Line 3467  while (src1 < end1) Line 3494  while (src1 < end1)
3494      return (pcre_uchar*)1;      return (pcre_uchar*)1;
3495    GETCHARINC(c1, src1);    GETCHARINC(c1, src1);
3496    GETCHARINC(c2, src2);    GETCHARINC(c2, src2);
3497    if (c1 != c2 && c1 != UCD_OTHERCASE(c2)) return NULL;    ur = GET_UCD(c2);
3498      if (c1 != c2 && c1 != c2 + ur->other_case)
3499        {
3500        pp = PRIV(ucd_caseless_sets) + ur->caseset;
3501        for (;;)
3502          {
3503          if (c1 < *pp) return NULL;
3504          if (c1 == *pp++) break;
3505          }
3506        }
3507    }    }
3508  return src2;  return src2;
3509  }  }
# Line 3489  if (caseless && char_has_othercase(commo Line 3525  if (caseless && char_has_othercase(commo
3525    othercasebit = char_get_othercase_bit(common, cc);    othercasebit = char_get_othercase_bit(common, cc);
3526    SLJIT_ASSERT(othercasebit);    SLJIT_ASSERT(othercasebit);
3527    /* Extracting bit difference info. */    /* Extracting bit difference info. */
3528  #ifdef COMPILE_PCRE8  #if defined COMPILE_PCRE8
3529    othercasechar = cc + (othercasebit >> 8);    othercasechar = cc + (othercasebit >> 8);
3530    othercasebit &= 0xff;    othercasebit &= 0xff;
3531  #else  #elif defined COMPILE_PCRE16 || defined COMPILE_PCRE32
 #ifdef COMPILE_PCRE16  
3532    othercasechar = cc + (othercasebit >> 9);    othercasechar = cc + (othercasebit >> 9);
3533    if ((othercasebit & 0x100) != 0)    if ((othercasebit & 0x100) != 0)
3534      othercasebit = (othercasebit & 0xff) << 8;      othercasebit = (othercasebit & 0xff) << 8;
3535    else    else
3536      othercasebit &= 0xff;      othercasebit &= 0xff;
3537  #endif  #endif /* COMPILE_PCRE[8|16|32] */
 #endif  
3538    }    }
3539    
3540  if (context->sourcereg == -1)  if (context->sourcereg == -1)
3541    {    {
3542  #ifdef COMPILE_PCRE8  #if defined COMPILE_PCRE8
3543  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
3544    if (context->length >= 4)    if (context->length >= 4)
3545      OP1(SLJIT_MOV_SI, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);      OP1(SLJIT_MOV_SI, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);
# Line 3514  if (context->sourcereg == -1) Line 3548  if (context->sourcereg == -1)
3548    else    else
3549  #endif  #endif
3550      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);
3551  #else  #elif defined COMPILE_PCRE16
 #ifdef COMPILE_PCRE16  
3552  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
3553    if (context->length >= 4)    if (context->length >= 4)
3554      OP1(SLJIT_MOV_SI, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);      OP1(SLJIT_MOV_SI, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);
3555    else    else
3556  #endif  #endif
3557      OP1(SLJIT_MOV_UH, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);
3558  #endif  #elif defined COMPILE_PCRE32
3559  #endif /* COMPILE_PCRE8 */    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);
3560    #endif /* COMPILE_PCRE[8|16|32] */
3561    context->sourcereg = TMP2;    context->sourcereg = TMP2;
3562    }    }
3563    
3564  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
3565  utflength = 1;  utflength = 1;
3566    #ifndef COMPILE_PCRE32
3567  if (common->utf && HAS_EXTRALEN(*cc))  if (common->utf && HAS_EXTRALEN(*cc))
3568    utflength += GET_EXTRALEN(*cc);    utflength += GET_EXTRALEN(*cc);
3569    #endif
3570    
3571  do  do
3572    {    {
# Line 3552  do Line 3588  do
3588      }      }
3589    context->ucharptr++;    context->ucharptr++;
3590    
3591  #ifdef COMPILE_PCRE8  #if defined COMPILE_PCRE8
3592    if (context->ucharptr >= 4 || context->length == 0 || (context->ucharptr == 2 && context->length == 1))    if (context->ucharptr >= 4 || context->length == 0 || (context->ucharptr == 2 && context->length == 1))
3593  #else  #elif defined COMPILE_PCRE16
3594    if (context->ucharptr >= 2 || context->length == 0)    if (context->ucharptr >= 2 || context->length == 0)
3595    #elif defined COMPILE_PCRE32
3596      if (1 /* context->ucharptr >= 1 || context->length == 0 */)
3597  #endif  #endif
3598      {      {
3599    #if defined COMPILE_PCRE8 || defined COMPILE_PCRE16
3600      if (context->length >= 4)      if (context->length >= 4)
3601        OP1(SLJIT_MOV_SI, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);        OP1(SLJIT_MOV_SI, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);
3602  #ifdef COMPILE_PCRE8  #if defined COMPILE_PCRE8
3603      else if (context->length >= 2)      else if (context->length >= 2)
3604        OP1(SLJIT_MOV_UH, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);        OP1(SLJIT_MOV_UH, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);
3605      else if (context->length >= 1)      else if (context->length >= 1)
3606        OP1(SLJIT_MOV_UB, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);        OP1(SLJIT_MOV_UB, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);
3607  #else  #elif defined COMPILE_PCRE16
3608      else if (context->length >= 2)      else if (context->length >= 2)
3609        OP1(SLJIT_MOV_UH, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);        OP1(SLJIT_MOV_UH, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);
3610  #endif  #endif /* COMPILE_PCRE[8|16] */
3611    #elif defined COMPILE_PCRE32
3612        OP1(MOV_UCHAR, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);
3613    #endif /* COMPILE_PCRE[8|16|32] */
3614      context->sourcereg = context->sourcereg == TMP1 ? TMP2 : TMP1;      context->sourcereg = context->sourcereg == TMP1 ? TMP2 : TMP1;
3615    
3616      switch(context->ucharptr)      switch(context->ucharptr)
# Line 3579  do Line 3621  do
3621        add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, context->sourcereg, 0, SLJIT_IMM, context->c.asint | context->oc.asint));        add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, context->sourcereg, 0, SLJIT_IMM, context->c.asint | context->oc.asint));
3622        break;        break;
3623    
3624    #if defined COMPILE_PCRE8 || defined COMPILE_PCRE16
3625        case 2 / sizeof(pcre_uchar):        case 2 / sizeof(pcre_uchar):
3626        if (context->oc.asushort != 0)        if (context->oc.asushort != 0)
3627          OP2(SLJIT_OR, context->sourcereg, 0, context->sourcereg, 0, SLJIT_IMM, context->oc.asushort);          OP2(SLJIT_OR, context->sourcereg, 0, context->sourcereg, 0, SLJIT_IMM, context->oc.asushort);
# Line 3593  do Line 3636  do
3636        break;        break;
3637  #endif  #endif
3638    
3639    #endif /* COMPILE_PCRE[8|16] */
3640    
3641        default:        default:
3642        SLJIT_ASSERT_STOP();        SLJIT_ASSERT_STOP();
3643        break;        break;
# Line 3603  do Line 3648  do
3648  #else  #else
3649    
3650    /* Unaligned read is unsupported. */    /* Unaligned read is unsupported. */
 #ifdef COMPILE_PCRE8  
   if (context->length > 0)  
     OP1(SLJIT_MOV_UB, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);  
 #else  
3651    if (context->length > 0)    if (context->length > 0)
3652      OP1(SLJIT_MOV_UH, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);      OP1(MOV_UCHAR, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);
3653  #endif  
3654    context->sourcereg = context->sourcereg == TMP1 ? TMP2 : TMP1;    context->sourcereg = context->sourcereg == TMP1 ? TMP2 : TMP1;
3655    
3656    if (othercasebit != 0 && othercasechar == cc)    if (othercasebit != 0 && othercasechar == cc)
# Line 3659  static void compile_xclass_matchingpath( Line 3700  static void compile_xclass_matchingpath(
3700  DEFINE_COMPILER;  DEFINE_COMPILER;
3701  jump_list *found = NULL;  jump_list *found = NULL;
3702  jump_list **list = (*cc & XCL_NOT) == 0 ? &found : backtracks;  jump_list **list = (*cc & XCL_NOT) == 0 ? &found : backtracks;
3703  unsigned int c;  pcre_int32 c, charoffset;
3704  int compares;  const pcre_uint32 *other_cases;
3705  struct sljit_jump *jump = NULL;  struct sljit_jump *jump = NULL;
3706  pcre_uchar *ccbegin;  pcre_uchar *ccbegin;
3707    int compares, invertcmp, numberofcmps;
3708  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
3709  BOOL needstype = FALSE, needsscript = FALSE, needschar = FALSE;  BOOL needstype = FALSE, needsscript = FALSE, needschar = FALSE;
3710  BOOL charsaved = FALSE;  BOOL charsaved = FALSE;
3711  int typereg = TMP1, scriptreg = TMP1;  int typereg = TMP1, scriptreg = TMP1;
3712  unsigned int typeoffset;  pcre_int32 typeoffset;
3713  #endif  #endif
 int invertcmp, numberofcmps;  
 unsigned int charoffset;  
3714    
3715  /* Although SUPPORT_UTF must be defined, we are  /* Although SUPPORT_UTF must be defined, we are
3716     not necessary in utf mode even in 8 bit mode. */     not necessary in utf mode even in 8 bit mode. */
# Line 3719  while (*cc != XCL_END) Line 3759  while (*cc != XCL_END)
3759    if (*cc == XCL_SINGLE)    if (*cc == XCL_SINGLE)
3760      {      {
3761      cc += 2;      cc += 2;
3762  #ifdef SUPPORT_UTF  #if defined SUPPORT_UTF && !defined COMPILE_PCRE32
3763      if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);      if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
3764  #endif  #endif
3765  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
# Line 3729  while (*cc != XCL_END) Line 3769  while (*cc != XCL_END)
3769    else if (*cc == XCL_RANGE)    else if (*cc == XCL_RANGE)
3770      {      {
3771      cc += 2;      cc += 2;
3772  #ifdef SUPPORT_UTF  #if defined SUPPORT_UTF && !defined COMPILE_PCRE32
3773      if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);      if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
3774  #endif  #endif
3775      cc++;      cc++;
3776  #ifdef SUPPORT_UTF  #if defined SUPPORT_UTF && !defined COMPILE_PCRE32
3777      if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);      if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
3778  #endif  #endif
3779  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
# Line 3768  while (*cc != XCL_END) Line 3808  while (*cc != XCL_END)
3808        needschar = TRUE;        needschar = TRUE;
3809        break;        break;
3810    
3811          case PT_CLIST:
3812          needschar = TRUE;
3813          break;
3814    
3815        default:        default:
3816        SLJIT_ASSERT_STOP();        SLJIT_ASSERT_STOP();
3817        break;        break;
# Line 3977  while (*cc != XCL_END) Line 4021  while (*cc != XCL_END)
4021        COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_LESS_EQUAL);        COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_LESS_EQUAL);
4022        jump = JUMP(SLJIT_C_NOT_ZERO ^ invertcmp);        jump = JUMP(SLJIT_C_NOT_ZERO ^ invertcmp);
4023        break;        break;
4024    
4025          case PT_CLIST:
4026          other_cases = PRIV(ucd_caseless_sets) + cc[1];
4027    
4028          /* At least three characters are required.
4029             Otherwise this case would be handled by the normal code path. */
4030          SLJIT_ASSERT(other_cases[0] != NOTACHAR && other_cases[1] != NOTACHAR && other_cases[2] != NOTACHAR);
4031          SLJIT_ASSERT(other_cases[0] < other_cases[1] && other_cases[1] < other_cases[2]);
4032    
4033          /* Optimizing character pairs, if their difference is power of 2. */
4034          if (is_powerof2(other_cases[1] ^ other_cases[0]))
4035            {
4036            if (charoffset == 0)
4037              OP2(SLJIT_OR, TMP2, 0, TMP1, 0, SLJIT_IMM, other_cases[1] ^ other_cases[0]);
4038            else
4039              {
4040              OP2(SLJIT_ADD, TMP2, 0, TMP1, 0, SLJIT_IMM, (sljit_w)charoffset);
4041              OP2(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_IMM, other_cases[1] ^ other_cases[0]);
4042              }
4043            OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, other_cases[1]);
4044            COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);
4045            other_cases += 2;
4046            }
4047          else if (is_powerof2(other_cases[2] ^ other_cases[1]))
4048            {
4049            if (charoffset == 0)
4050              OP2(SLJIT_OR, TMP2, 0, TMP1, 0, SLJIT_IMM, other_cases[2] ^ other_cases[1]);
4051            else
4052              {
4053              OP2(SLJIT_ADD, TMP2, 0, TMP1, 0, SLJIT_IMM, (sljit_w)charoffset);
4054              OP2(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_IMM, other_cases[1] ^ other_cases[0]);
4055              }
4056            OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, other_cases[2]);
4057            COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);
4058    
4059            OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, other_cases[0] - charoffset);
4060            COND_VALUE(SLJIT_OR | ((other_cases[3] == NOTACHAR) ? SLJIT_SET_E : 0), TMP2, 0, SLJIT_C_EQUAL);
4061    
4062            other_cases += 3;
4063            }
4064          else
4065            {
4066            OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, *other_cases++ - charoffset);
4067            COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);
4068            }
4069    
4070          while (*other_cases != NOTACHAR)
4071            {
4072            OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, *other_cases++ - charoffset);
4073            COND_VALUE(SLJIT_OR | ((*other_cases == NOTACHAR) ? SLJIT_SET_E : 0), TMP2, 0, SLJIT_C_EQUAL);
4074            }
4075          jump = JUMP(SLJIT_C_NOT_ZERO ^ invertcmp);
4076          break;
4077        }        }
4078      cc += 2;      cc += 2;
4079      }      }
# Line 4092  switch(type) Line 4189  switch(type)
4189      {      {
4190      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
4191      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
4192  #ifdef COMPILE_PCRE8  #if defined COMPILE_PCRE8 || defined COMPILE_PCRE16
4193    #if defined COMPILE_PCRE8
4194      jump[0] = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);      jump[0] = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);
4195      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)PRIV(utf8_table4) - 0xc0);      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)PRIV(utf8_table4) - 0xc0);
4196      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
4197  #else /* COMPILE_PCRE8 */  #elif defined COMPILE_PCRE16
 #ifdef COMPILE_PCRE16  
4198      jump[0] = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800);      jump[0] = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800);
4199      OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);      OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);
4200      OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xd800);      OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xd800);
4201      COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);      COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);
4202      OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);      OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
4203      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
4204  #endif /* COMPILE_PCRE16 */  #endif
 #endif /* COMPILE_PCRE8 */  
4205      JUMPHERE(jump[0]);      JUMPHERE(jump[0]);
4206    #endif /* COMPILE_PCRE[8|16] */
4207      return cc;      return cc;
4208      }      }
4209  #endif  #endif
# Line 4173  switch(type) Line 4270  switch(type)
4270    detect_partial_match(common, backtracks);    detect_partial_match(common, backtracks);
4271    read_char(common);    read_char(common);
4272    add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL));
4273    OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Mc);    OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, (sljit_w)PRIV(ucd_records) + SLJIT_OFFSETOF(ucd_record, gbprop));
4274    add_jump(compiler, backtracks, CMP(SLJIT_C_LESS_EQUAL, TMP1, 0, SLJIT_IMM, ucp_Mn - ucp_Mc));    /* Optimize register allocation: use a real register. */
4275      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, STACK_TOP, 0);
4276      OP1(SLJIT_MOV_UB, STACK_TOP, 0, SLJIT_MEM2(TMP1, TMP2), 3);
4277    
4278    label = LABEL();    label = LABEL();
4279    jump[0] = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);    jump[0] = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
4280    OP1(SLJIT_MOV, TMP3, 0, STR_PTR, 0);    OP1(SLJIT_MOV, TMP3, 0, STR_PTR, 0);
4281    read_char(common);    read_char(common);
4282    add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL));
4283    OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Mc);    OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, (sljit_w)PRIV(ucd_records) + SLJIT_OFFSETOF(ucd_record, gbprop));
4284    CMPTO(SLJIT_C_LESS_EQUAL, TMP1, 0, SLJIT_IMM, ucp_Mn - ucp_Mc, label);    OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM2(TMP1, TMP2), 3);
4285    
4286      OP2(SLJIT_SHL, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, 2);
4287      OP1(SLJIT_MOV_UI, TMP1, 0, SLJIT_MEM1(STACK_TOP), (sljit_w)PRIV(ucp_gbtable));
4288      OP1(SLJIT_MOV, STACK_TOP, 0, TMP2, 0);
4289      OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0);
4290      OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, TMP2, 0);
4291      JUMPTO(SLJIT_C_NOT_ZERO, label);
4292    
4293    OP1(SLJIT_MOV, STR_PTR, 0, TMP3, 0);    OP1(SLJIT_MOV, STR_PTR, 0, TMP3, 0);
4294    JUMPHERE(jump[0]);    JUMPHERE(jump[0]);
4295      OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);
4296    
4297    if (common->mode == JIT_PARTIAL_HARD_COMPILE)    if (common->mode == JIT_PARTIAL_HARD_COMPILE)
4298      {      {
4299      jump[0] = CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0);      jump[0] = CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0);
# Line 4359  switch(type) Line 4467  switch(type)
4467    case OP_CHAR:    case OP_CHAR:
4468    case OP_CHARI:    case OP_CHARI:
4469    length = 1;    length = 1;
4470  #ifdef SUPPORT_UTF  #if defined SUPPORT_UTF && !defined COMPILE_PCRE32
4471    if (common->utf && HAS_EXTRALEN(*cc)) length += GET_EXTRALEN(*cc);    if (common->utf && HAS_EXTRALEN(*cc)) length += GET_EXTRALEN(*cc);
4472  #endif  #endif
4473    if (common->mode == JIT_COMPILE && (type == OP_CHAR || !char_has_othercase(common, cc) || char_get_othercase_bit(common, cc) != 0))    if (common->mode == JIT_COMPILE && (type == OP_CHAR || !char_has_othercase(common, cc) || char_get_othercase_bit(common, cc) != 0))
# Line 4391  switch(type) Line 4499  switch(type)
4499      }      }
4500    oc = char_othercase(common, c);    oc = char_othercase(common, c);
4501    bit = c ^ oc;    bit = c ^ oc;
4502    if (ispowerof2(bit))    if (is_powerof2(bit))
4503      {      {
4504      OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, bit);      OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, bit);
4505      add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, c | bit));      add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, c | bit));
# Line 4452  switch(type) Line 4560  switch(type)
4560      {      {
4561      oc = char_othercase(common, c);      oc = char_othercase(common, c);
4562      bit = c ^ oc;      bit = c ^ oc;
4563      if (ispowerof2(bit))      if (is_powerof2(bit))
4564        {        {
4565        OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, bit);        OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, bit);
4566        add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, c | bit));        add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, c | bit));
# Line 4500  switch(type) Line 4608  switch(type)
4608  #endif /* SUPPORT_UTF || !COMPILE_PCRE8 */  #endif /* SUPPORT_UTF || !COMPILE_PCRE8 */
4609    return cc + 32 / sizeof(pcre_uchar);    return cc + 32 / sizeof(pcre_uchar);
4610    
4611  #if defined SUPPORT_UTF || defined COMPILE_PCRE16  #if defined SUPPORT_UTF || defined COMPILE_PCRE16 || defined COMPILE_PCRE32
4612    case OP_XCLASS:    case OP_XCLASS:
4613    compile_xclass_matchingpath(common, cc + LINK_SIZE, backtracks);    compile_xclass_matchingpath(common, cc + LINK_SIZE, backtracks);
4614    return cc + GET(cc, 0) - 1;    return cc + GET(cc, 0) - 1;
# Line 4554  do Line 4662  do
4662    if (*cc == OP_CHAR)    if (*cc == OP_CHAR)
4663      {      {
4664      size = 1;      size = 1;
4665  #ifdef SUPPORT_UTF  #if defined SUPPORT_UTF && !defined COMPILE_PCRE32
4666      if (common->utf && HAS_EXTRALEN(cc[1]))      if (common->utf && HAS_EXTRALEN(cc[1]))
4667        size += GET_EXTRALEN(cc[1]);        size += GET_EXTRALEN(cc[1]);
4668  #endif  #endif
# Line 4567  do Line 4675  do
4675        {        {
4676        if (char_has_othercase(common, cc + 1) && char_get_othercase_bit(common, cc + 1) == 0)        if (char_has_othercase(common, cc + 1) && char_get_othercase_bit(common, cc + 1) == 0)
4677          size = 0;          size = 0;
4678    #ifndef COMPILE_PCRE32
4679        else if (HAS_EXTRALEN(cc[1]))        else if (HAS_EXTRALEN(cc[1]))
4680          size += GET_EXTRALEN(cc[1]);          size += GET_EXTRALEN(cc[1]);
4681    #endif
4682        }        }
4683      else      else
4684  #endif  #endif
# Line 5454  if (opcode == OP_CBRA || opcode == OP_SC Line 5564  if (opcode == OP_CBRA || opcode == OP_SC
5564    {    {
5565    /* Capturing brackets has a pre-allocated space. */    /* Capturing brackets has a pre-allocated space. */
5566    offset = GET2(ccbegin, 1 + LINK_SIZE);    offset = GET2(ccbegin, 1 + LINK_SIZE);
5567    private_data_ptr = OVECTOR_PRIV(offset);    if (common->optimized_cbracket[offset] == 0)
5568    offset <<= 1;      {
5569        private_data_ptr = OVECTOR_PRIV(offset);
5570        offset <<= 1;
5571        }
5572      else
5573        {
5574        offset <<= 1;
5575        private_data_ptr = OVECTOR(offset);
5576        }
5577    BACKTRACK_AS(bracket_backtrack)->private_data_ptr = private_data_ptr;    BACKTRACK_AS(bracket_backtrack)->private_data_ptr = private_data_ptr;
5578    matchingpath += IMM2_SIZE;    matchingpath += IMM2_SIZE;
5579    }    }
# Line 5589  if (opcode == OP_ONCE) Line 5707  if (opcode == OP_ONCE)
5707  else if (opcode == OP_CBRA || opcode == OP_SCBRA)  else if (opcode == OP_CBRA || opcode == OP_SCBRA)
5708    {    {
5709    /* Saving the previous values. */    /* Saving the previous values. */
5710    allocate_stack(common, 3);    if (common->optimized_cbracket[offset >> 1] == 0)
5711    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));      {
5712    OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1));      allocate_stack(common, 3);
5713    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0);      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));
5714    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0);      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1));
5715    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0);
5716    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, STR_PTR, 0);      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
5717    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(2), TMP1, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0);
5718        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, STR_PTR, 0);
5719        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(2), TMP1, 0);
5720        }
5721      else
5722        {
5723        SLJIT_ASSERT(private_data_ptr == OVECTOR(offset));
5724        allocate_stack(common, 2);
5725        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
5726        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr + sizeof(sljit_w));
5727        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, STR_PTR, 0);
5728        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0);
5729        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0);
5730        }
5731    }    }
5732  else if (opcode == OP_SBRA || opcode == OP_SCOND)  else if (opcode == OP_SBRA || opcode == OP_SCOND)
5733    {    {
# Line 5866  switch(opcode) Line 5997  switch(opcode)
5997    case OP_CBRAPOS:    case OP_CBRAPOS:
5998    case OP_SCBRAPOS:    case OP_SCBRAPOS:
5999    offset = GET2(cc, 1 + LINK_SIZE);    offset = GET2(cc, 1 + LINK_SIZE);
6000      /* This case cannot be optimized in the same was as
6001      normal capturing brackets. */
6002      SLJIT_ASSERT(common->optimized_cbracket[offset] == 0);
6003    cbraprivptr = OVECTOR_PRIV(offset);    cbraprivptr = OVECTOR_PRIV(offset);
6004    offset <<= 1;    offset <<= 1;
6005    ccbegin = cc + 1 + LINK_SIZE + IMM2_SIZE;    ccbegin = cc + 1 + LINK_SIZE + IMM2_SIZE;
# Line 6132  if (*type == 0) Line 6266  if (*type == 0)
6266  if (end != NULL)  if (end != NULL)
6267    {    {
6268    *end = cc + 1;    *end = cc + 1;
6269  #ifdef SUPPORT_UTF  #if defined SUPPORT_UTF && !defined COMPILE_PCRE32
6270    if (common->utf && HAS_EXTRALEN(*cc)) *end += GET_EXTRALEN(*cc);    if (common->utf && HAS_EXTRALEN(*cc)) *end += GET_EXTRALEN(*cc);
6271  #endif  #endif
6272    }    }
# Line 6405  static SLJIT_INLINE pcre_uchar *compile_ Line 6539  static SLJIT_INLINE pcre_uchar *compile_
6539  {  {
6540  DEFINE_COMPILER;  DEFINE_COMPILER;
6541  int offset = GET2(cc, 1);  int offset = GET2(cc, 1);
6542    BOOL optimized_cbracket = common->optimized_cbracket[offset] != 0;
6543    
6544  /* Data will be discarded anyway... */  /* Data will be discarded anyway... */
6545  if (common->currententry != NULL)  if (common->currententry != NULL)
6546    return cc + 1 + IMM2_SIZE;    return cc + 1 + IMM2_SIZE;
6547    
6548  OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR_PRIV(offset));  if (!optimized_cbracket)
6549      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR_PRIV(offset));
6550  offset <<= 1;  offset <<= 1;
6551  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);
6552  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);  if (!optimized_cbracket)
6553      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);
6554  return cc + 1 + IMM2_SIZE;  return cc + 1 + IMM2_SIZE;
6555  }  }
6556    
# Line 6552  while (cc < ccend) Line 6689  while (cc < ccend)
6689        cc = compile_char1_matchingpath(common, *cc, cc + 1, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks);        cc = compile_char1_matchingpath(common, *cc, cc + 1, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks);
6690      break;      break;
6691    
6692  #if defined SUPPORT_UTF || defined COMPILE_PCRE16  #if defined SUPPORT_UTF || defined COMPILE_PCRE16 || defined COMPILE_PCRE32
6693      case OP_XCLASS:      case OP_XCLASS:
6694      if (*(cc + GET(cc, 1)) >= OP_CRSTAR && *(cc + GET(cc, 1)) <= OP_CRMINRANGE)      if (*(cc + GET(cc, 1)) >= OP_CRSTAR && *(cc + GET(cc, 1)) <= OP_CRMINRANGE)
6695        cc = compile_iterator_matchingpath(common, cc, parent);        cc = compile_iterator_matchingpath(common, cc, parent);
# Line 7235  if (has_alternatives) Line 7372  if (has_alternatives)
7372  if (offset != 0)  if (offset != 0)
7373    {    {
7374    /* Using both tmp register is better for instruction scheduling. */    /* Using both tmp register is better for instruction scheduling. */
7375    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));    if (common->optimized_cbracket[offset >> 1] == 0)
7376    OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(1));      {
7377    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
7378    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), TMP2, 0);      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
7379    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, SLJIT_MEM1(STACK_TOP), STACK(2));      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);
7380    free_stack(common, 3);      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(2));
7381        free_stack(common, 3);
7382        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), TMP2, 0);
7383        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, TMP1, 0);
7384        }
7385      else
7386        {
7387        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
7388        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
7389        free_stack(common, 2);
7390        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);
7391        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), TMP2, 0);
7392        }
7393    }    }
7394  else if (opcode == OP_SBRA || opcode == OP_SCOND)  else if (opcode == OP_SBRA || opcode == OP_SCOND)
7395    {    {
# Line 7717  common->name_count = re->name_count; Line 7866  common->name_count = re->name_count;
7866  common->name_entry_size = re->name_entry_size;  common->name_entry_size = re->name_entry_size;
7867  common->jscript_compat = (re->options & PCRE_JAVASCRIPT_COMPAT) != 0;  common->jscript_compat = (re->options & PCRE_JAVASCRIPT_COMPAT) != 0;
7868  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
7869  /* PCRE_UTF16 has the same value as PCRE_UTF8. */  /* PCRE_UTF[16|32] have the same value as PCRE_UTF8. */
7870  common->utf = (re->options & PCRE_UTF8) != 0;  common->utf = (re->options & PCRE_UTF8) != 0;
7871  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
7872  common->use_ucp = (re->options & PCRE_UCP) != 0;  common->use_ucp = (re->options & PCRE_UCP) != 0;
# Line 7727  ccend = bracketend(rootbacktrack.cc); Line 7876  ccend = bracketend(rootbacktrack.cc);
7876    
7877  /* Calculate the local space size on the stack. */  /* Calculate the local space size on the stack. */
7878  common->ovector_start = CALL_LIMIT + sizeof(sljit_w);  common->ovector_start = CALL_LIMIT + sizeof(sljit_w);
7879    common->optimized_cbracket = (pcre_uint8 *)SLJIT_MALLOC(re->top_bracket + 1);
7880    if (!common->optimized_cbracket)
7881      return;
7882    memset(common->optimized_cbracket, 1, re->top_bracket + 1);
7883    
7884  SLJIT_ASSERT(*rootbacktrack.cc == OP_BRA && ccend[-(1 + LINK_SIZE)] == OP_KET);  SLJIT_ASSERT(*rootbacktrack.cc == OP_BRA && ccend[-(1 + LINK_SIZE)] == OP_KET);
7885  private_data_size = get_private_data_length(common, rootbacktrack.cc, ccend);  private_data_size = get_private_data_length(common, rootbacktrack.cc, ccend);
7886  if (private_data_size < 0)  if (private_data_size < 0)
7887      {
7888      SLJIT_FREE(common->optimized_cbracket);
7889    return;    return;
7890      }
7891    
7892  /* Checking flags and updating ovector_start. */  /* Checking flags and updating ovector_start. */
7893  if (mode == JIT_COMPILE && (re->flags & PCRE_REQCHSET) != 0 && (re->options & PCRE_NO_START_OPTIMIZE) == 0)  if (mode == JIT_COMPILE && (re->flags & PCRE_REQCHSET) != 0 && (re->options & PCRE_NO_START_OPTIMIZE) == 0)
# Line 7763  SLJIT_ASSERT(!(common->req_char_ptr != 0 Line 7919  SLJIT_ASSERT(!(common->req_char_ptr != 0
7919  common->cbraptr = OVECTOR_START + (re->top_bracket + 1) * 2 * sizeof(sljit_w);  common->cbraptr = OVECTOR_START + (re->top_bracket + 1) * 2 * sizeof(sljit_w);
7920  private_data_size += common->cbraptr + (re->top_bracket + 1) * sizeof(sljit_w);  private_data_size += common->cbraptr + (re->top_bracket + 1) * sizeof(sljit_w);
7921  if (private_data_size > SLJIT_MAX_LOCAL_SIZE)  if (private_data_size > SLJIT_MAX_LOCAL_SIZE)
7922      {
7923      SLJIT_FREE(common->optimized_cbracket);
7924    return;    return;
7925      }
7926  common->private_data_ptrs = (int *)SLJIT_MALLOC((ccend - rootbacktrack.cc) * sizeof(int));  common->private_data_ptrs = (int *)SLJIT_MALLOC((ccend - rootbacktrack.cc) * sizeof(int));
7927  if (!common->private_data_ptrs)  if (!common->private_data_ptrs)
7928      {
7929      SLJIT_FREE(common->optimized_cbracket);
7930    return;    return;
7931      }
7932  memset(common->private_data_ptrs, 0, (ccend - rootbacktrack.cc) * sizeof(int));  memset(common->private_data_ptrs, 0, (ccend - rootbacktrack.cc) * sizeof(int));
7933  set_private_data_ptrs(common, common->cbraptr + (re->top_bracket + 1) * sizeof(sljit_w), ccend);  set_private_data_ptrs(common, common->cbraptr + (re->top_bracket + 1) * sizeof(sljit_w), ccend);
7934    
7935  compiler = sljit_create_compiler();  compiler = sljit_create_compiler();
7936  if (!compiler)  if (!compiler)
7937    {    {
7938      SLJIT_FREE(common->optimized_cbracket);
7939    SLJIT_FREE(common->private_data_ptrs);    SLJIT_FREE(common->private_data_ptrs);
7940    return;    return;
7941    }    }
# Line 7806  if ((re->options & PCRE_ANCHORED) == 0) Line 7969  if ((re->options & PCRE_ANCHORED) == 0)
7969    /* Forward search if possible. */    /* Forward search if possible. */
7970    if ((re->options & PCRE_NO_START_OPTIMIZE) == 0)    if ((re->options & PCRE_NO_START_OPTIMIZE) == 0)
7971      {      {
7972      if (mode == JIT_COMPILE && fast_forward_first_two_chars(common, (re->options & PCRE_FIRSTLINE) != 0))      if (mode == JIT_COMPILE && fast_forward_first_n_chars(common, (re->options & PCRE_FIRSTLINE) != 0))
7973        { /* Do nothing */ }        { /* Do nothing */ }
7974      else if ((re->flags & PCRE_FIRSTSET) != 0)      else if ((re->flags & PCRE_FIRSTSET) != 0)
7975        fast_forward_first_char(common, (pcre_uchar)re->first_char, (re->flags & PCRE_FCH_CASELESS) != 0, (re->options & PCRE_FIRSTLINE) != 0);        fast_forward_first_char(common, (pcre_uchar)re->first_char, (re->flags & PCRE_FCH_CASELESS) != 0, (re->options & PCRE_FIRSTLINE) != 0);
# Line 7839  compile_matchingpath(common, rootbacktra Line 8002  compile_matchingpath(common, rootbacktra
8002  if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))  if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
8003    {    {
8004    sljit_free_compiler(compiler);    sljit_free_compiler(compiler);
8005      SLJIT_FREE(common->optimized_cbracket);
8006    SLJIT_FREE(common->private_data_ptrs);    SLJIT_FREE(common->private_data_ptrs);
8007    return;    return;
8008    }    }
# Line 7869  compile_backtrackingpath(common, rootbac Line 8033  compile_backtrackingpath(common, rootbac
8033  if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))  if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
8034    {    {
8035    sljit_free_compiler(compiler);    sljit_free_compiler(compiler);
8036      SLJIT_FREE(common->optimized_cbracket);
8037    SLJIT_FREE(common->private_data_ptrs);    SLJIT_FREE(common->private_data_ptrs);
8038    return;    return;
8039    }    }
# Line 7947  while (common->currententry != NULL) Line 8112  while (common->currententry != NULL)
8112    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
8113      {      {
8114      sljit_free_compiler(compiler);      sljit_free_compiler(compiler);
8115        SLJIT_FREE(common->optimized_cbracket);
8116      SLJIT_FREE(common->private_data_ptrs);      SLJIT_FREE(common->private_data_ptrs);
8117      return;      return;
8118      }      }
# Line 8021  if (common->caselesscmp != NULL) Line 8187  if (common->caselesscmp != NULL)
8187    do_caselesscmp(common);    do_caselesscmp(common);
8188    }    }
8189  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
8190    #ifndef COMPILE_PCRE32
8191  if (common->utfreadchar != NULL)  if (common->utfreadchar != NULL)
8192    {    {
8193    set_jumps(common->utfreadchar, LABEL());    set_jumps(common->utfreadchar, LABEL());
8194    do_utfreadchar(common);    do_utfreadchar(common);
8195    }    }
8196    #endif /* !COMPILE_PCRE32 */
8197  #ifdef COMPILE_PCRE8  #ifdef COMPILE_PCRE8
8198  if (common->utfreadtype8 != NULL)  if (common->utfreadtype8 != NULL)
8199    {    {
8200    set_jumps(common->utfreadtype8, LABEL());    set_jumps(common->utfreadtype8, LABEL());
8201    do_utfreadtype8(common);    do_utfreadtype8(common);
8202    }    }
 #endif  
8203  #endif /* COMPILE_PCRE8 */  #endif /* COMPILE_PCRE8 */
8204    #endif /* SUPPORT_UTF */
8205  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
8206  if (common->getucd != NULL)  if (common->getucd != NULL)
8207    {    {
# Line 8042  if (common->getucd != NULL) Line 8210  if (common->getucd != NULL)
8210    }    }
8211  #endif  #endif
8212    
8213    SLJIT_FREE(common->optimized_cbracket);
8214  SLJIT_FREE(common->private_data_ptrs);  SLJIT_FREE(common->private_data_ptrs);
8215  executable_func = sljit_generate_code(compiler);  executable_func = sljit_generate_code(compiler);
8216  executable_size = sljit_get_generated_code_size(compiler);  executable_size = sljit_get_generated_code_size(compiler);
# Line 8198  PRIV(jit_get_target)(void) Line 8367  PRIV(jit_get_target)(void)
8367  return sljit_get_platform_name();  return sljit_get_platform_name();
8368  }  }
8369    
8370  #ifdef COMPILE_PCRE8  #if defined COMPILE_PCRE8
8371  PCRE_EXP_DECL pcre_jit_stack *  PCRE_EXP_DECL pcre_jit_stack *
8372  pcre_jit_stack_alloc(int startsize, int maxsize)  pcre_jit_stack_alloc(int startsize, int maxsize)
8373  #else  #elif defined COMPILE_PCRE16
8374  PCRE_EXP_DECL pcre16_jit_stack *  PCRE_EXP_DECL pcre16_jit_stack *
8375  pcre16_jit_stack_alloc(int startsize, int maxsize)  pcre16_jit_stack_alloc(int startsize, int maxsize)
8376    #elif defined COMPILE_PCRE32
8377    PCRE_EXP_DECL pcre32_jit_stack *
8378    pcre32_jit_stack_alloc(int startsize, int maxsize)
8379  #endif  #endif
8380  {  {
8381  if (startsize < 1 || maxsize < 1)  if (startsize < 1 || maxsize < 1)
# Line 8215  maxsize = (maxsize + STACK_GROWTH_RATE - Line 8387  maxsize = (maxsize + STACK_GROWTH_RATE -
8387  return (PUBL(jit_stack)*)sljit_allocate_stack(startsize, maxsize);  return (PUBL(jit_stack)*)sljit_allocate_stack(startsize, maxsize);
8388  }  }
8389    
8390  #ifdef COMPILE_PCRE8  #if defined COMPILE_PCRE8
8391  PCRE_EXP_DECL void  PCRE_EXP_DECL void
8392  pcre_jit_stack_free(pcre_jit_stack *stack)  pcre_jit_stack_free(pcre_jit_stack *stack)
8393  #else  #elif defined COMPILE_PCRE16
8394  PCRE_EXP_DECL void  PCRE_EXP_DECL void
8395  pcre16_jit_stack_free(pcre16_jit_stack *stack)  pcre16_jit_stack_free(pcre16_jit_stack *stack)
8396    #elif defined COMPILE_PCRE32
8397    PCRE_EXP_DECL void
8398    pcre32_jit_stack_free(pcre32_jit_stack *stack)
8399  #endif  #endif
8400  {  {
8401  sljit_free_stack((struct sljit_stack *)stack);  sljit_free_stack((struct sljit_stack *)stack);
8402  }  }
8403    
8404  #ifdef COMPILE_PCRE8  #if defined COMPILE_PCRE8
8405  PCRE_EXP_DECL void  PCRE_EXP_DECL void
8406  pcre_assign_jit_stack(pcre_extra *extra, pcre_jit_callback callback, void *userdata)  pcre_assign_jit_stack(pcre_extra *extra, pcre_jit_callback callback, void *userdata)
8407  #else  #elif defined COMPILE_PCRE16
8408  PCRE_EXP_DECL void  PCRE_EXP_DECL void
8409  pcre16_assign_jit_stack(pcre16_extra *extra, pcre16_jit_callback callback, void *userdata)  pcre16_assign_jit_stack(pcre16_extra *extra, pcre16_jit_callback callback, void *userdata)
8410    #elif defined COMPILE_PCRE32
8411    PCRE_EXP_DECL void
8412    pcre32_assign_jit_stack(pcre32_extra *extra, pcre32_jit_callback callback, void *userdata)
8413  #endif  #endif
8414  {  {
8415  executable_functions *functions;  executable_functions *functions;
# Line 8250  if (extra != NULL && Line 8428  if (extra != NULL &&
8428  /* These are dummy functions to avoid linking errors when JIT support is not  /* These are dummy functions to avoid linking errors when JIT support is not
8429  being compiled. */  being compiled. */
8430    
8431  #ifdef COMPILE_PCRE8  #if defined COMPILE_PCRE8
8432  PCRE_EXP_DECL pcre_jit_stack *  PCRE_EXP_DECL pcre_jit_stack *
8433  pcre_jit_stack_alloc(int startsize, int maxsize)  pcre_jit_stack_alloc(int startsize, int maxsize)
8434  #else  #elif defined COMPILE_PCRE16
8435  PCRE_EXP_DECL pcre16_jit_stack *  PCRE_EXP_DECL pcre16_jit_stack *
8436  pcre16_jit_stack_alloc(int startsize, int maxsize)  pcre16_jit_stack_alloc(int startsize, int maxsize)
8437    #elif defined COMPILE_PCRE32
8438    PCRE_EXP_DECL pcre32_jit_stack *
8439    pcre32_jit_stack_alloc(int startsize, int maxsize)
8440  #endif  #endif
8441  {  {
8442  (void)startsize;  (void)startsize;
# Line 8263  pcre16_jit_stack_alloc(int startsize, in Line 8444  pcre16_jit_stack_alloc(int startsize, in
8444  return NULL;  return NULL;
8445  }  }
8446    
8447  #ifdef COMPILE_PCRE8  #if defined COMPILE_PCRE8
8448  PCRE_EXP_DECL void  PCRE_EXP_DECL void
8449  pcre_jit_stack_free(pcre_jit_stack *stack)  pcre_jit_stack_free(pcre_jit_stack *stack)
8450  #else  #elif defined COMPILE_PCRE16
8451  PCRE_EXP_DECL void  PCRE_EXP_DECL void
8452  pcre16_jit_stack_free(pcre16_jit_stack *stack)  pcre16_jit_stack_free(pcre16_jit_stack *stack)
8453    #elif defined COMPILE_PCRE32
8454    PCRE_EXP_DECL void
8455    pcre32_jit_stack_free(pcre32_jit_stack *stack)
8456  #endif  #endif
8457  {  {
8458  (void)stack;  (void)stack;
8459  }  }
8460    
8461  #ifdef COMPILE_PCRE8  #if defined COMPILE_PCRE8
8462  PCRE_EXP_DECL void  PCRE_EXP_DECL void
8463  pcre_assign_jit_stack(pcre_extra *extra, pcre_jit_callback callback, void *userdata)  pcre_assign_jit_stack(pcre_extra *extra, pcre_jit_callback callback, void *userdata)
8464  #else  #elif defined COMPILE_PCRE16
8465  PCRE_EXP_DECL void  PCRE_EXP_DECL void
8466  pcre16_assign_jit_stack(pcre16_extra *extra, pcre16_jit_callback callback, void *userdata)  pcre16_assign_jit_stack(pcre16_extra *extra, pcre16_jit_callback callback, void *userdata)
8467    #elif defined COMPILE_PCRE32
8468    PCRE_EXP_DECL void
8469    pcre32_assign_jit_stack(pcre32_extra *extra, pcre32_jit_callback callback, void *userdata)
8470  #endif  #endif
8471  {  {
8472  (void)extra;  (void)extra;

Legend:
Removed from v.1002  
changed lines
  Added in v.1084

  ViewVC Help
Powered by ViewVC 1.1.5