/[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 970 by zherczeg, Sun May 27 05:28:19 2012 UTC revision 995 by zherczeg, Wed Jul 11 11:05:30 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;      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;
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;
959    
960        case OP_BRA:
961        bracketlen = 1 + LINK_SIZE;
962      break;      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 1994  if (firstline) Line 2419  if (firstline)
2419    {    {
2420    /* Search for the end of the first line. */    /* Search for the end of the first line. */
2421    SLJIT_ASSERT(common->first_line_end != 0);    SLJIT_ASSERT(common->first_line_end != 0);
2422    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, STR_PTR, 0);    OP1(SLJIT_MOV, TMP3, 0, STR_PTR, 0);
   OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end, STR_END, 0);  
2423    
2424    if (common->nltype == NLTYPE_FIXED && common->newline > 255)    if (common->nltype == NLTYPE_FIXED && common->newline > 255)
2425      {      {
# Line 2006  if (firstline) Line 2430  if (firstline)
2430      OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));      OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
2431      CMPTO(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff, mainloop);      CMPTO(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff, mainloop);
2432      CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff, mainloop);      CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff, mainloop);
2433        JUMPHERE(end);
2434      OP2(SLJIT_SUB, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));      OP2(SLJIT_SUB, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2435      }      }
2436    else    else
# Line 2017  if (firstline) Line 2442  if (firstline)
2442      read_char(common);      read_char(common);
2443      check_newlinechar(common, common->nltype, &newline, TRUE);      check_newlinechar(common, common->nltype, &newline, TRUE);
2444      CMPTO(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0, mainloop);      CMPTO(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0, mainloop);
2445        JUMPHERE(end);
2446      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end, STR_PTR, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end, STR_PTR, 0);
2447      set_jumps(newline, LABEL());      set_jumps(newline, LABEL());
2448      }      }
2449    
2450    JUMPHERE(end);    OP1(SLJIT_MOV, STR_PTR, 0, TMP3, 0);
   OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);  
2451    }    }
2452    
2453  start = JUMP(SLJIT_JUMP);  start = JUMP(SLJIT_JUMP);
# Line 2053  if (newlinecheck) readuchar = TRUE; Line 2478  if (newlinecheck) readuchar = TRUE;
2478  if (readuchar)  if (readuchar)
2479    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
2480    
2481  if (newlinecheck)  if (newlinecheck)
2482    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);
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      SLJIT_ASSERT(common->first_line_end != 0);
2651      OP1(SLJIT_MOV, TMP3, 0, STR_END, 0);
2652      OP2(SLJIT_SUB, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end, SLJIT_IMM, 1);
2653      }
2654    else
2655      OP2(SLJIT_SUB, STR_END, 0, STR_END, 0, SLJIT_IMM, 1);
2656    
2657    start = LABEL();
2658    quit = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
2659    #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
2660    #ifdef COMPILE_PCRE8
2661    OP1(SLJIT_MOV_UH, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
2662    #else /* COMPILE_PCRE8 */
2663    OP1(SLJIT_MOV_UI, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
2664    #endif
2665    
2666    #else /* SLJIT_UNALIGNED */
2667    
2668  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));  #if defined SLJIT_BIG_ENDIAN && SLJIT_BIG_ENDIAN
2669  #if defined SUPPORT_UTF && defined COMPILE_PCRE8  OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), 0);
2670  if (common->utf)  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
2671    {  #else /* SLJIT_BIG_ENDIAN */
2672    singlechar = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);  OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
2673    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)PRIV(utf8_table4) - 0xc0);  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
2674    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);  #endif /* SLJIT_BIG_ENDIAN */
2675    JUMPHERE(singlechar);  
2676    }  #ifdef COMPILE_PCRE8
2677    OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 8);
2678    #else /* COMPILE_PCRE8 */
2679    OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 16);
2680  #endif  #endif
2681  #if defined SUPPORT_UTF && defined COMPILE_PCRE16  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
2682  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);  
   }  
2683  #endif  #endif
 JUMPHERE(start);  
