OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #ifndef V8_PREPARSER_H | 5 #ifndef V8_PREPARSER_H |
6 #define V8_PREPARSER_H | 6 #define V8_PREPARSER_H |
7 | 7 |
8 #include "src/v8.h" | 8 #include "src/v8.h" |
9 | 9 |
10 #include "src/bailout-reason.h" | 10 #include "src/bailout-reason.h" |
(...skipping 452 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
463 static int Precedence(Token::Value token, bool accept_IN) { | 463 static int Precedence(Token::Value token, bool accept_IN) { |
464 if (token == Token::IN && !accept_IN) | 464 if (token == Token::IN && !accept_IN) |
465 return 0; // 0 precedence will terminate binary expression parsing | 465 return 0; // 0 precedence will terminate binary expression parsing |
466 return Token::Precedence(token); | 466 return Token::Precedence(token); |
467 } | 467 } |
468 | 468 |
469 typename Traits::Type::Factory* factory() { | 469 typename Traits::Type::Factory* factory() { |
470 return function_state_->factory(); | 470 return function_state_->factory(); |
471 } | 471 } |
472 | 472 |
473 StrictMode strict_mode() { return scope_->strict_mode(); } | 473 LanguageMode language_mode() { return scope_->language_mode(); } |
474 bool is_generator() const { return function_state_->is_generator(); } | 474 bool is_generator() const { return function_state_->is_generator(); } |
475 | 475 |
476 // Report syntax errors. | 476 // Report syntax errors. |
477 void ReportMessage(const char* message, const char* arg = NULL, | 477 void ReportMessage(const char* message, const char* arg = NULL, |
478 bool is_reference_error = false) { | 478 bool is_reference_error = false) { |
479 Scanner::Location source_location = scanner()->location(); | 479 Scanner::Location source_location = scanner()->location(); |
480 Traits::ReportMessageAt(source_location, message, arg, is_reference_error); | 480 Traits::ReportMessageAt(source_location, message, arg, is_reference_error); |
481 } | 481 } |
482 | 482 |
483 void ReportMessageAt(Scanner::Location location, const char* message, | 483 void ReportMessageAt(Scanner::Location location, const char* message, |
(...skipping 519 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1003 PreParserStatementList* operator->() { return this; } | 1003 PreParserStatementList* operator->() { return this; } |
1004 void Add(PreParserStatement, void*) {} | 1004 void Add(PreParserStatement, void*) {} |
1005 }; | 1005 }; |
1006 | 1006 |
1007 | 1007 |
1008 class PreParserScope { | 1008 class PreParserScope { |
1009 public: | 1009 public: |
1010 explicit PreParserScope(PreParserScope* outer_scope, ScopeType scope_type, | 1010 explicit PreParserScope(PreParserScope* outer_scope, ScopeType scope_type, |
1011 void* = NULL) | 1011 void* = NULL) |
1012 : scope_type_(scope_type) { | 1012 : scope_type_(scope_type) { |
1013 strict_mode_ = outer_scope ? outer_scope->strict_mode() : SLOPPY; | 1013 language_mode_ = outer_scope ? outer_scope->language_mode() : SLOPPY; |
1014 } | 1014 } |
1015 | 1015 |
1016 ScopeType type() { return scope_type_; } | 1016 ScopeType type() { return scope_type_; } |
1017 StrictMode strict_mode() const { return strict_mode_; } | 1017 LanguageMode language_mode() const { return language_mode_; } |
1018 void SetStrictMode(StrictMode strict_mode) { strict_mode_ = strict_mode; } | 1018 void SetLanguageMode(LanguageMode language_mode) { |
| 1019 language_mode_ = language_mode; |
| 1020 } |
1019 void SetScopeName(PreParserIdentifier name) {} | 1021 void SetScopeName(PreParserIdentifier name) {} |
1020 | 1022 |
1021 // When PreParser is in use, lazy compilation is already being done, | 1023 // When PreParser is in use, lazy compilation is already being done, |
1022 // things cannot get lazier than that. | 1024 // things cannot get lazier than that. |
1023 bool AllowsLazyCompilation() const { return false; } | 1025 bool AllowsLazyCompilation() const { return false; } |
1024 | 1026 |
1025 void set_start_position(int position) {} | 1027 void set_start_position(int position) {} |
1026 void set_end_position(int position) {} | 1028 void set_end_position(int position) {} |
1027 | 1029 |
1028 bool IsDeclared(const PreParserIdentifier& identifier) const { return false; } | 1030 bool IsDeclared(const PreParserIdentifier& identifier) const { return false; } |
1029 void DeclareParameter(const PreParserIdentifier& identifier, VariableMode) {} | 1031 void DeclareParameter(const PreParserIdentifier& identifier, VariableMode) {} |
1030 void RecordArgumentsUsage() {} | 1032 void RecordArgumentsUsage() {} |
1031 void RecordSuperPropertyUsage() {} | 1033 void RecordSuperPropertyUsage() {} |
1032 void RecordSuperConstructorCallUsage() {} | 1034 void RecordSuperConstructorCallUsage() {} |
1033 void RecordThisUsage() {} | 1035 void RecordThisUsage() {} |
1034 | 1036 |
1035 // Allow scope->Foo() to work. | 1037 // Allow scope->Foo() to work. |
1036 PreParserScope* operator->() { return this; } | 1038 PreParserScope* operator->() { return this; } |
1037 | 1039 |
1038 private: | 1040 private: |
1039 ScopeType scope_type_; | 1041 ScopeType scope_type_; |
1040 StrictMode strict_mode_; | 1042 LanguageMode language_mode_; |
1041 }; | 1043 }; |
1042 | 1044 |
1043 | 1045 |
1044 class PreParserFactory { | 1046 class PreParserFactory { |
1045 public: | 1047 public: |
1046 explicit PreParserFactory(void* unused_value_factory) {} | 1048 explicit PreParserFactory(void* unused_value_factory) {} |
1047 PreParserExpression NewStringLiteral(PreParserIdentifier identifier, | 1049 PreParserExpression NewStringLiteral(PreParserIdentifier identifier, |
1048 int pos) { | 1050 int pos) { |
1049 return PreParserExpression::Default(); | 1051 return PreParserExpression::Default(); |
1050 } | 1052 } |
(...skipping 469 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1520 PreParseResult PreParseProgram(int* materialized_literals = 0) { | 1522 PreParseResult PreParseProgram(int* materialized_literals = 0) { |
1521 PreParserScope scope(scope_, SCRIPT_SCOPE); | 1523 PreParserScope scope(scope_, SCRIPT_SCOPE); |
1522 PreParserFactory factory(NULL); | 1524 PreParserFactory factory(NULL); |
1523 FunctionState top_scope(&function_state_, &scope_, &scope, &factory); | 1525 FunctionState top_scope(&function_state_, &scope_, &scope, &factory); |
1524 bool ok = true; | 1526 bool ok = true; |
1525 int start_position = scanner()->peek_location().beg_pos; | 1527 int start_position = scanner()->peek_location().beg_pos; |
1526 ParseSourceElements(Token::EOS, &ok); | 1528 ParseSourceElements(Token::EOS, &ok); |
1527 if (stack_overflow()) return kPreParseStackOverflow; | 1529 if (stack_overflow()) return kPreParseStackOverflow; |
1528 if (!ok) { | 1530 if (!ok) { |
1529 ReportUnexpectedToken(scanner()->current_token()); | 1531 ReportUnexpectedToken(scanner()->current_token()); |
1530 } else if (scope_->strict_mode() == STRICT) { | 1532 } else if (is_strict(scope_->language_mode())) { |
1531 CheckStrictOctalLiteral(start_position, scanner()->location().end_pos, | 1533 CheckStrictOctalLiteral(start_position, scanner()->location().end_pos, |
1532 &ok); | 1534 &ok); |
1533 } | 1535 } |
1534 if (materialized_literals) { | 1536 if (materialized_literals) { |
1535 *materialized_literals = function_state_->materialized_literal_count(); | 1537 *materialized_literals = function_state_->materialized_literal_count(); |
1536 } | 1538 } |
1537 return kPreParseSuccess; | 1539 return kPreParseSuccess; |
1538 } | 1540 } |
1539 | 1541 |
1540 // Parses a single function literal, from the opening parentheses before | 1542 // Parses a single function literal, from the opening parentheses before |
1541 // parameters to the closing brace after the body. | 1543 // parameters to the closing brace after the body. |
1542 // Returns a FunctionEntry describing the body of the function in enough | 1544 // Returns a FunctionEntry describing the body of the function in enough |
1543 // detail that it can be lazily compiled. | 1545 // detail that it can be lazily compiled. |
1544 // The scanner is expected to have matched the "function" or "function*" | 1546 // The scanner is expected to have matched the "function" or "function*" |
1545 // keyword and parameters, and have consumed the initial '{'. | 1547 // keyword and parameters, and have consumed the initial '{'. |
1546 // At return, unless an error occurred, the scanner is positioned before the | 1548 // At return, unless an error occurred, the scanner is positioned before the |
1547 // the final '}'. | 1549 // the final '}'. |
1548 PreParseResult PreParseLazyFunction(StrictMode strict_mode, | 1550 PreParseResult PreParseLazyFunction(LanguageMode language_mode, |
1549 bool is_generator, | 1551 bool is_generator, ParserRecorder* log); |
1550 ParserRecorder* log); | |
1551 | 1552 |
1552 private: | 1553 private: |
1553 friend class PreParserTraits; | 1554 friend class PreParserTraits; |
1554 | 1555 |
1555 // These types form an algebra over syntactic categories that is just | 1556 // These types form an algebra over syntactic categories that is just |
1556 // rich enough to let us recognize and propagate the constructs that | 1557 // rich enough to let us recognize and propagate the constructs that |
1557 // are either being counted in the preparser data, or is important | 1558 // are either being counted in the preparser data, or is important |
1558 // to throw the correct syntax error exceptions. | 1559 // to throw the correct syntax error exceptions. |
1559 | 1560 |
1560 enum VariableDeclarationContext { | 1561 enum VariableDeclarationContext { |
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1699 case Token::STRING: | 1700 case Token::STRING: |
1700 return ReportMessageAt(source_location, "unexpected_token_string"); | 1701 return ReportMessageAt(source_location, "unexpected_token_string"); |
1701 case Token::IDENTIFIER: | 1702 case Token::IDENTIFIER: |
1702 return ReportMessageAt(source_location, "unexpected_token_identifier"); | 1703 return ReportMessageAt(source_location, "unexpected_token_identifier"); |
1703 case Token::FUTURE_RESERVED_WORD: | 1704 case Token::FUTURE_RESERVED_WORD: |
1704 return ReportMessageAt(source_location, "unexpected_reserved"); | 1705 return ReportMessageAt(source_location, "unexpected_reserved"); |
1705 case Token::LET: | 1706 case Token::LET: |
1706 case Token::STATIC: | 1707 case Token::STATIC: |
1707 case Token::YIELD: | 1708 case Token::YIELD: |
1708 case Token::FUTURE_STRICT_RESERVED_WORD: | 1709 case Token::FUTURE_STRICT_RESERVED_WORD: |
1709 return ReportMessageAt(source_location, strict_mode() == SLOPPY | 1710 return ReportMessageAt(source_location, |
1710 ? "unexpected_token_identifier" : "unexpected_strict_reserved"); | 1711 is_strict(language_mode()) |
| 1712 ? "unexpected_strict_reserved" |
| 1713 : "unexpected_token_identifier"); |
1711 case Token::TEMPLATE_SPAN: | 1714 case Token::TEMPLATE_SPAN: |
1712 case Token::TEMPLATE_TAIL: | 1715 case Token::TEMPLATE_TAIL: |
1713 return Traits::ReportMessageAt(source_location, | 1716 return Traits::ReportMessageAt(source_location, |
1714 "unexpected_template_string"); | 1717 "unexpected_template_string"); |
1715 default: | 1718 default: |
1716 const char* name = Token::String(token); | 1719 const char* name = Token::String(token); |
1717 DCHECK(name != NULL); | 1720 DCHECK(name != NULL); |
1718 Traits::ReportMessageAt(source_location, "unexpected_token", name); | 1721 Traits::ReportMessageAt(source_location, "unexpected_token", name); |
1719 } | 1722 } |
1720 } | 1723 } |
1721 | 1724 |
1722 | 1725 |
1723 template<class Traits> | 1726 template<class Traits> |
1724 typename ParserBase<Traits>::IdentifierT ParserBase<Traits>::ParseIdentifier( | 1727 typename ParserBase<Traits>::IdentifierT ParserBase<Traits>::ParseIdentifier( |
1725 AllowEvalOrArgumentsAsIdentifier allow_eval_or_arguments, | 1728 AllowEvalOrArgumentsAsIdentifier allow_eval_or_arguments, |
1726 bool* ok) { | 1729 bool* ok) { |
1727 Token::Value next = Next(); | 1730 Token::Value next = Next(); |
1728 if (next == Token::IDENTIFIER) { | 1731 if (next == Token::IDENTIFIER) { |
1729 IdentifierT name = this->GetSymbol(scanner()); | 1732 IdentifierT name = this->GetSymbol(scanner()); |
1730 if (allow_eval_or_arguments == kDontAllowEvalOrArguments && | 1733 if (allow_eval_or_arguments == kDontAllowEvalOrArguments && |
1731 strict_mode() == STRICT && this->IsEvalOrArguments(name)) { | 1734 is_strict(language_mode()) && this->IsEvalOrArguments(name)) { |
1732 ReportMessage("strict_eval_arguments"); | 1735 ReportMessage("strict_eval_arguments"); |
1733 *ok = false; | 1736 *ok = false; |
1734 } | 1737 } |
1735 if (name->IsArguments(this->ast_value_factory())) | 1738 if (name->IsArguments(this->ast_value_factory())) |
1736 scope_->RecordArgumentsUsage(); | 1739 scope_->RecordArgumentsUsage(); |
1737 return name; | 1740 return name; |
1738 } else if (strict_mode() == SLOPPY && | 1741 } else if (!is_strict(language_mode()) && |
1739 (next == Token::FUTURE_STRICT_RESERVED_WORD || | 1742 (next == Token::FUTURE_STRICT_RESERVED_WORD || |
1740 next == Token::LET || next == Token::STATIC || | 1743 next == Token::LET || next == Token::STATIC || |
1741 (next == Token::YIELD && !is_generator()))) { | 1744 (next == Token::YIELD && !is_generator()))) { |
1742 return this->GetSymbol(scanner()); | 1745 return this->GetSymbol(scanner()); |
1743 } else { | 1746 } else { |
1744 this->ReportUnexpectedToken(next); | 1747 this->ReportUnexpectedToken(next); |
1745 *ok = false; | 1748 *ok = false; |
1746 return Traits::EmptyIdentifier(); | 1749 return Traits::EmptyIdentifier(); |
1747 } | 1750 } |
1748 } | 1751 } |
(...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1925 // seeing the call parentheses. | 1928 // seeing the call parentheses. |
1926 parenthesized_function_ = (peek() == Token::FUNCTION); | 1929 parenthesized_function_ = (peek() == Token::FUNCTION); |
1927 result = this->ParseExpression(true, CHECK_OK); | 1930 result = this->ParseExpression(true, CHECK_OK); |
1928 result->increase_parenthesization_level(); | 1931 result->increase_parenthesization_level(); |
1929 Expect(Token::RPAREN, CHECK_OK); | 1932 Expect(Token::RPAREN, CHECK_OK); |
1930 } | 1933 } |
1931 break; | 1934 break; |
1932 | 1935 |
1933 case Token::CLASS: { | 1936 case Token::CLASS: { |
1934 Consume(Token::CLASS); | 1937 Consume(Token::CLASS); |
1935 if (!allow_harmony_sloppy() && strict_mode() == SLOPPY) { | 1938 if (!allow_harmony_sloppy() && !is_strict(language_mode())) { |
1936 ReportMessage("sloppy_lexical", NULL); | 1939 ReportMessage("sloppy_lexical", NULL); |
1937 *ok = false; | 1940 *ok = false; |
1938 break; | 1941 break; |
1939 } | 1942 } |
1940 int class_token_position = position(); | 1943 int class_token_position = position(); |
1941 IdentifierT name = this->EmptyIdentifier(); | 1944 IdentifierT name = this->EmptyIdentifier(); |
1942 bool is_strict_reserved_name = false; | 1945 bool is_strict_reserved_name = false; |
1943 Scanner::Location class_name_location = Scanner::Location::invalid(); | 1946 Scanner::Location class_name_location = Scanner::Location::invalid(); |
1944 if (peek_any_identifier()) { | 1947 if (peek_any_identifier()) { |
1945 name = ParseIdentifierOrStrictReservedWord(&is_strict_reserved_name, | 1948 name = ParseIdentifierOrStrictReservedWord(&is_strict_reserved_name, |
(...skipping 233 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2179 name_expression = | 2182 name_expression = |
2180 factory()->NewStringLiteral(name, name_expression->position()); | 2183 factory()->NewStringLiteral(name, name_expression->position()); |
2181 } | 2184 } |
2182 | 2185 |
2183 return factory()->NewObjectLiteralProperty( | 2186 return factory()->NewObjectLiteralProperty( |
2184 name_expression, value, | 2187 name_expression, value, |
2185 is_get ? ObjectLiteralProperty::GETTER : ObjectLiteralProperty::SETTER, | 2188 is_get ? ObjectLiteralProperty::GETTER : ObjectLiteralProperty::SETTER, |
2186 is_static, *is_computed_name); | 2189 is_static, *is_computed_name); |
2187 | 2190 |
2188 } else if (!in_class && allow_harmony_object_literals_ && | 2191 } else if (!in_class && allow_harmony_object_literals_ && |
2189 Token::IsIdentifier(name_token, strict_mode(), | 2192 Token::IsIdentifier(name_token, language_mode(), |
2190 this->is_generator())) { | 2193 this->is_generator())) { |
2191 DCHECK(!*is_computed_name); | 2194 DCHECK(!*is_computed_name); |
2192 DCHECK(!is_static); | 2195 DCHECK(!is_static); |
2193 value = this->ExpressionFromIdentifier(name, next_pos, scope_, factory()); | 2196 value = this->ExpressionFromIdentifier(name, next_pos, scope_, factory()); |
2194 return factory()->NewObjectLiteralProperty( | 2197 return factory()->NewObjectLiteralProperty( |
2195 name_expression, value, ObjectLiteralProperty::COMPUTED, false, false); | 2198 name_expression, value, ObjectLiteralProperty::COMPUTED, false, false); |
2196 | 2199 |
2197 } else { | 2200 } else { |
2198 Token::Value next = Next(); | 2201 Token::Value next = Next(); |
2199 ReportUnexpectedToken(next); | 2202 ReportUnexpectedToken(next); |
(...skipping 300 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2500 // '~' UnaryExpression | 2503 // '~' UnaryExpression |
2501 // '!' UnaryExpression | 2504 // '!' UnaryExpression |
2502 | 2505 |
2503 Token::Value op = peek(); | 2506 Token::Value op = peek(); |
2504 if (Token::IsUnaryOp(op)) { | 2507 if (Token::IsUnaryOp(op)) { |
2505 op = Next(); | 2508 op = Next(); |
2506 int pos = position(); | 2509 int pos = position(); |
2507 ExpressionT expression = ParseUnaryExpression(CHECK_OK); | 2510 ExpressionT expression = ParseUnaryExpression(CHECK_OK); |
2508 | 2511 |
2509 // "delete identifier" is a syntax error in strict mode. | 2512 // "delete identifier" is a syntax error in strict mode. |
2510 if (op == Token::DELETE && strict_mode() == STRICT && | 2513 if (op == Token::DELETE && is_strict(language_mode()) && |
2511 this->IsIdentifier(expression)) { | 2514 this->IsIdentifier(expression)) { |
2512 ReportMessage("strict_delete"); | 2515 ReportMessage("strict_delete"); |
2513 *ok = false; | 2516 *ok = false; |
2514 return this->EmptyExpression(); | 2517 return this->EmptyExpression(); |
2515 } | 2518 } |
2516 | 2519 |
2517 // Allow Traits do rewrite the expression. | 2520 // Allow Traits do rewrite the expression. |
2518 return this->BuildUnaryExpression(expression, op, pos, factory()); | 2521 return this->BuildUnaryExpression(expression, op, pos, factory()); |
2519 } else if (Token::IsCountOp(op)) { | 2522 } else if (Token::IsCountOp(op)) { |
2520 op = Next(); | 2523 op = Next(); |
(...skipping 347 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2868 bool function_name_is_strict_reserved = false; | 2871 bool function_name_is_strict_reserved = false; |
2869 Scanner::Location function_name_loc = Scanner::Location::invalid(); | 2872 Scanner::Location function_name_loc = Scanner::Location::invalid(); |
2870 Scanner::Location eval_args_error_loc = Scanner::Location::invalid(); | 2873 Scanner::Location eval_args_error_loc = Scanner::Location::invalid(); |
2871 Scanner::Location reserved_loc = Scanner::Location::invalid(); | 2874 Scanner::Location reserved_loc = Scanner::Location::invalid(); |
2872 this->CheckStrictFunctionNameAndParameters( | 2875 this->CheckStrictFunctionNameAndParameters( |
2873 this->EmptyIdentifier(), function_name_is_strict_reserved, | 2876 this->EmptyIdentifier(), function_name_is_strict_reserved, |
2874 function_name_loc, eval_args_error_loc, dupe_error_loc, reserved_loc, | 2877 function_name_loc, eval_args_error_loc, dupe_error_loc, reserved_loc, |
2875 CHECK_OK); | 2878 CHECK_OK); |
2876 | 2879 |
2877 // Validate strict mode. | 2880 // Validate strict mode. |
2878 if (strict_mode() == STRICT) { | 2881 if (is_strict(language_mode())) { |
2879 CheckStrictOctalLiteral(start_pos, scanner()->location().end_pos, | 2882 CheckStrictOctalLiteral(start_pos, scanner()->location().end_pos, |
2880 CHECK_OK); | 2883 CHECK_OK); |
2881 } | 2884 } |
2882 | 2885 |
2883 if (allow_harmony_scoping() && strict_mode() == STRICT) | 2886 if (allow_harmony_scoping() && is_strict(language_mode())) |
2884 this->CheckConflictingVarDeclarations(scope, CHECK_OK); | 2887 this->CheckConflictingVarDeclarations(scope, CHECK_OK); |
2885 } | 2888 } |
2886 | 2889 |
2887 FunctionLiteralT function_literal = factory()->NewFunctionLiteral( | 2890 FunctionLiteralT function_literal = factory()->NewFunctionLiteral( |
2888 this->EmptyIdentifierString(), this->ast_value_factory(), scope, body, | 2891 this->EmptyIdentifierString(), this->ast_value_factory(), scope, body, |
2889 materialized_literal_count, expected_property_count, handler_count, | 2892 materialized_literal_count, expected_property_count, handler_count, |
2890 num_parameters, FunctionLiteral::kNoDuplicateParameters, | 2893 num_parameters, FunctionLiteral::kNoDuplicateParameters, |
2891 FunctionLiteral::ANONYMOUS_EXPRESSION, FunctionLiteral::kIsFunction, | 2894 FunctionLiteral::ANONYMOUS_EXPRESSION, FunctionLiteral::kIsFunction, |
2892 FunctionLiteral::kNotParenthesized, FunctionKind::kArrowFunction, | 2895 FunctionLiteral::kNotParenthesized, FunctionKind::kArrowFunction, |
2893 start_pos); | 2896 start_pos); |
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2990 // Once we've reached a TEMPLATE_TAIL, we can close the TemplateLiteral. | 2993 // Once we've reached a TEMPLATE_TAIL, we can close the TemplateLiteral. |
2991 return Traits::CloseTemplateLiteral(&ts, start, tag); | 2994 return Traits::CloseTemplateLiteral(&ts, start, tag); |
2992 } | 2995 } |
2993 | 2996 |
2994 | 2997 |
2995 template <typename Traits> | 2998 template <typename Traits> |
2996 typename ParserBase<Traits>::ExpressionT ParserBase< | 2999 typename ParserBase<Traits>::ExpressionT ParserBase< |
2997 Traits>::CheckAndRewriteReferenceExpression(ExpressionT expression, | 3000 Traits>::CheckAndRewriteReferenceExpression(ExpressionT expression, |
2998 Scanner::Location location, | 3001 Scanner::Location location, |
2999 const char* message, bool* ok) { | 3002 const char* message, bool* ok) { |
3000 if (strict_mode() == STRICT && this->IsIdentifier(expression) && | 3003 if (is_strict(language_mode()) && this->IsIdentifier(expression) && |
3001 this->IsEvalOrArguments(this->AsIdentifier(expression))) { | 3004 this->IsEvalOrArguments(this->AsIdentifier(expression))) { |
3002 this->ReportMessageAt(location, "strict_eval_arguments", false); | 3005 this->ReportMessageAt(location, "strict_eval_arguments", false); |
3003 *ok = false; | 3006 *ok = false; |
3004 return this->EmptyExpression(); | 3007 return this->EmptyExpression(); |
3005 } else if (expression->IsValidReferenceExpression()) { | 3008 } else if (expression->IsValidReferenceExpression()) { |
3006 return expression; | 3009 return expression; |
3007 } else if (expression->IsCall()) { | 3010 } else if (expression->IsCall()) { |
3008 // If it is a call, make it a runtime error for legacy web compatibility. | 3011 // If it is a call, make it a runtime error for legacy web compatibility. |
3009 // Rewrite `expr' to `expr[throw ReferenceError]'. | 3012 // Rewrite `expr' to `expr[throw ReferenceError]'. |
3010 int pos = location.beg_pos; | 3013 int pos = location.beg_pos; |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3068 *ok = false; | 3071 *ok = false; |
3069 return; | 3072 return; |
3070 } | 3073 } |
3071 has_seen_constructor_ = true; | 3074 has_seen_constructor_ = true; |
3072 return; | 3075 return; |
3073 } | 3076 } |
3074 } | 3077 } |
3075 } } // v8::internal | 3078 } } // v8::internal |
3076 | 3079 |
3077 #endif // V8_PREPARSER_H | 3080 #endif // V8_PREPARSER_H |
OLD | NEW |