/[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 977 by zherczeg, Sun Jun 17 06:20:52 2012 UTC revision 991 by zherczeg, Sun Jul 8 16:44:39 2012 UTC
# Line 181  typedef struct stub_list { Line 181  typedef struct stub_list {
181    enum stub_types type;    enum stub_types type;
182    int data;    int data;
183    struct sljit_jump *start;    struct sljit_jump *start;
184    struct sljit_label *leave;    struct sljit_label *quit;
185    struct stub_list *next;    struct stub_list *next;
186  } stub_list;  } stub_list;
187    
# Line 268  typedef struct recurse_backtrack { Line 268  typedef struct recurse_backtrack {
268    backtrack_common common;    backtrack_common common;
269  } recurse_backtrack;  } recurse_backtrack;
270    
271    #define MAX_RANGE_SIZE 6
272    
273  typedef struct compiler_common {  typedef struct compiler_common {
274    struct sljit_compiler *compiler;    struct sljit_compiler *compiler;
275    pcre_uchar *start;    pcre_uchar *start;
# Line 290  typedef struct compiler_common { Line 292  typedef struct compiler_common {
292    /* Points to the marked string. */    /* Points to the marked string. */
293    int mark_ptr;    int mark_ptr;
294    
295    /* Other  */    /* Flipped and lower case tables. */
296    const pcre_uint8 *fcc;    const pcre_uint8 *fcc;
297    sljit_w lcc;    sljit_w lcc;
298      /* Mode can be PCRE_STUDY_JIT_COMPILE and others. */
299    int mode;    int mode;
300      /* Newline control. */
301    int nltype;    int nltype;
302    int newline;    int newline;
303    int bsr_nltype;    int bsr_nltype;
304      /* Dollar endonly. */
305    int endonly;    int endonly;
306    BOOL has_set_som;    BOOL has_set_som;
307      /* Tables. */
308    sljit_w ctypes;    sljit_w ctypes;
309      int digits[2 + MAX_RANGE_SIZE];
310      /* Named capturing brackets. */
311    sljit_uw name_table;    sljit_uw name_table;
312    sljit_w name_count;    sljit_w name_count;
313    sljit_w name_entry_size;    sljit_w name_entry_size;
314    
315    /* Labels and jump lists. */    /* Labels and jump lists. */
316    struct sljit_label *partialmatchlabel;    struct sljit_label *partialmatchlabel;
317    struct sljit_label *leavelabel;    struct sljit_label *quitlabel;
318    struct sljit_label *acceptlabel;    struct sljit_label *acceptlabel;
319    stub_list *stubs;    stub_list *stubs;
320    recurse_entry *entries;    recurse_entry *entries;
321    recurse_entry *currententry;    recurse_entry *currententry;
322    jump_list *partialmatch;    jump_list *partialmatch;
323    jump_list *leave;    jump_list *quit;
324    jump_list *accept;    jump_list *accept;
325    jump_list *calllimit;    jump_list *calllimit;
326    jump_list *stackalloc;    jump_list *stackalloc;
# Line 667  switch(*cc) Line 675  switch(*cc)
675    }    }
676  }  }
677    
678    #define CASE_ITERATOR_LOCAL1 \
679        case OP_MINSTAR: \
680        case OP_MINPLUS: \
681        case OP_QUERY: \
682        case OP_MINQUERY: \
683        case OP_MINSTARI: \
684        case OP_MINPLUSI: \
685        case OP_QUERYI: \
686        case OP_MINQUERYI: \
687        case OP_NOTMINSTAR: \
688        case OP_NOTMINPLUS: \
689        case OP_NOTQUERY: \
690        case OP_NOTMINQUERY: \
691        case OP_NOTMINSTARI: \
692        case OP_NOTMINPLUSI: \
693        case OP_NOTQUERYI: \
694        case OP_NOTMINQUERYI:
695    
696    #define CASE_ITERATOR_LOCAL2A \
697        case OP_STAR: \
698        case OP_PLUS: \
699        case OP_STARI: \
700        case OP_PLUSI: \
701        case OP_NOTSTAR: \
702        case OP_NOTPLUS: \
703        case OP_NOTSTARI: \
704        case OP_NOTPLUSI:
705    
706    #define CASE_ITERATOR_LOCAL2B \
707        case OP_UPTO: \
708        case OP_MINUPTO: \
709        case OP_UPTOI: \
710        case OP_MINUPTOI: \
711        case OP_NOTUPTO: \
712        case OP_NOTMINUPTO: \
713        case OP_NOTUPTOI: \
714        case OP_NOTMINUPTOI:
715    
716    #define CASE_ITERATOR_TYPE_LOCAL1 \
717        case OP_TYPEMINSTAR: \
718        case OP_TYPEMINPLUS: \
719        case OP_TYPEQUERY: \
720        case OP_TYPEMINQUERY:
721    
722    #define CASE_ITERATOR_TYPE_LOCAL2A \
723        case OP_TYPESTAR: \
724        case OP_TYPEPLUS:
725    
726    #define CASE_ITERATOR_TYPE_LOCAL2B \
727        case OP_TYPEUPTO: \
728        case OP_TYPEMINUPTO:
729    
730    static int get_class_iterator_size(pcre_uchar *cc)
731    {
732    switch(*cc)
733      {
734      case OP_CRSTAR:
735      case OP_CRPLUS:
736      return 2;
737    
738      case OP_CRMINSTAR:
739      case OP_CRMINPLUS:
740      case OP_CRQUERY:
741      case OP_CRMINQUERY:
742      return 1;
743    
744      case OP_CRRANGE:
745      case OP_CRMINRANGE:
746      if (GET2(cc, 1) == GET2(cc, 1 + IMM2_SIZE))
747        return 0;
748      return 2;
749    
750      default:
751      return 0;
752      }
753    }
754    
755  static int get_localspace(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend)  static int get_localspace(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend)
756  {  {
757  int localspace = 0;  int localspace = 0;
758  pcre_uchar *alternative;  pcre_uchar *alternative;
759    pcre_uchar *end = NULL;
760    int space, size, bracketlen;
761    
762  /* 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. */
763  while (cc < ccend)  while (cc < ccend)
764    {    {
765      space = 0;
766      size = 0;
767      bracketlen = 0;
768    switch(*cc)    switch(*cc)
769      {      {
770      case OP_SET_SOM:      case OP_SET_SOM:
# Line 692  while (cc < ccend) Line 783  while (cc < ccend)
783      case OP_SBRAPOS:      case OP_SBRAPOS:
784      case OP_SCOND:      case OP_SCOND:
785      localspace += sizeof(sljit_w);      localspace += sizeof(sljit_w);
786      cc += 1 + LINK_SIZE;      bracketlen = 1 + LINK_SIZE;
787      break;      break;
788    
789      case OP_CBRAPOS:      case OP_CBRAPOS:
790      case OP_SCBRAPOS:      case OP_SCBRAPOS:
791      localspace += sizeof(sljit_w);      localspace += sizeof(sljit_w);
792      cc += 1 + LINK_SIZE + IMM2_SIZE;      bracketlen = 1 + LINK_SIZE + IMM2_SIZE;
793      break;      break;
794    
795      case OP_COND:      case OP_COND:
# Line 706  while (cc < ccend) Line 797  while (cc < ccend)
797      alternative = cc + GET(cc, 1);      alternative = cc + GET(cc, 1);
798      if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)      if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)
799        localspace += sizeof(sljit_w);        localspace += sizeof(sljit_w);
800      cc += 1 + LINK_SIZE;      bracketlen = 1 + LINK_SIZE;
801        break;
802    
803        case OP_BRA:
804        bracketlen = 1 + LINK_SIZE;
805        break;
806    
807        case OP_CBRA:
808        case OP_SCBRA:
809        bracketlen = 1 + LINK_SIZE + IMM2_SIZE;
810        break;
811    
812        CASE_ITERATOR_LOCAL1
813        space = 1;
814        size = -2;
815      break;      break;
816    
817        CASE_ITERATOR_LOCAL2A
818        space = 2;
819        size = -2;
820        break;
821    
822        CASE_ITERATOR_LOCAL2B
823        space = 2;
824        size = -(2 + IMM2_SIZE);
825        break;
826    
827        CASE_ITERATOR_TYPE_LOCAL1
828        space = 1;
829        size = 1;
830        break;
831    
832        CASE_ITERATOR_TYPE_LOCAL2A
833        if (cc[1] != OP_ANYNL && cc[1] != OP_EXTUNI)
834          space = 2;
835        size = 1;
836        break;
837    
838        CASE_ITERATOR_TYPE_LOCAL2B
839        if (cc[1 + IMM2_SIZE] != OP_ANYNL && cc[1 + IMM2_SIZE] != OP_EXTUNI)
840          space = 2;
841        size = 1 + IMM2_SIZE;
842        break;
843    
844        case OP_CLASS:
845        case OP_NCLASS:
846        size += 1 + 32 / sizeof(pcre_uchar);
847        space = get_class_iterator_size(cc + size);
848        break;
849    
850    #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
851        case OP_XCLASS:
852        size = GET(cc, 1);
853        space = get_class_iterator_size(cc + size);
854        break;
855    #endif
856    
857      case OP_RECURSE:      case OP_RECURSE:
858      /* Set its value only once. */      /* Set its value only once. */
859      if (common->recursive_head == 0)      if (common->recursive_head == 0)
# Line 734  while (cc < ccend) Line 879  while (cc < ccend)
879        return -1;        return -1;
880      break;      break;
881      }      }
882    
883      if (space > 0 && cc >= end)
884        localspace += sizeof(sljit_w) * space;
885    
886      if (size != 0)
887        {
888        if (size < 0)
889          {
890          cc += -size;
891    #ifdef SUPPORT_UTF
892          if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
893    #endif
894          }
895        else
896          cc += size;
897        }
898    
899      if (bracketlen > 0)
900        {
901        if (cc >= end)
902          {
903          end = bracketend(cc);
904          if (end[-1 - LINK_SIZE] == OP_KET)
905            end = NULL;
906          }
907        cc += bracketlen;
908        }
909    }    }
910  return localspace;  return localspace;
911  }  }
# Line 742  static void set_localptrs(compiler_commo Line 914  static void set_localptrs(compiler_commo
914  {  {
915  pcre_uchar *cc = common->start;  pcre_uchar *cc = common->start;
916  pcre_uchar *alternative;  pcre_uchar *alternative;
917    pcre_uchar *end = NULL;
918    int space, size, bracketlen;
919    
920  while (cc < ccend)  while (cc < ccend)
921    {    {
922      space = 0;
923      size = 0;
924      bracketlen = 0;
925    switch(*cc)    switch(*cc)
926      {      {
927      case OP_ASSERT:      case OP_ASSERT:
# Line 758  while (cc < ccend) Line 936  while (cc < ccend)
936      case OP_SCOND:      case OP_SCOND:
937      common->localptrs[cc - common->start] = localptr;      common->localptrs[cc - common->start] = localptr;
938      localptr += sizeof(sljit_w);      localptr += sizeof(sljit_w);
939      cc += 1 + LINK_SIZE;      bracketlen = 1 + LINK_SIZE;
940      break;      break;
941    
942      case OP_CBRAPOS:      case OP_CBRAPOS:
943      case OP_SCBRAPOS:      case OP_SCBRAPOS:
944      common->localptrs[cc - common->start] = localptr;      common->localptrs[cc - common->start] = localptr;
945      localptr += sizeof(sljit_w);      localptr += sizeof(sljit_w);
946      cc += 1 + LINK_SIZE + IMM2_SIZE;      bracketlen = 1 + LINK_SIZE + IMM2_SIZE;
947      break;      break;
948    
949      case OP_COND:      case OP_COND:
# Line 776  while (cc < ccend) Line 954  while (cc < ccend)
954        common->localptrs[cc - common->start] = localptr;        common->localptrs[cc - common->start] = localptr;
955        localptr += sizeof(sljit_w);        localptr += sizeof(sljit_w);
956        }        }
957      cc += 1 + LINK_SIZE;      bracketlen = 1 + LINK_SIZE;
958      break;      break;
959    
960        case OP_BRA:
961        bracketlen = 1 + LINK_SIZE;
962        break;
963    
964        case OP_CBRA:
965        case OP_SCBRA:
966        bracketlen = 1 + LINK_SIZE + IMM2_SIZE;
967        break;
968    
969        CASE_ITERATOR_LOCAL1
970        space = 1;
971        size = -2;
972        break;
973    
974        CASE_ITERATOR_LOCAL2A
975        space = 2;
976        size = -2;
977        break;
978    
979        CASE_ITERATOR_LOCAL2B
980        space = 2;
981        size = -(2 + IMM2_SIZE);
982        break;
983    
984        CASE_ITERATOR_TYPE_LOCAL1
985        space = 1;
986        size = 1;
987        break;
988    
989        CASE_ITERATOR_TYPE_LOCAL2A
990        if (cc[1] != OP_ANYNL && cc[1] != OP_EXTUNI)
991          space = 2;
992        size = 1;
993        break;
994    
995        CASE_ITERATOR_TYPE_LOCAL2B
996        if (cc[1 + IMM2_SIZE] != OP_ANYNL && cc[1 + IMM2_SIZE] != OP_EXTUNI)
997          space = 2;
998        size = 1 + IMM2_SIZE;
999        break;
1000    
1001        case OP_CLASS:
1002        case OP_NCLASS:
1003        size += 1 + 32 / sizeof(pcre_uchar);
1004        space = get_class_iterator_size(cc + size);
1005        break;
1006    
1007    #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
1008        case OP_XCLASS:
1009        size = GET(cc, 1);
1010        space = get_class_iterator_size(cc + size);
1011        break;
1012    #endif
1013    
1014      default:      default:
1015      cc = next_opcode(common, cc);      cc = next_opcode(common, cc);
1016      SLJIT_ASSERT(cc != NULL);      SLJIT_ASSERT(cc != NULL);
1017      break;      break;
1018      }      }
1019    
1020      if (space > 0 && cc >= end)
1021        {
1022        common->localptrs[cc - common->start] = localptr;
1023        localptr += sizeof(sljit_w) * space;
1024        }
1025    
1026      if (size != 0)
1027        {
1028        if (size < 0)
1029          {
1030          cc += -size;
1031    #ifdef SUPPORT_UTF
1032          if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
1033    #endif
1034          }
1035        else
1036          cc += size;
1037        }
1038    
1039      if (bracketlen > 0)
1040        {
1041        if (cc >= end)
1042          {
1043          end = bracketend(cc);
1044          if (end[-1 - LINK_SIZE] == OP_KET)
1045            end = NULL;
1046          }
1047        cc += bracketlen;
1048        }
1049    }    }
1050  }  }
1051    
# Line 963  SLJIT_ASSERT(stackpos == STACK(stacktop) Line 1225  SLJIT_ASSERT(stackpos == STACK(stacktop)
1225  static SLJIT_INLINE int get_localsize(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend)  static SLJIT_INLINE int get_localsize(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend)
1226  {  {
1227  int localsize = 2;  int localsize = 2;
1228    int size;
1229  pcre_uchar *alternative;  pcre_uchar *alternative;
1230  /* Calculate the sum of the local variables. */  /* Calculate the sum of the local variables. */
1231  while (cc < ccend)  while (cc < ccend)
1232    {    {
1233      size = 0;
1234    switch(*cc)    switch(*cc)
1235      {      {
1236      case OP_ASSERT:      case OP_ASSERT:
# Line 1003  while (cc < ccend) Line 1267  while (cc < ccend)
1267      cc += 1 + LINK_SIZE;      cc += 1 + LINK_SIZE;
1268      break;      break;
1269    
1270        CASE_ITERATOR_LOCAL1
1271        if (PRIV_DATA(cc))
1272          localsize++;
1273        cc += 2;
1274    #ifdef SUPPORT_UTF
1275        if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
1276    #endif
1277        break;
1278    
1279        CASE_ITERATOR_LOCAL2A
1280        if (PRIV_DATA(cc))
1281          localsize += 2;
1282        cc += 2;
1283    #ifdef SUPPORT_UTF
1284        if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
1285    #endif
1286        break;
1287    
1288        CASE_ITERATOR_LOCAL2B
1289        if (PRIV_DATA(cc))
1290          localsize += 2;
1291        cc += 2 + IMM2_SIZE;
1292    #ifdef SUPPORT_UTF
1293        if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
1294    #endif
1295        break;
1296    
1297        CASE_ITERATOR_TYPE_LOCAL1
1298        if (PRIV_DATA(cc))
1299          localsize++;
1300        cc += 1;
1301        break;
1302    
1303        CASE_ITERATOR_TYPE_LOCAL2A
1304        if (PRIV_DATA(cc))
1305          localsize += 2;
1306        cc += 1;
1307        break;
1308    
1309        CASE_ITERATOR_TYPE_LOCAL2B
1310        if (PRIV_DATA(cc))
1311          localsize += 2;
1312        cc += 1 + IMM2_SIZE;
1313        break;
1314    
1315        case OP_CLASS:
1316        case OP_NCLASS:
1317    #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
1318        case OP_XCLASS:
1319        size = (*cc == OP_XCLASS) ? GET(cc, 1) : 1 + 32 / (int)sizeof(pcre_uchar);
1320    #else
1321        size = 1 + 32 / (int)sizeof(pcre_uchar);
1322    #endif
1323        if (PRIV_DATA(cc))
1324          localsize += get_class_iterator_size(cc + size);
1325        cc += size;
1326        break;
1327    
1328      default:      default:
1329      cc = next_opcode(common, cc);      cc = next_opcode(common, cc);
1330      SLJIT_ASSERT(cc != NULL);      SLJIT_ASSERT(cc != NULL);
# Line 1018  static void copy_locals(compiler_common Line 1340  static void copy_locals(compiler_common
1340  {  {
1341  DEFINE_COMPILER;  DEFINE_COMPILER;
1342  int srcw[2];  int srcw[2];
1343  int count;  int count, size;
1344  BOOL tmp1next = TRUE;  BOOL tmp1next = TRUE;
1345  BOOL tmp1empty = TRUE;  BOOL tmp1empty = TRUE;
1346  BOOL tmp2empty = TRUE;  BOOL tmp2empty = TRUE;
# Line 1098  while (status != end) Line 1420  while (status != end)
1420        case OP_CBRAPOS:        case OP_CBRAPOS:
1421        case OP_SCBRAPOS:        case OP_SCBRAPOS:
1422        count = 2;        count = 2;
1423        srcw[1] = OVECTOR_PRIV(GET2(cc, 1 + LINK_SIZE));        srcw[0] = OVECTOR_PRIV(GET2(cc, 1 + LINK_SIZE));
1424        srcw[0] = PRIV_DATA(cc);        srcw[1] = PRIV_DATA(cc);
1425        SLJIT_ASSERT(srcw[0] != 0);        SLJIT_ASSERT(srcw[0] != 0);
1426        cc += 1 + LINK_SIZE + IMM2_SIZE;        cc += 1 + LINK_SIZE + IMM2_SIZE;
1427        break;        break;
# Line 1116  while (status != end) Line 1438  while (status != end)
1438        cc += 1 + LINK_SIZE;        cc += 1 + LINK_SIZE;
1439        break;        break;
1440    
1441          CASE_ITERATOR_LOCAL1
1442          if (PRIV_DATA(cc))
1443            {
1444            count = 1;
1445            srcw[0] = PRIV_DATA(cc);
1446            }
1447          cc += 2;
1448    #ifdef SUPPORT_UTF
1449          if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
1450    #endif
1451          break;
1452    
1453          CASE_ITERATOR_LOCAL2A
1454          if (PRIV_DATA(cc))
1455            {
1456            count = 2;
1457            srcw[0] = PRIV_DATA(cc);
1458            srcw[1] = PRIV_DATA(cc) + sizeof(sljit_w);
1459            }
1460          cc += 2;
1461    #ifdef SUPPORT_UTF
1462          if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
1463    #endif
1464          break;
1465    
1466          CASE_ITERATOR_LOCAL2B
1467          if (PRIV_DATA(cc))
1468            {
1469            count = 2;
1470            srcw[0] = PRIV_DATA(cc);
1471            srcw[1] = PRIV_DATA(cc) + sizeof(sljit_w);
1472            }
1473          cc += 2 + IMM2_SIZE;
1474    #ifdef SUPPORT_UTF
1475          if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
1476    #endif
1477          break;
1478    
1479          CASE_ITERATOR_TYPE_LOCAL1
1480          if (PRIV_DATA(cc))
1481            {
1482            count = 1;
1483            srcw[0] = PRIV_DATA(cc);
1484            }
1485          cc += 1;
1486          break;
1487    
1488          CASE_ITERATOR_TYPE_LOCAL2A
1489          if (PRIV_DATA(cc))
1490            {
1491            count = 2;
1492            srcw[0] = PRIV_DATA(cc);
1493            srcw[1] = srcw[0] + sizeof(sljit_w);
1494            }
1495          cc += 1;
1496          break;
1497    
1498          CASE_ITERATOR_TYPE_LOCAL2B
1499          if (PRIV_DATA(cc))
1500            {
1501            count = 2;
1502            srcw[0] = PRIV_DATA(cc);
1503            srcw[1] = srcw[0] + sizeof(sljit_w);
1504            }
1505          cc += 1 + IMM2_SIZE;
1506          break;
1507    
1508          case OP_CLASS:
1509          case OP_NCLASS:
1510    #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
1511          case OP_XCLASS:
1512          size = (*cc == OP_XCLASS) ? GET(cc, 1) : 1 + 32 / (int)sizeof(pcre_uchar);
1513    #else
1514          size = 1 + 32 / (int)sizeof(pcre_uchar);
1515    #endif
1516          if (PRIV_DATA(cc))
1517            switch(get_class_iterator_size(cc + size))
1518              {
1519              case 1:
1520              count = 1;
1521              srcw[0] = PRIV_DATA(cc);
1522              break;
1523    
1524              case 2:
1525              count = 2;
1526              srcw[0] = PRIV_DATA(cc);
1527              srcw[1] = srcw[0] + sizeof(sljit_w);
1528              break;
1529    
1530              default:
1531              SLJIT_ASSERT_STOP();
1532              break;
1533              }
1534          cc += size;
1535          break;
1536    
1537        default:        default:
1538        cc = next_opcode(common, cc);        cc = next_opcode(common, cc);
1539        SLJIT_ASSERT(cc != NULL);        SLJIT_ASSERT(cc != NULL);
# Line 1218  if (save) Line 1636  if (save)
1636  SLJIT_ASSERT(cc == ccend && stackptr == stacktop && (save || (tmp1empty && tmp2empty)));  SLJIT_ASSERT(cc == ccend && stackptr == stacktop && (save || (tmp1empty && tmp2empty)));
1637  }  }
1638    
1639    #undef CASE_ITERATOR_LOCAL1
1640    #undef CASE_ITERATOR_LOCAL2A
1641    #undef CASE_ITERATOR_LOCAL2B
1642    #undef CASE_ITERATOR_TYPE_LOCAL1
1643    #undef CASE_ITERATOR_TYPE_LOCAL2A
1644    #undef CASE_ITERATOR_TYPE_LOCAL2B
1645    
1646  static SLJIT_INLINE BOOL ispowerof2(unsigned int value)  static SLJIT_INLINE BOOL ispowerof2(unsigned int value)
1647  {  {
1648  return (value & (value - 1)) == 0;  return (value & (value - 1)) == 0;
# Line 1255  if (list_item) Line 1680  if (list_item)
1680    list_item->type = type;    list_item->type = type;
1681    list_item->data = data;    list_item->data = data;
1682    list_item->start = start;    list_item->start = start;
1683    list_item->leave = LABEL();    list_item->quit = LABEL();
1684    list_item->next = common->stubs;    list_item->next = common->stubs;
1685    common->stubs = list_item;    common->stubs = list_item;
1686    }    }
# Line 1275  while (list_item) Line 1700  while (list_item)
1700      add_jump(compiler, &common->stackalloc, JUMP(SLJIT_FAST_CALL));      add_jump(compiler, &common->stackalloc, JUMP(SLJIT_FAST_CALL));
1701      break;      break;
1702      }      }
1703    JUMPTO(SLJIT_JUMP, list_item->leave);    JUMPTO(SLJIT_JUMP, list_item->quit);
1704    list_item = list_item->next;    list_item = list_item->next;
1705    }    }
1706  common->stubs = NULL;  common->stubs = NULL;
# Line 1385  else Line 1810  else
1810    OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, 1);    OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, 1);
1811  }  }
1812    
1813  static SLJIT_INLINE void return_with_partial_match(compiler_common *common, struct sljit_label *leave)  static SLJIT_INLINE void return_with_partial_match(compiler_common *common, struct sljit_label *quit)
1814  {  {
1815  DEFINE_COMPILER;  DEFINE_COMPILER;
1816    
# Line 1395  SLJIT_ASSERT(common->start_used_ptr != 0 Line 1820  SLJIT_ASSERT(common->start_used_ptr != 0
1820  OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, ARGUMENTS, 0);  OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, ARGUMENTS, 0);
1821  OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_PARTIAL);  OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_PARTIAL);
1822  OP1(SLJIT_MOV_SI, SLJIT_TEMPORARY_REG3, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), SLJIT_OFFSETOF(jit_arguments, offsetcount));  OP1(SLJIT_MOV_SI, SLJIT_TEMPORARY_REG3, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), SLJIT_OFFSETOF(jit_arguments, offsetcount));
1823  CMPTO(SLJIT_C_LESS, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, 2, leave);  CMPTO(SLJIT_C_LESS, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, 2, quit);
1824    
1825  /* Store match begin and end. */  /* Store match begin and end. */
1826  OP1(SLJIT_MOV, SLJIT_SAVED_REG1, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), SLJIT_OFFSETOF(jit_arguments, begin));  OP1(SLJIT_MOV, SLJIT_SAVED_REG1, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), SLJIT_OFFSETOF(jit_arguments, begin));
# Line 1413  OP2(SLJIT_ASHR, SLJIT_TEMPORARY_REG3, 0, Line 1838  OP2(SLJIT_ASHR, SLJIT_TEMPORARY_REG3, 0,
1838  #endif  #endif
1839  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);
1840    
1841  JUMPTO(SLJIT_JUMP, leave);  JUMPTO(SLJIT_JUMP, quit);
1842  }  }
1843    
1844  static SLJIT_INLINE void check_start_used_ptr(compiler_common *common)  static SLJIT_INLINE void check_start_used_ptr(compiler_common *common)
# Line 2027  if (firstline) Line 2452  if (firstline)
2452    
2453  start = JUMP(SLJIT_JUMP);  start = JUMP(SLJIT_JUMP);
2454    
2455  if (newlinecheck)  if (newlinecheck)
2456      {
2457      newlinelabel = LABEL();
2458      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2459      end = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
2460      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
2461      OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, common->newline & 0xff);
2462      COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);
2463    #ifdef COMPILE_PCRE16
2464      OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
2465    #endif
2466      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2467      nl = JUMP(SLJIT_JUMP);
2468      }
2469    
2470    mainloop = LABEL();
2471    
2472    /* Increasing the STR_PTR here requires one less jump in the most common case. */
2473    #ifdef SUPPORT_UTF
2474    if (common->utf) readuchar = TRUE;
2475    #endif
2476    if (newlinecheck) readuchar = TRUE;
2477    
2478    if (readuchar)
2479      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
2480    
2481    if (newlinecheck)
2482      CMPTO(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff, newlinelabel);
2483    
2484    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2485    #if defined SUPPORT_UTF && defined COMPILE_PCRE8
2486    if (common->utf)
2487      {
2488      singlechar = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);
2489      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)PRIV(utf8_table4) - 0xc0);
2490      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2491      JUMPHERE(singlechar);
2492      }
2493    #endif
2494    #if defined SUPPORT_UTF && defined COMPILE_PCRE16
2495    if (common->utf)
2496      {
2497      singlechar = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800);
2498      OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);
2499      OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xd800);
2500      COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);
2501      OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
2502      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2503      JUMPHERE(singlechar);
2504      }
2505    #endif
2506    JUMPHERE(start);
2507    
2508    if (newlinecheck)
2509      {
2510      JUMPHERE(end);
2511      JUMPHERE(nl);
2512      }
2513    
2514    return mainloop;
2515    }
2516    
2517    static SLJIT_INLINE BOOL fast_forward_first_two_chars(compiler_common *common, BOOL firstline)
2518    {
2519    DEFINE_COMPILER;
2520    struct sljit_label *start;
2521    struct sljit_jump *quit;
2522    struct sljit_jump *found;
2523    pcre_int32 chars[4];
2524    pcre_uchar *cc = common->start + 1 + IMM2_SIZE;
2525    int location = 0;
2526    pcre_int32 len, c, bit, caseless;
2527    BOOL must_end;
2528    
2529    #ifdef COMPILE_PCRE8
2530    union {
2531        sljit_uh ascombined;
2532        sljit_ub asuchars[2];
2533    } pair;
2534    #else
2535    union {
2536        sljit_ui ascombined;
2537        sljit_uh asuchars[2];
2538    } pair;
2539    #endif
2540    
2541    if (*(common->start + GET(common->start, 1)) == OP_ALT)
2542      return FALSE;
2543    
2544    while (TRUE)
2545      {
2546      caseless = 0;
2547      must_end = TRUE;
2548      switch(*cc)
2549        {
2550        case OP_CHAR:
2551        must_end = FALSE;
2552        cc++;
2553        break;
2554    
2555        case OP_CHARI:
2556        caseless = 1;
2557        must_end = FALSE;
2558        cc++;
2559        break;
2560    
2561        case OP_SOD:
2562        case OP_SOM:
2563        case OP_SET_SOM:
2564        case OP_NOT_WORD_BOUNDARY:
2565        case OP_WORD_BOUNDARY:
2566        case OP_EODN:
2567        case OP_EOD:
2568        case OP_CIRC:
2569        case OP_CIRCM:
2570        case OP_DOLL:
2571        case OP_DOLLM:
2572        /* Zero width assertions. */
2573        cc++;
2574        continue;
2575    
2576        case OP_PLUS:
2577        case OP_MINPLUS:
2578        case OP_POSPLUS:
2579        cc++;
2580        break;
2581    
2582        case OP_EXACT:
2583        cc += 1 + IMM2_SIZE;
2584        break;
2585    
2586        case OP_PLUSI:
2587        case OP_MINPLUSI:
2588        case OP_POSPLUSI:
2589        caseless = 1;
2590        cc++;
2591        break;
2592    
2593        case OP_EXACTI:
2594        caseless = 1;
2595        cc += 1 + IMM2_SIZE;
2596        break;
2597    
2598        default:
2599        return FALSE;
2600        }
2601    
2602      len = 1;
2603    #ifdef SUPPORT_UTF
2604      if (common->utf && HAS_EXTRALEN(cc[0])) len += GET_EXTRALEN(cc[0]);
2605    #endif
2606    
2607      if (caseless && char_has_othercase(common, cc))
2608        {
2609        caseless = char_get_othercase_bit(common, cc);
2610        if (caseless == 0)
2611          return FALSE;
2612    #ifdef COMPILE_PCRE8
2613        caseless = ((caseless & 0xff) << 8) | (len - (caseless >> 8));
2614    #else
2615        if ((caseless & 0x100) != 0)
2616          caseless = ((caseless & 0xff) << 16) | (len - (caseless >> 9));
2617        else
2618          caseless = ((caseless & 0xff) << 8) | (len - (caseless >> 9));
2619    #endif
2620        }
2621      else
2622        caseless = 0;
2623    
2624      while (len > 0 && location < 2 * 2)
2625        {
2626        c = *cc;
2627        bit = 0;
2628        if (len == (caseless & 0xff))
2629          {
2630          bit = caseless >> 8;
2631          c |= bit;
2632          }
2633    
2634        chars[location] = c;
2635        chars[location + 1] = bit;
2636    
2637        len--;
2638        location += 2;
2639        cc++;
2640        }
2641    
2642      if (location == 2 * 2)
2643        break;
2644      else if (must_end)
2645        return FALSE;
2646      }
2647    
2648    if (firstline)
2649    {    {
2650    newlinelabel = LABEL();    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, STR_END, 0);
2651    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));    OP2(SLJIT_SUB, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end, SLJIT_IMM, 1);
   end = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);  
   OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);  
   OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, common->newline & 0xff);  
   COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);  
 #ifdef COMPILE_PCRE16  
   OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);  
 #endif  
   OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);  
   nl = JUMP(SLJIT_JUMP);  