2684    
2685  if (newlinecheck)  if (chars[1] != 0 || chars[3] != 0)
2686    {    {
2687    JUMPHERE(end);    pair.asuchars[0] = chars[1];
2688    JUMPHERE(nl);    pair.asuchars[1] = chars[3];
2689      OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, pair.ascombined);
2690    }    }
2691    
2692  return mainloop;  pair.asuchars[0] = chars[0];
2693    pair.asuchars[1] = chars[2];
2694    found = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, pair.ascombined);
2695    
2696    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2697    JUMPTO(SLJIT_JUMP, start);
2698    JUMPHERE(found);
2699    JUMPHERE(quit);
2700    
2701    if (firstline)
2702      OP1(SLJIT_MOV, STR_END, 0, TMP3, 0);
2703    else
2704      OP2(SLJIT_ADD, STR_END, 0, STR_END, 0, SLJIT_IMM, 1);
2705    return TRUE;
2706  }  }
2707    
2708  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)
2709  {  {
2710  DEFINE_COMPILER;  DEFINE_COMPILER;
2711  struct sljit_label *start;  struct sljit_label *start;
2712  struct sljit_jump *leave;  struct sljit_jump *quit;
2713  struct sljit_jump *found;  struct sljit_jump *found;
2714  pcre_uchar oc, bit;  pcre_uchar oc, bit;
2715    
2716  if (firstline)  if (firstline)
2717    {    {
2718    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, STR_END, 0);    SLJIT_ASSERT(common->first_line_end != 0);
2719      OP1(SLJIT_MOV, TMP3, 0, STR_END, 0);
2720    OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end);    OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end);
2721    }    }
2722    
2723  start = LABEL();  start = LABEL();
2724  leave = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);  quit = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
2725  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
2726    
2727  oc = first_char;  oc = first_char;
# Line 2137  else Line 2754  else
2754    }    }
2755    
2756  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  
2757  JUMPTO(SLJIT_JUMP, start);  JUMPTO(SLJIT_JUMP, start);
2758  JUMPHERE(found);  JUMPHERE(found);
2759  JUMPHERE(leave);  JUMPHERE(quit);
2760    
2761  if (firstline)  if (firstline)
2762    OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0);    OP1(SLJIT_MOV, STR_END, 0, TMP3, 0);
2763  }  }
2764    
2765  static SLJIT_INLINE void fast_forward_newline(compiler_common *common, BOOL firstline)  static SLJIT_INLINE void fast_forward_newline(compiler_common *common, BOOL firstline)
# Line 2170  DEFINE_COMPILER; Line 2768  DEFINE_COMPILER;
2768  struct sljit_label *loop;  struct sljit_label *loop;
2769  struct sljit_jump *lastchar;  struct sljit_jump *lastchar;
2770  struct sljit_jump *firstchar;  struct sljit_jump *firstchar;
2771  struct sljit_jump *leave;  struct sljit_jump *quit;
2772  struct sljit_jump *foundcr = NULL;  struct sljit_jump *foundcr = NULL;
2773  struct sljit_jump *notfoundnl;  struct sljit_jump *notfoundnl;
2774  jump_list *newline = NULL;  jump_list *newline = NULL;
2775    
2776  if (firstline)  if (firstline)
2777    {    {
2778    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, STR_END, 0);    SLJIT_ASSERT(common->first_line_end != 0);
2779      OP1(SLJIT_MOV, TMP3, 0, STR_END, 0);
2780    OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end);    OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end);
2781    }    }
2782    
# Line 2199  if (common->nltype == NLTYPE_FIXED && co Line 2798  if (common->nltype == NLTYPE_FIXED && co
2798    
2799    loop = LABEL();    loop = LABEL();
2800    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));
2801    leave = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);    quit = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
2802    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-2));    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-2));
2803    OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-1));    OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-1));
2804    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);
2805    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);
2806    
2807    JUMPHERE(leave);    JUMPHERE(quit);
2808    JUMPHERE(firstchar);    JUMPHERE(firstchar);
2809    JUMPHERE(lastchar);    JUMPHERE(lastchar);
2810    
# Line 2229  set_jumps(newline, loop); Line 2828  set_jumps(newline, loop);
2828    
2829  if (common->nltype == NLTYPE_ANY || common->nltype == NLTYPE_ANYCRLF)  if (common->nltype == NLTYPE_ANY || common->nltype == NLTYPE_ANYCRLF)
2830    {    {
2831    leave = JUMP(SLJIT_JUMP);    quit = JUMP(SLJIT_JUMP);
2832    JUMPHERE(foundcr);    JUMPHERE(foundcr);
2833    notfoundnl = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);    notfoundnl = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
2834    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 2839  if (common->nltype == NLTYPE_ANY || comm
2839  #endif  #endif
2840    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2841    JUMPHERE(notfoundnl);    JUMPHERE(notfoundnl);
2842    JUMPHERE(leave);    JUMPHERE(quit);
2843    }    }
2844  JUMPHERE(lastchar);  JUMPHERE(lastchar);
2845  JUMPHERE(firstchar);  JUMPHERE(firstchar);
2846    
2847  if (firstline)  if (firstline)
2848    OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0);    OP1(SLJIT_MOV, STR_END, 0, TMP3, 0);
2849  }  }
2850    
2851  static SLJIT_INLINE void fast_forward_start_bits(compiler_common *common, sljit_uw start_bits, BOOL firstline)  static SLJIT_INLINE void fast_forward_start_bits(compiler_common *common, sljit_uw start_bits, BOOL firstline)
2852  {  {
2853  DEFINE_COMPILER;  DEFINE_COMPILER;
2854  struct sljit_label *start;  struct sljit_label *start;
2855  struct sljit_jump *leave;  struct sljit_jump *quit;
2856  struct sljit_jump *found;  struct sljit_jump *found;
2857  #ifndef COMPILE_PCRE8  #ifndef COMPILE_PCRE8
2858  struct sljit_jump *jump;  struct sljit_jump *jump;
# Line 2261  struct sljit_jump *jump; Line 2860  struct sljit_jump *jump;
2860    
2861  if (firstline)  if (firstline)
2862    {    {
2863    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, STR_END, 0);    SLJIT_ASSERT(common->first_line_end != 0);
2864      OP1(SLJIT_MOV, RETURN_ADDR, 0, STR_END, 0);
2865    OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end);    OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end);
2866    }    }
2867    
2868  start = LABEL();  start = LABEL();
2869  leave = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);  quit = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
2870  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
2871  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
2872  if (common->utf)  if (common->utf)
# Line 2310  if (common->utf) Line 2910  if (common->utf)
2910  #endif  #endif
2911  JUMPTO(SLJIT_JUMP, start);  JUMPTO(SLJIT_JUMP, start);
2912  JUMPHERE(found);  JUMPHERE(found);
2913  JUMPHERE(leave);  JUMPHERE(quit);
2914    
2915  if (firstline)  if (firstline)
2916    OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0);    OP1(SLJIT_MOV, STR_END, 0, RETURN_ADDR, 0);
2917  }  }
2918    
2919  static SLJIT_INLINE struct sljit_jump *search_requested_char(compiler_common *common, pcre_uchar req_char, BOOL caseless, BOOL has_firstchar)  static SLJIT_INLINE struct sljit_jump *search_requested_char(compiler_common *common, pcre_uchar req_char, BOOL caseless, BOOL has_firstchar)
# Line 2537  OP2(SLJIT_XOR | SLJIT_SET_E, SLJIT_UNUSE Line 3137  OP2(SLJIT_XOR | SLJIT_SET_E, SLJIT_UNUSE
3137  sljit_emit_fast_return(compiler, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);  sljit_emit_fast_return(compiler, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);
3138  }  }
3139    
3140    /*
3141      range format:
3142    
3143      ranges[0] = length of the range (max MAX_RANGE_SIZE, -1 means invalid range).
3144      ranges[1] = first bit (0 or 1)
3145      ranges[2-length] = position of the bit change (when the current bit is not equal to the previous)
3146    */
3147    
3148    static BOOL check_ranges(compiler_common *common, int *ranges, jump_list **backtracks, BOOL readch)
3149    {
3150    DEFINE_COMPILER;
3151    struct sljit_jump *jump;
3152    
3153    if (ranges[0] < 0)
3154      return FALSE;
3155    
3156    switch(ranges[0])
3157      {
3158      case 1:
3159      if (readch)
3160        read_char(common);
3161      add_jump(compiler, backtracks, CMP(ranges[1] == 0 ? SLJIT_C_LESS : SLJIT_C_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, ranges[2]));
3162      return TRUE;
3163    
3164      case 2:
3165      if (readch)
3166        read_char(common);
3167      OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[2]);
3168      add_jump(compiler, backtracks, CMP(ranges[1] != 0 ? SLJIT_C_LESS : SLJIT_C_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, ranges[3] - ranges[2]));
3169      return TRUE;
3170    
3171      case 4:
3172      if (ranges[2] + 1 == ranges[3] && ranges[4] + 1 == ranges[5])
3173        {
3174        if (readch)
3175          read_char(common);
3176        if (ranges[1] != 0)
3177          {
3178          add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, ranges[2]));
3179          add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, ranges[4]));
3180          }
3181        else
3182          {
3183          jump = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, ranges[2]);
3184          add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, ranges[4]));
3185          JUMPHERE(jump);
3186          }
3187        return TRUE;
3188        }
3189      if ((ranges[3] - ranges[2]) == (ranges[5] - ranges[4]) && ispowerof2(ranges[4] - ranges[2]))
3190        {
3191        if (readch)
3192          read_char(common);
3193        OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[4] - ranges[2]);
3194        OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[4]);
3195        add_jump(compiler, backtracks, CMP(ranges[1] != 0 ? SLJIT_C_LESS : SLJIT_C_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, ranges[5] - ranges[4]));
3196        return TRUE;
3197        }
3198      return FALSE;
3199    
3200      default:
3201      return FALSE;
3202      }
3203    }
3204    
3205    static void get_ctype_ranges(compiler_common *common, int flag, int *ranges)
3206    {
3207    int i, bit, length;
3208    const pcre_uint8 *ctypes = (const pcre_uint8*)common->ctypes;
3209    
3210    bit = ctypes[0] & flag;
3211    ranges[0] = -1;
3212    ranges[1] = bit != 0 ? 1 : 0;
3213    length = 0;
3214    
3215    for (i = 1; i < 256; i++)
3216      if ((ctypes[i] & flag) != bit)
3217        {
3218        if (length >= MAX_RANGE_SIZE)
3219          return;
3220        ranges[2 + length] = i;
3221        length++;
3222        bit ^= flag;
3223        }
3224    
3225    if (bit != 0)
3226      {
3227      if (length >= MAX_RANGE_SIZE)
3228        return;
3229      ranges[2 + length] = 256;
3230      length++;
3231      }
3232    ranges[0] = length;
3233    }
3234    
3235    static BOOL check_class_ranges(compiler_common *common, const pcre_uint8 *bits, BOOL nclass, jump_list **backtracks)
3236    {
3237    int ranges[2 + MAX_RANGE_SIZE];
3238    pcre_uint8 bit, cbit, all;
3239    int i, byte, length = 0;
3240    
3241    bit = bits[0] & 0x1;
3242    ranges[1] = bit;
3243    /* Can be 0 or 255. */
3244    all = -bit;
3245    
3246    for (i = 0; i < 256; )
3247      {
3248      byte = i >> 3;
3249      if ((i & 0x7) == 0 && bits[byte] == all)
3250        i += 8;
3251      else
3252        {
3253        cbit = (bits[byte] >> (i & 0x7)) & 0x1;
3254        if (cbit != bit)
3255          {
3256          if (length >= MAX_RANGE_SIZE)
3257            return FALSE;
3258          ranges[2 + length] = i;
3259          length++;
3260          bit = cbit;
3261          all = -cbit;
3262          }
3263        i++;
3264        }
3265      }
3266    
3267    if (((bit == 0) && nclass) || ((bit == 1) && !nclass))
3268      {
3269      if (length >= MAX_RANGE_SIZE)
3270        return FALSE;
3271      ranges[2 + length] = 256;
3272      length++;
3273      }
3274    ranges[0] = length;
3275    
3276    return check_ranges(common, ranges, backtracks, FALSE);
3277    }
3278    
3279  static void check_anynewline(compiler_common *common)  static void check_anynewline(compiler_common *common)
3280  {  {
3281  /* Check whether TMP1 contains a newline character. TMP2 destroyed. */  /* Check whether TMP1 contains a newline character. TMP2 destroyed. */
# Line 2930  unsigned int typeoffset; Line 3669  unsigned int typeoffset;
3669  int invertcmp, numberofcmps;  int invertcmp, numberofcmps;
3670  unsigned int charoffset;  unsigned int charoffset;
3671    
3672  /* Although SUPPORT_UTF must be defined, we are not necessary in utf mode. */  /* Although SUPPORT_UTF must be defined, we are
3673       not necessary in utf mode even in 8 bit mode. */
3674  detect_partial_match(common, backtracks);  detect_partial_match(common, backtracks);
3675  read_char(common);  read_char(common);
3676    
# Line 2944  if ((*cc++ & XCL_MAP) != 0) Line 3684  if ((*cc++ & XCL_MAP) != 0)
3684      jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);      jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);
3685  #endif  #endif
3686    
3687    OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);    if (!check_class_ranges(common, (const pcre_uint8 *)cc, TRUE, list))
3688    OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);      {
3689    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)cc);      OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);
3690    OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0);      OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);
3691    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);
3692    add_jump(compiler, list, JUMP(SLJIT_C_NOT_ZERO));      OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0);
3693        OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, TMP2, 0);
3694        add_jump(compiler, list, JUMP(SLJIT_C_NOT_ZERO));
3695        }
3696    
3697  #ifndef COMPILE_PCRE8  #ifndef COMPILE_PCRE8
3698    JUMPHERE(jump);    JUMPHERE(jump);
# Line 3285  switch(type) Line 4028  switch(type)
4028    
4029    case OP_NOT_DIGIT:    case OP_NOT_DIGIT:
4030    case OP_DIGIT:    case OP_DIGIT:
4031      /* Digits are usually 0-9, so it is worth to optimize them. */
4032      if (common->digits[0] == -2)
4033        get_ctype_ranges(common, ctype_digit, common->digits);
4034    detect_partial_match(common, backtracks);    detect_partial_match(common, backtracks);
4035    read_char8_type(common);    /* Flip the starting bit in the negative case. */
4036    OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ctype_digit);    if (type == OP_NOT_DIGIT)
4037    add_jump(compiler, backtracks, JUMP(type == OP_DIGIT ? SLJIT_C_ZERO : SLJIT_C_NOT_ZERO));      common->digits[1] ^= 1;
4038      if (!check_ranges(common, common->digits, backtracks, TRUE))
4039        {
4040        read_char8_type(common);
4041        OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ctype_digit);
4042        add_jump(compiler, backtracks, JUMP(type == OP_DIGIT ? SLJIT_C_ZERO : SLJIT_C_NOT_ZERO));
4043        }
4044      if (type == OP_NOT_DIGIT)
4045        common->digits[1] ^= 1;
4046    return cc;    return cc;
4047    
4048    case OP_NOT_WHITESPACE:    case OP_NOT_WHITESPACE:
# Line 3642  switch(type) Line 4396  switch(type)
4396      }      }
4397    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, c);    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, c);
4398    COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);    COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);
4399    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, char_othercase(common, c));    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, oc);
4400    COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);    COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);
4401    add_jump(compiler, backtracks, JUMP(SLJIT_C_ZERO));    add_jump(compiler, backtracks, JUMP(SLJIT_C_ZERO));
4402    return cc + length;    return cc + length;
# Line 3712  switch(type) Line 4466  switch(type)
4466    case OP_NCLASS:    case OP_NCLASS:
4467    detect_partial_match(common, backtracks);    detect_partial_match(common, backtracks);
4468    read_char(common);    read_char(common);
4469      if (check_class_ranges(common, (const pcre_uint8 *)cc, type == OP_NCLASS, backtracks))
4470        return cc + 32 / sizeof(pcre_uchar);
4471    
4472  #if defined SUPPORT_UTF || !defined COMPILE_PCRE8  #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
4473    jump[0] = NULL;    jump[0] = NULL;
4474  #ifdef COMPILE_PCRE8  #ifdef COMPILE_PCRE8
# Line 4192  jump_list *tmp = NULL; Line 4949  jump_list *tmp = NULL;
4949  jump_list **target = (conditional) ? &backtrack->condfailed : &backtrack->common.topbacktracks;  jump_list **target = (conditional) ? &backtrack->condfailed : &backtrack->common.topbacktracks;
4950  jump_list **found;  jump_list **found;
4951  /* Saving previous accept variables. */  /* Saving previous accept variables. */
4952  struct sljit_label *save_leavelabel = common->leavelabel;  struct sljit_label *save_quitlabel = common->quitlabel;
4953  struct sljit_label *save_acceptlabel = common->acceptlabel;  struct sljit_label *save_acceptlabel = common->acceptlabel;
4954  jump_list *save_leave = common->leave;  jump_list *save_quit = common->quit;
4955  jump_list *save_accept = common->accept;  jump_list *save_accept = common->accept;
4956  struct sljit_jump *jump;  struct sljit_jump *jump;
4957  struct sljit_jump *brajump = NULL;  struct sljit_jump *brajump = NULL;
# Line 4242  else Line 4999  else
4999    }    }
5000    
5001  memset(&altbacktrack, 0, sizeof(backtrack_common));  memset(&altbacktrack, 0, sizeof(backtrack_common));
5002  common->leavelabel = NULL;  common->quitlabel = NULL;
5003  common->leave = NULL;  common->quit = NULL;
5004  while (1)  while (1)
5005    {    {
5006    common->acceptlabel = NULL;    common->acceptlabel = NULL;
# Line 4258  while (1) Line 5015  while (1)
5015    compile_trypath(common, ccbegin + 1 + LINK_SIZE, cc, &altbacktrack);    compile_trypath(common, ccbegin + 1 + LINK_SIZE, cc, &altbacktrack);
5016    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
5017      {      {
5018      common->leavelabel = save_leavelabel;      common->quitlabel = save_quitlabel;
5019      common->acceptlabel = save_acceptlabel;      common->acceptlabel = save_acceptlabel;
5020      common->leave = save_leave;      common->quit = save_quit;
5021      common->accept = save_accept;      common->accept = save_accept;
5022      return NULL;      return NULL;
5023      }      }
# Line 4313  while (1) Line 5070  while (1)
5070    compile_backtrackpath(common, altbacktrack.top);    compile_backtrackpath(common, altbacktrack.top);
5071    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
5072      {      {
5073      common->leavelabel = save_leavelabel;      common->quitlabel = save_quitlabel;
5074      common->acceptlabel = save_acceptlabel;      common->acceptlabel = save_acceptlabel;
5075      common->leave = save_leave;      common->quit = save_quit;
5076      common->accept = save_accept;      common->accept = save_accept;
5077      return NULL;      return NULL;
5078      }      }
# Line 4328  while (1) Line 5085  while (1)
5085    cc += GET(cc, 1);    cc += GET(cc, 1);
5086    }    }
5087  /* None of them matched. */  /* None of them matched. */
5088  if (common->leave != NULL)  if (common->quit != NULL)
5089    set_jumps(common->leave, LABEL());    set_jumps(common->quit, LABEL());
5090    
5091  if (opcode == OP_ASSERT || opcode == OP_ASSERTBACK)  if (opcode == OP_ASSERT || opcode == OP_ASSERTBACK)
5092    {    {
# Line 4454  else Line 5211  else
5211      }      }
5212    }    }
5213    
5214  common->leavelabel = save_leavelabel;  common->quitlabel = save_quitlabel;
5215  common->acceptlabel = save_acceptlabel;  common->acceptlabel = save_acceptlabel;
5216  common->leave = save_leave;  common->quit = save_quit;
5217  common->accept = save_accept;  common->accept = save_accept;
5218  return cc + 1 + LINK_SIZE;  return cc + 1 + LINK_SIZE;
5219  }  }
# Line 5020  if (ket == OP_KETRMAX) Line 5777  if (ket == OP_KETRMAX)
5777        BACKTRACK_AS(bracket_backtrack)->alttrypath = LABEL();        BACKTRACK_AS(bracket_backtrack)->alttrypath = LABEL();
5778      /* Checking zero-length iteration. */      /* Checking zero-length iteration. */
5779      if (opcode != OP_ONCE)      if (opcode != OP_ONCE)
5780          {
5781        CMPTO(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, STR_PTR, 0, rmaxlabel);        CMPTO(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, STR_PTR, 0, rmaxlabel);
5782          /* Drop STR_PTR for greedy plus quantifier. */
5783          if (bra != OP_BRAZERO)
5784            free_stack(common, 1);
5785          }
5786      else      else
5787        /* TMP2 must contain the starting STR_PTR. */        /* TMP2 must contain the starting STR_PTR. */
5788        CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, STR_PTR, 0, rmaxlabel);        CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, STR_PTR, 0, rmaxlabel);
# Line 5385  pcre_uchar* end; Line 6147  pcre_uchar* end;
6147  jump_list *nomatch = NULL;  jump_list *nomatch = NULL;
6148  struct sljit_jump *jump = NULL;  struct sljit_jump *jump = NULL;
6149  struct sljit_label *label;  struct sljit_label *label;
6150    int localptr = PRIV_DATA(cc);
6151    int base = (localptr == 0) ? SLJIT_MEM1(STACK_TOP) : SLJIT_MEM1(SLJIT_LOCALS_REG);
6152    int offset0 = (localptr == 0) ? STACK(0) : localptr;
6153    int offset1 = (localptr == 0) ? STACK(1) : localptr + (int)sizeof(sljit_w);
6154    int tmp_base, tmp_offset;
6155    
6156  PUSH_BACKTRACK(sizeof(iterator_backtrack), cc, NULL);  PUSH_BACKTRACK(sizeof(iterator_backtrack), cc, NULL);
6157    
6158  cc = get_iterator_parameters(common, cc, &opcode, &type, &arg1, &arg2, &end);  cc = get_iterator_parameters(common, cc, &opcode, &type, &arg1, &arg2, &end);
6159    
6160    switch (type)
6161      {
6162      case OP_NOT_DIGIT:
6163      case OP_DIGIT:
6164      case OP_NOT_WHITESPACE:
6165      case OP_WHITESPACE:
6166      case OP_NOT_WORDCHAR:
6167      case OP_WORDCHAR:
6168      case OP_ANY:
6169      case OP_ALLANY:
6170      case OP_ANYBYTE:
6171      case OP_ANYNL:
6172      case OP_NOT_HSPACE:
6173      case OP_HSPACE:
6174      case OP_NOT_VSPACE:
6175      case OP_VSPACE:
6176      case OP_CHAR:
6177      case OP_CHARI:
6178      case OP_NOT:
6179      case OP_NOTI:
6180      case OP_CLASS:
6181      case OP_NCLASS:
6182      tmp_base = TMP3;
6183      tmp_offset = 0;
6184      break;
6185    
6186      default:
6187      SLJIT_ASSERT_STOP();
6188      /* Fall through. */
6189    
6190      case OP_EXTUNI:
6191      case OP_XCLASS:
6192      case OP_NOTPROP:
6193      case OP_PROP:
6194      tmp_base = SLJIT_MEM1(SLJIT_LOCALS_REG);
6195      tmp_offset = POSSESSIVE0;
6196      break;
6197      }
6198    
6199  switch(opcode)  switch(opcode)
6200    {    {
6201    case OP_STAR:    case OP_STAR:
# Line 5398  switch(opcode) Line 6204  switch(opcode)
6204    case OP_CRRANGE:    case OP_CRRANGE:
6205    if (type == OP_ANYNL || type == OP_EXTUNI)    if (type == OP_ANYNL || type == OP_EXTUNI)
6206      {      {
6207        SLJIT_ASSERT(localptr == 0);
6208      if (opcode == OP_STAR || opcode == OP_UPTO)      if (opcode == OP_STAR || opcode == OP_UPTO)
6209        {        {
6210        allocate_stack(common, 2);        allocate_stack(common, 2);
# Line 5409  switch(opcode) Line 6216  switch(opcode)
6216        allocate_stack(common, 1);        allocate_stack(common, 1);
6217        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
6218        }        }
6219    
6220      if (opcode == OP_UPTO || opcode == OP_CRRANGE)      if (opcode == OP_UPTO || opcode == OP_CRRANGE)
6221        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, 0);
6222    
# Line 5425  switch(opcode) Line 6233  switch(opcode)
6233        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, TMP1, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, TMP1, 0);
6234        }        }
6235    
6236        /* We cannot use TMP3 because of this allocate_stack. */
6237      allocate_stack(common, 1);      allocate_stack(common, 1);
6238      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
6239      JUMPTO(SLJIT_JUMP, label);      JUMPTO(SLJIT_JUMP, label);
# Line 5433  switch(opcode) Line 6242  switch(opcode)
6242      }      }
6243    else    else
6244      {      {
6245      allocate_stack(common, 2);      if (opcode == OP_PLUS)
6246      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);        compile_char1_trypath(common, type, cc, &backtrack->topbacktracks);
6247      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, 1);      if (localptr == 0)
6248          allocate_stack(common, 2);
6249        OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);
6250        if (opcode <= OP_PLUS)
6251          OP1(SLJIT_MOV, base, offset1, STR_PTR, 0);
6252        else
6253          OP1(SLJIT_MOV, base, offset1, SLJIT_IMM, 1);
6254      label = LABEL();      label = LABEL();
6255      compile_char1_trypath(common, type, cc, &nomatch);      compile_char1_trypath(common, type, cc, &nomatch);
6256      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);      OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);
6257      if (opcode <= OP_PLUS || (opcode == OP_CRRANGE && arg1 == 0))      if (opcode <= OP_PLUS)
6258          JUMPTO(SLJIT_JUMP, label);
6259        else if (opcode == OP_CRRANGE && arg1 == 0)
6260        {        {
6261        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);
6262        JUMPTO(SLJIT_JUMP, label);        JUMPTO(SLJIT_JUMP, label);
6263        }        }
6264      else      else
6265        {        {
6266        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1));        OP1(SLJIT_MOV, TMP1, 0, base, offset1);
6267        OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);        OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
6268        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);        OP1(SLJIT_MOV, base, offset1, TMP1, 0);
6269        CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, arg1 + 1, label);        CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, arg1 + 1, label);
6270        }        }
6271      set_jumps(nomatch, LABEL());      set_jumps(nomatch, LABEL());
6272      if (opcode == OP_PLUS || opcode == OP_CRRANGE)      if (opcode == OP_CRRANGE)
6273        add_jump(compiler, &backtrack->topbacktracks,        add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_C_LESS, base, offset1, SLJIT_IMM, arg2 + 1));
6274          CMP(SLJIT_C_LESS, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, opcode == OP_PLUS ? 2 : arg2 + 1));      OP1(SLJIT_MOV, STR_PTR, 0, base, offset0);
     OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));  
