| OLD | NEW |
| 1 // Copyright 2006-2008 the V8 project authors. All rights reserved. | 1 // Copyright 2006-2008 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 718 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 729 private: | 729 private: |
| 730 RegExpNode* on_failure_; | 730 RegExpNode* on_failure_; |
| 731 int start_reg_; | 731 int start_reg_; |
| 732 int end_reg_; | 732 int end_reg_; |
| 733 }; | 733 }; |
| 734 | 734 |
| 735 | 735 |
| 736 class CharacterClassNode: public SeqRegExpNode { | 736 class CharacterClassNode: public SeqRegExpNode { |
| 737 public: | 737 public: |
| 738 CharacterClassNode(ZoneList<CharacterRange>* ranges, | 738 CharacterClassNode(ZoneList<CharacterRange>* ranges, |
| 739 bool is_negated, |
| 739 RegExpNode* on_success, | 740 RegExpNode* on_success, |
| 740 RegExpNode* on_failure) | 741 RegExpNode* on_failure) |
| 741 : SeqRegExpNode(on_success), | 742 : SeqRegExpNode(on_success), |
| 742 on_failure_(on_failure), | 743 on_failure_(on_failure), |
| 743 ranges_(ranges) { } | 744 ranges_(ranges), |
| 745 is_negated_(is_negated ){ } |
| 744 virtual void Accept(NodeVisitor* visitor); | 746 virtual void Accept(NodeVisitor* visitor); |
| 745 ZoneList<CharacterRange>* ranges() { return ranges_; } | 747 ZoneList<CharacterRange>* ranges() { return ranges_; } |
| 748 bool is_negated() { return is_negated_; } |
| 746 RegExpNode* on_failure() { return on_failure_; } | 749 RegExpNode* on_failure() { return on_failure_; } |
| 750 static void AddInverseToTable(List<CharacterRange> ranges, |
| 751 DispatchTable* table, |
| 752 int index); |
| 747 private: | 753 private: |
| 748 RegExpNode* on_failure_; | 754 RegExpNode* on_failure_; |
| 749 ZoneList<CharacterRange>* ranges_; | 755 ZoneList<CharacterRange>* ranges_; |
| 756 bool is_negated_; |
| 750 }; | 757 }; |
| 751 | 758 |
| 752 | 759 |
| 753 class Guard: public ZoneObject { | 760 class Guard: public ZoneObject { |
| 754 public: | 761 public: |
| 755 enum Relation { LT, GEQ }; | 762 enum Relation { LT, GEQ }; |
| 756 Guard(int reg, Relation op, int value) | 763 Guard(int reg, Relation op, int value) |
| 757 : reg_(reg), | 764 : reg_(reg), |
| 758 op_(op), | 765 op_(op), |
| 759 value_(value) { } | 766 value_(value) { } |
| (...skipping 320 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1080 DispatchTableDumper(StringStream* stream) : stream_(stream) { } | 1087 DispatchTableDumper(StringStream* stream) : stream_(stream) { } |
| 1081 void Call(uc16 key, DispatchTable::Entry entry); | 1088 void Call(uc16 key, DispatchTable::Entry entry); |
| 1082 StringStream* stream() { return stream_; } | 1089 StringStream* stream() { return stream_; } |
| 1083 private: | 1090 private: |
| 1084 StringStream* stream_; | 1091 StringStream* stream_; |
| 1085 }; | 1092 }; |
| 1086 | 1093 |
| 1087 | 1094 |
| 1088 void DispatchTableDumper::Call(uc16 key, DispatchTable::Entry entry) { | 1095 void DispatchTableDumper::Call(uc16 key, DispatchTable::Entry entry) { |
| 1089 stream()->Add("[%k-%k]: {", key, entry.to()); | 1096 stream()->Add("[%k-%k]: {", key, entry.to()); |
| 1090 OutSet set = entry.out_set(); | 1097 OutSet* set = entry.out_set(); |
| 1091 bool first = true; | 1098 bool first = true; |
| 1092 for (unsigned i = 0; i < OutSet::kFirstLimit; i++) { | 1099 for (unsigned i = 0; i < OutSet::kFirstLimit; i++) { |
| 1093 if (set.Get(i)) { | 1100 if (set->Get(i)) { |
| 1094 if (first) first = false; | 1101 if (first) first = false; |
| 1095 else stream()->Add(", "); | 1102 else stream()->Add(", "); |
| 1096 stream()->Add("%i", i); | 1103 stream()->Add("%i", i); |
| 1097 } | 1104 } |
| 1098 } | 1105 } |
| 1099 stream()->Add("}\n"); | 1106 stream()->Add("}\n"); |
| 1100 } | 1107 } |
| 1101 | 1108 |
| 1102 | 1109 |
| 1103 void DispatchTable::Dump() { | 1110 void DispatchTable::Dump() { |
| (...skipping 20 matching lines...) Expand all Loading... |
| 1124 RegExpNode* RegExpAtom::ToNode(RegExpCompiler* compiler, | 1131 RegExpNode* RegExpAtom::ToNode(RegExpCompiler* compiler, |
| 1125 RegExpNode* on_success, | 1132 RegExpNode* on_success, |
| 1126 RegExpNode* on_failure) { | 1133 RegExpNode* on_failure) { |
| 1127 return new AtomNode(data(), on_success, on_failure); | 1134 return new AtomNode(data(), on_success, on_failure); |
| 1128 } | 1135 } |
| 1129 | 1136 |
| 1130 | 1137 |
| 1131 RegExpNode* RegExpCharacterClass::ToNode(RegExpCompiler* compiler, | 1138 RegExpNode* RegExpCharacterClass::ToNode(RegExpCompiler* compiler, |
| 1132 RegExpNode* on_success, | 1139 RegExpNode* on_success, |
| 1133 RegExpNode* on_failure) { | 1140 RegExpNode* on_failure) { |
| 1134 return new CharacterClassNode(ranges(), on_success, on_failure); | 1141 return new CharacterClassNode(ranges(), |
| 1142 is_negated(), |
| 1143 on_success, |
| 1144 on_failure); |
| 1135 } | 1145 } |
| 1136 | 1146 |
| 1137 | 1147 |
| 1138 RegExpNode* RegExpDisjunction::ToNode(RegExpCompiler* compiler, | 1148 RegExpNode* RegExpDisjunction::ToNode(RegExpCompiler* compiler, |
| 1139 RegExpNode* on_success, | 1149 RegExpNode* on_success, |
| 1140 RegExpNode* on_failure) { | 1150 RegExpNode* on_failure) { |
| 1141 ZoneList<RegExpTree*>* children = nodes(); | 1151 ZoneList<RegExpTree*>* children = nodes(); |
| 1142 int length = children->length(); | 1152 int length = children->length(); |
| 1143 ChoiceNode* result = new ChoiceNode(length, on_failure); | 1153 ChoiceNode* result = new ChoiceNode(length, on_failure); |
| 1144 for (int i = 0; i < length; i++) { | 1154 for (int i = 0; i < length; i++) { |
| (...skipping 221 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1366 default: | 1376 default: |
| 1367 UNREACHABLE(); | 1377 UNREACHABLE(); |
| 1368 } | 1378 } |
| 1369 } | 1379 } |
| 1370 | 1380 |
| 1371 | 1381 |
| 1372 // ------------------------------------------------------------------- | 1382 // ------------------------------------------------------------------- |
| 1373 // Splay tree | 1383 // Splay tree |
| 1374 | 1384 |
| 1375 | 1385 |
| 1386 OutSet* OutSet::Extend(unsigned value) { |
| 1387 if (Get(value)) |
| 1388 return this; |
| 1389 if (successors() != NULL) { |
| 1390 for (int i = 0; i < successors()->length(); i++) { |
| 1391 OutSet* successor = successors()->at(i); |
| 1392 if (successor->Get(value)) |
| 1393 return successor; |
| 1394 } |
| 1395 } else { |
| 1396 successors_ = new ZoneList<OutSet*>(2); |
| 1397 } |
| 1398 OutSet* result = new OutSet(first_, remaining_); |
| 1399 result->Set(value); |
| 1400 successors()->Add(result); |
| 1401 return result; |
| 1402 } |
| 1403 |
| 1404 |
| 1376 void OutSet::Set(unsigned value) { | 1405 void OutSet::Set(unsigned value) { |
| 1377 if (value < kFirstLimit) { | 1406 if (value < kFirstLimit) { |
| 1378 first_ |= (1 << value); | 1407 first_ |= (1 << value); |
| 1379 } else { | 1408 } else { |
| 1380 if (remaining_ == NULL) | 1409 if (remaining_ == NULL) |
| 1381 remaining_ = new ZoneList<unsigned>(1); | 1410 remaining_ = new ZoneList<unsigned>(1); |
| 1382 if (remaining_->is_empty() || !remaining_->Contains(value)) | 1411 if (remaining_->is_empty() || !remaining_->Contains(value)) |
| 1383 remaining_->Add(value); | 1412 remaining_->Add(value); |
| 1384 } | 1413 } |
| 1385 } | 1414 } |
| 1386 | 1415 |
| 1387 | 1416 |
| 1388 bool OutSet::Get(unsigned value) { | 1417 bool OutSet::Get(unsigned value) { |
| 1389 if (value < kFirstLimit) { | 1418 if (value < kFirstLimit) { |
| 1390 return (first_ & (1 << value)) != 0; | 1419 return (first_ & (1 << value)) != 0; |
| 1391 } else if (remaining_ == NULL) { | 1420 } else if (remaining_ == NULL) { |
| 1392 return false; | 1421 return false; |
| 1393 } else { | 1422 } else { |
| 1394 return remaining_->Contains(value); | 1423 return remaining_->Contains(value); |
| 1395 } | 1424 } |
| 1396 } | 1425 } |
| 1397 | 1426 |
| 1398 | 1427 |
| 1399 OutSet OutSet::Clone() { | |
| 1400 if (remaining_ == NULL) { | |
| 1401 return OutSet(first_, NULL); | |
| 1402 } else { | |
| 1403 int length = remaining_->length(); | |
| 1404 ZoneList<unsigned>* clone = new ZoneList<unsigned>(length); | |
| 1405 for (int i = 0; i < length; i++) | |
| 1406 clone->Add(remaining_->at(i)); | |
| 1407 return OutSet(first_, clone); | |
| 1408 } | |
| 1409 } | |
| 1410 | |
| 1411 | |
| 1412 const uc16 DispatchTable::Config::kNoKey = unibrow::Utf8::kBadChar; | 1428 const uc16 DispatchTable::Config::kNoKey = unibrow::Utf8::kBadChar; |
| 1413 const DispatchTable::Entry DispatchTable::Config::kNoValue; | 1429 const DispatchTable::Entry DispatchTable::Config::kNoValue; |
| 1414 | 1430 |
| 1415 | 1431 |
| 1416 void DispatchTable::AddRange(CharacterRange full_range, int value) { | 1432 void DispatchTable::AddRange(CharacterRange full_range, int value) { |
| 1417 CharacterRange current = full_range; | 1433 CharacterRange current = full_range; |
| 1418 if (tree()->is_empty()) { | 1434 if (tree()->is_empty()) { |
| 1419 // If this is the first range we just insert into the table. | 1435 // If this is the first range we just insert into the table. |
| 1420 ZoneSplayTree<Config>::Locator loc; | 1436 ZoneSplayTree<Config>::Locator loc; |
| 1421 ASSERT_RESULT(tree()->Insert(current.from(), &loc)); | 1437 ASSERT_RESULT(tree()->Insert(current.from(), &loc)); |
| 1422 loc.set_value(Entry(current.from(), current.to(), value)); | 1438 loc.set_value(Entry(current.from(), current.to(), empty()->Extend(value))); |
| 1423 return; | 1439 return; |
| 1424 } | 1440 } |
| 1425 // First see if there is a range to the left of this one that | 1441 // First see if there is a range to the left of this one that |
| 1426 // overlaps. | 1442 // overlaps. |
| 1427 ZoneSplayTree<Config>::Locator loc; | 1443 ZoneSplayTree<Config>::Locator loc; |
| 1428 if (tree()->FindGreatestLessThan(current.from(), &loc)) { | 1444 if (tree()->FindGreatestLessThan(current.from(), &loc)) { |
| 1429 Entry* entry = &loc.value(); | 1445 Entry* entry = &loc.value(); |
| 1430 // If we've found a range that overlaps with this one, and it | 1446 // If we've found a range that overlaps with this one, and it |
| 1431 // starts strictly to the left of this one, we have to fix it | 1447 // starts strictly to the left of this one, we have to fix it |
| 1432 // because the following code only handles ranges that start on | 1448 // because the following code only handles ranges that start on |
| 1433 // or after the start point of the range we're adding. | 1449 // or after the start point of the range we're adding. |
| 1434 if (entry->from() < current.from() && entry->to() >= current.from()) { | 1450 if (entry->from() < current.from() && entry->to() >= current.from()) { |
| 1435 // Snap the overlapping range in half around the start point of | 1451 // Snap the overlapping range in half around the start point of |
| 1436 // the range we're adding. | 1452 // the range we're adding. |
| 1437 CharacterRange left(entry->from(), current.from() - 1); | 1453 CharacterRange left(entry->from(), current.from() - 1); |
| 1438 CharacterRange right(current.from(), entry->to()); | 1454 CharacterRange right(current.from(), entry->to()); |
| 1439 // The left part of the overlapping range doesn't overlap. | 1455 // The left part of the overlapping range doesn't overlap. |
| 1440 // Truncate the whole entry to be just the left part. | 1456 // Truncate the whole entry to be just the left part. |
| 1441 entry->set_to(left.to()); | 1457 entry->set_to(left.to()); |
| 1442 // The right part is the one that overlaps. We add this part | 1458 // The right part is the one that overlaps. We add this part |
| 1443 // to the map and let the next step deal with merging it with | 1459 // to the map and let the next step deal with merging it with |
| 1444 // the range we're adding. | 1460 // the range we're adding. |
| 1445 ZoneSplayTree<Config>::Locator loc; | 1461 ZoneSplayTree<Config>::Locator loc; |
| 1446 ASSERT_RESULT(tree()->Insert(right.from(), &loc)); | 1462 ASSERT_RESULT(tree()->Insert(right.from(), &loc)); |
| 1447 loc.set_value(Entry(right.from(), | 1463 loc.set_value(Entry(right.from(), |
| 1448 right.to(), | 1464 right.to(), |
| 1449 entry->out_set().Clone())); | 1465 entry->out_set())); |
| 1450 } | 1466 } |
| 1451 } | 1467 } |
| 1452 while (current.is_valid()) { | 1468 while (current.is_valid()) { |
| 1453 if (tree()->FindLeastGreaterThan(current.from(), &loc) && | 1469 if (tree()->FindLeastGreaterThan(current.from(), &loc) && |
| 1454 (loc.value().from() <= current.to())) { | 1470 (loc.value().from() <= current.to())) { |
| 1455 Entry* entry = &loc.value(); | 1471 Entry* entry = &loc.value(); |
| 1456 // We have overlap. If there is space between the start point of | 1472 // We have overlap. If there is space between the start point of |
| 1457 // the range we're adding and where the overlapping range starts | 1473 // the range we're adding and where the overlapping range starts |
| 1458 // then we have to add a range covering just that space. | 1474 // then we have to add a range covering just that space. |
| 1459 if (current.from() < entry->from()) { | 1475 if (current.from() < entry->from()) { |
| 1460 ZoneSplayTree<Config>::Locator ins; | 1476 ZoneSplayTree<Config>::Locator ins; |
| 1461 ASSERT_RESULT(tree()->Insert(current.from(), &ins)); | 1477 ASSERT_RESULT(tree()->Insert(current.from(), &ins)); |
| 1462 ins.set_value(Entry(current.from(), entry->from() - 1, value)); | 1478 ins.set_value(Entry(current.from(), |
| 1479 entry->from() - 1, |
| 1480 empty()->Extend(value))); |
| 1463 current.set_from(entry->from()); | 1481 current.set_from(entry->from()); |
| 1464 } | 1482 } |
| 1465 ASSERT_EQ(current.from(), entry->from()); | 1483 ASSERT_EQ(current.from(), entry->from()); |
| 1466 // If the overlapping range extends beyond the one we want to add | 1484 // If the overlapping range extends beyond the one we want to add |
| 1467 // we have to snap the right part off and add it separately. | 1485 // we have to snap the right part off and add it separately. |
| 1468 if (entry->to() > current.to()) { | 1486 if (entry->to() > current.to()) { |
| 1469 ZoneSplayTree<Config>::Locator ins; | 1487 ZoneSplayTree<Config>::Locator ins; |
| 1470 ASSERT_RESULT(tree()->Insert(current.to() + 1, &ins)); | 1488 ASSERT_RESULT(tree()->Insert(current.to() + 1, &ins)); |
| 1471 ins.set_value(Entry(current.to() + 1, | 1489 ins.set_value(Entry(current.to() + 1, |
| 1472 entry->to(), | 1490 entry->to(), |
| 1473 entry->out_set().Clone())); | 1491 entry->out_set())); |
| 1474 entry->set_to(current.to()); | 1492 entry->set_to(current.to()); |
| 1475 } | 1493 } |
| 1476 ASSERT(entry->to() <= current.to()); | 1494 ASSERT(entry->to() <= current.to()); |
| 1477 // The overlapping range is now completely contained by the range | 1495 // The overlapping range is now completely contained by the range |
| 1478 // we're adding so we can just update it and move the start point | 1496 // we're adding so we can just update it and move the start point |
| 1479 // of the range we're adding just past it. | 1497 // of the range we're adding just past it. |
| 1480 entry->AddValue(value); | 1498 entry->AddValue(value); |
| 1481 current.set_from(entry->to() + 1); | 1499 current.set_from(entry->to() + 1); |
| 1482 } else { | 1500 } else { |
| 1483 // There is no overlap so we can just add the range | 1501 // There is no overlap so we can just add the range |
| 1484 ZoneSplayTree<Config>::Locator ins; | 1502 ZoneSplayTree<Config>::Locator ins; |
| 1485 ASSERT_RESULT(tree()->Insert(current.from(), &ins)); | 1503 ASSERT_RESULT(tree()->Insert(current.from(), &ins)); |
| 1486 ins.set_value(Entry(current.from(), current.to(), value)); | 1504 ins.set_value(Entry(current.from(), |
| 1505 current.to(), |
| 1506 empty()->Extend(value))); |
| 1487 break; | 1507 break; |
| 1488 } | 1508 } |
| 1489 } | 1509 } |
| 1490 } | 1510 } |
| 1491 | 1511 |
| 1492 | 1512 |
| 1493 OutSet DispatchTable::Get(uc16 value) { | 1513 OutSet* DispatchTable::Get(uc16 value) { |
| 1494 ZoneSplayTree<Config>::Locator loc; | 1514 ZoneSplayTree<Config>::Locator loc; |
| 1495 if (!tree()->FindGreatestLessThan(value, &loc)) | 1515 if (!tree()->FindGreatestLessThan(value, &loc)) |
| 1496 return OutSet::empty(); | 1516 return empty(); |
| 1497 Entry* entry = &loc.value(); | 1517 Entry* entry = &loc.value(); |
| 1498 if (value <= entry->to()) | 1518 if (value <= entry->to()) |
| 1499 return entry->out_set(); | 1519 return entry->out_set(); |
| 1500 else | 1520 else |
| 1501 return OutSet::empty(); | 1521 return empty(); |
| 1502 } | 1522 } |
| 1503 | 1523 |
| 1504 | 1524 |
| 1505 // ------------------------------------------------------------------- | 1525 // ------------------------------------------------------------------- |
| 1506 // Analysis | 1526 // Analysis |
| 1507 | 1527 |
| 1508 | 1528 |
| 1509 class Analysis: public NodeVisitor { | 1529 class Analysis: public NodeVisitor { |
| 1510 public: | 1530 public: |
| 1511 Analysis(RegExpCompiler* compiler) | 1531 Analysis(RegExpCompiler* compiler) |
| (...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1626 RegExpNode* RegExpEngine::Compile(RegExpParseResult* input) { | 1646 RegExpNode* RegExpEngine::Compile(RegExpParseResult* input) { |
| 1627 RegExpCompiler compiler(input->capture_count); | 1647 RegExpCompiler compiler(input->capture_count); |
| 1628 RegExpNode* node = compiler.Compile(input->tree, | 1648 RegExpNode* node = compiler.Compile(input->tree, |
| 1629 EndNode::GetAccept(), | 1649 EndNode::GetAccept(), |
| 1630 EndNode::GetBacktrack()); | 1650 EndNode::GetBacktrack()); |
| 1631 return node; | 1651 return node; |
| 1632 } | 1652 } |
| 1633 | 1653 |
| 1634 | 1654 |
| 1635 }} // namespace v8::internal | 1655 }} // namespace v8::internal |
| OLD | NEW |