2652    }    }
2653    else
2654      OP2(SLJIT_SUB, STR_END, 0, STR_END, 0, SLJIT_IMM, 1);
2655    
2656  mainloop = LABEL();  start = LABEL();
2657    quit = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
2658  /* Increasing the STR_PTR here requires one less jump in the most common case. */  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
2659  #ifdef SUPPORT_UTF  #ifdef COMPILE_PCRE8
2660  if (common->utf) readuchar = TRUE;  OP1(SLJIT_MOV_UH, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
2661    #else /* COMPILE_PCRE8 */
2662    OP1(SLJIT_MOV_UI, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
2663  #endif  #endif
 if (newlinecheck) readuchar = TRUE;  
2664    
2665  if (readuchar)  #else /* SLJIT_UNALIGNED */
   OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);  
2666    
2667  if (newlinecheck)  #if defined SLJIT_BIG_ENDIAN && SLJIT_BIG_ENDIAN
2668    CMPTO(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff, newlinelabel);  OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), 0);
2669    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
2670    #else /* SLJIT_BIG_ENDIAN */
2671    OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
2672    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
2673    #endif /* SLJIT_BIG_ENDIAN */
2674    
2675  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));  #ifdef COMPILE_PCRE8
2676  #if defined SUPPORT_UTF && defined COMPILE_PCRE8  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 8);
2677  if (common->utf)  #else /* COMPILE_PCRE8 */
2678    {  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 16);
   singlechar = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);  
   OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)PRIV(utf8_table4) - 0xc0);  
   OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);  
   JUMPHERE(singlechar);  
   }  