6275      }      }
6276    BACKTRACK_AS(iterator_backtrack)->trypath = LABEL();    BACKTRACK_AS(iterator_backtrack)->trypath = LABEL();
6277    break;    break;
6278    
6279    case OP_MINSTAR:    case OP_MINSTAR:
6280    case OP_MINPLUS:    case OP_MINPLUS:
   allocate_stack(common, 1);  
   OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);  
6281    if (opcode == OP_MINPLUS)    if (opcode == OP_MINPLUS)
6282      add_jump(compiler, &backtrack->topbacktracks, JUMP(SLJIT_JUMP));      compile_char1_trypath(common, type, cc, &backtrack->topbacktracks);
6283      if (localptr == 0)
6284        allocate_stack(common, 1);
6285      OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);
6286    BACKTRACK_AS(iterator_backtrack)->trypath = LABEL();    BACKTRACK_AS(iterator_backtrack)->trypath = LABEL();
6287    break;    break;
6288    
6289    case OP_MINUPTO:    case OP_MINUPTO:
6290    case OP_CRMINRANGE:    case OP_CRMINRANGE:
6291    allocate_stack(common, 2);    if (localptr == 0)
6292    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);      allocate_stack(common, 2);
6293    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, 1);    OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);
6294      OP1(SLJIT_MOV, base, offset1, SLJIT_IMM, 1);
6295    if (opcode == OP_CRMINRANGE)    if (opcode == OP_CRMINRANGE)
6296      add_jump(compiler, &backtrack->topbacktracks, JUMP(SLJIT_JUMP));      add_jump(compiler, &backtrack->topbacktracks, JUMP(SLJIT_JUMP));
6297    BACKTRACK_AS(iterator_backtrack)->trypath = LABEL();    BACKTRACK_AS(iterator_backtrack)->trypath = LABEL();
# Line 5481  switch(opcode) Line 6299  switch(opcode)
6299    
6300    case OP_QUERY:    case OP_QUERY:
6301    case OP_MINQUERY:    case OP_MINQUERY:
6302    allocate_stack(common, 1);    if (localptr == 0)
6303    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);      allocate_stack(common, 1);
6304      OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);
6305    if (opcode == OP_QUERY)    if (opcode == OP_QUERY)
6306      compile_char1_trypath(common, type, cc, &backtrack->topbacktracks);      compile_char1_trypath(common, type, cc, &backtrack->topbacktracks);
6307    BACKTRACK_AS(iterator_backtrack)->trypath = LABEL();    BACKTRACK_AS(iterator_backtrack)->trypath = LABEL();
6308    break;    break;
6309    
6310    case OP_EXACT:    case OP_EXACT:
6311    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, 1);    OP1(SLJIT_MOV, tmp_base, tmp_offset, SLJIT_IMM, arg1);
6312    label = LABEL();    label = LABEL();
6313    compile_char1_trypath(common, type, cc, &backtrack->topbacktracks);    compile_char1_trypath(common, type, cc, &backtrack->topbacktracks);
6314    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);
6315    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);  
6316    break;    break;
6317    
6318    case OP_POSSTAR:    case OP_POSSTAR:
6319    case OP_POSPLUS:    case OP_POSPLUS:
6320    case OP_POSUPTO:    case OP_POSUPTO:
6321    if (opcode != OP_POSSTAR)    if (opcode == OP_POSPLUS)
6322      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, 1);      compile_char1_trypath(common, type, cc, &backtrack->topbacktracks);
6323    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STR_PTR, 0);    if (opcode == OP_POSUPTO)
6324        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, SLJIT_IMM, arg1);
6325      OP1(SLJIT_MOV, tmp_base, tmp_offset, STR_PTR, 0);
6326    label = LABEL();    label = LABEL();
6327    compile_char1_trypath(common, type, cc, &nomatch);    compile_char1_trypath(common, type, cc, &nomatch);
6328    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STR_PTR, 0);    OP1(SLJIT_MOV, tmp_base, tmp_offset, STR_PTR, 0);
6329    if (opcode != OP_POSUPTO)    if (opcode != OP_POSUPTO)
     {  
     if (opcode == OP_POSPLUS)  
       OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, 2);  
