Chromium Code Reviews| 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/v8.h" | 5 #include "src/v8.h" |
| 6 | 6 |
| 7 #include "src/api.h" | 7 #include "src/api.h" |
| 8 #include "src/ast.h" | 8 #include "src/ast.h" |
| 9 #include "src/bailout-reason.h" | 9 #include "src/bailout-reason.h" |
| 10 #include "src/base/platform/platform.h" | 10 #include "src/base/platform/platform.h" |
| (...skipping 688 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 699 return factory->NewNumberLiteral(value, pos); | 699 return factory->NewNumberLiteral(value, pos); |
| 700 } | 700 } |
| 701 default: | 701 default: |
| 702 DCHECK(false); | 702 DCHECK(false); |
| 703 } | 703 } |
| 704 return NULL; | 704 return NULL; |
| 705 } | 705 } |
| 706 | 706 |
| 707 | 707 |
| 708 Expression* ParserTraits::ExpressionFromIdentifier(const AstRawString* name, | 708 Expression* ParserTraits::ExpressionFromIdentifier(const AstRawString* name, |
| 709 int pos, Scope* scope, | 709 int start_position, |
| 710 int end_position, | |
| 711 Scope* scope, | |
| 710 AstNodeFactory* factory) { | 712 AstNodeFactory* factory) { |
| 711 if (parser_->fni_ != NULL) parser_->fni_->PushVariableName(name); | 713 if (parser_->fni_ != NULL) parser_->fni_->PushVariableName(name); |
| 712 | 714 |
| 713 // Arrow function parameters are parsed as an expression. When | 715 // Arrow function parameters are parsed as an expression. When |
| 714 // parsing lazily, it is enough to create a VariableProxy in order | 716 // parsing lazily, it is enough to create a VariableProxy in order |
| 715 // for Traits::DeclareArrowParametersFromExpression() to be able to | 717 // for Traits::DeclareArrowParametersFromExpression() to be able to |
| 716 // pick the names of the parameters. | 718 // pick the names of the parameters. |
| 717 return parser_->parsing_lazy_arrow_parameters_ | 719 return parser_->parsing_lazy_arrow_parameters_ |
| 718 ? factory->NewVariableProxy(name, false, pos) | 720 ? factory->NewVariableProxy(name, false, start_position, |
| 719 : scope->NewUnresolved(factory, name, pos); | 721 end_position) |
| 722 : scope->NewUnresolved(factory, name, start_position, | |
| 723 end_position); | |
| 720 } | 724 } |
| 721 | 725 |
| 722 | 726 |
| 723 Expression* ParserTraits::ExpressionFromString(int pos, Scanner* scanner, | 727 Expression* ParserTraits::ExpressionFromString(int pos, Scanner* scanner, |
| 724 AstNodeFactory* factory) { | 728 AstNodeFactory* factory) { |
| 725 const AstRawString* symbol = GetSymbol(scanner); | 729 const AstRawString* symbol = GetSymbol(scanner); |
| 726 if (parser_->fni_ != NULL) parser_->fni_->PushLiteralName(symbol); | 730 if (parser_->fni_ != NULL) parser_->fni_->PushLiteralName(symbol); |
| 727 return factory->NewStringLiteral(symbol, pos); | 731 return factory->NewStringLiteral(symbol, pos); |
| 728 } | 732 } |
| 729 | 733 |
| (...skipping 1034 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1764 } | 1768 } |
| 1765 | 1769 |
| 1766 | 1770 |
| 1767 VariableProxy* Parser::NewUnresolved(const AstRawString* name, | 1771 VariableProxy* Parser::NewUnresolved(const AstRawString* name, |
| 1768 VariableMode mode) { | 1772 VariableMode mode) { |
| 1769 // If we are inside a function, a declaration of a var/const variable is a | 1773 // If we are inside a function, a declaration of a var/const variable is a |
| 1770 // truly local variable, and the scope of the variable is always the function | 1774 // truly local variable, and the scope of the variable is always the function |
| 1771 // scope. | 1775 // scope. |
| 1772 // Let/const variables in harmony mode are always added to the immediately | 1776 // Let/const variables in harmony mode are always added to the immediately |
| 1773 // enclosing scope. | 1777 // enclosing scope. |
| 1774 return DeclarationScope(mode)->NewUnresolved(factory(), name, position()); | 1778 return DeclarationScope(mode)->NewUnresolved(factory(), name, |
| 1779 scanner()->location().beg_pos, | |
| 1780 scanner()->location().end_pos); | |
| 1775 } | 1781 } |
| 1776 | 1782 |
| 1777 | 1783 |
| 1778 void Parser::Declare(Declaration* declaration, bool resolve, bool* ok) { | 1784 Variable* Parser::Declare(Declaration* declaration, bool resolve, bool* ok) { |
| 1779 VariableProxy* proxy = declaration->proxy(); | 1785 VariableProxy* proxy = declaration->proxy(); |
| 1780 DCHECK(proxy->raw_name() != NULL); | 1786 DCHECK(proxy->raw_name() != NULL); |
| 1781 const AstRawString* name = proxy->raw_name(); | 1787 const AstRawString* name = proxy->raw_name(); |
| 1782 VariableMode mode = declaration->mode(); | 1788 VariableMode mode = declaration->mode(); |
| 1783 Scope* declaration_scope = DeclarationScope(mode); | 1789 Scope* declaration_scope = DeclarationScope(mode); |
| 1784 Variable* var = NULL; | 1790 Variable* var = NULL; |
| 1785 | 1791 |
| 1786 // If a suitable scope exists, then we can statically declare this | 1792 // If a suitable scope exists, then we can statically declare this |
| 1787 // variable and also set its mode. In any case, a Declaration node | 1793 // variable and also set its mode. In any case, a Declaration node |
| 1788 // will be added to the scope so that the declaration can be added | 1794 // will be added to the scope so that the declaration can be added |
| 1789 // to the corresponding activation frame at runtime if necessary. | 1795 // to the corresponding activation frame at runtime if necessary. |
| 1790 // For instance declarations inside an eval scope need to be added | 1796 // For instance declarations inside an eval scope need to be added |
| 1791 // to the calling function context. | 1797 // to the calling function context. |
| 1792 // Similarly, strict mode eval scope does not leak variable declarations to | 1798 // Similarly, strict mode eval scope does not leak variable declarations to |
| 1793 // the caller's scope so we declare all locals, too. | 1799 // the caller's scope so we declare all locals, too. |
| 1794 if (declaration_scope->is_function_scope() || | 1800 if (declaration_scope->is_function_scope() || |
| 1795 declaration_scope->is_strict_eval_scope() || | 1801 declaration_scope->is_strict_eval_scope() || |
| 1796 declaration_scope->is_block_scope() || | 1802 declaration_scope->is_block_scope() || |
| 1797 declaration_scope->is_module_scope() || | 1803 declaration_scope->is_module_scope() || |
| 1798 declaration_scope->is_script_scope()) { | 1804 declaration_scope->is_script_scope()) { |
| 1799 // Declare the variable in the declaration scope. | 1805 // Declare the variable in the declaration scope. |
| 1800 var = declaration_scope->LookupLocal(name); | 1806 var = declaration_scope->LookupLocal(name); |
| 1801 if (var == NULL) { | 1807 if (var == NULL) { |
| 1802 // Declare the name. | 1808 // Declare the name. |
| 1803 var = declaration_scope->DeclareLocal( | 1809 var = declaration_scope->DeclareLocal( |
| 1804 name, mode, declaration->initialization(), kNotAssigned); | 1810 name, mode, declaration->initialization(), |
| 1805 } else if (IsLexicalVariableMode(mode) || IsLexicalVariableMode(var->mode()) | 1811 declaration->IsFunctionDeclaration(), kNotAssigned); |
| 1806 || ((mode == CONST_LEGACY || var->mode() == CONST_LEGACY) && | 1812 } else if (IsLexicalVariableMode(mode) || |
| 1807 !declaration_scope->is_script_scope())) { | 1813 IsLexicalVariableMode(var->mode()) || |
| 1814 ((mode == CONST_LEGACY || var->mode() == CONST_LEGACY) && | |
| 1815 !declaration_scope->is_script_scope())) { | |
| 1808 // The name was declared in this scope before; check for conflicting | 1816 // The name was declared in this scope before; check for conflicting |
| 1809 // re-declarations. We have a conflict if either of the declarations is | 1817 // re-declarations. We have a conflict if either of the declarations is |
| 1810 // not a var (in script scope, we also have to ignore legacy const for | 1818 // not a var (in script scope, we also have to ignore legacy const for |
| 1811 // compatibility). There is similar code in runtime.cc in the Declare | 1819 // compatibility). There is similar code in runtime.cc in the Declare |
| 1812 // functions. The function CheckConflictingVarDeclarations checks for | 1820 // functions. The function CheckConflictingVarDeclarations checks for |
| 1813 // var and let bindings from different scopes whereas this is a check for | 1821 // var and let bindings from different scopes whereas this is a check for |
| 1814 // conflicting declarations within the same scope. This check also covers | 1822 // conflicting declarations within the same scope. This check also covers |
| 1815 // the special case | 1823 // the special case |
| 1816 // | 1824 // |
| 1817 // function () { let x; { var x; } } | 1825 // function () { let x; { var x; } } |
| 1818 // | 1826 // |
| 1819 // because the var declaration is hoisted to the function scope where 'x' | 1827 // because the var declaration is hoisted to the function scope where 'x' |
| 1820 // is already bound. | 1828 // is already bound. |
| 1821 DCHECK(IsDeclaredVariableMode(var->mode())); | 1829 DCHECK(IsDeclaredVariableMode(var->mode())); |
| 1822 if (allow_harmony_scoping() && is_strict(language_mode())) { | 1830 if (allow_harmony_scoping() && is_strict(language_mode())) { |
| 1823 // In harmony we treat re-declarations as early errors. See | 1831 // In harmony we treat re-declarations as early errors. See |
| 1824 // ES5 16 for a definition of early errors. | 1832 // ES5 16 for a definition of early errors. |
| 1825 ParserTraits::ReportMessage("var_redeclaration", name); | 1833 ParserTraits::ReportMessage("var_redeclaration", name); |
| 1826 *ok = false; | 1834 *ok = false; |
| 1827 return; | 1835 return nullptr; |
| 1828 } | 1836 } |
| 1829 Expression* expression = NewThrowTypeError( | 1837 Expression* expression = NewThrowTypeError( |
| 1830 "var_redeclaration", name, declaration->position()); | 1838 "var_redeclaration", name, declaration->position()); |
| 1831 declaration_scope->SetIllegalRedeclaration(expression); | 1839 declaration_scope->SetIllegalRedeclaration(expression); |
| 1832 } else if (mode == VAR) { | 1840 } else if (mode == VAR) { |
| 1833 var->set_maybe_assigned(); | 1841 var->set_maybe_assigned(); |
| 1834 } | 1842 } |
| 1835 } | 1843 } |
| 1836 | 1844 |
| 1837 // We add a declaration node for every declaration. The compiler | 1845 // We add a declaration node for every declaration. The compiler |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1891 // Note that if 'f' is accessed from inside the 'with' statement, it | 1899 // Note that if 'f' is accessed from inside the 'with' statement, it |
| 1892 // will be allocated in the context (because we must be able to look | 1900 // will be allocated in the context (because we must be able to look |
| 1893 // it up dynamically) but it will also be accessed statically, i.e., | 1901 // it up dynamically) but it will also be accessed statically, i.e., |
| 1894 // with a context slot index and a context chain length for this | 1902 // with a context slot index and a context chain length for this |
| 1895 // initialization code. Thus, inside the 'with' statement, we need | 1903 // initialization code. Thus, inside the 'with' statement, we need |
| 1896 // both access to the static and the dynamic context chain; the | 1904 // both access to the static and the dynamic context chain; the |
| 1897 // runtime needs to provide both. | 1905 // runtime needs to provide both. |
| 1898 if (resolve && var != NULL) { | 1906 if (resolve && var != NULL) { |
| 1899 proxy->BindTo(var); | 1907 proxy->BindTo(var); |
| 1900 } | 1908 } |
| 1909 return var; | |
| 1901 } | 1910 } |
| 1902 | 1911 |
| 1903 | 1912 |
| 1904 // Language extension which is only enabled for source files loaded | 1913 // Language extension which is only enabled for source files loaded |
| 1905 // through the API's extension mechanism. A native function | 1914 // through the API's extension mechanism. A native function |
| 1906 // declaration is resolved by looking up the function through a | 1915 // declaration is resolved by looking up the function through a |
| 1907 // callback provided by the extension. | 1916 // callback provided by the extension. |
| 1908 Statement* Parser::ParseNativeDeclaration(bool* ok) { | 1917 Statement* Parser::ParseNativeDeclaration(bool* ok) { |
| 1909 int pos = peek_position(); | 1918 int pos = peek_position(); |
| 1910 Expect(Token::FUNCTION, CHECK_OK); | 1919 Expect(Token::FUNCTION, CHECK_OK); |
| (...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2011 const AstRawString* name = | 2020 const AstRawString* name = |
| 2012 ParseIdentifierOrStrictReservedWord(&is_strict_reserved, CHECK_OK); | 2021 ParseIdentifierOrStrictReservedWord(&is_strict_reserved, CHECK_OK); |
| 2013 ClassLiteral* value = ParseClassLiteral(name, scanner()->location(), | 2022 ClassLiteral* value = ParseClassLiteral(name, scanner()->location(), |
| 2014 is_strict_reserved, pos, CHECK_OK); | 2023 is_strict_reserved, pos, CHECK_OK); |
| 2015 | 2024 |
| 2016 VariableMode mode = is_strong(language_mode()) ? CONST : LET; | 2025 VariableMode mode = is_strong(language_mode()) ? CONST : LET; |
| 2017 VariableProxy* proxy = NewUnresolved(name, mode); | 2026 VariableProxy* proxy = NewUnresolved(name, mode); |
| 2018 Declaration* declaration = | 2027 Declaration* declaration = |
| 2019 factory()->NewVariableDeclaration(proxy, mode, scope_, pos); | 2028 factory()->NewVariableDeclaration(proxy, mode, scope_, pos); |
| 2020 Declare(declaration, true, CHECK_OK); | 2029 Declare(declaration, true, CHECK_OK); |
| 2021 proxy->var()->set_initializer_position(pos); | 2030 proxy->var()->set_initializer_position(position()); |
| 2022 | 2031 |
| 2023 Token::Value init_op = | 2032 Token::Value init_op = |
| 2024 is_strong(language_mode()) ? Token::INIT_CONST : Token::INIT_LET; | 2033 is_strong(language_mode()) ? Token::INIT_CONST : Token::INIT_LET; |
| 2025 Assignment* assignment = factory()->NewAssignment(init_op, proxy, value, pos); | 2034 Assignment* assignment = factory()->NewAssignment(init_op, proxy, value, pos); |
| 2026 Statement* assignment_statement = | 2035 Statement* assignment_statement = |
| 2027 factory()->NewExpressionStatement(assignment, RelocInfo::kNoPosition); | 2036 factory()->NewExpressionStatement(assignment, RelocInfo::kNoPosition); |
| 2028 if (names) names->Add(name, zone()); | 2037 if (names) names->Add(name, zone()); |
| 2029 return assignment_statement; | 2038 return assignment_statement; |
| 2030 } | 2039 } |
| 2031 | 2040 |
| (...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2220 is_for_iteration_variable = | 2229 is_for_iteration_variable = |
| 2221 var_context == kForStatement && | 2230 var_context == kForStatement && |
| 2222 (peek() == Token::IN || PeekContextualKeyword(CStrVector("of"))); | 2231 (peek() == Token::IN || PeekContextualKeyword(CStrVector("of"))); |
| 2223 if (is_for_iteration_variable && mode == CONST) { | 2232 if (is_for_iteration_variable && mode == CONST) { |
| 2224 needs_init = false; | 2233 needs_init = false; |
| 2225 } | 2234 } |
| 2226 | 2235 |
| 2227 VariableProxy* proxy = NewUnresolved(name, mode); | 2236 VariableProxy* proxy = NewUnresolved(name, mode); |
| 2228 Declaration* declaration = | 2237 Declaration* declaration = |
| 2229 factory()->NewVariableDeclaration(proxy, mode, scope_, pos); | 2238 factory()->NewVariableDeclaration(proxy, mode, scope_, pos); |
| 2230 Declare(declaration, mode != VAR, CHECK_OK); | 2239 Variable* var = Declare(declaration, mode != VAR, CHECK_OK); |
| 2240 DCHECK(var != nullptr); | |
|
arv (Not doing code reviews)
2015/02/25 16:37:32
DCHECK_NOT_NULL
marja
2015/02/26 12:55:42
Done.
| |
| 2241 DCHECK(!proxy->is_resolved() || proxy->var() == var); | |
| 2231 nvars++; | 2242 nvars++; |
| 2232 if (declaration_scope->num_var_or_const() > kMaxNumFunctionLocals) { | 2243 if (declaration_scope->num_var_or_const() > kMaxNumFunctionLocals) { |
| 2233 ReportMessage("too_many_variables"); | 2244 ReportMessage("too_many_variables"); |
| 2234 *ok = false; | 2245 *ok = false; |
| 2235 return NULL; | 2246 return NULL; |
| 2236 } | 2247 } |
| 2237 if (names) names->Add(name, zone()); | 2248 if (names) names->Add(name, zone()); |
| 2238 | 2249 |
| 2239 // Parse initialization expression if present and/or needed. A | 2250 // Parse initialization expression if present and/or needed. A |
| 2240 // declaration of the form: | 2251 // declaration of the form: |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2274 value = ParseAssignmentExpression(var_context != kForStatement, CHECK_OK); | 2285 value = ParseAssignmentExpression(var_context != kForStatement, CHECK_OK); |
| 2275 // Don't infer if it is "a = function(){...}();"-like expression. | 2286 // Don't infer if it is "a = function(){...}();"-like expression. |
| 2276 if (fni_ != NULL && | 2287 if (fni_ != NULL && |
| 2277 value->AsCall() == NULL && | 2288 value->AsCall() == NULL && |
| 2278 value->AsCallNew() == NULL) { | 2289 value->AsCallNew() == NULL) { |
| 2279 fni_->Infer(); | 2290 fni_->Infer(); |
| 2280 } else { | 2291 } else { |
| 2281 fni_->RemoveLastFunction(); | 2292 fni_->RemoveLastFunction(); |
| 2282 } | 2293 } |
| 2283 if (decl_props != NULL) *decl_props = kHasInitializers; | 2294 if (decl_props != NULL) *decl_props = kHasInitializers; |
| 2284 } | 2295 // Record the end position of the initializer. |
| 2285 | 2296 var->set_initializer_position(scanner()->location().end_pos); |
| 2286 // Record the end position of the initializer. | 2297 } else { |
| 2287 if (proxy->is_resolved()) { | 2298 // Record the end position of the initializer. |
|
arv (Not doing code reviews)
2015/02/25 16:37:32
Maybe move this comment to before the if since it
marja
2015/02/26 12:55:42
Hmm, that's kinda far away... instead, I made thes
| |
| 2288 proxy->var()->set_initializer_position(position()); | 2299 var->set_initializer_position(position()); |
| 2289 } | 2300 } |
| 2290 | 2301 |
| 2291 // Make sure that 'const x' and 'let x' initialize 'x' to undefined. | 2302 // Make sure that 'const x' and 'let x' initialize 'x' to undefined. |
| 2292 if (value == NULL && needs_init) { | 2303 if (value == NULL && needs_init) { |
| 2293 value = GetLiteralUndefined(position()); | 2304 value = GetLiteralUndefined(position()); |
| 2294 } | 2305 } |
| 2295 | 2306 |
| 2296 // Global variable declarations must be compiled in a specific | 2307 // Global variable declarations must be compiled in a specific |
| 2297 // way. When the script containing the global variable declaration | 2308 // way. When the script containing the global variable declaration |
| 2298 // is entered, the global variable must be declared, so that if it | 2309 // is entered, the global variable must be declared, so that if it |
| (...skipping 484 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2783 if (tok == Token::CATCH) { | 2794 if (tok == Token::CATCH) { |
| 2784 Consume(Token::CATCH); | 2795 Consume(Token::CATCH); |
| 2785 | 2796 |
| 2786 Expect(Token::LPAREN, CHECK_OK); | 2797 Expect(Token::LPAREN, CHECK_OK); |
| 2787 catch_scope = NewScope(scope_, CATCH_SCOPE); | 2798 catch_scope = NewScope(scope_, CATCH_SCOPE); |
| 2788 catch_scope->set_start_position(scanner()->location().beg_pos); | 2799 catch_scope->set_start_position(scanner()->location().beg_pos); |
| 2789 name = ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK); | 2800 name = ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK); |
| 2790 | 2801 |
| 2791 Expect(Token::RPAREN, CHECK_OK); | 2802 Expect(Token::RPAREN, CHECK_OK); |
| 2792 | 2803 |
| 2793 catch_variable = catch_scope->DeclareLocal(name, VAR, kCreatedInitialized); | 2804 catch_variable = |
| 2805 catch_scope->DeclareLocal(name, VAR, kCreatedInitialized, false); | |
| 2794 BlockState block_state(&scope_, catch_scope); | 2806 BlockState block_state(&scope_, catch_scope); |
| 2795 catch_block = ParseBlock(NULL, CHECK_OK); | 2807 catch_block = ParseBlock(NULL, CHECK_OK); |
| 2796 | 2808 |
| 2797 catch_scope->set_end_position(scanner()->location().end_pos); | 2809 catch_scope->set_end_position(scanner()->location().end_pos); |
| 2798 tok = peek(); | 2810 tok = peek(); |
| 2799 } | 2811 } |
| 2800 | 2812 |
| 2801 Block* finally_block = NULL; | 2813 Block* finally_block = NULL; |
| 2802 DCHECK(tok == Token::FINALLY || catch_block != NULL); | 2814 DCHECK(tok == Token::FINALLY || catch_block != NULL); |
| 2803 if (tok == Token::FINALLY) { | 2815 if (tok == Token::FINALLY) { |
| (...skipping 271 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3075 | 3087 |
| 3076 Block* inner_block = factory()->NewBlock(NULL, names->length() + 4, false, | 3088 Block* inner_block = factory()->NewBlock(NULL, names->length() + 4, false, |
| 3077 RelocInfo::kNoPosition); | 3089 RelocInfo::kNoPosition); |
| 3078 int pos = scanner()->location().beg_pos; | 3090 int pos = scanner()->location().beg_pos; |
| 3079 ZoneList<Variable*> inner_vars(names->length(), zone()); | 3091 ZoneList<Variable*> inner_vars(names->length(), zone()); |
| 3080 | 3092 |
| 3081 // For each let variable x: | 3093 // For each let variable x: |
| 3082 // make statement: let x = temp_x. | 3094 // make statement: let x = temp_x. |
| 3083 for (int i = 0; i < names->length(); i++) { | 3095 for (int i = 0; i < names->length(); i++) { |
| 3084 VariableProxy* proxy = NewUnresolved(names->at(i), LET); | 3096 VariableProxy* proxy = NewUnresolved(names->at(i), LET); |
| 3085 Declaration* declaration = | 3097 Declaration* declaration = factory()->NewVariableDeclaration( |
| 3086 factory()->NewVariableDeclaration(proxy, LET, scope_, pos); | 3098 proxy, LET, scope_, RelocInfo::kNoPosition); |
| 3087 Declare(declaration, true, CHECK_OK); | 3099 Declare(declaration, true, CHECK_OK); |
| 3088 inner_vars.Add(declaration->proxy()->var(), zone()); | 3100 inner_vars.Add(declaration->proxy()->var(), zone()); |
| 3089 VariableProxy* temp_proxy = factory()->NewVariableProxy(temps.at(i)); | 3101 VariableProxy* temp_proxy = factory()->NewVariableProxy(temps.at(i)); |
| 3090 Assignment* assignment = factory()->NewAssignment( | 3102 Assignment* assignment = factory()->NewAssignment( |
| 3091 Token::INIT_LET, proxy, temp_proxy, pos); | 3103 Token::INIT_LET, proxy, temp_proxy, pos); |
| 3092 Statement* assignment_statement = factory()->NewExpressionStatement( | 3104 Statement* assignment_statement = |
| 3093 assignment, pos); | 3105 factory()->NewExpressionStatement(assignment, RelocInfo::kNoPosition); |
| 3094 proxy->var()->set_initializer_position(pos); | 3106 proxy->var()->set_initializer_position(init->position()); |
| 3095 inner_block->AddStatement(assignment_statement, zone()); | 3107 inner_block->AddStatement(assignment_statement, zone()); |
| 3096 } | 3108 } |
| 3097 | 3109 |
| 3098 // Make statement: if (first == 1) { first = 0; } else { next; } | 3110 // Make statement: if (first == 1) { first = 0; } else { next; } |
| 3099 if (next) { | 3111 if (next) { |
| 3100 DCHECK(first); | 3112 DCHECK(first); |
| 3101 Expression* compare = NULL; | 3113 Expression* compare = NULL; |
| 3102 // Make compare expression: first == 1. | 3114 // Make compare expression: first == 1. |
| 3103 { | 3115 { |
| 3104 Expression* const1 = factory()->NewSmiLiteral(1, RelocInfo::kNoPosition); | 3116 Expression* const1 = factory()->NewSmiLiteral(1, RelocInfo::kNoPosition); |
| (...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3232 if (peek() != Token::SEMICOLON) { | 3244 if (peek() != Token::SEMICOLON) { |
| 3233 if (peek() == Token::VAR || | 3245 if (peek() == Token::VAR || |
| 3234 (peek() == Token::CONST && is_sloppy(language_mode()))) { | 3246 (peek() == Token::CONST && is_sloppy(language_mode()))) { |
| 3235 const AstRawString* name = NULL; | 3247 const AstRawString* name = NULL; |
| 3236 VariableDeclarationProperties decl_props = kHasNoInitializers; | 3248 VariableDeclarationProperties decl_props = kHasNoInitializers; |
| 3237 Block* variable_statement = | 3249 Block* variable_statement = |
| 3238 ParseVariableDeclarations(kForStatement, &decl_props, NULL, &name, | 3250 ParseVariableDeclarations(kForStatement, &decl_props, NULL, &name, |
| 3239 CHECK_OK); | 3251 CHECK_OK); |
| 3240 bool accept_OF = decl_props == kHasNoInitializers; | 3252 bool accept_OF = decl_props == kHasNoInitializers; |
| 3241 ForEachStatement::VisitMode mode; | 3253 ForEachStatement::VisitMode mode; |
| 3242 int each_pos = position(); | 3254 int each_beg_pos = scanner()->location().beg_pos; |
| 3255 int each_end_pos = scanner()->location().end_pos; | |
| 3243 | 3256 |
| 3244 if (name != NULL && CheckInOrOf(accept_OF, &mode, ok)) { | 3257 if (name != NULL && CheckInOrOf(accept_OF, &mode, ok)) { |
| 3245 if (!*ok) return nullptr; | 3258 if (!*ok) return nullptr; |
| 3246 ForEachStatement* loop = | 3259 ForEachStatement* loop = |
| 3247 factory()->NewForEachStatement(mode, labels, stmt_pos); | 3260 factory()->NewForEachStatement(mode, labels, stmt_pos); |
| 3248 Target target(&this->target_stack_, loop); | 3261 Target target(&this->target_stack_, loop); |
| 3249 | 3262 |
| 3250 Expression* enumerable = ParseExpression(true, CHECK_OK); | 3263 Expression* enumerable = ParseExpression(true, CHECK_OK); |
| 3251 Expect(Token::RPAREN, CHECK_OK); | 3264 Expect(Token::RPAREN, CHECK_OK); |
| 3252 | 3265 |
| 3253 VariableProxy* each = scope_->NewUnresolved(factory(), name, each_pos); | 3266 VariableProxy* each = |
| 3267 scope_->NewUnresolved(factory(), name, each_beg_pos, each_end_pos); | |
| 3254 Statement* body = ParseSubStatement(NULL, CHECK_OK); | 3268 Statement* body = ParseSubStatement(NULL, CHECK_OK); |
| 3255 InitializeForEachStatement(loop, each, enumerable, body); | 3269 InitializeForEachStatement(loop, each, enumerable, body); |
| 3256 Block* result = | 3270 Block* result = |
| 3257 factory()->NewBlock(NULL, 2, false, RelocInfo::kNoPosition); | 3271 factory()->NewBlock(NULL, 2, false, RelocInfo::kNoPosition); |
| 3258 result->AddStatement(variable_statement, zone()); | 3272 result->AddStatement(variable_statement, zone()); |
| 3259 result->AddStatement(loop, zone()); | 3273 result->AddStatement(loop, zone()); |
| 3260 scope_ = saved_scope; | 3274 scope_ = saved_scope; |
| 3261 for_scope->set_end_position(scanner()->location().end_pos); | 3275 for_scope->set_end_position(scanner()->location().end_pos); |
| 3262 for_scope = for_scope->FinalizeBlockScope(); | 3276 for_scope = for_scope->FinalizeBlockScope(); |
| 3263 DCHECK(for_scope == NULL); | 3277 DCHECK(for_scope == NULL); |
| 3264 // Parsed for-in loop w/ variable/const declaration. | 3278 // Parsed for-in loop w/ variable/const declaration. |
| 3265 return result; | 3279 return result; |
| 3266 } else { | 3280 } else { |
| 3267 init = variable_statement; | 3281 init = variable_statement; |
| 3268 } | 3282 } |
| 3269 } else if ((peek() == Token::LET || peek() == Token::CONST) && | 3283 } else if ((peek() == Token::LET || peek() == Token::CONST) && |
| 3270 is_strict(language_mode())) { | 3284 is_strict(language_mode())) { |
| 3271 bool is_const = peek() == Token::CONST; | 3285 bool is_const = peek() == Token::CONST; |
| 3272 const AstRawString* name = NULL; | 3286 const AstRawString* name = NULL; |
| 3273 VariableDeclarationProperties decl_props = kHasNoInitializers; | 3287 VariableDeclarationProperties decl_props = kHasNoInitializers; |
| 3274 Block* variable_statement = | 3288 Block* variable_statement = |
| 3275 ParseVariableDeclarations(kForStatement, &decl_props, &let_bindings, | 3289 ParseVariableDeclarations(kForStatement, &decl_props, &let_bindings, |
| 3276 &name, CHECK_OK); | 3290 &name, CHECK_OK); |
| 3277 bool accept_IN = name != NULL && decl_props != kHasInitializers; | 3291 bool accept_IN = name != NULL && decl_props != kHasInitializers; |
| 3278 bool accept_OF = decl_props == kHasNoInitializers; | 3292 bool accept_OF = decl_props == kHasNoInitializers; |
| 3279 ForEachStatement::VisitMode mode; | 3293 ForEachStatement::VisitMode mode; |
| 3280 int each_pos = position(); | 3294 int each_beg_pos = scanner()->location().beg_pos; |
| 3295 int each_end_pos = scanner()->location().end_pos; | |
| 3281 | 3296 |
| 3282 if (accept_IN && CheckInOrOf(accept_OF, &mode, ok)) { | 3297 if (accept_IN && CheckInOrOf(accept_OF, &mode, ok)) { |
| 3283 if (!*ok) return nullptr; | 3298 if (!*ok) return nullptr; |
| 3284 | 3299 |
| 3285 // Rewrite a for-in statement of the form | 3300 // Rewrite a for-in statement of the form |
| 3286 // | 3301 // |
| 3287 // for (let/const x in e) b | 3302 // for (let/const x in e) b |
| 3288 // | 3303 // |
| 3289 // into | 3304 // into |
| 3290 // | 3305 // |
| 3291 // <let x' be a temporary variable> | 3306 // <let x' be a temporary variable> |
| 3292 // for (x' in e) { | 3307 // for (x' in e) { |
| 3293 // let/const x; | 3308 // let/const x; |
| 3294 // x = x'; | 3309 // x = x'; |
| 3295 // b; | 3310 // b; |
| 3296 // } | 3311 // } |
| 3297 | 3312 |
| 3298 // TODO(keuchel): Move the temporary variable to the block scope, after | 3313 // TODO(keuchel): Move the temporary variable to the block scope, after |
| 3299 // implementing stack allocated block scoped variables. | 3314 // implementing stack allocated block scoped variables. |
| 3300 Variable* temp = scope_->DeclarationScope()->NewTemporary( | 3315 Variable* temp = scope_->DeclarationScope()->NewTemporary( |
| 3301 ast_value_factory()->dot_for_string()); | 3316 ast_value_factory()->dot_for_string()); |
| 3302 VariableProxy* temp_proxy = factory()->NewVariableProxy(temp, each_pos); | 3317 VariableProxy* temp_proxy = |
| 3318 factory()->NewVariableProxy(temp, each_beg_pos, each_end_pos); | |
| 3303 ForEachStatement* loop = | 3319 ForEachStatement* loop = |
| 3304 factory()->NewForEachStatement(mode, labels, stmt_pos); | 3320 factory()->NewForEachStatement(mode, labels, stmt_pos); |
| 3305 Target target(&this->target_stack_, loop); | 3321 Target target(&this->target_stack_, loop); |
| 3306 | 3322 |
| 3307 // The expression does not see the loop variable. | 3323 // The expression does not see the loop variable. |
| 3308 scope_ = saved_scope; | 3324 scope_ = saved_scope; |
| 3309 Expression* enumerable = ParseExpression(true, CHECK_OK); | 3325 Expression* enumerable = ParseExpression(true, CHECK_OK); |
| 3310 scope_ = for_scope; | 3326 scope_ = for_scope; |
| 3311 Expect(Token::RPAREN, CHECK_OK); | 3327 Expect(Token::RPAREN, CHECK_OK); |
| 3312 | 3328 |
| 3313 VariableProxy* each = scope_->NewUnresolved(factory(), name, each_pos); | 3329 VariableProxy* each = |
| 3330 scope_->NewUnresolved(factory(), name, each_beg_pos, each_end_pos); | |
| 3314 Statement* body = ParseSubStatement(NULL, CHECK_OK); | 3331 Statement* body = ParseSubStatement(NULL, CHECK_OK); |
| 3315 Block* body_block = | 3332 Block* body_block = |
| 3316 factory()->NewBlock(NULL, 3, false, RelocInfo::kNoPosition); | 3333 factory()->NewBlock(NULL, 3, false, RelocInfo::kNoPosition); |
| 3317 Token::Value init_op = is_const ? Token::INIT_CONST : Token::ASSIGN; | 3334 Token::Value init_op = is_const ? Token::INIT_CONST : Token::ASSIGN; |
| 3318 Assignment* assignment = factory()->NewAssignment( | 3335 Assignment* assignment = factory()->NewAssignment( |
| 3319 init_op, each, temp_proxy, RelocInfo::kNoPosition); | 3336 init_op, each, temp_proxy, RelocInfo::kNoPosition); |
| 3320 Statement* assignment_statement = factory()->NewExpressionStatement( | 3337 Statement* assignment_statement = factory()->NewExpressionStatement( |
| 3321 assignment, RelocInfo::kNoPosition); | 3338 assignment, RelocInfo::kNoPosition); |
| 3322 body_block->AddStatement(variable_statement, zone()); | 3339 body_block->AddStatement(variable_statement, zone()); |
| 3323 body_block->AddStatement(assignment_statement, zone()); | 3340 body_block->AddStatement(assignment_statement, zone()); |
| (...skipping 763 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4087 block_scope->set_start_position(scanner()->location().end_pos); | 4104 block_scope->set_start_position(scanner()->location().end_pos); |
| 4088 } | 4105 } |
| 4089 | 4106 |
| 4090 | 4107 |
| 4091 ClassLiteralChecker checker(this); | 4108 ClassLiteralChecker checker(this); |
| 4092 ZoneList<ObjectLiteral::Property*>* properties = NewPropertyList(4, zone()); | 4109 ZoneList<ObjectLiteral::Property*>* properties = NewPropertyList(4, zone()); |
| 4093 FunctionLiteral* constructor = NULL; | 4110 FunctionLiteral* constructor = NULL; |
| 4094 bool has_seen_constructor = false; | 4111 bool has_seen_constructor = false; |
| 4095 | 4112 |
| 4096 Expect(Token::LBRACE, CHECK_OK); | 4113 Expect(Token::LBRACE, CHECK_OK); |
| 4114 int body_beg_pos = scanner()->location().beg_pos; | |
| 4115 | |
| 4097 const bool has_extends = extends != nullptr; | 4116 const bool has_extends = extends != nullptr; |
| 4098 while (peek() != Token::RBRACE) { | 4117 while (peek() != Token::RBRACE) { |
| 4099 if (Check(Token::SEMICOLON)) continue; | 4118 if (Check(Token::SEMICOLON)) continue; |
| 4100 if (fni_ != NULL) fni_->Enter(); | 4119 if (fni_ != NULL) fni_->Enter(); |
| 4101 const bool in_class = true; | 4120 const bool in_class = true; |
| 4102 const bool is_static = false; | 4121 const bool is_static = false; |
| 4103 bool is_computed_name = false; // Classes do not care about computed | 4122 bool is_computed_name = false; // Classes do not care about computed |
| 4104 // property names here. | 4123 // property names here. |
| 4105 ObjectLiteral::Property* property = ParsePropertyDefinition( | 4124 ObjectLiteral::Property* property = ParsePropertyDefinition( |
| 4106 &checker, in_class, has_extends, is_static, &is_computed_name, | 4125 &checker, in_class, has_extends, is_static, &is_computed_name, |
| (...skipping 19 matching lines...) Expand all Loading... | |
| 4126 constructor = | 4145 constructor = |
| 4127 DefaultConstructor(extends != NULL, block_scope, pos, end_pos); | 4146 DefaultConstructor(extends != NULL, block_scope, pos, end_pos); |
| 4128 } | 4147 } |
| 4129 | 4148 |
| 4130 block_scope->set_end_position(end_pos); | 4149 block_scope->set_end_position(end_pos); |
| 4131 block_scope = block_scope->FinalizeBlockScope(); | 4150 block_scope = block_scope->FinalizeBlockScope(); |
| 4132 | 4151 |
| 4133 if (name != NULL) { | 4152 if (name != NULL) { |
| 4134 DCHECK_NOT_NULL(proxy); | 4153 DCHECK_NOT_NULL(proxy); |
| 4135 DCHECK_NOT_NULL(block_scope); | 4154 DCHECK_NOT_NULL(block_scope); |
| 4136 proxy->var()->set_initializer_position(end_pos); | 4155 proxy->var()->set_initializer_position(body_beg_pos); |
| 4137 } | 4156 } |
| 4138 | 4157 |
| 4139 return factory()->NewClassLiteral(name, block_scope, proxy, extends, | 4158 return factory()->NewClassLiteral(name, block_scope, proxy, extends, |
| 4140 constructor, properties, pos, end_pos); | 4159 constructor, properties, pos, end_pos); |
| 4141 } | 4160 } |
| 4142 | 4161 |
| 4143 | 4162 |
| 4144 Expression* Parser::ParseV8Intrinsic(bool* ok) { | 4163 Expression* Parser::ParseV8Intrinsic(bool* ok) { |
| 4145 // CallRuntime :: | 4164 // CallRuntime :: |
| 4146 // '%' Identifier Arguments | 4165 // '%' Identifier Arguments |
| (...skipping 1267 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 5414 } else { | 5433 } else { |
| 5415 const uc16* data = reinterpret_cast<const uc16*>(raw_string->raw_data()); | 5434 const uc16* data = reinterpret_cast<const uc16*>(raw_string->raw_data()); |
| 5416 running_hash = StringHasher::ComputeRunningHash(running_hash, data, | 5435 running_hash = StringHasher::ComputeRunningHash(running_hash, data, |
| 5417 raw_string->length()); | 5436 raw_string->length()); |
| 5418 } | 5437 } |
| 5419 } | 5438 } |
| 5420 | 5439 |
| 5421 return running_hash; | 5440 return running_hash; |
| 5422 } | 5441 } |
| 5423 } } // namespace v8::internal | 5442 } } // namespace v8::internal |
| OLD | NEW |