2679  #endif  #endif
2680  #if defined SUPPORT_UTF && defined COMPILE_PCRE16  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
2681  if (common->utf)  
   {  
   singlechar = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800);  
   OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);  
   OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xd800);  
   COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);  
   OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);  
   OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);  
   JUMPHERE(singlechar);  
   }  
2682  #endif  #endif
 JUMPHERE(start);  
2683    
2684  if (newlinecheck)  if (chars[1] != 0 || chars[3] != 0)
2685    {    {
2686    JUMPHERE(end);    pair.asuchars[0] = chars[1];
2687    JUMPHERE(nl);    pair.asuchars[1] = chars[3];
2688      OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, pair.ascombined);
2689    }    }
2690    
2691  return mainloop;  pair.asuchars[0] = chars[0];
2692    pair.asuchars[1] = chars[2];
2693    found = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, pair.ascombined);
2694    
2695    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2696    JUMPTO(SLJIT_JUMP, start);
2697    JUMPHERE(found);
2698    JUMPHERE(quit);
2699    
2700    if (firstline)
2701      OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0);
2702    OP2(SLJIT_ADD, STR_END, 0, STR_END, 0, SLJIT_IMM, 1);
2703    return TRUE;
2704  }  }
2705    
2706  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)
2707  {  {
2708  DEFINE_COMPILER;  DEFINE_COMPILER;
2709  struct sljit_label *start;  struct sljit_label *start;
2710  struct sljit_jump *leave;  struct sljit_jump *quit;
2711  struct sljit_jump *found;  struct sljit_jump *found;
2712  pcre_uchar oc, bit;  pcre_uchar oc, bit;
2713    
# Line 2104  if (firstline) Line 2718  if (firstline)
2718    }    }
2719    
2720  start = LABEL();  start = LABEL();
2721  leave = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);  quit = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
2722  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
2723    
2724  oc = first_char;  oc = first_char;
# Line 2137  else Line 2751  else
2751    }    }
2752    
2753  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));
 #if defined SUPPORT_UTF && defined COMPILE_PCRE8  
 if (common->utf)  
   {  
   CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0, start);  
   OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)PRIV(utf8_table4) - 0xc0);  
   OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);  
   }  
 #endif  
 #if defined SUPPORT_UTF && defined COMPILE_PCRE16  
 if (common->utf)  
   {  
   CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800, start);  
   OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);  
   OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xd800);  
   COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);  
   OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);  
   OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);  
   }  
 #endif  