6330      JUMPTO(SLJIT_JUMP, label);      JUMPTO(SLJIT_JUMP, label);
     }  
6331    else    else
6332      {      {
6333      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);
6334      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);  
6335      }      }
6336    set_jumps(nomatch, LABEL());    set_jumps(nomatch, LABEL());
6337    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);  
6338    break;    break;
6339    
6340    case OP_POSQUERY:    case OP_POSQUERY:
6341    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STR_PTR, 0);    OP1(SLJIT_MOV, tmp_base, tmp_offset, STR_PTR, 0);
6342    compile_char1_trypath(common, type, cc, &nomatch);    compile_char1_trypath(common, type, cc, &nomatch);
6343    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STR_PTR, 0);    OP1(SLJIT_MOV, tmp_base, tmp_offset, STR_PTR, 0);
6344    set_jumps(nomatch, LABEL());    set_jumps(nomatch, LABEL());
6345    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1);    OP1(SLJIT_MOV, STR_PTR, 0, tmp_base, tmp_offset);
6346    break;    break;
6347    
6348    default:    default:
# Line 5881  pcre_uchar type; Line 6692  pcre_uchar type;
6692  int arg1 = -1, arg2 = -1;  int arg1 = -1, arg2 = -1;
6693  struct sljit_label *label = NULL;  struct sljit_label *label = NULL;
6694  struct sljit_jump *jump = NULL;  struct sljit_jump *jump = NULL;
6695    jump_list *jumplist = NULL;
6696    int localptr = PRIV_DATA(cc);
6697    int base = (localptr == 0) ? SLJIT_MEM1(STACK_TOP) : SLJIT_MEM1(SLJIT_LOCALS_REG);
6698    int offset0 = (localptr == 0) ? STACK(0) : localptr;
6699    int offset1 = (localptr == 0) ? STACK(1) : localptr + (int)sizeof(sljit_w);
6700    
6701  cc = get_iterator_parameters(common, cc, &opcode, &type, &arg1, &arg2, NULL);  cc = get_iterator_parameters(common, cc, &opcode, &type, &arg1, &arg2, NULL);
6702    
# Line 5892  switch(opcode) Line 6708  switch(opcode)
6708    case OP_CRRANGE:    case OP_CRRANGE:
6709    if (type == OP_ANYNL || type == OP_EXTUNI)    if (type == OP_ANYNL || type == OP_EXTUNI)
6710      {      {
6711        SLJIT_ASSERT(localptr == 0);
6712      set_jumps(current->topbacktracks, LABEL());      set_jumps(current->topbacktracks, LABEL());
6713      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
6714      free_stack(common, 1);      free_stack(common, 1);
# Line 5899  switch(opcode) Line 6716  switch(opcode)
6716      }      }
6717    else    else
6718      {      {
6719      if (opcode == OP_STAR || opcode == OP_UPTO)      if (opcode == OP_UPTO)
6720        arg2 = 0;        arg2 = 0;
6721      else if (opcode == OP_PLUS)      if (opcode <= OP_PLUS)
6722        arg2 = 1;        {
6723      jump = CMP(SLJIT_C_LESS_EQUAL, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, arg2 + 1);        OP1(SLJIT_MOV, STR_PTR, 0, base, offset0);
6724      OP2(SLJIT_SUB, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, 1);        jump = CMP(SLJIT_C_LESS_EQUAL, STR_PTR, 0, base, offset1);
6725      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));        }
6726        else
6727          {
6728          OP1(SLJIT_MOV, TMP1, 0, base, offset1);
6729          OP1(SLJIT_MOV, STR_PTR, 0, base, offset0);
6730          jump = CMP(SLJIT_C_LESS_EQUAL, TMP1, 0, SLJIT_IMM, arg2 + 1);
6731          OP2(SLJIT_SUB, base, offset1, TMP1, 0, SLJIT_IMM, 1);
6732          }
6733      skip_char_back(common);      skip_char_back(common);
6734      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);      OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);
6735      JUMPTO(SLJIT_JUMP, CURRENT_AS(iterator_backtrack)->trypath);      JUMPTO(SLJIT_JUMP, CURRENT_AS(iterator_backtrack)->trypath);
6736      if (opcode == OP_PLUS || opcode == OP_CRRANGE)      if (opcode == OP_CRRANGE)
6737        set_jumps(current->topbacktracks, LABEL());        set_jumps(current->topbacktracks, LABEL());
6738      JUMPHERE(jump);      JUMPHERE(jump);
6739      free_stack(common, 2);      if (localptr == 0)
6740          free_stack(common, 2);
6741        if (opcode == OP_PLUS)
6742          set_jumps(current->topbacktracks, LABEL());
6743      }      }
6744    break;    break;
6745    
6746    case OP_MINSTAR:    case OP_MINSTAR:
6747    case OP_MINPLUS:    case OP_MINPLUS:
6748    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));    OP1(SLJIT_MOV, STR_PTR, 0, base, offset0);
6749      compile_char1_trypath(common, type, cc, &jumplist);
6750      OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);
6751      JUMPTO(SLJIT_JUMP, CURRENT_AS(iterator_backtrack)->trypath);
6752      set_jumps(jumplist, LABEL());
6753      if (localptr == 0)
6754        free_stack(common, 1);
6755    if (opcode == OP_MINPLUS)    if (opcode == OP_MINPLUS)
     {  
6756      set_jumps(current->topbacktracks, LABEL());      set_jumps(current->topbacktracks, LABEL());
     current->topbacktracks = NULL;  
     }  
   compile_char1_trypath(common, type, cc, &current->topbacktracks);  
   OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);  
   JUMPTO(SLJIT_JUMP, CURRENT_AS(iterator_backtrack)->trypath);  
   set_jumps(current->topbacktracks, LABEL());  
   free_stack(common, 1);  
