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 | |
1267 | 1234 |
1268 PreParser::Expression PreParser::ParseObjectLiteral(bool* ok) { | 1235 PreParser::Expression PreParser::ParseObjectLiteral(bool* ok) { |
1269 // ObjectLiteral :: | 1236 // ObjectLiteral :: |
1270 // '{' ( | 1237 // '{' ( |
1271 // ((IdentifierName | String | Number) ':' AssignmentExpression) | 1238 // ((IdentifierName | String | Number) ':' AssignmentExpression) |
1272 // | (('get' | 'set') (IdentifierName | String | Number) FunctionLiteral) | 1239 // | (('get' | 'set') (IdentifierName | String | Number) FunctionLiteral) |
1273 // )*[','] '}' | 1240 // )*[','] '}' |
1274 | 1241 |
| 1242 i::ObjectLiteralChecker<PreParser> checker(this, scanner_, language_mode()); |
| 1243 |
1275 Expect(i::Token::LBRACE, CHECK_OK); | 1244 Expect(i::Token::LBRACE, CHECK_OK); |
1276 DuplicateFinder duplicate_finder(scanner_->unicode_cache()); | |
1277 while (peek() != i::Token::RBRACE) { | 1245 while (peek() != i::Token::RBRACE) { |
1278 i::Token::Value next = peek(); | 1246 i::Token::Value next = peek(); |
1279 switch (next) { | 1247 switch (next) { |
1280 case i::Token::IDENTIFIER: | 1248 case i::Token::IDENTIFIER: |
1281 case i::Token::FUTURE_RESERVED_WORD: | 1249 case i::Token::FUTURE_RESERVED_WORD: |
1282 case i::Token::FUTURE_STRICT_RESERVED_WORD: { | 1250 case i::Token::FUTURE_STRICT_RESERVED_WORD: { |
1283 bool is_getter = false; | 1251 bool is_getter = false; |
1284 bool is_setter = false; | 1252 bool is_setter = false; |
1285 ParseIdentifierNameOrGetOrSet(&is_getter, &is_setter, CHECK_OK); | 1253 ParseIdentifierNameOrGetOrSet(&is_getter, &is_setter, CHECK_OK); |
1286 if ((is_getter || is_setter) && peek() != i::Token::COLON) { | 1254 if ((is_getter || is_setter) && peek() != i::Token::COLON) { |
1287 i::Token::Value name = Next(); | 1255 i::Token::Value name = Next(); |
1288 bool is_keyword = i::Token::IsKeyword(name); | 1256 bool is_keyword = i::Token::IsKeyword(name); |
1289 if (name != i::Token::IDENTIFIER && | 1257 if (name != i::Token::IDENTIFIER && |
1290 name != i::Token::FUTURE_RESERVED_WORD && | 1258 name != i::Token::FUTURE_RESERVED_WORD && |
1291 name != i::Token::FUTURE_STRICT_RESERVED_WORD && | 1259 name != i::Token::FUTURE_STRICT_RESERVED_WORD && |
1292 name != i::Token::NUMBER && | 1260 name != i::Token::NUMBER && |
1293 name != i::Token::STRING && | 1261 name != i::Token::STRING && |
1294 !is_keyword) { | 1262 !is_keyword) { |
1295 *ok = false; | 1263 *ok = false; |
1296 return Expression::Default(); | 1264 return Expression::Default(); |
1297 } | 1265 } |
1298 if (!is_keyword) { | 1266 if (!is_keyword) { |
1299 LogSymbol(); | 1267 LogSymbol(); |
1300 } | 1268 } |
1301 PropertyType type = is_getter ? kGetterProperty : kSetterProperty; | 1269 i::PropertyKind type = is_getter ? i::kGetterProperty |
1302 CheckDuplicate(&duplicate_finder, name, type, CHECK_OK); | 1270 : i::kSetterProperty; |
| 1271 checker.CheckProperty(name, type, CHECK_OK); |
1303 ParseFunctionLiteral(false, CHECK_OK); | 1272 ParseFunctionLiteral(false, CHECK_OK); |
1304 if (peek() != i::Token::RBRACE) { | 1273 if (peek() != i::Token::RBRACE) { |
1305 Expect(i::Token::COMMA, CHECK_OK); | 1274 Expect(i::Token::COMMA, CHECK_OK); |
1306 } | 1275 } |
1307 continue; // restart the while | 1276 continue; // restart the while |
1308 } | 1277 } |
1309 CheckDuplicate(&duplicate_finder, next, kValueProperty, CHECK_OK); | 1278 checker.CheckProperty(next, i::kValueProperty, CHECK_OK); |
1310 break; | 1279 break; |
1311 } | 1280 } |
1312 case i::Token::STRING: | 1281 case i::Token::STRING: |
1313 Consume(next); | 1282 Consume(next); |
1314 CheckDuplicate(&duplicate_finder, next, kValueProperty, CHECK_OK); | 1283 checker.CheckProperty(next, i::kValueProperty, CHECK_OK); |
1315 GetStringSymbol(); | 1284 GetStringSymbol(); |
1316 break; | 1285 break; |
1317 case i::Token::NUMBER: | 1286 case i::Token::NUMBER: |
1318 Consume(next); | 1287 Consume(next); |
1319 CheckDuplicate(&duplicate_finder, next, kValueProperty, CHECK_OK); | 1288 checker.CheckProperty(next, i::kValueProperty, CHECK_OK); |
1320 break; | 1289 break; |
1321 default: | 1290 default: |
1322 if (i::Token::IsKeyword(next)) { | 1291 if (i::Token::IsKeyword(next)) { |
1323 Consume(next); | 1292 Consume(next); |
1324 CheckDuplicate(&duplicate_finder, next, kValueProperty, CHECK_OK); | 1293 checker.CheckProperty(next, i::kValueProperty, CHECK_OK); |
1325 } else { | 1294 } else { |
1326 // Unexpected token. | 1295 // Unexpected token. |
1327 *ok = false; | 1296 *ok = false; |
1328 return Expression::Default(); | 1297 return Expression::Default(); |
1329 } | 1298 } |
1330 } | 1299 } |
1331 | 1300 |
1332 Expect(i::Token::COLON, CHECK_OK); | 1301 Expect(i::Token::COLON, CHECK_OK); |
1333 ParseAssignmentExpression(true, CHECK_OK); | 1302 ParseAssignmentExpression(true, CHECK_OK); |
1334 | 1303 |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1395 // Parse function body. | 1364 // Parse function body. |
1396 ScopeType outer_scope_type = scope_->type(); | 1365 ScopeType outer_scope_type = scope_->type(); |
1397 bool inside_with = scope_->IsInsideWith(); | 1366 bool inside_with = scope_->IsInsideWith(); |
1398 Scope function_scope(&scope_, kFunctionScope); | 1367 Scope function_scope(&scope_, kFunctionScope); |
1399 function_scope.set_is_generator(is_generator); | 1368 function_scope.set_is_generator(is_generator); |
1400 // FormalParameterList :: | 1369 // FormalParameterList :: |
1401 // '(' (Identifier)*[','] ')' | 1370 // '(' (Identifier)*[','] ')' |
1402 Expect(i::Token::LPAREN, CHECK_OK); | 1371 Expect(i::Token::LPAREN, CHECK_OK); |
1403 int start_position = scanner_->location().beg_pos; | 1372 int start_position = scanner_->location().beg_pos; |
1404 bool done = (peek() == i::Token::RPAREN); | 1373 bool done = (peek() == i::Token::RPAREN); |
1405 DuplicateFinder duplicate_finder(scanner_->unicode_cache()); | 1374 i::DuplicateFinder duplicate_finder(scanner_->unicode_cache()); |
1406 while (!done) { | 1375 while (!done) { |
1407 Identifier id = ParseIdentifier(CHECK_OK); | 1376 Identifier id = ParseIdentifier(CHECK_OK); |
1408 if (!id.IsValidStrictVariable()) { | 1377 if (!id.IsValidStrictVariable()) { |
1409 StrictModeIdentifierViolation(scanner_->location(), | 1378 StrictModeIdentifierViolation(scanner_->location(), |
1410 "strict_param_name", | 1379 "strict_param_name", |
1411 id, | 1380 id, |
1412 CHECK_OK); | 1381 CHECK_OK); |
1413 } | 1382 } |
1414 int prev_value; | 1383 int prev_value; |
1415 if (scanner_->is_literal_ascii()) { | 1384 if (scanner_->is_literal_ascii()) { |
(...skipping 271 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1687 | 1656 |
1688 | 1657 |
1689 bool PreParser::peek_any_identifier() { | 1658 bool PreParser::peek_any_identifier() { |
1690 i::Token::Value next = peek(); | 1659 i::Token::Value next = peek(); |
1691 return next == i::Token::IDENTIFIER || | 1660 return next == i::Token::IDENTIFIER || |
1692 next == i::Token::FUTURE_RESERVED_WORD || | 1661 next == i::Token::FUTURE_RESERVED_WORD || |
1693 next == i::Token::FUTURE_STRICT_RESERVED_WORD || | 1662 next == i::Token::FUTURE_STRICT_RESERVED_WORD || |
1694 next == i::Token::YIELD; | 1663 next == i::Token::YIELD; |
1695 } | 1664 } |
1696 | 1665 |
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 } | |
1832 } } // v8::preparser | 1666 } } // v8::preparser |
OLD | NEW |