| 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 #include "src/parsing/parser.h" | 5 #include "src/parsing/parser.h" |
| 6 | 6 |
| 7 #include <memory> | 7 #include <memory> |
| 8 | 8 |
| 9 #include "src/api.h" | 9 #include "src/api.h" |
| 10 #include "src/ast/ast-expression-rewriter.h" | 10 #include "src/ast/ast-expression-rewriter.h" |
| 11 #include "src/ast/ast-literal-reindexer.h" | 11 #include "src/ast/ast-literal-reindexer.h" |
| 12 #include "src/ast/ast-traversal-visitor.h" | 12 #include "src/ast/ast-traversal-visitor.h" |
| 13 #include "src/ast/ast.h" | 13 #include "src/ast/ast.h" |
| 14 #include "src/bailout-reason.h" | 14 #include "src/bailout-reason.h" |
| 15 #include "src/base/platform/platform.h" | 15 #include "src/base/platform/platform.h" |
| 16 #include "src/char-predicates-inl.h" | 16 #include "src/char-predicates-inl.h" |
| 17 #include "src/messages.h" | 17 #include "src/messages.h" |
| 18 #include "src/parsing/declaration-descriptor.h" |
| 18 #include "src/parsing/duplicate-finder.h" | 19 #include "src/parsing/duplicate-finder.h" |
| 19 #include "src/parsing/parameter-initializer-rewriter.h" | 20 #include "src/parsing/parameter-initializer-rewriter.h" |
| 20 #include "src/parsing/parse-info.h" | 21 #include "src/parsing/parse-info.h" |
| 21 #include "src/parsing/rewriter.h" | 22 #include "src/parsing/rewriter.h" |
| 22 #include "src/parsing/scanner-character-streams.h" | 23 #include "src/parsing/scanner-character-streams.h" |
| 23 #include "src/runtime/runtime.h" | 24 #include "src/runtime/runtime.h" |
| 24 #include "src/string-stream.h" | 25 #include "src/string-stream.h" |
| 25 #include "src/tracing/trace-event.h" | 26 #include "src/tracing/trace-event.h" |
| 26 | 27 |
| 27 namespace v8 { | 28 namespace v8 { |
| (...skipping 1631 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1659 VariableMode mode, InitializationFlag init, | 1660 VariableMode mode, InitializationFlag init, |
| 1660 int pos, bool* ok) { | 1661 int pos, bool* ok) { |
| 1661 DCHECK_NOT_NULL(name); | 1662 DCHECK_NOT_NULL(name); |
| 1662 Scope* scope = | 1663 Scope* scope = |
| 1663 IsLexicalVariableMode(mode) ? this->scope() : GetDeclarationScope(); | 1664 IsLexicalVariableMode(mode) ? this->scope() : GetDeclarationScope(); |
| 1664 VariableProxy* proxy = | 1665 VariableProxy* proxy = |
| 1665 scope->NewUnresolved(factory(), name, scanner()->location().beg_pos, | 1666 scope->NewUnresolved(factory(), name, scanner()->location().beg_pos, |
| 1666 scanner()->location().end_pos); | 1667 scanner()->location().end_pos); |
| 1667 Declaration* declaration = | 1668 Declaration* declaration = |
| 1668 factory()->NewVariableDeclaration(proxy, this->scope(), pos); | 1669 factory()->NewVariableDeclaration(proxy, this->scope(), pos); |
| 1669 Declare(declaration, DeclarationDescriptor::NORMAL, mode, init, CHECK_OK); | 1670 this->scope()->DeclareVariableOrParameter( |
| 1671 declaration, DeclarationDescriptor::NORMAL, mode, init, |
| 1672 allow_harmony_restrictive_generators(), &pending_error_handler_, |
| 1673 use_counts_, CHECK_OK); |
| 1670 return declaration; | 1674 return declaration; |
| 1671 } | 1675 } |
| 1672 | 1676 |
| 1673 Variable* Parser::Declare(Declaration* declaration, | |
| 1674 DeclarationDescriptor::Kind declaration_kind, | |
| 1675 VariableMode mode, InitializationFlag init, bool* ok, | |
| 1676 Scope* scope) { | |
| 1677 DCHECK(IsDeclaredVariableMode(mode) && mode != CONST_LEGACY); | |
| 1678 | |
| 1679 VariableProxy* proxy = declaration->proxy(); | |
| 1680 DCHECK(proxy->raw_name() != NULL); | |
| 1681 const AstRawString* name = proxy->raw_name(); | |
| 1682 | |
| 1683 if (scope == nullptr) scope = this->scope(); | |
| 1684 if (mode == VAR) scope = scope->GetDeclarationScope(); | |
| 1685 DCHECK(!scope->is_catch_scope()); | |
| 1686 DCHECK(!scope->is_with_scope()); | |
| 1687 DCHECK(scope->is_declaration_scope() || | |
| 1688 (IsLexicalVariableMode(mode) && scope->is_block_scope())); | |
| 1689 | |
| 1690 bool is_function_declaration = declaration->IsFunctionDeclaration(); | |
| 1691 | |
| 1692 Variable* var = NULL; | |
| 1693 if (scope->is_eval_scope() && is_sloppy(scope->language_mode()) && | |
| 1694 mode == VAR) { | |
| 1695 // In a var binding in a sloppy direct eval, pollute the enclosing scope | |
| 1696 // with this new binding by doing the following: | |
| 1697 // The proxy is bound to a lookup variable to force a dynamic declaration | |
| 1698 // using the DeclareEvalVar or DeclareEvalFunction runtime functions. | |
| 1699 Variable::Kind kind = Variable::NORMAL; | |
| 1700 // TODO(sigurds) figure out if kNotAssigned is OK here | |
| 1701 var = new (zone()) Variable(scope, name, mode, kind, init, kNotAssigned); | |
| 1702 var->AllocateTo(VariableLocation::LOOKUP, -1); | |
| 1703 } else { | |
| 1704 // Declare the variable in the declaration scope. | |
| 1705 var = scope->LookupLocal(name); | |
| 1706 if (var == NULL) { | |
| 1707 // Declare the name. | |
| 1708 Variable::Kind kind = Variable::NORMAL; | |
| 1709 if (is_function_declaration) { | |
| 1710 kind = Variable::FUNCTION; | |
| 1711 } | |
| 1712 var = scope->DeclareLocal(name, mode, init, kind, kNotAssigned); | |
| 1713 } else if (IsLexicalVariableMode(mode) || | |
| 1714 IsLexicalVariableMode(var->mode())) { | |
| 1715 // Allow duplicate function decls for web compat, see bug 4693. | |
| 1716 bool duplicate_allowed = false; | |
| 1717 if (is_sloppy(scope->language_mode()) && is_function_declaration && | |
| 1718 var->is_function()) { | |
| 1719 DCHECK(IsLexicalVariableMode(mode) && | |
| 1720 IsLexicalVariableMode(var->mode())); | |
| 1721 // If the duplication is allowed, then the var will show up | |
| 1722 // in the SloppyBlockFunctionMap and the new FunctionKind | |
| 1723 // will be a permitted duplicate. | |
| 1724 FunctionKind function_kind = | |
| 1725 declaration->AsFunctionDeclaration()->fun()->kind(); | |
| 1726 duplicate_allowed = | |
| 1727 scope->GetDeclarationScope()->sloppy_block_function_map()->Lookup( | |
| 1728 const_cast<AstRawString*>(name), name->hash()) != nullptr && | |
| 1729 !IsAsyncFunction(function_kind) && | |
| 1730 !(allow_harmony_restrictive_generators() && | |
| 1731 IsGeneratorFunction(function_kind)); | |
| 1732 } | |
| 1733 if (duplicate_allowed) { | |
| 1734 ++use_counts_[v8::Isolate::kSloppyModeBlockScopedFunctionRedefinition]; | |
| 1735 } else { | |
| 1736 // The name was declared in this scope before; check for conflicting | |
| 1737 // re-declarations. We have a conflict if either of the declarations | |
| 1738 // is not a var (in script scope, we also have to ignore legacy const | |
| 1739 // for compatibility). There is similar code in runtime.cc in the | |
| 1740 // Declare functions. The function CheckConflictingVarDeclarations | |
| 1741 // checks for var and let bindings from different scopes whereas this | |
| 1742 // is a check for conflicting declarations within the same scope. This | |
| 1743 // check also covers the special case | |
| 1744 // | |
| 1745 // function () { let x; { var x; } } | |
| 1746 // | |
| 1747 // because the var declaration is hoisted to the function scope where | |
| 1748 // 'x' is already bound. | |
| 1749 DCHECK(IsDeclaredVariableMode(var->mode())); | |
| 1750 // In harmony we treat re-declarations as early errors. See | |
| 1751 // ES5 16 for a definition of early errors. | |
| 1752 if (declaration_kind == DeclarationDescriptor::NORMAL) { | |
| 1753 ReportMessage(MessageTemplate::kVarRedeclaration, name); | |
| 1754 } else { | |
| 1755 ReportMessage(MessageTemplate::kParamDupe); | |
| 1756 } | |
| 1757 *ok = false; | |
| 1758 return nullptr; | |
| 1759 } | |
| 1760 } else if (mode == VAR) { | |
| 1761 var->set_maybe_assigned(); | |
| 1762 } | |
| 1763 } | |
| 1764 DCHECK_NOT_NULL(var); | |
| 1765 | |
| 1766 // We add a declaration node for every declaration. The compiler | |
| 1767 // will only generate code if necessary. In particular, declarations | |
| 1768 // for inner local variables that do not represent functions won't | |
| 1769 // result in any generated code. | |
| 1770 // | |
| 1771 // This will lead to multiple declaration nodes for the | |
| 1772 // same variable if it is declared several times. This is not a | |
| 1773 // semantic issue, but it may be a performance issue since it may | |
| 1774 // lead to repeated DeclareEvalVar or DeclareEvalFunction calls. | |
| 1775 scope->AddDeclaration(declaration); | |
| 1776 proxy->BindTo(var); | |
| 1777 return var; | |
| 1778 } | |
| 1779 | |
| 1780 | |
| 1781 // Language extension which is only enabled for source files loaded | 1677 // Language extension which is only enabled for source files loaded |
| 1782 // through the API's extension mechanism. A native function | 1678 // through the API's extension mechanism. A native function |
| 1783 // declaration is resolved by looking up the function through a | 1679 // declaration is resolved by looking up the function through a |
| 1784 // callback provided by the extension. | 1680 // callback provided by the extension. |
| 1785 Statement* Parser::ParseNativeDeclaration(bool* ok) { | 1681 Statement* Parser::ParseNativeDeclaration(bool* ok) { |
| 1786 int pos = peek_position(); | 1682 int pos = peek_position(); |
| 1787 Expect(Token::FUNCTION, CHECK_OK); | 1683 Expect(Token::FUNCTION, CHECK_OK); |
| 1788 // Allow "eval" or "arguments" for backward compatibility. | 1684 // Allow "eval" or "arguments" for backward compatibility. |
| 1789 const AstRawString* name = | 1685 const AstRawString* name = |
| 1790 ParseIdentifier(kAllowRestrictedIdentifiers, CHECK_OK); | 1686 ParseIdentifier(kAllowRestrictedIdentifiers, CHECK_OK); |
| (...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1886 pos, FunctionLiteral::kDeclaration, language_mode(), CHECK_OK); | 1782 pos, FunctionLiteral::kDeclaration, language_mode(), CHECK_OK); |
| 1887 | 1783 |
| 1888 // In ES6, a function behaves as a lexical binding, except in | 1784 // In ES6, a function behaves as a lexical binding, except in |
| 1889 // a script scope, or the initial scope of eval or another function. | 1785 // a script scope, or the initial scope of eval or another function. |
| 1890 VariableMode mode = | 1786 VariableMode mode = |
| 1891 (!scope()->is_declaration_scope() || scope()->is_module_scope()) ? LET | 1787 (!scope()->is_declaration_scope() || scope()->is_module_scope()) ? LET |
| 1892 : VAR; | 1788 : VAR; |
| 1893 VariableProxy* proxy = NewUnresolved(variable_name); | 1789 VariableProxy* proxy = NewUnresolved(variable_name); |
| 1894 Declaration* declaration = | 1790 Declaration* declaration = |
| 1895 factory()->NewFunctionDeclaration(proxy, fun, scope(), pos); | 1791 factory()->NewFunctionDeclaration(proxy, fun, scope(), pos); |
| 1896 Declare(declaration, DeclarationDescriptor::NORMAL, mode, kCreatedInitialized, | 1792 this->scope()->DeclareVariableOrParameter( |
| 1897 CHECK_OK); | 1793 declaration, DeclarationDescriptor::NORMAL, mode, kCreatedInitialized, |
| 1794 allow_harmony_restrictive_generators(), &pending_error_handler_, |
| 1795 use_counts_, CHECK_OK); |
| 1898 if (names) names->Add(variable_name, zone()); | 1796 if (names) names->Add(variable_name, zone()); |
| 1899 EmptyStatement* empty = factory()->NewEmptyStatement(kNoSourcePosition); | 1797 EmptyStatement* empty = factory()->NewEmptyStatement(kNoSourcePosition); |
| 1900 // Async functions don't undergo sloppy mode block scoped hoisting, and don't | 1798 // Async functions don't undergo sloppy mode block scoped hoisting, and don't |
| 1901 // allow duplicates in a block. Both are represented by the | 1799 // allow duplicates in a block. Both are represented by the |
| 1902 // sloppy_block_function_map. Don't add them to the map for async functions. | 1800 // sloppy_block_function_map. Don't add them to the map for async functions. |
| 1903 // Generators are also supposed to be prohibited; currently doing this behind | 1801 // Generators are also supposed to be prohibited; currently doing this behind |
| 1904 // a flag and UseCounting violations to assess web compatibility. | 1802 // a flag and UseCounting violations to assess web compatibility. |
| 1905 if (is_sloppy(language_mode()) && !scope()->is_declaration_scope() && | 1803 if (is_sloppy(language_mode()) && !scope()->is_declaration_scope() && |
| 1906 !is_async && !(allow_harmony_restrictive_generators() && is_generator)) { | 1804 !is_async && !(allow_harmony_restrictive_generators() && is_generator)) { |
| 1907 SloppyBlockFunctionStatement* delegate = | 1805 SloppyBlockFunctionStatement* delegate = |
| (...skipping 2848 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4756 #ifdef DEBUG | 4654 #ifdef DEBUG |
| 4757 scope()->SetScopeName(name); | 4655 scope()->SetScopeName(name); |
| 4758 #endif | 4656 #endif |
| 4759 | 4657 |
| 4760 VariableProxy* proxy = nullptr; | 4658 VariableProxy* proxy = nullptr; |
| 4761 if (name != nullptr) { | 4659 if (name != nullptr) { |
| 4762 proxy = NewUnresolved(name); | 4660 proxy = NewUnresolved(name); |
| 4763 // TODO(verwaest): declare via block_state. | 4661 // TODO(verwaest): declare via block_state. |
| 4764 Declaration* declaration = | 4662 Declaration* declaration = |
| 4765 factory()->NewVariableDeclaration(proxy, block_state.scope(), pos); | 4663 factory()->NewVariableDeclaration(proxy, block_state.scope(), pos); |
| 4766 Declare(declaration, DeclarationDescriptor::NORMAL, CONST, | 4664 this->scope()->DeclareVariableOrParameter( |
| 4767 DefaultInitializationFlag(CONST), CHECK_OK); | 4665 declaration, DeclarationDescriptor::NORMAL, CONST, |
| 4666 DefaultInitializationFlag(CONST), |
| 4667 allow_harmony_restrictive_generators(), &pending_error_handler_, |
| 4668 use_counts_, CHECK_OK); |
| 4768 } | 4669 } |
| 4769 | 4670 |
| 4770 Expression* extends = nullptr; | 4671 Expression* extends = nullptr; |
| 4771 if (Check(Token::EXTENDS)) { | 4672 if (Check(Token::EXTENDS)) { |
| 4772 block_state.set_start_position(scanner()->location().end_pos); | 4673 block_state.set_start_position(scanner()->location().end_pos); |
| 4773 ExpressionClassifier extends_classifier(this); | 4674 ExpressionClassifier extends_classifier(this); |
| 4774 extends = ParseLeftHandSideExpression(&extends_classifier, CHECK_OK); | 4675 extends = ParseLeftHandSideExpression(&extends_classifier, CHECK_OK); |
| 4775 CheckNoTailCallExpressions(&extends_classifier, CHECK_OK); | 4676 CheckNoTailCallExpressions(&extends_classifier, CHECK_OK); |
| 4776 RewriteNonPattern(&extends_classifier, CHECK_OK); | 4677 RewriteNonPattern(&extends_classifier, CHECK_OK); |
| 4777 if (classifier != nullptr) { | 4678 if (classifier != nullptr) { |
| (...skipping 257 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5035 } while (query_scope != outer_scope); | 4936 } while (query_scope != outer_scope); |
| 5036 | 4937 |
| 5037 if (!should_hoist) continue; | 4938 if (!should_hoist) continue; |
| 5038 | 4939 |
| 5039 // Declare a var-style binding for the function in the outer scope | 4940 // Declare a var-style binding for the function in the outer scope |
| 5040 if (!var_created) { | 4941 if (!var_created) { |
| 5041 var_created = true; | 4942 var_created = true; |
| 5042 VariableProxy* proxy = scope->NewUnresolved(factory(), name); | 4943 VariableProxy* proxy = scope->NewUnresolved(factory(), name); |
| 5043 Declaration* declaration = | 4944 Declaration* declaration = |
| 5044 factory()->NewVariableDeclaration(proxy, scope, kNoSourcePosition); | 4945 factory()->NewVariableDeclaration(proxy, scope, kNoSourcePosition); |
| 5045 Declare(declaration, DeclarationDescriptor::NORMAL, VAR, | 4946 scope->DeclareVariableOrParameter( |
| 5046 DefaultInitializationFlag(VAR), ok, scope); | 4947 declaration, DeclarationDescriptor::NORMAL, VAR, |
| 5047 DCHECK(ok); // Based on the preceding check, this should not fail | 4948 DefaultInitializationFlag(VAR), |
| 5048 if (!ok) return; | 4949 allow_harmony_restrictive_generators(), &pending_error_handler_, |
| 4950 use_counts_, ok); |
| 4951 DCHECK(*ok); // Based on the preceding check, this should not fail |
| 4952 if (!*ok) return; |
| 5049 } | 4953 } |
| 5050 | 4954 |
| 5051 // Read from the local lexical scope and write to the function scope | 4955 // Read from the local lexical scope and write to the function scope |
| 5052 VariableProxy* to = scope->NewUnresolved(factory(), name); | 4956 VariableProxy* to = scope->NewUnresolved(factory(), name); |
| 5053 VariableProxy* from = delegate->scope()->NewUnresolved(factory(), name); | 4957 VariableProxy* from = delegate->scope()->NewUnresolved(factory(), name); |
| 5054 Expression* assignment = | 4958 Expression* assignment = |
| 5055 factory()->NewAssignment(Token::ASSIGN, to, from, kNoSourcePosition); | 4959 factory()->NewAssignment(Token::ASSIGN, to, from, kNoSourcePosition); |
| 5056 Statement* statement = | 4960 Statement* statement = |
| 5057 factory()->NewExpressionStatement(assignment, kNoSourcePosition); | 4961 factory()->NewExpressionStatement(assignment, kNoSourcePosition); |
| 5058 delegate->set_statement(statement); | 4962 delegate->set_statement(statement); |
| (...skipping 1682 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6741 node->Print(Isolate::Current()); | 6645 node->Print(Isolate::Current()); |
| 6742 } | 6646 } |
| 6743 #endif // DEBUG | 6647 #endif // DEBUG |
| 6744 | 6648 |
| 6745 #undef CHECK_OK | 6649 #undef CHECK_OK |
| 6746 #undef CHECK_OK_VOID | 6650 #undef CHECK_OK_VOID |
| 6747 #undef CHECK_FAILED | 6651 #undef CHECK_FAILED |
| 6748 | 6652 |
| 6749 } // namespace internal | 6653 } // namespace internal |
| 6750 } // namespace v8 | 6654 } // namespace v8 |
| OLD | NEW |