2754  JUMPTO(SLJIT_JUMP, start);  JUMPTO(SLJIT_JUMP, start);
2755  JUMPHERE(found);  JUMPHERE(found);
2756  JUMPHERE(leave);  JUMPHERE(quit);
2757    
2758  if (firstline)  if (firstline)
2759    OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0);    OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0);
# Line 2170  DEFINE_COMPILER; Line 2765  DEFINE_COMPILER;
2765  struct sljit_label *loop;  struct sljit_label *loop;
2766  struct sljit_jump *lastchar;  struct sljit_jump *lastchar;
2767  struct sljit_jump *firstchar;  struct sljit_jump *firstchar;
2768  struct sljit_jump *leave;  struct sljit_jump *quit;
2769  struct sljit_jump *foundcr = NULL;  struct sljit_jump *foundcr = NULL;
2770  struct sljit_jump *notfoundnl;  struct sljit_jump *notfoundnl;
2771  jump_list *newline = NULL;  jump_list *newline = NULL;
# Line 2199  if (common->nltype == NLTYPE_FIXED && co Line 2794  if (common->nltype == NLTYPE_FIXED && co
2794    
2795    loop = LABEL();    loop = LABEL();
2796    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));
2797    leave = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);    quit = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
2798    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-2));    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-2));
2799    OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-1));    OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-1));
2800    CMPTO(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff, loop);    CMPTO(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff, loop);
2801    CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff, loop);    CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff, loop);
2802    
2803    JUMPHERE(leave);    JUMPHERE(quit);
2804    JUMPHERE(firstchar);    JUMPHERE(firstchar);
2805    JUMPHERE(lastchar);    JUMPHERE(lastchar);
2806    
# Line 2229  set_jumps(newline, loop); Line 2824  set_jumps(newline, loop);
2824    
2825  if (common->nltype == NLTYPE_ANY || common->nltype == NLTYPE_ANYCRLF)  if (common->nltype == NLTYPE_ANY || common->nltype == NLTYPE_ANYCRLF)
2826    {    {
2827    leave = JUMP(SLJIT_JUMP);    quit = JUMP(SLJIT_JUMP);
2828    JUMPHERE(foundcr);    JUMPHERE(foundcr);
2829    notfoundnl = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);    notfoundnl = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
2830    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
# Line 2240  if (common->nltype == NLTYPE_ANY || comm Line 2835  if (common->nltype == NLTYPE_ANY || comm
2835  #endif  #endif
2836    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2837    JUMPHERE(notfoundnl);    JUMPHERE(notfoundnl);
2838    JUMPHERE(leave);    JUMPHERE(quit);
2839    }    }
2840  JUMPHERE(lastchar);  JUMPHERE(lastchar);
2841  JUMPHERE(firstchar);  JUMPHERE(firstchar);
# Line 2253  static SLJIT_INLINE void fast_forward_st Line 2848  static SLJIT_INLINE void fast_forward_st
2848  {  {
2849  DEFINE_COMPILER;  DEFINE_COMPILER;
2850  struct sljit_label *start;  struct sljit_label *start;
2851  struct sljit_jump *leave;  struct sljit_jump *quit;
2852  struct sljit_jump *found;  struct sljit_jump *found;
2853  #ifndef COMPILE_PCRE8  #ifndef COMPILE_PCRE8
2854  struct sljit_jump *jump;  struct sljit_jump *jump;
# Line 2266  if (firstline) Line 2861  if (firstline)
2861    }    }
2862    
2863  start = LABEL();  start = LABEL();
2864  leave = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);  quit = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
2865  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
2866  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
2867  if (common->utf)  if (common->utf)
# Line 2310  if (common->utf) Line 2905  if (common->utf)
2905  #endif  #endif
2906  JUMPTO(SLJIT_JUMP, start);  JUMPTO(SLJIT_JUMP, start);
2907  JUMPHERE(found);  JUMPHERE(found);
2908  JUMPHERE(leave);  JUMPHERE(quit);
2909    
2910  if (firstline)  if (firstline)
2911    OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0);    OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0);
# Line 2537  OP2(SLJIT_XOR | SLJIT_SET_E, SLJIT_UNUSE Line 3132  OP2(SLJIT_XOR | SLJIT_SET_E, SLJIT_UNUSE
3132  sljit_emit_fast_return(compiler, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);  sljit_emit_fast_return(compiler, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);
3133  }  }
3134    
3135    /*
3136      range format:
3137    
3138      ranges[0] = length of the range (max MAX_RANGE_SIZE, -1 means invalid range).
3139      ranges[1] = first bit (0 or 1)
3140      ranges[2-length] = position of the bit change (when the current bit is not equal to the previous)
3141    */
3142    
3143    static BOOL check_ranges(compiler_common *common, int *ranges, jump_list **backtracks, BOOL readch)
3144    {
3145    DEFINE_COMPILER;
3146    struct sljit_jump *jump;
3147    
3148    if (ranges[0] < 0)
3149      return FALSE;
3150    
3151    switch(ranges[0])
3152      {
3153      case 1:
3154      if (readch)
3155        read_char(common);
3156      add_jump(compiler, backtracks, CMP(ranges[1] == 0 ? SLJIT_C_LESS : SLJIT_C_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, ranges[2]));
3157      return TRUE;
3158    
3159      case 2:
3160      if (readch)
3161        read_char(common);
3162      OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[2]);
3163      add_jump(compiler, backtracks, CMP(ranges[1] != 0 ? SLJIT_C_LESS : SLJIT_C_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, ranges[3] - ranges[2]));
3164      return TRUE;
3165    
3166      case 4:
3167      if (ranges[2] + 1 == ranges[3] && ranges[4] + 1 == ranges[5])
3168        {
3169        if (readch)
3170          read_char(common);
3171        if (ranges[1] != 0)
3172          {
3173          add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, ranges[2]));
3174          add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, ranges[4]));
3175          }
3176        else
3177          {
3178          jump = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, ranges[2]);
3179          add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, ranges[4]));
3180          JUMPHERE(jump);
3181          }
3182        return TRUE;
3183        }
3184      return FALSE;
3185    
3186      default:
3187      return FALSE;
3188      }
3189    }
3190    
3191    static void get_ctype_ranges(compiler_common *common, int flag, int *ranges)
3192    {
3193    int i, bit, length;
3194    const pcre_uint8 *ctypes = (const pcre_uint8*)common->ctypes;
3195    
3196    bit = ctypes[0] & flag;
3197    ranges[1] = bit != 0 ? 1 : 0;
3198    length = 0;
3199    
3200    for (i = 1; i < 256; i++)
3201      if ((ctypes[i] & flag) != bit)
3202        {
3203        if (length >= MAX_RANGE_SIZE)
3204          {
3205          ranges[0] = -1;
3206          return;
3207          }
3208        ranges[2 + length] = i;
3209        length++;
3210        bit ^= flag;
3211        }
3212    
3213    if (bit != 0)
3214      {
3215      if (length >= MAX_RANGE_SIZE)
3216        {
3217        ranges[0] = -1;
3218        return;
3219        }
3220      ranges[2 + length] = 256;
3221      length++;
3222      }
3223    ranges[0] = length;
3224    }
3225    
3226    static BOOL check_class_ranges(compiler_common *common, const pcre_uint8 *bits, BOOL nclass, jump_list **backtracks)
3227    {
3228    int ranges[2 + MAX_RANGE_SIZE];
3229    pcre_uint8 bit, cbit, all;
3230    int i, byte, length = 0;
3231    
3232    bit = bits[0] & 0x1;
3233    ranges[1] = bit;
3234    /* Can be 0 or 255. */
3235    all = -bit;
3236    
3237    for (i = 0; i < 256; )
3238      {
3239      byte = i >> 3;
3240      if ((i & 0x7) == 0 && bits[byte] == all)
3241        i += 8;
3242      else
3243        {
3244        cbit = (bits[byte] >> (i & 0x7)) & 0x1;
3245        if (cbit != bit)
3246          {
3247          if (length >= MAX_RANGE_SIZE)
3248            return FALSE;
3249          ranges[2 + length] = i;
3250          length++;
3251          bit = cbit;
3252          all = -cbit;
3253          }
3254        i++;
3255        }
3256      }
3257    
3258    if (((bit == 0) && nclass) || ((bit == 1) && !nclass))
3259      {
3260      if (length >= MAX_RANGE_SIZE)
3261        return FALSE;
3262      ranges[2 + length] = 256;
3263      length++;
3264      }
3265    ranges[0] = length;
3266    
3267    return check_ranges(common, ranges, backtracks, FALSE);
3268    }
3269    
3270  static void check_anynewline(compiler_common *common)  static void check_anynewline(compiler_common *common)
3271  {  {
3272  /* Check whether TMP1 contains a newline character. TMP2 destroyed. */  /* Check whether TMP1 contains a newline character. TMP2 destroyed. */
# Line 2930  unsigned int typeoffset; Line 3660  unsigned int typeoffset;
3660  int invertcmp, numberofcmps;  int invertcmp, numberofcmps;
3661  unsigned int charoffset;  unsigned int charoffset;
3662    
3663  /* Although SUPPORT_UTF must be defined, we are not necessary in utf mode. */  /* Although SUPPORT_UTF must be defined, we are
3664       not necessary in utf mode even in 8 bit mode. */
3665  detect_partial_match(common, backtracks);  detect_partial_match(common, backtracks);
3666  read_char(common);  read_char(common);
3667    
# Line 2944  if ((*cc++ & XCL_MAP) != 0) Line 3675  if ((*cc++ & XCL_MAP) != 0)
3675      jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);      jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);
3676  #endif  #endif
3677    
3678    OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);    if (!check_class_ranges(common, (const pcre_uint8 *)cc, TRUE, list))
3679    OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);      {
3680    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)cc);      OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);
3681    OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0);      OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);
3682    OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, TMP2, 0);      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)cc);
3683    add_jump(compiler, list, JUMP(SLJIT_C_NOT_ZERO));      OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0);
3684        OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, TMP2, 0);
3685        add_jump(compiler, list, JUMP(SLJIT_C_NOT_ZERO));
3686        }
3687    
3688  #ifndef COMPILE_PCRE8  #ifndef COMPILE_PCRE8
3689    JUMPHERE(jump);    JUMPHERE(jump);
# Line 3285  switch(type) Line 4019  switch(type)
4019    
4020    case OP_NOT_DIGIT:    case OP_NOT_DIGIT:
4021    case OP_DIGIT:    case OP_DIGIT:
4022      /* Digits are usually 0-9, so it is worth to optimize them. */
4023      if (common->digits[0] == -2)
4024        get_ctype_ranges(common, ctype_digit, common->digits);
4025    detect_partial_match(common, backtracks);    detect_partial_match(common, backtracks);
4026    read_char8_type(common);    /* Flip the starting bit in the negative case. */
4027    OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ctype_digit);    if (type == OP_NOT_DIGIT)
4028    add_jump(compiler, backtracks, JUMP(type == OP_DIGIT ? SLJIT_C_ZERO : SLJIT_C_NOT_ZERO));      common->digits[1] ^= 1;
4029      if (!check_ranges(common, common->digits, backtracks, TRUE))
4030        {
4031        read_char8_type(common);
4032        OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ctype_digit);
4033        add_jump(compiler, backtracks, JUMP(type == OP_DIGIT ? SLJIT_C_ZERO : SLJIT_C_NOT_ZERO));
4034        }
4035      if (type == OP_NOT_DIGIT)
4036        common->digits[1] ^= 1;
4037    return cc;    return cc;
4038    
4039    case OP_NOT_WHITESPACE:    case OP_NOT_WHITESPACE:
# Line 3712  switch(type) Line 4457  switch(type)
4457    case OP_NCLASS:    case OP_NCLASS:
4458    detect_partial_match(common, backtracks);    detect_partial_match(common, backtracks);
4459    read_char(common);    read_char(common);
4460      if (check_class_ranges(common, (const pcre_uint8 *)cc, type == OP_NCLASS, backtracks))
4461        return cc + 32 / sizeof(pcre_uchar);
4462    
4463  #if defined SUPPORT_UTF || !defined COMPILE_PCRE8  #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
4464    jump[0] = NULL;    jump[0] = NULL;
4465  #ifdef COMPILE_PCRE8  #ifdef COMPILE_PCRE8
# Line 4192  jump_list *tmp = NULL; Line 4940  jump_list *tmp = NULL;
4940  jump_list **target = (conditional) ? &backtrack->condfailed : &backtrack->common.topbacktracks;  jump_list **target = (conditional) ? &backtrack->condfailed : &backtrack->common.topbacktracks;
4941  jump_list **found;  jump_list **found;
4942  /* Saving previous accept variables. */  /* Saving previous accept variables. */
4943  struct sljit_label *save_leavelabel = common->leavelabel;  struct sljit_label *save_quitlabel = common->quitlabel;
4944  struct sljit_label *save_acceptlabel = common->acceptlabel;  struct sljit_label *save_acceptlabel = common->acceptlabel;
4945  jump_list *save_leave = common->leave;  jump_list *save_quit = common->quit;
4946  jump_list *save_accept = common->accept;  jump_list *save_accept = common->accept;
4947  struct sljit_jump *jump;  struct sljit_jump *jump;
4948  struct sljit_jump *brajump = NULL;  struct sljit_jump *brajump = NULL;
# Line 4242  else Line 4990  else
4990    }    }
4991    
4992  memset(&altbacktrack, 0, sizeof(backtrack_common));  memset(&altbacktrack, 0, sizeof(backtrack_common));
4993  common->leavelabel = NULL;  common->quitlabel = NULL;
4994  common->leave = NULL;  common->quit = NULL;
4995  while (1)  while (1)
4996    {    {
4997    common->acceptlabel = NULL;    common->acceptlabel = NULL;
# Line 4258  while (1) Line 5006  while (1)
5006    compile_trypath(common, ccbegin + 1 + LINK_SIZE, cc, &altbacktrack);    compile_trypath(common, ccbegin + 1 + LINK_SIZE, cc, &altbacktrack);
5007    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
5008      {      {
5009      common->leavelabel = save_leavelabel;      common->quitlabel = save_quitlabel;
5010      common->acceptlabel = save_acceptlabel;      common->acceptlabel = save_acceptlabel;
5011      common->leave = save_leave;      common->quit = save_quit;
5012      common->accept = save_accept;      common->accept = save_accept;
5013      return NULL;      return NULL;
5014      }      }
# Line 4313  while (1) Line 5061  while (1)
5061    compile_backtrackpath(common, altbacktrack.top);    compile_backtrackpath(common, altbacktrack.top);
5062    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
5063      {      {
5064      common->leavelabel = save_leavelabel;      common->quitlabel = save_quitlabel;
5065      common->acceptlabel = save_acceptlabel;      common->acceptlabel = save_acceptlabel;
5066      common->leave = save_leave;      common->quit = save_quit;
5067      common->accept = save_accept;      common->accept = save_accept;
5068      return NULL;      return NULL;
5069      }      }
# Line 4328  while (1) Line 5076  while (1)
5076    cc += GET(cc, 1);    cc += GET(cc, 1);
5077    }    }
5078  /* None of them matched. */  /* None of them matched. */
5079  if (common->leave != NULL)  if (common->quit != NULL)
5080    set_jumps(common->leave, LABEL());    set_jumps(common->quit, LABEL());
5081    
5082  if (opcode == OP_ASSERT || opcode == OP_ASSERTBACK)  if (opcode == OP_ASSERT || opcode == OP_ASSERTBACK)
5083    {    {
# Line 4454  else Line 5202  else
5202      }      }
5203    }    }
5204    
5205  common->leavelabel = save_leavelabel;  common->quitlabel = save_quitlabel;
5206  common->acceptlabel = save_acceptlabel;  common->acceptlabel = save_acceptlabel;
5207  common->leave = save_leave;  common->quit = save_quit;
5208  common->accept = save_accept;  common->accept = save_accept;
5209  return cc + 1 + LINK_SIZE;  return cc + 1 + LINK_SIZE;
5210  }  }
# Line 5390  pcre_uchar* end; Line 6138  pcre_uchar* end;
6138  jump_list *nomatch = NULL;  jump_list *nomatch = NULL;
6139  struct sljit_jump *jump = NULL;  struct sljit_jump *jump = NULL;
6140  struct sljit_label *label;  struct sljit_label *label;
6141    int localptr = PRIV_DATA(cc);
6142    int base = (localptr == 0) ? SLJIT_MEM1(STACK_TOP) : SLJIT_MEM1(SLJIT_LOCALS_REG);
6143    int offset0 = (localptr == 0) ? STACK(0) : localptr;
6144    int offset1 = (localptr == 0) ? STACK(1) : localptr + (int)sizeof(sljit_w);
6145    int tmp_base, tmp_offset;
6146    
6147  PUSH_BACKTRACK(sizeof(iterator_backtrack), cc, NULL);  PUSH_BACKTRACK(sizeof(iterator_backtrack), cc, NULL);
6148    
6149  cc = get_iterator_parameters(common, cc, &opcode, &type, &arg1, &arg2, &end);  cc = get_iterator_parameters(common, cc, &opcode, &type, &arg1, &arg2, &end);
6150    
6151    switch (type)
6152      {
6153      case OP_NOT_DIGIT:
6154      case OP_DIGIT:
6155      case OP_NOT_WHITESPACE:
6156      case OP_WHITESPACE:
6157      case OP_NOT_WORDCHAR:
6158      case OP_WORDCHAR:
6159      case OP_ANY:
6160      case OP_ALLANY:
6161      case OP_ANYBYTE:
6162      case OP_ANYNL:
6163      case OP_NOT_HSPACE:
6164      case OP_HSPACE:
6165      case OP_NOT_VSPACE:
6166      case OP_VSPACE:
6167      case OP_CHAR:
6168      case OP_CHARI:
6169      case OP_NOT:
6170      case OP_NOTI:
6171      case OP_CLASS:
6172      case OP_NCLASS:
6173      tmp_base = TMP3;
6174      tmp_offset = 0;
6175      break;
6176    
6177      default:
6178      SLJIT_ASSERT_STOP();
6179      /* Fall through. */
6180    
6181      case OP_EXTUNI:
6182      case OP_XCLASS:
6183      case OP_NOTPROP:
6184      case OP_PROP:
6185      tmp_base = SLJIT_MEM1(SLJIT_LOCALS_REG);
6186      tmp_offset = POSSESSIVE0;
6187      break;
6188      }
6189    
6190  switch(opcode)  switch(opcode)
6191    {    {
6192    case OP_STAR:    case OP_STAR:
# Line 5403  switch(opcode) Line 6195  switch(opcode)
6195    case OP_CRRANGE:    case OP_CRRANGE:
6196    if (type == OP_ANYNL || type == OP_EXTUNI)    if (type == OP_ANYNL || type == OP_EXTUNI)
6197      {      {
6198        SLJIT_ASSERT(localptr == 0);
6199      if (opcode == OP_STAR || opcode == OP_UPTO)      if (opcode == OP_STAR || opcode == OP_UPTO)
6200        {        {
6201        allocate_stack(common, 2);        allocate_stack(common, 2);
# Line 5414  switch(opcode) Line 6207  switch(opcode)
6207        allocate_stack(common, 1);        allocate_stack(common, 1);
6208        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
6209        }        }
6210    
6211      if (opcode == OP_UPTO || opcode == OP_CRRANGE)      if (opcode == OP_UPTO || opcode == OP_CRRANGE)
6212        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, 0);
6213    
# Line 5430  switch(opcode) Line 6224  switch(opcode)
6224        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, TMP1, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, TMP1, 0);
6225        }        }
6226    
6227        /* We cannot use TMP3 because of this allocate_stack. */
6228      allocate_stack(common, 1);      allocate_stack(common, 1);
6229      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
6230      JUMPTO(SLJIT_JUMP, label);      JUMPTO(SLJIT_JUMP, label);
# Line 5440  switch(opcode) Line 6235  switch(opcode)
6235      {      {
6236      if (opcode == OP_PLUS)      if (opcode == OP_PLUS)
6237        compile_char1_trypath(common, type, cc, &backtrack->topbacktracks);        compile_char1_trypath(common, type, cc, &backtrack->topbacktracks);
6238      allocate_stack(common, 2);      if (localptr == 0)
6239      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);        allocate_stack(common, 2);
6240      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, 1);      OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);
6241        if (opcode <= OP_PLUS)
6242          OP1(SLJIT_MOV, base, offset1, STR_PTR, 0);
6243        else
6244          OP1(SLJIT_MOV, base, offset1, SLJIT_IMM, 1);
6245      label = LABEL();      label = LABEL();
6246      compile_char1_trypath(common, type, cc, &nomatch);      compile_char1_trypath(common, type, cc, &nomatch);
6247      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);      OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);
6248      if (opcode <= OP_PLUS || (opcode == OP_CRRANGE && arg1 == 0))      if (opcode <= OP_PLUS)
6249          JUMPTO(SLJIT_JUMP, label);
6250        else if (opcode == OP_CRRANGE && arg1 == 0)
6251        {        {
6252        OP2(SLJIT_ADD, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, 1);        OP2(SLJIT_ADD, base, offset1, base, offset1, SLJIT_IMM, 1);
6253        JUMPTO(SLJIT_JUMP, label);        JUMPTO(SLJIT_JUMP, label);
6254        }        }
6255      else      else
6256        {        {
6257        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1));        OP1(SLJIT_MOV, TMP1, 0, base, offset1);
6258        OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);        OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
6259        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);        OP1(SLJIT_MOV, base, offset1, TMP1, 0);
6260        CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, arg1 + 1, label);        CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, arg1 + 1, label);
6261        }        }
6262      set_jumps(nomatch, LABEL());      set_jumps(nomatch, LABEL());
6263      if (opcode == OP_CRRANGE)      if (opcode == OP_CRRANGE)
6264        add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_C_LESS, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, arg2 + 1));        add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_C_LESS, base, offset1, SLJIT_IMM, arg2 + 1));
6265      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));      OP1(SLJIT_MOV, STR_PTR, 0, base, offset0);
6266      }      }
6267    BACKTRACK_AS(iterator_backtrack)->trypath = LABEL();    BACKTRACK_AS(iterator_backtrack)->trypath = LABEL();
6268    break;    break;
# Line 5470  switch(opcode) Line 6271  switch(opcode)
6271    case OP_MINPLUS:    case OP_MINPLUS:
6272    if (opcode == OP_MINPLUS)    if (opcode == OP_MINPLUS)
6273      compile_char1_trypath(common, type, cc, &backtrack->topbacktracks);      compile_char1_trypath(common, type, cc, &backtrack->topbacktracks);
6274    allocate_stack(common, 1);    if (localptr == 0)
6275    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);      allocate_stack(common, 1);
6276      OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);
6277    BACKTRACK_AS(iterator_backtrack)->trypath = LABEL();    BACKTRACK_AS(iterator_backtrack)->trypath = LABEL();
6278    break;    break;
6279    
6280    case OP_MINUPTO:    case OP_MINUPTO:
6281    case OP_CRMINRANGE:    case OP_CRMINRANGE:
6282    allocate_stack(common, 2);    if (localptr == 0)
6283    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);      allocate_stack(common, 2);
6284    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, 1);    OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);
6285      OP1(SLJIT_MOV, base, offset1, SLJIT_IMM, 1);
6286    if (opcode == OP_CRMINRANGE)    if (opcode == OP_CRMINRANGE)
6287      add_jump(compiler, &backtrack->topbacktracks, JUMP(SLJIT_JUMP));      add_jump(compiler, &backtrack->topbacktracks, JUMP(SLJIT_JUMP));
6288    BACKTRACK_AS(iterator_backtrack)->trypath = LABEL();    BACKTRACK_AS(iterator_backtrack)->trypath = LABEL();
# Line 5487  switch(opcode) Line 6290  switch(opcode)
6290    
6291    case OP_QUERY:    case OP_QUERY:
6292    case OP_MINQUERY:    case OP_MINQUERY:
6293    allocate_stack(common, 1);    if (localptr == 0)
6294    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);      allocate_stack(common, 1);
6295      OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);
6296    if (opcode == OP_QUERY)    if (opcode == OP_QUERY)
6297      compile_char1_trypath(common, type, cc, &backtrack->topbacktracks);      compile_char1_trypath(common, type, cc, &backtrack->topbacktracks);
6298    BACKTRACK_AS(iterator_backtrack)->trypath = LABEL();    BACKTRACK_AS(iterator_backtrack)->trypath = LABEL();
6299    break;    break;
6300    
6301    case OP_EXACT:    case OP_EXACT:
6302    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, 1);    OP1(SLJIT_MOV, tmp_base, tmp_offset, SLJIT_IMM, arg1);
6303    label = LABEL();    label = LABEL();
6304    compile_char1_trypath(common, type, cc, &backtrack->topbacktracks);    compile_char1_trypath(common, type, cc, &backtrack->topbacktracks);
6305    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0);    OP2(SLJIT_SUB | SLJIT_SET_E, tmp_base, tmp_offset, tmp_base, tmp_offset, SLJIT_IMM, 1);
6306    OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);    JUMPTO(SLJIT_C_NOT_ZERO, label);
   OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, TMP1, 0);  
   CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, arg1 + 1, label);  
