OLD | NEW |
1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 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 1213 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1224 if (peek() != i::Token::RBRACK) { | 1224 if (peek() != i::Token::RBRACK) { |
1225 Expect(i::Token::COMMA, CHECK_OK); | 1225 Expect(i::Token::COMMA, CHECK_OK); |
1226 } | 1226 } |
1227 } | 1227 } |
1228 Expect(i::Token::RBRACK, CHECK_OK); | 1228 Expect(i::Token::RBRACK, CHECK_OK); |
1229 | 1229 |
1230 scope_->NextMaterializedLiteralIndex(); | 1230 scope_->NextMaterializedLiteralIndex(); |
1231 return Expression::Default(); | 1231 return Expression::Default(); |
1232 } | 1232 } |
1233 | 1233 |
| 1234 void PreParser::CheckDuplicate(DuplicateFinder* finder, |
| 1235 i::Token::Value property, |
| 1236 int type, |
| 1237 bool* ok) { |
| 1238 int old_type; |
| 1239 if (property == i::Token::NUMBER) { |
| 1240 old_type = finder->AddNumber(scanner_->literal_ascii_string(), type); |
| 1241 } else if (scanner_->is_literal_ascii()) { |
| 1242 old_type = finder->AddAsciiSymbol(scanner_->literal_ascii_string(), |
| 1243 type); |
| 1244 } else { |
| 1245 old_type = finder->AddUtf16Symbol(scanner_->literal_utf16_string(), type); |
| 1246 } |
| 1247 if (HasConflict(old_type, type)) { |
| 1248 if (IsDataDataConflict(old_type, type)) { |
| 1249 // Both are data properties. |
| 1250 if (is_classic_mode()) return; |
| 1251 ReportMessageAt(scanner_->location(), |
| 1252 "strict_duplicate_property", NULL); |
| 1253 } else if (IsDataAccessorConflict(old_type, type)) { |
| 1254 // Both a data and an accessor property with the same name. |
| 1255 ReportMessageAt(scanner_->location(), |
| 1256 "accessor_data_property", NULL); |
| 1257 } else { |
| 1258 ASSERT(IsAccessorAccessorConflict(old_type, type)); |
| 1259 // Both accessors of the same type. |
| 1260 ReportMessageAt(scanner_->location(), |
| 1261 "accessor_get_set", NULL); |
| 1262 } |
| 1263 *ok = false; |
| 1264 } |
| 1265 } |
| 1266 |
1234 | 1267 |
1235 PreParser::Expression PreParser::ParseObjectLiteral(bool* ok) { | 1268 PreParser::Expression PreParser::ParseObjectLiteral(bool* ok) { |
1236 // ObjectLiteral :: | 1269 // ObjectLiteral :: |
1237 // '{' ( | 1270 // '{' ( |
1238 // ((IdentifierName | String | Number) ':' AssignmentExpression) | 1271 // ((IdentifierName | String | Number) ':' AssignmentExpression) |
1239 // | (('get' | 'set') (IdentifierName | String | Number) FunctionLiteral) | 1272 // | (('get' | 'set') (IdentifierName | String | Number) FunctionLiteral) |
1240 // )*[','] '}' | 1273 // )*[','] '}' |
1241 | 1274 |
1242 i::ObjectLiteralChecker<PreParser> checker(this, scanner_, language_mode()); | |
1243 | |
1244 Expect(i::Token::LBRACE, CHECK_OK); | 1275 Expect(i::Token::LBRACE, CHECK_OK); |
| 1276 DuplicateFinder duplicate_finder(scanner_->unicode_cache()); |
1245 while (peek() != i::Token::RBRACE) { | 1277 while (peek() != i::Token::RBRACE) { |
1246 i::Token::Value next = peek(); | 1278 i::Token::Value next = peek(); |
1247 switch (next) { | 1279 switch (next) { |
1248 case i::Token::IDENTIFIER: | 1280 case i::Token::IDENTIFIER: |
1249 case i::Token::FUTURE_RESERVED_WORD: | 1281 case i::Token::FUTURE_RESERVED_WORD: |
1250 case i::Token::FUTURE_STRICT_RESERVED_WORD: { | 1282 case i::Token::FUTURE_STRICT_RESERVED_WORD: { |
1251 bool is_getter = false; | 1283 bool is_getter = false; |
1252 bool is_setter = false; | 1284 bool is_setter = false; |
1253 ParseIdentifierNameOrGetOrSet(&is_getter, &is_setter, CHECK_OK); | 1285 ParseIdentifierNameOrGetOrSet(&is_getter, &is_setter, CHECK_OK); |
1254 if ((is_getter || is_setter) && peek() != i::Token::COLON) { | 1286 if ((is_getter || is_setter) && peek() != i::Token::COLON) { |
1255 i::Token::Value name = Next(); | 1287 i::Token::Value name = Next(); |
1256 bool is_keyword = i::Token::IsKeyword(name); | 1288 bool is_keyword = i::Token::IsKeyword(name); |
1257 if (name != i::Token::IDENTIFIER && | 1289 if (name != i::Token::IDENTIFIER && |
1258 name != i::Token::FUTURE_RESERVED_WORD && | 1290 name != i::Token::FUTURE_RESERVED_WORD && |
1259 name != i::Token::FUTURE_STRICT_RESERVED_WORD && | 1291 name != i::Token::FUTURE_STRICT_RESERVED_WORD && |
1260 name != i::Token::NUMBER && | 1292 name != i::Token::NUMBER && |
1261 name != i::Token::STRING && | 1293 name != i::Token::STRING && |
1262 !is_keyword) { | 1294 !is_keyword) { |
1263 *ok = false; | 1295 *ok = false; |
1264 return Expression::Default(); | 1296 return Expression::Default(); |
1265 } | 1297 } |
1266 if (!is_keyword) { | 1298 if (!is_keyword) { |
1267 LogSymbol(); | 1299 LogSymbol(); |
1268 } | 1300 } |
1269 i::PropertyKind type = is_getter ? i::kGetterProperty | 1301 PropertyType type = is_getter ? kGetterProperty : kSetterProperty; |
1270 : i::kSetterProperty; | 1302 CheckDuplicate(&duplicate_finder, name, type, CHECK_OK); |
1271 checker.CheckProperty(name, type, CHECK_OK); | |
1272 ParseFunctionLiteral(false, CHECK_OK); | 1303 ParseFunctionLiteral(false, CHECK_OK); |
1273 if (peek() != i::Token::RBRACE) { | 1304 if (peek() != i::Token::RBRACE) { |
1274 Expect(i::Token::COMMA, CHECK_OK); | 1305 Expect(i::Token::COMMA, CHECK_OK); |
1275 } | 1306 } |
1276 continue; // restart the while | 1307 continue; // restart the while |
1277 } | 1308 } |
1278 checker.CheckProperty(next, i::kValueProperty, CHECK_OK); | 1309 CheckDuplicate(&duplicate_finder, next, kValueProperty, CHECK_OK); |
1279 break; | 1310 break; |
1280 } | 1311 } |
1281 case i::Token::STRING: | 1312 case i::Token::STRING: |
1282 Consume(next); | 1313 Consume(next); |
1283 checker.CheckProperty(next, i::kValueProperty, CHECK_OK); | 1314 CheckDuplicate(&duplicate_finder, next, kValueProperty, CHECK_OK); |
1284 GetStringSymbol(); | 1315 GetStringSymbol(); |
1285 break; | 1316 break; |
1286 case i::Token::NUMBER: | 1317 case i::Token::NUMBER: |
1287 Consume(next); | 1318 Consume(next); |
1288 checker.CheckProperty(next, i::kValueProperty, CHECK_OK); | 1319 CheckDuplicate(&duplicate_finder, next, kValueProperty, CHECK_OK); |
1289 break; | 1320 break; |
1290 default: | 1321 default: |
1291 if (i::Token::IsKeyword(next)) { | 1322 if (i::Token::IsKeyword(next)) { |
1292 Consume(next); | 1323 Consume(next); |
1293 checker.CheckProperty(next, i::kValueProperty, CHECK_OK); | 1324 CheckDuplicate(&duplicate_finder, next, kValueProperty, CHECK_OK); |
1294 } else { | 1325 } else { |
1295 // Unexpected token. | 1326 // Unexpected token. |
1296 *ok = false; | 1327 *ok = false; |
1297 return Expression::Default(); | 1328 return Expression::Default(); |
1298 } | 1329 } |
1299 } | 1330 } |
1300 | 1331 |
1301 Expect(i::Token::COLON, CHECK_OK); | 1332 Expect(i::Token::COLON, CHECK_OK); |
1302 ParseAssignmentExpression(true, CHECK_OK); | 1333 ParseAssignmentExpression(true, CHECK_OK); |
1303 | 1334 |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1364 // Parse function body. | 1395 // Parse function body. |
1365 ScopeType outer_scope_type = scope_->type(); | 1396 ScopeType outer_scope_type = scope_->type(); |
1366 bool inside_with = scope_->IsInsideWith(); | 1397 bool inside_with = scope_->IsInsideWith(); |
1367 Scope function_scope(&scope_, kFunctionScope); | 1398 Scope function_scope(&scope_, kFunctionScope); |
1368 function_scope.set_is_generator(is_generator); | 1399 function_scope.set_is_generator(is_generator); |
1369 // FormalParameterList :: | 1400 // FormalParameterList :: |
1370 // '(' (Identifier)*[','] ')' | 1401 // '(' (Identifier)*[','] ')' |
1371 Expect(i::Token::LPAREN, CHECK_OK); | 1402 Expect(i::Token::LPAREN, CHECK_OK); |
1372 int start_position = scanner_->location().beg_pos; | 1403 int start_position = scanner_->location().beg_pos; |
1373 bool done = (peek() == i::Token::RPAREN); | 1404 bool done = (peek() == i::Token::RPAREN); |
1374 i::DuplicateFinder duplicate_finder(scanner_->unicode_cache()); | 1405 DuplicateFinder duplicate_finder(scanner_->unicode_cache()); |
1375 while (!done) { | 1406 while (!done) { |
1376 Identifier id = ParseIdentifier(CHECK_OK); | 1407 Identifier id = ParseIdentifier(CHECK_OK); |
1377 if (!id.IsValidStrictVariable()) { | 1408 if (!id.IsValidStrictVariable()) { |
1378 StrictModeIdentifierViolation(scanner_->location(), | 1409 StrictModeIdentifierViolation(scanner_->location(), |
1379 "strict_param_name", | 1410 "strict_param_name", |
1380 id, | 1411 id, |
1381 CHECK_OK); | 1412 CHECK_OK); |
1382 } | 1413 } |
1383 int prev_value; | 1414 int prev_value; |
1384 if (scanner_->is_literal_ascii()) { | 1415 if (scanner_->is_literal_ascii()) { |
(...skipping 271 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1656 | 1687 |
1657 | 1688 |
1658 bool PreParser::peek_any_identifier() { | 1689 bool PreParser::peek_any_identifier() { |
1659 i::Token::Value next = peek(); | 1690 i::Token::Value next = peek(); |
1660 return next == i::Token::IDENTIFIER || | 1691 return next == i::Token::IDENTIFIER || |
1661 next == i::Token::FUTURE_RESERVED_WORD || | 1692 next == i::Token::FUTURE_RESERVED_WORD || |
1662 next == i::Token::FUTURE_STRICT_RESERVED_WORD || | 1693 next == i::Token::FUTURE_STRICT_RESERVED_WORD || |
1663 next == i::Token::YIELD; | 1694 next == i::Token::YIELD; |
1664 } | 1695 } |
1665 | 1696 |
| 1697 |
| 1698 int DuplicateFinder::AddAsciiSymbol(i::Vector<const char> key, int value) { |
| 1699 return AddSymbol(i::Vector<const byte>::cast(key), true, value); |
| 1700 } |
| 1701 |
| 1702 |
| 1703 int DuplicateFinder::AddUtf16Symbol(i::Vector<const uint16_t> key, int value) { |
| 1704 return AddSymbol(i::Vector<const byte>::cast(key), false, value); |
| 1705 } |
| 1706 |
| 1707 int DuplicateFinder::AddSymbol(i::Vector<const byte> key, |
| 1708 bool is_ascii, |
| 1709 int value) { |
| 1710 uint32_t hash = Hash(key, is_ascii); |
| 1711 byte* encoding = BackupKey(key, is_ascii); |
| 1712 i::HashMap::Entry* entry = map_.Lookup(encoding, hash, true); |
| 1713 int old_value = static_cast<int>(reinterpret_cast<intptr_t>(entry->value)); |
| 1714 entry->value = |
| 1715 reinterpret_cast<void*>(static_cast<intptr_t>(value | old_value)); |
| 1716 return old_value; |
| 1717 } |
| 1718 |
| 1719 |
| 1720 int DuplicateFinder::AddNumber(i::Vector<const char> key, int value) { |
| 1721 ASSERT(key.length() > 0); |
| 1722 // Quick check for already being in canonical form. |
| 1723 if (IsNumberCanonical(key)) { |
| 1724 return AddAsciiSymbol(key, value); |
| 1725 } |
| 1726 |
| 1727 int flags = i::ALLOW_HEX | i::ALLOW_OCTAL | i::ALLOW_IMPLICIT_OCTAL | |
| 1728 i::ALLOW_BINARY; |
| 1729 double double_value = StringToDouble(unicode_constants_, key, flags, 0.0); |
| 1730 int length; |
| 1731 const char* string; |
| 1732 if (!std::isfinite(double_value)) { |
| 1733 string = "Infinity"; |
| 1734 length = 8; // strlen("Infinity"); |
| 1735 } else { |
| 1736 string = DoubleToCString(double_value, |
| 1737 i::Vector<char>(number_buffer_, kBufferSize)); |
| 1738 length = i::StrLength(string); |
| 1739 } |
| 1740 return AddSymbol(i::Vector<const byte>(reinterpret_cast<const byte*>(string), |
| 1741 length), true, value); |
| 1742 } |
| 1743 |
| 1744 |
| 1745 bool DuplicateFinder::IsNumberCanonical(i::Vector<const char> number) { |
| 1746 // Test for a safe approximation of number literals that are already |
| 1747 // in canonical form: max 15 digits, no leading zeroes, except an |
| 1748 // integer part that is a single zero, and no trailing zeros below |
| 1749 // the decimal point. |
| 1750 int pos = 0; |
| 1751 int length = number.length(); |
| 1752 if (number.length() > 15) return false; |
| 1753 if (number[pos] == '0') { |
| 1754 pos++; |
| 1755 } else { |
| 1756 while (pos < length && |
| 1757 static_cast<unsigned>(number[pos] - '0') <= ('9' - '0')) pos++; |
| 1758 } |
| 1759 if (length == pos) return true; |
| 1760 if (number[pos] != '.') return false; |
| 1761 pos++; |
| 1762 bool invalid_last_digit = true; |
| 1763 while (pos < length) { |
| 1764 byte digit = number[pos] - '0'; |
| 1765 if (digit > '9' - '0') return false; |
| 1766 invalid_last_digit = (digit == 0); |
| 1767 pos++; |
| 1768 } |
| 1769 return !invalid_last_digit; |
| 1770 } |
| 1771 |
| 1772 |
| 1773 uint32_t DuplicateFinder::Hash(i::Vector<const byte> key, bool is_ascii) { |
| 1774 // Primitive hash function, almost identical to the one used |
| 1775 // for strings (except that it's seeded by the length and ASCII-ness). |
| 1776 int length = key.length(); |
| 1777 uint32_t hash = (length << 1) | (is_ascii ? 1 : 0) ; |
| 1778 for (int i = 0; i < length; i++) { |
| 1779 uint32_t c = key[i]; |
| 1780 hash = (hash + c) * 1025; |
| 1781 hash ^= (hash >> 6); |
| 1782 } |
| 1783 return hash; |
| 1784 } |
| 1785 |
| 1786 |
| 1787 bool DuplicateFinder::Match(void* first, void* second) { |
| 1788 // Decode lengths. |
| 1789 // Length + ASCII-bit is encoded as base 128, most significant heptet first, |
| 1790 // with a 8th bit being non-zero while there are more heptets. |
| 1791 // The value encodes the number of bytes following, and whether the original |
| 1792 // was ASCII. |
| 1793 byte* s1 = reinterpret_cast<byte*>(first); |
| 1794 byte* s2 = reinterpret_cast<byte*>(second); |
| 1795 uint32_t length_ascii_field = 0; |
| 1796 byte c1; |
| 1797 do { |
| 1798 c1 = *s1; |
| 1799 if (c1 != *s2) return false; |
| 1800 length_ascii_field = (length_ascii_field << 7) | (c1 & 0x7f); |
| 1801 s1++; |
| 1802 s2++; |
| 1803 } while ((c1 & 0x80) != 0); |
| 1804 int length = static_cast<int>(length_ascii_field >> 1); |
| 1805 return memcmp(s1, s2, length) == 0; |
| 1806 } |
| 1807 |
| 1808 |
| 1809 byte* DuplicateFinder::BackupKey(i::Vector<const byte> bytes, |
| 1810 bool is_ascii) { |
| 1811 uint32_t ascii_length = (bytes.length() << 1) | (is_ascii ? 1 : 0); |
| 1812 backing_store_.StartSequence(); |
| 1813 // Emit ascii_length as base-128 encoded number, with the 7th bit set |
| 1814 // on the byte of every heptet except the last, least significant, one. |
| 1815 if (ascii_length >= (1 << 7)) { |
| 1816 if (ascii_length >= (1 << 14)) { |
| 1817 if (ascii_length >= (1 << 21)) { |
| 1818 if (ascii_length >= (1 << 28)) { |
| 1819 backing_store_.Add(static_cast<byte>((ascii_length >> 28) | 0x80)); |
| 1820 } |
| 1821 backing_store_.Add(static_cast<byte>((ascii_length >> 21) | 0x80u)); |
| 1822 } |
| 1823 backing_store_.Add(static_cast<byte>((ascii_length >> 14) | 0x80u)); |
| 1824 } |
| 1825 backing_store_.Add(static_cast<byte>((ascii_length >> 7) | 0x80u)); |
| 1826 } |
| 1827 backing_store_.Add(static_cast<byte>(ascii_length & 0x7f)); |
| 1828 |
| 1829 backing_store_.AddBlock(bytes); |
| 1830 return backing_store_.EndSequence().start(); |
| 1831 } |
1666 } } // v8::preparser | 1832 } } // v8::preparser |
OLD | NEW |