6757    break;    break;
6758    
6759    case OP_MINUPTO:    case OP_MINUPTO:
6760    case OP_CRMINRANGE:    case OP_CRMINRANGE:
6761    if (opcode == OP_CRMINRANGE)    if (opcode == OP_CRMINRANGE)
6762      {      {
     set_jumps(current->topbacktracks, LABEL());  
     current->topbacktracks = NULL;  
6763      label = LABEL();      label = LABEL();
6764        set_jumps(current->topbacktracks, label);
6765      }      }
6766    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));    OP1(SLJIT_MOV, STR_PTR, 0, base, offset0);
6767    compile_char1_trypath(common, type, cc, &current->topbacktracks);    compile_char1_trypath(common, type, cc, &jumplist);
6768    
6769    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1));    OP1(SLJIT_MOV, TMP1, 0, base, offset1);
6770    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);    OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);
6771    OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);    OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
6772    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);    OP1(SLJIT_MOV, base, offset1, TMP1, 0);
6773    
6774    if (opcode == OP_CRMINRANGE)    if (opcode == OP_CRMINRANGE)
6775      CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, arg2 + 1, label);      CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, arg2 + 1, label);
# Line 5955  switch(opcode) Line 6779  switch(opcode)
6779    else    else
6780      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);
6781    
6782    set_jumps(current->topbacktracks, LABEL());    set_jumps(jumplist, LABEL());
6783    free_stack(common, 2);    if (localptr == 0)
6784        free_stack(common, 2);
6785    break;    break;
6786    
6787    case OP_QUERY:    case OP_QUERY:
6788    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));    OP1(SLJIT_MOV, STR_PTR, 0, base, offset0);
6789    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);    OP1(SLJIT_MOV, base, offset0, SLJIT_IMM, 0);
6790    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);
6791    jump = JUMP(SLJIT_JUMP);    jump = JUMP(SLJIT_JUMP);
6792    set_jumps(current->topbacktracks, LABEL());    set_jumps(current->topbacktracks, LABEL());
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    JUMPTO(SLJIT_JUMP, CURRENT_AS(iterator_backtrack)->trypath);    JUMPTO(SLJIT_JUMP, CURRENT_AS(iterator_backtrack)->trypath);
6796    JUMPHERE(jump);    JUMPHERE(jump);
6797    free_stack(common, 1);    if (localptr == 0)
6798        free_stack(common, 1);
6799    break;    break;
6800    
6801    case OP_MINQUERY:    case OP_MINQUERY:
6802    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));    OP1(SLJIT_MOV, STR_PTR, 0, base, offset0);
6803    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);    OP1(SLJIT_MOV, base, offset0, SLJIT_IMM, 0);
6804    jump = CMP(SLJIT_C_EQUAL, STR_PTR, 0, SLJIT_IMM, 0);    jump = CMP(SLJIT_C_EQUAL, STR_PTR, 0, SLJIT_IMM, 0);
6805    compile_char1_trypath(common, type, cc, &current->topbacktracks);    compile_char1_trypath(common, type, cc, &jumplist);
6806    JUMPTO(SLJIT_JUMP, CURRENT_AS(iterator_backtrack)->trypath);    JUMPTO(SLJIT_JUMP, CURRENT_AS(iterator_backtrack)->trypath);
6807    set_jumps(current->topbacktracks, LABEL());    set_jumps(jumplist, LABEL());
6808    JUMPHERE(jump);    JUMPHERE(jump);
6809    free_stack(common, 1);    if (localptr == 0)
6810        free_stack(common, 1);
6811    break;    break;
6812    
6813    case OP_EXACT:    case OP_EXACT:
# Line 6154  if (SLJIT_UNLIKELY(opcode == OP_ONCE_NC) Line 6981  if (SLJIT_UNLIKELY(opcode == OP_ONCE_NC)
6981    
6982  if (ket == OP_KETRMAX)  if (ket == OP_KETRMAX)
6983    {    {
6984    if (bra != OP_BRAZERO)    if (bra == OP_BRAZERO)
     free_stack(common, 1);  
   else  
6985      {      {
6986      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
6987      free_stack(common, 1);      free_stack(common, 1);
# Line 6450  else if (opcode == OP_ONCE) Line 7275  else if (opcode == OP_ONCE)
7275  if (ket == OP_KETRMAX)  if (ket == OP_KETRMAX)
7276    {    {
7277    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
7278      if (bra != OP_BRAZERO)
7279        free_stack(common, 1);
7280    CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(bracket_backtrack)->recursivetrypath);    CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(bracket_backtrack)->recursivetrypath);
7281    if (bra == OP_BRAZERO)    if (bra == OP_BRAZERO)
7282      {      {
7283      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(1));      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
7284      JUMPTO(SLJIT_JUMP, CURRENT_AS(bracket_backtrack)->zerotrypath);      JUMPTO(SLJIT_JUMP, CURRENT_AS(bracket_backtrack)->zerotrypath);
7285      JUMPHERE(brazero);      JUMPHERE(brazero);
7286        free_stack(common, 1);
7287      }      }
   free_stack(common, 1);  
7288    }    }
7289  else if (ket == OP_KETRMIN)  else if (ket == OP_KETRMIN)
7290    {    {
# Line 6684  while (current) Line 7511  while (current)
7511    
7512      case OP_COMMIT:      case OP_COMMIT:
7513      OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_NOMATCH);      OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_NOMATCH);
7514      if (common->leavelabel == NULL)      if (common->quitlabel == NULL)
7515        add_jump(compiler, &common->leave, JUMP(SLJIT_JUMP));        add_jump(compiler, &common->quit, JUMP(SLJIT_JUMP));
7516      else      else
7517        JUMPTO(SLJIT_JUMP, common->leavelabel);        JUMPTO(SLJIT_JUMP, common->quitlabel);
7518      break;      break;
7519    
7520      case OP_FAIL:      case OP_FAIL:
# Line 6715  int framesize = get_framesize(common, cc Line 7542  int framesize = get_framesize(common, cc
7542  int alternativesize;  int alternativesize;
7543  BOOL needsframe;  BOOL needsframe;
7544  backtrack_common altbacktrack;  backtrack_common altbacktrack;
7545  struct sljit_label *save_leavelabel = common->leavelabel;  struct sljit_label *save_quitlabel = common->quitlabel;
7546  jump_list *save_leave = common->leave;  jump_list *save_quit = common->quit;
7547  struct sljit_jump *jump;  struct sljit_jump *jump;
7548    
7549  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 6741  if (alternativesize > 0) Line 7568  if (alternativesize > 0)
7568    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
7569    
7570  memset(&altbacktrack, 0, sizeof(backtrack_common));  memset(&altbacktrack, 0, sizeof(backtrack_common));
7571  common->leavelabel = NULL;  common->quitlabel = NULL;
7572  common->acceptlabel = NULL;  common->acceptlabel = NULL;
7573  common->leave = NULL;  common->quit = NULL;
7574  common->accept = NULL;  common->accept = NULL;
7575  altbacktrack.cc = ccbegin;  altbacktrack.cc = ccbegin;
7576  cc += GET(cc, 1);  cc += GET(cc, 1);
# Line 6758  while (1) Line 7585  while (1)
7585    compile_trypath(common, altbacktrack.cc, cc, &altbacktrack);    compile_trypath(common, altbacktrack.cc, cc, &altbacktrack);
7586    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
7587      {      {
7588      common->leavelabel = save_leavelabel;      common->quitlabel = save_quitlabel;
7589      common->leave = save_leave;      common->quit = save_quit;
7590      return;      return;
7591      }      }
7592    
# Line 6768  while (1) Line 7595  while (1)
7595    compile_backtrackpath(common, altbacktrack.top);    compile_backtrackpath(common, altbacktrack.top);
7596    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
7597      {      {
7598      common->leavelabel = save_leavelabel;      common->quitlabel = save_quitlabel;
7599      common->leave = save_leave;      common->quit = save_quit;
7600      return;      return;
7601      }      }
7602    set_jumps(altbacktrack.topbacktracks, LABEL());    set_jumps(altbacktrack.topbacktracks, LABEL());
# Line 6781  while (1) Line 7608  while (1)
7608    cc += GET(cc, 1);    cc += GET(cc, 1);
7609    }    }
7610  /* None of them matched. */  /* None of them matched. */
7611  if (common->leave != NULL)  if (common->quit != NULL)
7612    set_jumps(common->leave, LABEL());    set_jumps(common->quit, LABEL());
7613    
7614  OP1(SLJIT_MOV, TMP3, 0, SLJIT_IMM, 0);  OP1(SLJIT_MOV, TMP3, 0, SLJIT_IMM, 0);
7615  jump = JUMP(SLJIT_JUMP);  jump = JUMP(SLJIT_JUMP);
# Line 6805  OP1(SLJIT_MOV, TMP1, 0, TMP3, 0); Line 7632  OP1(SLJIT_MOV, TMP1, 0, TMP3, 0);
7632  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);
7633  sljit_emit_fast_return(compiler, SLJIT_MEM1(STACK_TOP), 0);  sljit_emit_fast_return(compiler, SLJIT_MEM1(STACK_TOP), 0);
7634    
7635  common->leavelabel = save_leavelabel;  common->quitlabel = save_quitlabel;
7636  common->leave = save_leave;  common->quit = save_quit;
7637  }  }
7638    
7639  #undef COMPILE_BACKTRACKPATH  #undef COMPILE_BACKTRACKPATH
# Line 6852  switch(re->options & PCRE_NEWLINE_BITS) Line 7679  switch(re->options & PCRE_NEWLINE_BITS)
7679    {    {
7680    case 0:    case 0:
7681    /* Compile-time default */    /* Compile-time default */
7682    switch (NEWLINE)    switch(NEWLINE)
7683      {      {
7684      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;
7685      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 6881  else Line 7708  else
7708    }    }
7709  common->endonly = (re->options & PCRE_DOLLAR_ENDONLY) != 0;  common->endonly = (re->options & PCRE_DOLLAR_ENDONLY) != 0;
7710  common->ctypes = (sljit_w)(tables + ctypes_offset);  common->ctypes = (sljit_w)(tables + ctypes_offset);
7711    common->digits[0] = -2;
7712  common->name_table = (sljit_w)((pcre_uchar *)re + re->name_table_offset);  common->name_table = (sljit_w)((pcre_uchar *)re + re->name_table_offset);
7713  common->name_count = re->name_count;  common->name_count = re->name_count;
7714  common->name_entry_size = re->name_entry_size;  common->name_entry_size = re->name_entry_size;
# Line 6975  if ((re->options & PCRE_ANCHORED) == 0) Line 7803  if ((re->options & PCRE_ANCHORED) == 0)
7803    /* Forward search if possible. */    /* Forward search if possible. */
7804    if ((re->options & PCRE_NO_START_OPTIMIZE) == 0)    if ((re->options & PCRE_NO_START_OPTIMIZE) == 0)
7805      {      {
7806      if ((re->flags & PCRE_FIRSTSET) != 0)      if (mode == JIT_COMPILE && fast_forward_first_two_chars(common, (re->options & PCRE_FIRSTLINE) != 0))
7807          /* Do nothing */;
7808        else if ((re->flags & PCRE_FIRSTSET) != 0)
7809        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);
7810      else if ((re->flags & PCRE_STARTLINE) != 0)      else if ((re->flags & PCRE_STARTLINE) != 0)
7811        fast_forward_newline(common, (re->options & PCRE_FIRSTLINE) != 0);        fast_forward_newline(common, (re->options & PCRE_FIRSTLINE) != 0);
# Line 7019  if (common->accept != NULL) Line 7849  if (common->accept != NULL)
7849    
7850  /* This means we have a match. Update the ovector. */  /* This means we have a match. Update the ovector. */
7851  copy_ovector(common, re->top_bracket + 1);  copy_ovector(common, re->top_bracket + 1);
7852  common->leavelabel = LABEL();  common->quitlabel = LABEL();
7853  if (common->leave != NULL)  if (common->quit != NULL)
7854    set_jumps(common->leave, common->leavelabel);    set_jumps(common->quit, common->quitlabel);
7855  sljit_emit_return(compiler, SLJIT_MOV, SLJIT_RETURN_REG, 0);  sljit_emit_return(compiler, SLJIT_MOV, SLJIT_RETURN_REG, 0);
7856    
7857  if (mode != JIT_COMPILE)  if (mode != JIT_COMPILE)
7858    {    {
7859    common->partialmatchlabel = LABEL();    common->partialmatchlabel = LABEL();
7860    set_jumps(common->partialmatch, common->partialmatchlabel);    set_jumps(common->partialmatch, common->partialmatchlabel);
7861    return_with_partial_match(common, common->leavelabel);    return_with_partial_match(common, common->quitlabel);
7862    }    }
7863    
7864  empty_match_backtrack = LABEL();  empty_match_backtrack = LABEL();
# Line 7092  if (mode == JIT_PARTIAL_SOFT_COMPILE) Line 7922  if (mode == JIT_PARTIAL_SOFT_COMPILE)
7922    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);
7923    
7924  OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_NOMATCH);  OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_NOMATCH);
7925  JUMPTO(SLJIT_JUMP, common->leavelabel);  JUMPTO(SLJIT_JUMP, common->quitlabel);
7926    
7927  flush_stubs(common);  flush_stubs(common);
7928    
# Line 7145  sljit_emit_fast_return(compiler, SLJIT_M Line 7975  sljit_emit_fast_return(compiler, SLJIT_M
7975  JUMPHERE(jump);  JUMPHERE(jump);
7976  /* 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. */
7977  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);
7978  JUMPTO(SLJIT_JUMP, common->leavelabel);  JUMPTO(SLJIT_JUMP, common->quitlabel);
7979    
7980  /* Call limit reached. */  /* Call limit reached. */
7981  set_jumps(common->calllimit, LABEL());  set_jumps(common->calllimit, LABEL());
7982  OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_MATCHLIMIT);  OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_MATCHLIMIT);
7983  JUMPTO(SLJIT_JUMP, common->leavelabel);  JUMPTO(SLJIT_JUMP, common->quitlabel);
7984    
7985  if (common->revertframes != NULL)  if (common->revertframes != NULL)
7986    {    {
# Line 7221  if ((extra->flags & PCRE_EXTRA_EXECUTABL Line 8051  if ((extra->flags & PCRE_EXTRA_EXECUTABL
8051    functions = (executable_functions *)extra->executable_jit;    functions = (executable_functions *)extra->executable_jit;
8052  else  else
8053    {    {
8054      /* Note: If your memory-checker has flagged the allocation below as a
8055       * memory leak, it is probably because you either forgot to call
8056       * pcre_free_study() (or pcre16_free_study()) on the pcre_extra (or
8057       * pcre16_extra) object, or you called said function after having
8058       * cleared the PCRE_EXTRA_EXECUTABLE_JIT bit from the "flags" field
8059       * of the object. (The function will only free the JIT data if the
8060       * bit remains set, as the bit indicates that the pointer to the data
8061       * is valid.)
8062       */
8063    functions = SLJIT_MALLOC(sizeof(executable_functions));    functions = SLJIT_MALLOC(sizeof(executable_functions));
8064    if (functions == NULL)    if (functions == NULL)
8065      {      {

Legend:
Removed from v.970  
changed lines
  Added in v.995

  ViewVC Help
Powered by ViewVC 1.1.5