6307    break;    break;
6308    
6309    case OP_POSSTAR:    case OP_POSSTAR:
6310    case OP_POSPLUS:    case OP_POSPLUS:
6311    case OP_POSUPTO:    case OP_POSUPTO:
6312    if (opcode != OP_POSSTAR)    if (opcode == OP_POSPLUS)
6313      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, 1);      compile_char1_trypath(common, type, cc, &backtrack->topbacktracks);
6314    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STR_PTR, 0);    if (opcode == OP_POSUPTO)
6315        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, SLJIT_IMM, arg1);
6316      OP1(SLJIT_MOV, tmp_base, tmp_offset, STR_PTR, 0);
6317    label = LABEL();    label = LABEL();
6318    compile_char1_trypath(common, type, cc, &nomatch);    compile_char1_trypath(common, type, cc, &nomatch);
6319    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STR_PTR, 0);    OP1(SLJIT_MOV, tmp_base, tmp_offset, STR_PTR, 0);
6320    if (opcode != OP_POSUPTO)    if (opcode != OP_POSUPTO)
     {  
     if (opcode == OP_POSPLUS)  
       OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, 2);  
6321      JUMPTO(SLJIT_JUMP, label);      JUMPTO(SLJIT_JUMP, label);
     }  
6322    else    else
6323      {      {
6324      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0);      OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, SLJIT_IMM, 1);
6325      OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);      JUMPTO(SLJIT_C_NOT_ZERO, label);
     OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, TMP1, 0);  
     CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, arg1 + 1, label);  
