| 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 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 58 PreParser::PreParseResult PreParser::PreParseLazyFunction( | 58 PreParser::PreParseResult PreParser::PreParseLazyFunction( |
| 59 i::LanguageMode mode, bool is_generator, i::ParserRecorder* log) { | 59 i::LanguageMode mode, bool is_generator, i::ParserRecorder* log) { |
| 60 log_ = log; | 60 log_ = log; |
| 61 // Lazy functions always have trivial outer scopes (no with/catch scopes). | 61 // Lazy functions always have trivial outer scopes (no with/catch scopes). |
| 62 Scope top_scope(&scope_, kTopLevelScope); | 62 Scope top_scope(&scope_, kTopLevelScope); |
| 63 set_language_mode(mode); | 63 set_language_mode(mode); |
| 64 Scope function_scope(&scope_, kFunctionScope); | 64 Scope function_scope(&scope_, kFunctionScope); |
| 65 function_scope.set_is_generator(is_generator); | 65 function_scope.set_is_generator(is_generator); |
| 66 ASSERT_EQ(i::Token::LBRACE, scanner()->current_token()); | 66 ASSERT_EQ(i::Token::LBRACE, scanner()->current_token()); |
| 67 bool ok = true; | 67 bool ok = true; |
| 68 int start_position = scanner()->peek_location().beg_pos; | 68 int start_position = peek_position(); |
| 69 ParseLazyFunctionLiteralBody(&ok); | 69 ParseLazyFunctionLiteralBody(&ok); |
| 70 if (stack_overflow()) return kPreParseStackOverflow; | 70 if (stack_overflow()) return kPreParseStackOverflow; |
| 71 if (!ok) { | 71 if (!ok) { |
| 72 ReportUnexpectedToken(scanner()->current_token()); | 72 ReportUnexpectedToken(scanner()->current_token()); |
| 73 } else { | 73 } else { |
| 74 ASSERT_EQ(i::Token::RBRACE, scanner()->peek()); | 74 ASSERT_EQ(i::Token::RBRACE, scanner()->peek()); |
| 75 if (!is_classic_mode()) { | 75 if (!is_classic_mode()) { |
| 76 int end_pos = scanner()->location().end_pos; | 76 int end_pos = scanner()->location().end_pos; |
| 77 CheckOctalLiteral(start_position, end_pos, &ok); | 77 CheckOctalLiteral(start_position, end_pos, &ok); |
| 78 if (ok) { | 78 if (ok) { |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 122 case i::Token::FUTURE_STRICT_RESERVED_WORD: | 122 case i::Token::FUTURE_STRICT_RESERVED_WORD: |
| 123 return ReportMessageAt(source_location, | 123 return ReportMessageAt(source_location, |
| 124 "unexpected_strict_reserved", NULL); | 124 "unexpected_strict_reserved", NULL); |
| 125 default: | 125 default: |
| 126 const char* name = i::Token::String(token); | 126 const char* name = i::Token::String(token); |
| 127 ReportMessageAt(source_location, "unexpected_token", name); | 127 ReportMessageAt(source_location, "unexpected_token", name); |
| 128 } | 128 } |
| 129 } | 129 } |
| 130 | 130 |
| 131 | 131 |
| 132 // Checks whether octal literal last seen is between beg_pos and end_pos. | |
| 133 // If so, reports an error. | |
| 134 void PreParser::CheckOctalLiteral(int beg_pos, int end_pos, bool* ok) { | |
| 135 i::Scanner::Location octal = scanner()->octal_position(); | |
| 136 if (beg_pos <= octal.beg_pos && octal.end_pos <= end_pos) { | |
| 137 ReportMessageAt(octal, "strict_octal_literal", NULL); | |
| 138 scanner()->clear_octal_position(); | |
| 139 *ok = false; | |
| 140 } | |
| 141 } | |
| 142 | |
| 143 | |
| 144 #define CHECK_OK ok); \ | 132 #define CHECK_OK ok); \ |
| 145 if (!*ok) return kUnknownSourceElements; \ | 133 if (!*ok) return kUnknownSourceElements; \ |
| 146 ((void)0 | 134 ((void)0 |
| 147 #define DUMMY ) // to make indentation work | 135 #define DUMMY ) // to make indentation work |
| 148 #undef DUMMY | 136 #undef DUMMY |
| 149 | 137 |
| 150 | 138 |
| 151 PreParser::Statement PreParser::ParseSourceElement(bool* ok) { | 139 PreParser::Statement PreParser::ParseSourceElement(bool* ok) { |
| 152 // (Ecma 262 5th Edition, clause 14): | 140 // (Ecma 262 5th Edition, clause 14): |
| 153 // SourceElement: | 141 // SourceElement: |
| (...skipping 498 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 652 Expect(i::Token::WHILE, CHECK_OK); | 640 Expect(i::Token::WHILE, CHECK_OK); |
| 653 Expect(i::Token::LPAREN, CHECK_OK); | 641 Expect(i::Token::LPAREN, CHECK_OK); |
| 654 ParseExpression(true, CHECK_OK); | 642 ParseExpression(true, CHECK_OK); |
| 655 Expect(i::Token::RPAREN, CHECK_OK); | 643 Expect(i::Token::RPAREN, CHECK_OK); |
| 656 ParseStatement(ok); | 644 ParseStatement(ok); |
| 657 return Statement::Default(); | 645 return Statement::Default(); |
| 658 } | 646 } |
| 659 | 647 |
| 660 | 648 |
| 661 bool PreParser::CheckInOrOf(bool accept_OF) { | 649 bool PreParser::CheckInOrOf(bool accept_OF) { |
| 662 if (peek() == i::Token::IN || | 650 if (Check(Token::IN) || |
| 663 (allow_for_of() && accept_OF && peek() == i::Token::IDENTIFIER && | 651 (allow_for_of() && accept_OF && |
| 664 scanner()->is_next_contextual_keyword(v8::internal::CStrVector("of")))) { | 652 CheckContextualKeyword(CStrVector("of")))) { |
| 665 Next(); | |
| 666 return true; | 653 return true; |
| 667 } | 654 } |
| 668 return false; | 655 return false; |
| 669 } | 656 } |
| 670 | 657 |
| 671 | 658 |
| 672 PreParser::Statement PreParser::ParseForStatement(bool* ok) { | 659 PreParser::Statement PreParser::ParseForStatement(bool* ok) { |
| 673 // ForStatement :: | 660 // ForStatement :: |
| 674 // 'for' '(' Expression? ';' Expression? ';' Expression? ')' Statement | 661 // 'for' '(' Expression? ';' Expression? ';' Expression? ')' Statement |
| 675 | 662 |
| (...skipping 218 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 894 // In parsing the first assignment expression in conditional | 881 // In parsing the first assignment expression in conditional |
| 895 // expressions we always accept the 'in' keyword; see ECMA-262, | 882 // expressions we always accept the 'in' keyword; see ECMA-262, |
| 896 // section 11.12, page 58. | 883 // section 11.12, page 58. |
| 897 ParseAssignmentExpression(true, CHECK_OK); | 884 ParseAssignmentExpression(true, CHECK_OK); |
| 898 Expect(i::Token::COLON, CHECK_OK); | 885 Expect(i::Token::COLON, CHECK_OK); |
| 899 ParseAssignmentExpression(accept_IN, CHECK_OK); | 886 ParseAssignmentExpression(accept_IN, CHECK_OK); |
| 900 return Expression::Default(); | 887 return Expression::Default(); |
| 901 } | 888 } |
| 902 | 889 |
| 903 | 890 |
| 904 int PreParser::Precedence(i::Token::Value tok, bool accept_IN) { | |
| 905 if (tok == i::Token::IN && !accept_IN) | |
| 906 return 0; // 0 precedence will terminate binary expression parsing | |
| 907 | |
| 908 return i::Token::Precedence(tok); | |
| 909 } | |
| 910 | |
| 911 | |
| 912 // Precedence >= 4 | 891 // Precedence >= 4 |
| 913 PreParser::Expression PreParser::ParseBinaryExpression(int prec, | 892 PreParser::Expression PreParser::ParseBinaryExpression(int prec, |
| 914 bool accept_IN, | 893 bool accept_IN, |
| 915 bool* ok) { | 894 bool* ok) { |
| 916 Expression result = ParseUnaryExpression(CHECK_OK); | 895 Expression result = ParseUnaryExpression(CHECK_OK); |
| 917 for (int prec1 = Precedence(peek(), accept_IN); prec1 >= prec; prec1--) { | 896 for (int prec1 = Precedence(peek(), accept_IN); prec1 >= prec; prec1--) { |
| 918 // prec1 >= 4 | 897 // prec1 >= 4 |
| 919 while (Precedence(peek(), accept_IN) == prec1) { | 898 while (Precedence(peek(), accept_IN) == prec1) { |
| 920 Next(); | 899 Next(); |
| 921 ParseBinaryExpression(prec1 + 1, accept_IN, CHECK_OK); | 900 ParseBinaryExpression(prec1 + 1, accept_IN, CHECK_OK); |
| (...skipping 309 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1231 } | 1210 } |
| 1232 | 1211 |
| 1233 | 1212 |
| 1234 PreParser::Expression PreParser::ParseObjectLiteral(bool* ok) { | 1213 PreParser::Expression PreParser::ParseObjectLiteral(bool* ok) { |
| 1235 // ObjectLiteral :: | 1214 // ObjectLiteral :: |
| 1236 // '{' ( | 1215 // '{' ( |
| 1237 // ((IdentifierName | String | Number) ':' AssignmentExpression) | 1216 // ((IdentifierName | String | Number) ':' AssignmentExpression) |
| 1238 // | (('get' | 'set') (IdentifierName | String | Number) FunctionLiteral) | 1217 // | (('get' | 'set') (IdentifierName | String | Number) FunctionLiteral) |
| 1239 // )*[','] '}' | 1218 // )*[','] '}' |
| 1240 | 1219 |
| 1241 i::ObjectLiteralChecker<PreParser> checker(this, scanner(), language_mode()); | 1220 ObjectLiteralChecker checker(this, language_mode()); |
| 1242 | 1221 |
| 1243 Expect(i::Token::LBRACE, CHECK_OK); | 1222 Expect(i::Token::LBRACE, CHECK_OK); |
| 1244 while (peek() != i::Token::RBRACE) { | 1223 while (peek() != i::Token::RBRACE) { |
| 1245 i::Token::Value next = peek(); | 1224 i::Token::Value next = peek(); |
| 1246 switch (next) { | 1225 switch (next) { |
| 1247 case i::Token::IDENTIFIER: | 1226 case i::Token::IDENTIFIER: |
| 1248 case i::Token::FUTURE_RESERVED_WORD: | 1227 case i::Token::FUTURE_RESERVED_WORD: |
| 1249 case i::Token::FUTURE_STRICT_RESERVED_WORD: { | 1228 case i::Token::FUTURE_STRICT_RESERVED_WORD: { |
| 1250 bool is_getter = false; | 1229 bool is_getter = false; |
| 1251 bool is_setter = false; | 1230 bool is_setter = false; |
| 1252 ParseIdentifierNameOrGetOrSet(&is_getter, &is_setter, CHECK_OK); | 1231 ParseIdentifierNameOrGetOrSet(&is_getter, &is_setter, CHECK_OK); |
| 1253 if ((is_getter || is_setter) && peek() != i::Token::COLON) { | 1232 if ((is_getter || is_setter) && peek() != i::Token::COLON) { |
| 1254 i::Token::Value name = Next(); | 1233 i::Token::Value name = Next(); |
| 1255 bool is_keyword = i::Token::IsKeyword(name); | 1234 bool is_keyword = i::Token::IsKeyword(name); |
| 1256 if (name != i::Token::IDENTIFIER && | 1235 if (name != i::Token::IDENTIFIER && |
| 1257 name != i::Token::FUTURE_RESERVED_WORD && | 1236 name != i::Token::FUTURE_RESERVED_WORD && |
| 1258 name != i::Token::FUTURE_STRICT_RESERVED_WORD && | 1237 name != i::Token::FUTURE_STRICT_RESERVED_WORD && |
| 1259 name != i::Token::NUMBER && | 1238 name != i::Token::NUMBER && |
| 1260 name != i::Token::STRING && | 1239 name != i::Token::STRING && |
| 1261 !is_keyword) { | 1240 !is_keyword) { |
| 1262 *ok = false; | 1241 *ok = false; |
| 1263 return Expression::Default(); | 1242 return Expression::Default(); |
| 1264 } | 1243 } |
| 1265 if (!is_keyword) { | 1244 if (!is_keyword) { |
| 1266 LogSymbol(); | 1245 LogSymbol(); |
| 1267 } | 1246 } |
| 1268 i::PropertyKind type = is_getter ? i::kGetterProperty | 1247 PropertyKind type = is_getter ? kGetterProperty : kSetterProperty; |
| 1269 : i::kSetterProperty; | |
| 1270 checker.CheckProperty(name, type, CHECK_OK); | 1248 checker.CheckProperty(name, type, CHECK_OK); |
| 1271 ParseFunctionLiteral(false, CHECK_OK); | 1249 ParseFunctionLiteral(false, CHECK_OK); |
| 1272 if (peek() != i::Token::RBRACE) { | 1250 if (peek() != i::Token::RBRACE) { |
| 1273 Expect(i::Token::COMMA, CHECK_OK); | 1251 Expect(i::Token::COMMA, CHECK_OK); |
| 1274 } | 1252 } |
| 1275 continue; // restart the while | 1253 continue; // restart the while |
| 1276 } | 1254 } |
| 1277 checker.CheckProperty(next, i::kValueProperty, CHECK_OK); | 1255 checker.CheckProperty(next, kValueProperty, CHECK_OK); |
| 1278 break; | 1256 break; |
| 1279 } | 1257 } |
| 1280 case i::Token::STRING: | 1258 case i::Token::STRING: |
| 1281 Consume(next); | 1259 Consume(next); |
| 1282 checker.CheckProperty(next, i::kValueProperty, CHECK_OK); | 1260 checker.CheckProperty(next, kValueProperty, CHECK_OK); |
| 1283 GetStringSymbol(); | 1261 GetStringSymbol(); |
| 1284 break; | 1262 break; |
| 1285 case i::Token::NUMBER: | 1263 case i::Token::NUMBER: |
| 1286 Consume(next); | 1264 Consume(next); |
| 1287 checker.CheckProperty(next, i::kValueProperty, CHECK_OK); | 1265 checker.CheckProperty(next, kValueProperty, CHECK_OK); |
| 1288 break; | 1266 break; |
| 1289 default: | 1267 default: |
| 1290 if (i::Token::IsKeyword(next)) { | 1268 if (i::Token::IsKeyword(next)) { |
| 1291 Consume(next); | 1269 Consume(next); |
| 1292 checker.CheckProperty(next, i::kValueProperty, CHECK_OK); | 1270 checker.CheckProperty(next, kValueProperty, CHECK_OK); |
| 1293 } else { | 1271 } else { |
| 1294 // Unexpected token. | 1272 // Unexpected token. |
| 1295 *ok = false; | 1273 *ok = false; |
| 1296 return Expression::Default(); | 1274 return Expression::Default(); |
| 1297 } | 1275 } |
| 1298 } | 1276 } |
| 1299 | 1277 |
| 1300 Expect(i::Token::COLON, CHECK_OK); | 1278 Expect(i::Token::COLON, CHECK_OK); |
| 1301 ParseAssignmentExpression(true, CHECK_OK); | 1279 ParseAssignmentExpression(true, CHECK_OK); |
| 1302 | 1280 |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1361 // '(' FormalParameterList? ')' '{' FunctionBody '}' | 1339 // '(' FormalParameterList? ')' '{' FunctionBody '}' |
| 1362 | 1340 |
| 1363 // Parse function body. | 1341 // Parse function body. |
| 1364 ScopeType outer_scope_type = scope_->type(); | 1342 ScopeType outer_scope_type = scope_->type(); |
| 1365 bool inside_with = scope_->IsInsideWith(); | 1343 bool inside_with = scope_->IsInsideWith(); |
| 1366 Scope function_scope(&scope_, kFunctionScope); | 1344 Scope function_scope(&scope_, kFunctionScope); |
| 1367 function_scope.set_is_generator(is_generator); | 1345 function_scope.set_is_generator(is_generator); |
| 1368 // FormalParameterList :: | 1346 // FormalParameterList :: |
| 1369 // '(' (Identifier)*[','] ')' | 1347 // '(' (Identifier)*[','] ')' |
| 1370 Expect(i::Token::LPAREN, CHECK_OK); | 1348 Expect(i::Token::LPAREN, CHECK_OK); |
| 1371 int start_position = scanner()->location().beg_pos; | 1349 int start_position = position(); |
| 1372 bool done = (peek() == i::Token::RPAREN); | 1350 bool done = (peek() == i::Token::RPAREN); |
| 1373 i::DuplicateFinder duplicate_finder(scanner()->unicode_cache()); | 1351 i::DuplicateFinder duplicate_finder(scanner()->unicode_cache()); |
| 1374 while (!done) { | 1352 while (!done) { |
| 1375 Identifier id = ParseIdentifier(CHECK_OK); | 1353 Identifier id = ParseIdentifier(CHECK_OK); |
| 1376 if (!id.IsValidStrictVariable()) { | 1354 if (!id.IsValidStrictVariable()) { |
| 1377 StrictModeIdentifierViolation(scanner()->location(), | 1355 StrictModeIdentifierViolation(scanner()->location(), |
| 1378 "strict_param_name", | 1356 "strict_param_name", |
| 1379 id, | 1357 id, |
| 1380 CHECK_OK); | 1358 CHECK_OK); |
| 1381 } | 1359 } |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1421 CheckOctalLiteral(start_position, end_position, CHECK_OK); | 1399 CheckOctalLiteral(start_position, end_position, CHECK_OK); |
| 1422 CheckDelayedStrictModeViolation(start_position, end_position, CHECK_OK); | 1400 CheckDelayedStrictModeViolation(start_position, end_position, CHECK_OK); |
| 1423 return Expression::StrictFunction(); | 1401 return Expression::StrictFunction(); |
| 1424 } | 1402 } |
| 1425 | 1403 |
| 1426 return Expression::Default(); | 1404 return Expression::Default(); |
| 1427 } | 1405 } |
| 1428 | 1406 |
| 1429 | 1407 |
| 1430 void PreParser::ParseLazyFunctionLiteralBody(bool* ok) { | 1408 void PreParser::ParseLazyFunctionLiteralBody(bool* ok) { |
| 1431 int body_start = scanner()->location().beg_pos; | 1409 int body_start = position(); |
| 1432 log_->PauseRecording(); | 1410 log_->PauseRecording(); |
| 1433 ParseSourceElements(i::Token::RBRACE, ok); | 1411 ParseSourceElements(i::Token::RBRACE, ok); |
| 1434 log_->ResumeRecording(); | 1412 log_->ResumeRecording(); |
| 1435 if (!*ok) return; | 1413 if (!*ok) return; |
| 1436 | 1414 |
| 1437 // Position right after terminal '}'. | 1415 // Position right after terminal '}'. |
| 1438 ASSERT_EQ(i::Token::RBRACE, scanner()->peek()); | 1416 ASSERT_EQ(i::Token::RBRACE, scanner()->peek()); |
| 1439 int body_end = scanner()->peek_location().end_pos; | 1417 int body_end = scanner()->peek_location().end_pos; |
| 1440 log_->LogFunction(body_start, body_end, | 1418 log_->LogFunction(body_start, body_end, |
| 1441 scope_->materialized_literal_count(), | 1419 scope_->materialized_literal_count(), |
| (...skipping 13 matching lines...) Expand all Loading... |
| 1455 ParseIdentifier(CHECK_OK); | 1433 ParseIdentifier(CHECK_OK); |
| 1456 ParseArguments(ok); | 1434 ParseArguments(ok); |
| 1457 | 1435 |
| 1458 return Expression::Default(); | 1436 return Expression::Default(); |
| 1459 } | 1437 } |
| 1460 | 1438 |
| 1461 #undef CHECK_OK | 1439 #undef CHECK_OK |
| 1462 | 1440 |
| 1463 | 1441 |
| 1464 void PreParser::LogSymbol() { | 1442 void PreParser::LogSymbol() { |
| 1465 int identifier_pos = scanner()->location().beg_pos; | 1443 int identifier_pos = position(); |
| 1466 if (scanner()->is_literal_ascii()) { | 1444 if (scanner()->is_literal_ascii()) { |
| 1467 log_->LogAsciiSymbol(identifier_pos, scanner()->literal_ascii_string()); | 1445 log_->LogAsciiSymbol(identifier_pos, scanner()->literal_ascii_string()); |
| 1468 } else { | 1446 } else { |
| 1469 log_->LogUtf16Symbol(identifier_pos, scanner()->literal_utf16_string()); | 1447 log_->LogUtf16Symbol(identifier_pos, scanner()->literal_utf16_string()); |
| 1470 } | 1448 } |
| 1471 } | 1449 } |
| 1472 | 1450 |
| 1473 | 1451 |
| 1474 PreParser::Expression PreParser::GetStringSymbol() { | 1452 PreParser::Expression PreParser::GetStringSymbol() { |
| 1475 const int kUseStrictLength = 10; | 1453 const int kUseStrictLength = 10; |
| (...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1595 return; | 1573 return; |
| 1596 } | 1574 } |
| 1597 strict_mode_violation_location_ = location; | 1575 strict_mode_violation_location_ = location; |
| 1598 strict_mode_violation_type_ = type; | 1576 strict_mode_violation_type_ = type; |
| 1599 } | 1577 } |
| 1600 | 1578 |
| 1601 | 1579 |
| 1602 PreParser::Identifier PreParser::ParseIdentifierName(bool* ok) { | 1580 PreParser::Identifier PreParser::ParseIdentifierName(bool* ok) { |
| 1603 i::Token::Value next = Next(); | 1581 i::Token::Value next = Next(); |
| 1604 if (i::Token::IsKeyword(next)) { | 1582 if (i::Token::IsKeyword(next)) { |
| 1605 int pos = scanner()->location().beg_pos; | 1583 int pos = position(); |
| 1606 const char* keyword = i::Token::String(next); | 1584 const char* keyword = i::Token::String(next); |
| 1607 log_->LogAsciiSymbol(pos, i::Vector<const char>(keyword, | 1585 log_->LogAsciiSymbol(pos, i::Vector<const char>(keyword, |
| 1608 i::StrLength(keyword))); | 1586 i::StrLength(keyword))); |
| 1609 return Identifier::Default(); | 1587 return Identifier::Default(); |
| 1610 } | 1588 } |
| 1611 if (next == i::Token::IDENTIFIER || | 1589 if (next == i::Token::IDENTIFIER || |
| 1612 next == i::Token::FUTURE_RESERVED_WORD || | 1590 next == i::Token::FUTURE_RESERVED_WORD || |
| 1613 next == i::Token::FUTURE_STRICT_RESERVED_WORD) { | 1591 next == i::Token::FUTURE_STRICT_RESERVED_WORD) { |
| 1614 return GetIdentifierSymbol(); | 1592 return GetIdentifierSymbol(); |
| 1615 } | 1593 } |
| (...skipping 14 matching lines...) Expand all Loading... |
| 1630 if (scanner()->is_literal_ascii() && | 1608 if (scanner()->is_literal_ascii() && |
| 1631 scanner()->literal_length() == 3) { | 1609 scanner()->literal_length() == 3) { |
| 1632 const char* token = scanner()->literal_ascii_string().start(); | 1610 const char* token = scanner()->literal_ascii_string().start(); |
| 1633 *is_get = strncmp(token, "get", 3) == 0; | 1611 *is_get = strncmp(token, "get", 3) == 0; |
| 1634 *is_set = !*is_get && strncmp(token, "set", 3) == 0; | 1612 *is_set = !*is_get && strncmp(token, "set", 3) == 0; |
| 1635 } | 1613 } |
| 1636 return result; | 1614 return result; |
| 1637 } | 1615 } |
| 1638 | 1616 |
| 1639 | 1617 |
| 1618 void PreParser::ObjectLiteralChecker::CheckProperty(Token::Value property, |
| 1619 PropertyKind type, |
| 1620 bool* ok) { |
| 1621 int old; |
| 1622 if (property == Token::NUMBER) { |
| 1623 old = finder_.AddNumber(scanner()->literal_ascii_string(), type); |
| 1624 } else if (scanner()->is_literal_ascii()) { |
| 1625 old = finder_.AddAsciiSymbol(scanner()->literal_ascii_string(), type); |
| 1626 } else { |
| 1627 old = finder_.AddUtf16Symbol(scanner()->literal_utf16_string(), type); |
| 1628 } |
| 1629 PropertyKind old_type = static_cast<PropertyKind>(old); |
| 1630 if (HasConflict(old_type, type)) { |
| 1631 if (IsDataDataConflict(old_type, type)) { |
| 1632 // Both are data properties. |
| 1633 if (language_mode_ == CLASSIC_MODE) return; |
| 1634 parser()->ReportMessageAt(scanner()->location(), |
| 1635 "strict_duplicate_property"); |
| 1636 } else if (IsDataAccessorConflict(old_type, type)) { |
| 1637 // Both a data and an accessor property with the same name. |
| 1638 parser()->ReportMessageAt(scanner()->location(), |
| 1639 "accessor_data_property"); |
| 1640 } else { |
| 1641 ASSERT(IsAccessorAccessorConflict(old_type, type)); |
| 1642 // Both accessors of the same type. |
| 1643 parser()->ReportMessageAt(scanner()->location(), |
| 1644 "accessor_get_set"); |
| 1645 } |
| 1646 *ok = false; |
| 1647 } |
| 1648 } |
| 1649 |
| 1640 } } // v8::internal | 1650 } } // v8::internal |
| OLD | NEW |