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