6326      }      }
6327    set_jumps(nomatch, LABEL());    set_jumps(nomatch, LABEL());
6328    if (opcode == OP_POSPLUS)    OP1(SLJIT_MOV, STR_PTR, 0, tmp_base, tmp_offset);
     add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_C_LESS, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, 2));  
   OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1);  
6329    break;    break;
6330    
6331    case OP_POSQUERY:    case OP_POSQUERY:
6332    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STR_PTR, 0);    OP1(SLJIT_MOV, tmp_base, tmp_offset, STR_PTR, 0);
6333    compile_char1_trypath(common, type, cc, &nomatch);    compile_char1_trypath(common, type, cc, &nomatch);
6334    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STR_PTR, 0);    OP1(SLJIT_MOV, tmp_base, tmp_offset, STR_PTR, 0);
6335    set_jumps(nomatch, LABEL());    set_jumps(nomatch, LABEL());
6336    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1);    OP1(SLJIT_MOV, STR_PTR, 0, tmp_base, tmp_offset);
6337    break;    break;
6338    
6339    default:    default:
# Line 5888  int arg1 = -1, arg2 = -1; Line 6684  int arg1 = -1, arg2 = -1;
6684  struct sljit_label *label = NULL;  struct sljit_label *label = NULL;
6685  struct sljit_jump *jump = NULL;  struct sljit_jump *jump = NULL;
6686  jump_list *jumplist = NULL;  jump_list *jumplist = NULL;
6687    int localptr = PRIV_DATA(cc);
6688    int base = (localptr == 0) ? SLJIT_MEM1(STACK_TOP) : SLJIT_MEM1(SLJIT_LOCALS_REG);
6689    int offset0 = (localptr == 0) ? STACK(0) : localptr;
6690    int offset1 = (localptr == 0) ? STACK(1) : localptr + (int)sizeof(sljit_w);
6691    
6692  cc = get_iterator_parameters(common, cc, &opcode, &type, &arg1, &arg2, NULL);  cc = get_iterator_parameters(common, cc, &opcode, &type, &arg1, &arg2, NULL);
6693    
# Line 5899  switch(opcode) Line 6699  switch(opcode)
6699    case OP_CRRANGE:    case OP_CRRANGE:
6700    if (type == OP_ANYNL || type == OP_EXTUNI)    if (type == OP_ANYNL || type == OP_EXTUNI)
6701      {      {
6702        SLJIT_ASSERT(localptr == 0);
6703      set_jumps(current->topbacktracks, LABEL());      set_jumps(current->topbacktracks, LABEL());
6704      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
6705      free_stack(common, 1);      free_stack(common, 1);
# Line 5906  switch(opcode) Line 6707  switch(opcode)
6707      }      }
6708    else    else
6709      {      {
6710      if (opcode <= OP_PLUS || opcode == OP_UPTO)      if (opcode == OP_UPTO)
6711        arg2 = 0;        arg2 = 0;
6712      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1));      if (opcode <= OP_PLUS)
6713      jump = CMP(SLJIT_C_LESS_EQUAL, TMP1, 0, SLJIT_IMM, arg2 + 1);        {
6714      OP2(SLJIT_SUB, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0, SLJIT_IMM, 1);        OP1(SLJIT_MOV, STR_PTR, 0, base, offset0);
6715      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));        jump = CMP(SLJIT_C_LESS_EQUAL, STR_PTR, 0, base, offset1);
6716          }
6717        else
6718          {
6719          OP1(SLJIT_MOV, TMP1, 0, base, offset1);
6720          OP1(SLJIT_MOV, STR_PTR, 0, base, offset0);
6721          jump = CMP(SLJIT_C_LESS_EQUAL, TMP1, 0, SLJIT_IMM, arg2 + 1);
6722          OP2(SLJIT_SUB, base, offset1, TMP1, 0, SLJIT_IMM, 1);
6723          }
6724      skip_char_back(common);      skip_char_back(common);
6725      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);      OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);
6726      JUMPTO(SLJIT_JUMP, CURRENT_AS(iterator_backtrack)->trypath);      JUMPTO(SLJIT_JUMP, CURRENT_AS(iterator_backtrack)->trypath);
6727      if (opcode == OP_CRRANGE)      if (opcode == OP_CRRANGE)
6728        set_jumps(current->topbacktracks, LABEL());        set_jumps(current->topbacktracks, LABEL());
6729      JUMPHERE(jump);      JUMPHERE(jump);
6730      free_stack(common, 2);      if (localptr == 0)
6731          free_stack(common, 2);
6732      if (opcode == OP_PLUS)      if (opcode == OP_PLUS)
6733        set_jumps(current->topbacktracks, LABEL());        set_jumps(current->topbacktracks, LABEL());
6734      }      }
# Line 5926  switch(opcode) Line 6736  switch(opcode)
6736    
6737    case OP_MINSTAR:    case OP_MINSTAR:
6738    case OP_MINPLUS:    case OP_MINPLUS:
6739    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));    OP1(SLJIT_MOV, STR_PTR, 0, base, offset0);
6740    compile_char1_trypath(common, type, cc, &jumplist);    compile_char1_trypath(common, type, cc, &jumplist);
6741    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);    OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);
6742    JUMPTO(SLJIT_JUMP, CURRENT_AS(iterator_backtrack)->trypath);    JUMPTO(SLJIT_JUMP, CURRENT_AS(iterator_backtrack)->trypath);
6743    set_jumps(jumplist, LABEL());    set_jumps(jumplist, LABEL());
6744    free_stack(common, 1);    if (localptr == 0)
6745        free_stack(common, 1);
6746    if (opcode == OP_MINPLUS)    if (opcode == OP_MINPLUS)
6747      set_jumps(current->topbacktracks, LABEL());      set_jumps(current->topbacktracks, LABEL());
6748    break;    break;
# Line 5943  switch(opcode) Line 6754  switch(opcode)
6754      label = LABEL();      label = LABEL();
6755      set_jumps(current->topbacktracks, label);      set_jumps(current->topbacktracks, label);
6756      }      }
6757    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));    OP1(SLJIT_MOV, STR_PTR, 0, base, offset0);
6758    compile_char1_trypath(common, type, cc, &jumplist);    compile_char1_trypath(common, type, cc, &jumplist);
6759    
6760    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1));    OP1(SLJIT_MOV, TMP1, 0, base, offset1);
6761    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);    OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);
6762    OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);    OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
6763    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);    OP1(SLJIT_MOV, base, offset1, TMP1, 0);
6764    
6765    if (opcode == OP_CRMINRANGE)    if (opcode == OP_CRMINRANGE)
6766      CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, arg2 + 1, label);      CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, arg2 + 1, label);
# Line 5960  switch(opcode) Line 6771  switch(opcode)
6771      CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, arg1 + 2, CURRENT_AS(iterator_backtrack)->trypath);      CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, arg1 + 2, CURRENT_AS(iterator_backtrack)->trypath);
6772    
6773    set_jumps(jumplist, LABEL());    set_jumps(jumplist, LABEL());
6774    free_stack(common, 2);    if (localptr == 0)
6775        free_stack(common, 2);
6776    break;    break;
6777    
6778    case OP_QUERY:    case OP_QUERY:
6779    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));    OP1(SLJIT_MOV, STR_PTR, 0, base, offset0);
6780    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);    OP1(SLJIT_MOV, base, offset0, SLJIT_IMM, 0);
6781    CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(iterator_backtrack)->trypath);    CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(iterator_backtrack)->trypath);
6782    jump = JUMP(SLJIT_JUMP);    jump = JUMP(SLJIT_JUMP);
6783    set_jumps(current->topbacktracks, LABEL());    set_jumps(current->topbacktracks, LABEL());
6784    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));    OP1(SLJIT_MOV, STR_PTR, 0, base, offset0);
6785    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);    OP1(SLJIT_MOV, base, offset0, SLJIT_IMM, 0);
6786    JUMPTO(SLJIT_JUMP, CURRENT_AS(iterator_backtrack)->trypath);    JUMPTO(SLJIT_JUMP, CURRENT_AS(iterator_backtrack)->trypath);
6787    JUMPHERE(jump);    JUMPHERE(jump);
6788    free_stack(common, 1);    if (localptr == 0)
6789        free_stack(common, 1);
6790    break;    break;
6791    
6792    case OP_MINQUERY:    case OP_MINQUERY:
6793    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));    OP1(SLJIT_MOV, STR_PTR, 0, base, offset0);
6794    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);    OP1(SLJIT_MOV, base, offset0, SLJIT_IMM, 0);
6795    jump = CMP(SLJIT_C_EQUAL, STR_PTR, 0, SLJIT_IMM, 0);    jump = CMP(SLJIT_C_EQUAL, STR_PTR, 0, SLJIT_IMM, 0);
6796    compile_char1_trypath(common, type, cc, &jumplist);    compile_char1_trypath(common, type, cc, &jumplist);
6797    JUMPTO(SLJIT_JUMP, CURRENT_AS(iterator_backtrack)->trypath);    JUMPTO(SLJIT_JUMP, CURRENT_AS(iterator_backtrack)->trypath);
6798    set_jumps(jumplist, LABEL());    set_jumps(jumplist, LABEL());
6799    JUMPHERE(jump);    JUMPHERE(jump);
6800    free_stack(common, 1);    if (localptr == 0)
6801        free_stack(common, 1);
6802    break;    break;
6803    
6804    case OP_EXACT:    case OP_EXACT:
# Line 6688  while (current) Line 7502  while (current)
7502    
7503      case OP_COMMIT:      case OP_COMMIT:
7504      OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_NOMATCH);      OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_NOMATCH);
7505      if (common->leavelabel == NULL)      if (common->quitlabel == NULL)
7506        add_jump(compiler, &common->leave, JUMP(SLJIT_JUMP));        add_jump(compiler, &common->quit, JUMP(SLJIT_JUMP));
7507      else      else
7508        JUMPTO(SLJIT_JUMP, common->leavelabel);        JUMPTO(SLJIT_JUMP, common->quitlabel);
7509      break;      break;
7510    
7511      case OP_FAIL:      case OP_FAIL:
# Line 6719  int framesize = get_framesize(common, cc Line 7533  int framesize = get_framesize(common, cc
7533  int alternativesize;  int alternativesize;
7534  BOOL needsframe;  BOOL needsframe;
7535  backtrack_common altbacktrack;  backtrack_common altbacktrack;
7536  struct sljit_label *save_leavelabel = common->leavelabel;  struct sljit_label *save_quitlabel = common->quitlabel;
7537  jump_list *save_leave = common->leave;  jump_list *save_quit = common->quit;
7538  struct sljit_jump *jump;  struct sljit_jump *jump;
7539    
7540  SLJIT_ASSERT(*cc == OP_BRA || *cc == OP_CBRA || *cc == OP_CBRAPOS || *cc == OP_SCBRA || *cc == OP_SCBRAPOS);  SLJIT_ASSERT(*cc == OP_BRA || *cc == OP_CBRA || *cc == OP_CBRAPOS || *cc == OP_SCBRA || *cc == OP_SCBRAPOS);
# Line 6745  if (alternativesize > 0) Line 7559  if (alternativesize > 0)
7559    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
7560    
7561  memset(&altbacktrack, 0, sizeof(backtrack_common));  memset(&altbacktrack, 0, sizeof(backtrack_common));
7562  common->leavelabel = NULL;  common->quitlabel = NULL;
7563  common->acceptlabel = NULL;  common->acceptlabel = NULL;
7564  common->leave = NULL;  common->quit = NULL;
7565  common->accept = NULL;  common->accept = NULL;
7566  altbacktrack.cc = ccbegin;  altbacktrack.cc = ccbegin;
7567  cc += GET(cc, 1);  cc += GET(cc, 1);
# Line 6762  while (1) Line 7576  while (1)
7576    compile_trypath(common, altbacktrack.cc, cc, &altbacktrack);    compile_trypath(common, altbacktrack.cc, cc, &altbacktrack);
7577    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
7578      {      {
7579      common->leavelabel = save_leavelabel;      common->quitlabel = save_quitlabel;
7580      common->leave = save_leave;      common->quit = save_quit;
7581      return;      return;
7582      }      }
7583    
# Line 6772  while (1) Line 7586  while (1)
7586    compile_backtrackpath(common, altbacktrack.top);    compile_backtrackpath(common, altbacktrack.top);
7587    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
7588      {      {
7589      common->leavelabel = save_leavelabel;      common->quitlabel = save_quitlabel;
7590      common->leave = save_leave;      common->quit = save_quit;
7591      return;      return;
7592      }      }
7593    set_jumps(altbacktrack.topbacktracks, LABEL());    set_jumps(altbacktrack.topbacktracks, LABEL());
# Line 6785  while (1) Line 7599  while (1)
7599    cc += GET(cc, 1);    cc += GET(cc, 1);
7600    }    }
7601  /* None of them matched. */  /* None of them matched. */
7602  if (common->leave != NULL)  if (common->quit != NULL)
7603    set_jumps(common->leave, LABEL());    set_jumps(common->quit, LABEL());
7604    
7605  OP1(SLJIT_MOV, TMP3, 0, SLJIT_IMM, 0);  OP1(SLJIT_MOV, TMP3, 0, SLJIT_IMM, 0);
7606  jump = JUMP(SLJIT_JUMP);  jump = JUMP(SLJIT_JUMP);
# Line 6809  OP1(SLJIT_MOV, TMP1, 0, TMP3, 0); Line 7623  OP1(SLJIT_MOV, TMP1, 0, TMP3, 0);
7623  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->recursive_head, TMP2, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->recursive_head, TMP2, 0);
7624  sljit_emit_fast_return(compiler, SLJIT_MEM1(STACK_TOP), 0);  sljit_emit_fast_return(compiler, SLJIT_MEM1(STACK_TOP), 0);
7625    
7626  common->leavelabel = save_leavelabel;  common->quitlabel = save_quitlabel;
7627  common->leave = save_leave;  common->quit = save_quit;
7628  }  }
7629    
7630  #undef COMPILE_BACKTRACKPATH  #undef COMPILE_BACKTRACKPATH
# Line 6856  switch(re->options & PCRE_NEWLINE_BITS) Line 7670  switch(re->options & PCRE_NEWLINE_BITS)
7670    {    {
7671    case 0:    case 0:
7672    /* Compile-time default */    /* Compile-time default */
7673    switch (NEWLINE)    switch(NEWLINE)
7674      {      {
7675      case -1: common->newline = (CHAR_CR << 8) | CHAR_NL; common->nltype = NLTYPE_ANY; break;      case -1: common->newline = (CHAR_CR << 8) | CHAR_NL; common->nltype = NLTYPE_ANY; break;
7676      case -2: common->newline = (CHAR_CR << 8) | CHAR_NL; common->nltype = NLTYPE_ANYCRLF; break;      case -2: common->newline = (CHAR_CR << 8) | CHAR_NL; common->nltype = NLTYPE_ANYCRLF; break;
# Line 6885  else Line 7699  else
7699    }    }
7700  common->endonly = (re->options & PCRE_DOLLAR_ENDONLY) != 0;  common->endonly = (re->options & PCRE_DOLLAR_ENDONLY) != 0;
7701  common->ctypes = (sljit_w)(tables + ctypes_offset);  common->ctypes = (sljit_w)(tables + ctypes_offset);
7702    common->digits[0] = -2;
7703  common->name_table = (sljit_w)((pcre_uchar *)re + re->name_table_offset);  common->name_table = (sljit_w)((pcre_uchar *)re + re->name_table_offset);
7704  common->name_count = re->name_count;  common->name_count = re->name_count;
7705  common->name_entry_size = re->name_entry_size;  common->name_entry_size = re->name_entry_size;
# Line 6979  if ((re->options & PCRE_ANCHORED) == 0) Line 7794  if ((re->options & PCRE_ANCHORED) == 0)
7794    /* Forward search if possible. */    /* Forward search if possible. */
7795    if ((re->options & PCRE_NO_START_OPTIMIZE) == 0)    if ((re->options & PCRE_NO_START_OPTIMIZE) == 0)
7796      {      {
7797        if (mode == JIT_COMPILE && fast_forward_first_two_chars(common, (re->options & PCRE_FIRSTLINE) != 0))
7798          /* Do nothing */;
7799      if ((re->flags & PCRE_FIRSTSET) != 0)      if ((re->flags & PCRE_FIRSTSET) != 0)
7800        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);
7801      else if ((re->flags & PCRE_STARTLINE) != 0)      else if ((re->flags & PCRE_STARTLINE) != 0)
# Line 7023  if (common->accept != NULL) Line 7840  if (common->accept != NULL)
7840    
7841  /* This means we have a match. Update the ovector. */  /* This means we have a match. Update the ovector. */
7842  copy_ovector(common, re->top_bracket + 1);  copy_ovector(common, re->top_bracket + 1);
7843  common->leavelabel = LABEL();  common->quitlabel = LABEL();
7844  if (common->leave != NULL)  if (common->quit != NULL)
7845    set_jumps(common->leave, common->leavelabel);    set_jumps(common->quit, common->quitlabel);
7846  sljit_emit_return(compiler, SLJIT_MOV, SLJIT_RETURN_REG, 0);  sljit_emit_return(compiler, SLJIT_MOV, SLJIT_RETURN_REG, 0);
7847    
7848  if (mode != JIT_COMPILE)  if (mode != JIT_COMPILE)
7849    {    {
7850    common->partialmatchlabel = LABEL();    common->partialmatchlabel = LABEL();
7851    set_jumps(common->partialmatch, common->partialmatchlabel);    set_jumps(common->partialmatch, common->partialmatchlabel);
7852    return_with_partial_match(common, common->leavelabel);    return_with_partial_match(common, common->quitlabel);
7853    }    }
7854    
7855  empty_match_backtrack = LABEL();  empty_match_backtrack = LABEL();
# Line 7096  if (mode == JIT_PARTIAL_SOFT_COMPILE) Line 7913  if (mode == JIT_PARTIAL_SOFT_COMPILE)
7913    CMPTO(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, 0, common->partialmatchlabel);    CMPTO(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, 0, common->partialmatchlabel);
7914    
7915  OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_NOMATCH);  OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_NOMATCH);
7916  JUMPTO(SLJIT_JUMP, common->leavelabel);  JUMPTO(SLJIT_JUMP, common->quitlabel);
7917    
7918  flush_stubs(common);  flush_stubs(common);
7919    
# Line 7149  sljit_emit_fast_return(compiler, SLJIT_M Line 7966  sljit_emit_fast_return(compiler, SLJIT_M
7966  JUMPHERE(jump);  JUMPHERE(jump);
7967  /* We break the return address cache here, but this is a really rare case. */  /* We break the return address cache here, but this is a really rare case. */
7968  OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_JIT_STACKLIMIT);  OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_JIT_STACKLIMIT);
7969  JUMPTO(SLJIT_JUMP, common->leavelabel);  JUMPTO(SLJIT_JUMP, common->quitlabel);
7970    
7971  /* Call limit reached. */  /* Call limit reached. */
7972  set_jumps(common->calllimit, LABEL());  set_jumps(common->calllimit, LABEL());
7973  OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_MATCHLIMIT);  OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_MATCHLIMIT);
7974  JUMPTO(SLJIT_JUMP, common->leavelabel);  JUMPTO(SLJIT_JUMP, common->quitlabel);
7975    
7976  if (common->revertframes != NULL)  if (common->revertframes != NULL)
7977    {    {
# Line 7225  if ((extra->flags & PCRE_EXTRA_EXECUTABL Line 8042  if ((extra->flags & PCRE_EXTRA_EXECUTABL
8042    functions = (executable_functions *)extra->executable_jit;    functions = (executable_functions *)extra->executable_jit;
8043  else  else
8044    {    {
8045      /* Note: If your memory-checker has flagged the allocation below as a
8046       * memory leak, it is probably because you either forgot to call
8047       * pcre_free_study() (or pcre16_free_study()) on the pcre_extra (or
8048       * pcre16_extra) object, or you called said function after having
8049       * cleared the PCRE_EXTRA_EXECUTABLE_JIT bit from the "flags" field
8050       * of the object. (The function will only free the JIT data if the
8051       * bit remains set, as the bit indicates that the pointer to the data
8052       * is valid.)
8053       */
8054    functions = SLJIT_MALLOC(sizeof(executable_functions));    functions = SLJIT_MALLOC(sizeof(executable_functions));
8055    if (functions == NULL)    if (functions == NULL)
8056      {      {

Legend:
Removed from v.977  
changed lines
  Added in v.991

  ViewVC Help
Powered by ViewVC 1.1.5