| 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() ? Variable::FUNCTION |
| 1806 || ((mode == CONST_LEGACY || var->mode() == CONST_LEGACY) && | 1812 : Variable::NORMAL, |
| 1807 !declaration_scope->is_script_scope())) { | 1813 kNotAssigned); |
| 1814 } else if (IsLexicalVariableMode(mode) || |
| 1815 IsLexicalVariableMode(var->mode()) || |
| 1816 ((mode == CONST_LEGACY || var->mode() == CONST_LEGACY) && |
| 1817 !declaration_scope->is_script_scope())) { |
| 1808 // The name was declared in this scope before; check for conflicting | 1818 // The name was declared in this scope before; check for conflicting |
| 1809 // re-declarations. We have a conflict if either of the declarations is | 1819 // 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 | 1820 // 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 | 1821 // compatibility). There is similar code in runtime.cc in the Declare |
| 1812 // functions. The function CheckConflictingVarDeclarations checks for | 1822 // functions. The function CheckConflictingVarDeclarations checks for |
| 1813 // var and let bindings from different scopes whereas this is a check for | 1823 // var and let bindings from different scopes whereas this is a check for |
| 1814 // conflicting declarations within the same scope. This check also covers | 1824 // conflicting declarations within the same scope. This check also covers |
| 1815 // the special case | 1825 // the special case |
| 1816 // | 1826 // |
| 1817 // function () { let x; { var x; } } | 1827 // function () { let x; { var x; } } |
| 1818 // | 1828 // |
| 1819 // because the var declaration is hoisted to the function scope where 'x' | 1829 // because the var declaration is hoisted to the function scope where 'x' |
| 1820 // is already bound. | 1830 // is already bound. |
| 1821 DCHECK(IsDeclaredVariableMode(var->mode())); | 1831 DCHECK(IsDeclaredVariableMode(var->mode())); |
| 1822 if (allow_harmony_scoping() && is_strict(language_mode())) { | 1832 if (allow_harmony_scoping() && is_strict(language_mode())) { |
| 1823 // In harmony we treat re-declarations as early errors. See | 1833 // In harmony we treat re-declarations as early errors. See |
| 1824 // ES5 16 for a definition of early errors. | 1834 // ES5 16 for a definition of early errors. |
| 1825 ParserTraits::ReportMessage("var_redeclaration", name); | 1835 ParserTraits::ReportMessage("var_redeclaration", name); |
| 1826 *ok = false; | 1836 *ok = false; |
| 1827 return; | 1837 return nullptr; |
| 1828 } | 1838 } |
| 1829 Expression* expression = NewThrowTypeError( | 1839 Expression* expression = NewThrowTypeError( |
| 1830 "var_redeclaration", name, declaration->position()); | 1840 "var_redeclaration", name, declaration->position()); |
| 1831 declaration_scope->SetIllegalRedeclaration(expression); | 1841 declaration_scope->SetIllegalRedeclaration(expression); |
| 1832 } else if (mode == VAR) { | 1842 } else if (mode == VAR) { |
| 1833 var->set_maybe_assigned(); | 1843 var->set_maybe_assigned(); |
| 1834 } | 1844 } |
| 1835 } | 1845 } |
| 1836 | 1846 |
| 1837 // We add a declaration node for every declaration. The compiler | 1847 // 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 | 1901 // 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 | 1902 // 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., | 1903 // 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 | 1904 // with a context slot index and a context chain length for this |
| 1895 // initialization code. Thus, inside the 'with' statement, we need | 1905 // initialization code. Thus, inside the 'with' statement, we need |
| 1896 // both access to the static and the dynamic context chain; the | 1906 // both access to the static and the dynamic context chain; the |
| 1897 // runtime needs to provide both. | 1907 // runtime needs to provide both. |
| 1898 if (resolve && var != NULL) { | 1908 if (resolve && var != NULL) { |
| 1899 proxy->BindTo(var); | 1909 proxy->BindTo(var); |
| 1900 } | 1910 } |
| 1911 return var; |
| 1901 } | 1912 } |
| 1902 | 1913 |
| 1903 | 1914 |
| 1904 // Language extension which is only enabled for source files loaded | 1915 // Language extension which is only enabled for source files loaded |
| 1905 // through the API's extension mechanism. A native function | 1916 // through the API's extension mechanism. A native function |
| 1906 // declaration is resolved by looking up the function through a | 1917 // declaration is resolved by looking up the function through a |
| 1907 // callback provided by the extension. | 1918 // callback provided by the extension. |
| 1908 Statement* Parser::ParseNativeDeclaration(bool* ok) { | 1919 Statement* Parser::ParseNativeDeclaration(bool* ok) { |
| 1909 int pos = peek_position(); | 1920 int pos = peek_position(); |
| 1910 Expect(Token::FUNCTION, CHECK_OK); | 1921 Expect(Token::FUNCTION, CHECK_OK); |
| (...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2011 const AstRawString* name = | 2022 const AstRawString* name = |
| 2012 ParseIdentifierOrStrictReservedWord(&is_strict_reserved, CHECK_OK); | 2023 ParseIdentifierOrStrictReservedWord(&is_strict_reserved, CHECK_OK); |
| 2013 ClassLiteral* value = ParseClassLiteral(name, scanner()->location(), | 2024 ClassLiteral* value = ParseClassLiteral(name, scanner()->location(), |
| 2014 is_strict_reserved, pos, CHECK_OK); | 2025 is_strict_reserved, pos, CHECK_OK); |
| 2015 | 2026 |
| 2016 VariableMode mode = is_strong(language_mode()) ? CONST : LET; | 2027 VariableMode mode = is_strong(language_mode()) ? CONST : LET; |
| 2017 VariableProxy* proxy = NewUnresolved(name, mode); | 2028 VariableProxy* proxy = NewUnresolved(name, mode); |
| 2018 Declaration* declaration = | 2029 Declaration* declaration = |
| 2019 factory()->NewVariableDeclaration(proxy, mode, scope_, pos); | 2030 factory()->NewVariableDeclaration(proxy, mode, scope_, pos); |
| 2020 Declare(declaration, true, CHECK_OK); | 2031 Declare(declaration, true, CHECK_OK); |
| 2021 proxy->var()->set_initializer_position(pos); | 2032 proxy->var()->set_initializer_position(position()); |
| 2022 | 2033 |
| 2023 Token::Value init_op = | 2034 Token::Value init_op = |
| 2024 is_strong(language_mode()) ? Token::INIT_CONST : Token::INIT_LET; | 2035 is_strong(language_mode()) ? Token::INIT_CONST : Token::INIT_LET; |
| 2025 Assignment* assignment = factory()->NewAssignment(init_op, proxy, value, pos); | 2036 Assignment* assignment = factory()->NewAssignment(init_op, proxy, value, pos); |
| 2026 Statement* assignment_statement = | 2037 Statement* assignment_statement = |
| 2027 factory()->NewExpressionStatement(assignment, RelocInfo::kNoPosition); | 2038 factory()->NewExpressionStatement(assignment, RelocInfo::kNoPosition); |
| 2028 if (names) names->Add(name, zone()); | 2039 if (names) names->Add(name, zone()); |
| 2029 return assignment_statement; | 2040 return assignment_statement; |
| 2030 } | 2041 } |
| 2031 | 2042 |
| (...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2220 is_for_iteration_variable = | 2231 is_for_iteration_variable = |
| 2221 var_context == kForStatement && | 2232 var_context == kForStatement && |
| 2222 (peek() == Token::IN || PeekContextualKeyword(CStrVector("of"))); | 2233 (peek() == Token::IN || PeekContextualKeyword(CStrVector("of"))); |
| 2223 if (is_for_iteration_variable && mode == CONST) { | 2234 if (is_for_iteration_variable && mode == CONST) { |
| 2224 needs_init = false; | 2235 needs_init = false; |
| 2225 } | 2236 } |
| 2226 | 2237 |
| 2227 VariableProxy* proxy = NewUnresolved(name, mode); | 2238 VariableProxy* proxy = NewUnresolved(name, mode); |
| 2228 Declaration* declaration = | 2239 Declaration* declaration = |
| 2229 factory()->NewVariableDeclaration(proxy, mode, scope_, pos); | 2240 factory()->NewVariableDeclaration(proxy, mode, scope_, pos); |
| 2230 Declare(declaration, mode != VAR, CHECK_OK); | 2241 Variable* var = Declare(declaration, mode != VAR, CHECK_OK); |
| 2242 DCHECK_NOT_NULL(var); |
| 2243 DCHECK(!proxy->is_resolved() || proxy->var() == var); |
| 2231 nvars++; | 2244 nvars++; |
| 2232 if (declaration_scope->num_var_or_const() > kMaxNumFunctionLocals) { | 2245 if (declaration_scope->num_var_or_const() > kMaxNumFunctionLocals) { |
| 2233 ReportMessage("too_many_variables"); | 2246 ReportMessage("too_many_variables"); |
| 2234 *ok = false; | 2247 *ok = false; |
| 2235 return NULL; | 2248 return NULL; |
| 2236 } | 2249 } |
| 2237 if (names) names->Add(name, zone()); | 2250 if (names) names->Add(name, zone()); |
| 2238 | 2251 |
| 2239 // Parse initialization expression if present and/or needed. A | 2252 // Parse initialization expression if present and/or needed. A |
| 2240 // declaration of the form: | 2253 // 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); | 2287 value = ParseAssignmentExpression(var_context != kForStatement, CHECK_OK); |
| 2275 // Don't infer if it is "a = function(){...}();"-like expression. | 2288 // Don't infer if it is "a = function(){...}();"-like expression. |
| 2276 if (fni_ != NULL && | 2289 if (fni_ != NULL && |
| 2277 value->AsCall() == NULL && | 2290 value->AsCall() == NULL && |
| 2278 value->AsCallNew() == NULL) { | 2291 value->AsCallNew() == NULL) { |
| 2279 fni_->Infer(); | 2292 fni_->Infer(); |
| 2280 } else { | 2293 } else { |
| 2281 fni_->RemoveLastFunction(); | 2294 fni_->RemoveLastFunction(); |
| 2282 } | 2295 } |
| 2283 if (decl_props != NULL) *decl_props = kHasInitializers; | 2296 if (decl_props != NULL) *decl_props = kHasInitializers; |
| 2284 } | 2297 // End position of the initializer is after the assignment expression. |
| 2285 | 2298 var->set_initializer_position(scanner()->location().end_pos); |
| 2286 // Record the end position of the initializer. | 2299 } else { |
| 2287 if (proxy->is_resolved()) { | 2300 // End position of the initializer is after the variable. |
| 2288 proxy->var()->set_initializer_position(position()); | 2301 var->set_initializer_position(position()); |
| 2289 } | 2302 } |
| 2290 | 2303 |
| 2291 // Make sure that 'const x' and 'let x' initialize 'x' to undefined. | 2304 // Make sure that 'const x' and 'let x' initialize 'x' to undefined. |
| 2292 if (value == NULL && needs_init) { | 2305 if (value == NULL && needs_init) { |
| 2293 value = GetLiteralUndefined(position()); | 2306 value = GetLiteralUndefined(position()); |
| 2294 } | 2307 } |
| 2295 | 2308 |
| 2296 // Global variable declarations must be compiled in a specific | 2309 // Global variable declarations must be compiled in a specific |
| 2297 // way. When the script containing the global variable declaration | 2310 // way. When the script containing the global variable declaration |
| 2298 // is entered, the global variable must be declared, so that if it | 2311 // 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) { | 2796 if (tok == Token::CATCH) { |
| 2784 Consume(Token::CATCH); | 2797 Consume(Token::CATCH); |
| 2785 | 2798 |
| 2786 Expect(Token::LPAREN, CHECK_OK); | 2799 Expect(Token::LPAREN, CHECK_OK); |
| 2787 catch_scope = NewScope(scope_, CATCH_SCOPE); | 2800 catch_scope = NewScope(scope_, CATCH_SCOPE); |
| 2788 catch_scope->set_start_position(scanner()->location().beg_pos); | 2801 catch_scope->set_start_position(scanner()->location().beg_pos); |
| 2789 name = ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK); | 2802 name = ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK); |
| 2790 | 2803 |
| 2791 Expect(Token::RPAREN, CHECK_OK); | 2804 Expect(Token::RPAREN, CHECK_OK); |
| 2792 | 2805 |
| 2793 catch_variable = catch_scope->DeclareLocal(name, VAR, kCreatedInitialized); | 2806 catch_variable = catch_scope->DeclareLocal(name, VAR, kCreatedInitialized, |
| 2807 Variable::NORMAL); |
| 2794 BlockState block_state(&scope_, catch_scope); | 2808 BlockState block_state(&scope_, catch_scope); |
| 2795 catch_block = ParseBlock(NULL, CHECK_OK); | 2809 catch_block = ParseBlock(NULL, CHECK_OK); |
| 2796 | 2810 |
| 2797 catch_scope->set_end_position(scanner()->location().end_pos); | 2811 catch_scope->set_end_position(scanner()->location().end_pos); |
| 2798 tok = peek(); | 2812 tok = peek(); |
| 2799 } | 2813 } |
| 2800 | 2814 |
| 2801 Block* finally_block = NULL; | 2815 Block* finally_block = NULL; |
| 2802 DCHECK(tok == Token::FINALLY || catch_block != NULL); | 2816 DCHECK(tok == Token::FINALLY || catch_block != NULL); |
| 2803 if (tok == Token::FINALLY) { | 2817 if (tok == Token::FINALLY) { |
| (...skipping 271 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3075 | 3089 |
| 3076 Block* inner_block = factory()->NewBlock(NULL, names->length() + 4, false, | 3090 Block* inner_block = factory()->NewBlock(NULL, names->length() + 4, false, |
| 3077 RelocInfo::kNoPosition); | 3091 RelocInfo::kNoPosition); |
| 3078 int pos = scanner()->location().beg_pos; | 3092 int pos = scanner()->location().beg_pos; |
| 3079 ZoneList<Variable*> inner_vars(names->length(), zone()); | 3093 ZoneList<Variable*> inner_vars(names->length(), zone()); |
| 3080 | 3094 |
| 3081 // For each let variable x: | 3095 // For each let variable x: |
| 3082 // make statement: let x = temp_x. | 3096 // make statement: let x = temp_x. |
| 3083 for (int i = 0; i < names->length(); i++) { | 3097 for (int i = 0; i < names->length(); i++) { |
| 3084 VariableProxy* proxy = NewUnresolved(names->at(i), LET); | 3098 VariableProxy* proxy = NewUnresolved(names->at(i), LET); |
| 3085 Declaration* declaration = | 3099 Declaration* declaration = factory()->NewVariableDeclaration( |
| 3086 factory()->NewVariableDeclaration(proxy, LET, scope_, pos); | 3100 proxy, LET, scope_, RelocInfo::kNoPosition); |
| 3087 Declare(declaration, true, CHECK_OK); | 3101 Declare(declaration, true, CHECK_OK); |
| 3088 inner_vars.Add(declaration->proxy()->var(), zone()); | 3102 inner_vars.Add(declaration->proxy()->var(), zone()); |
| 3089 VariableProxy* temp_proxy = factory()->NewVariableProxy(temps.at(i)); | 3103 VariableProxy* temp_proxy = factory()->NewVariableProxy(temps.at(i)); |
| 3090 Assignment* assignment = factory()->NewAssignment( | 3104 Assignment* assignment = factory()->NewAssignment( |
| 3091 Token::INIT_LET, proxy, temp_proxy, pos); | 3105 Token::INIT_LET, proxy, temp_proxy, pos); |
| 3092 Statement* assignment_statement = factory()->NewExpressionStatement( | 3106 Statement* assignment_statement = |
| 3093 assignment, pos); | 3107 factory()->NewExpressionStatement(assignment, RelocInfo::kNoPosition); |
| 3094 proxy->var()->set_initializer_position(pos); | 3108 proxy->var()->set_initializer_position(init->position()); |
| 3095 inner_block->AddStatement(assignment_statement, zone()); | 3109 inner_block->AddStatement(assignment_statement, zone()); |
| 3096 } | 3110 } |
| 3097 | 3111 |
| 3098 // Make statement: if (first == 1) { first = 0; } else { next; } | 3112 // Make statement: if (first == 1) { first = 0; } else { next; } |
| 3099 if (next) { | 3113 if (next) { |
| 3100 DCHECK(first); | 3114 DCHECK(first); |
| 3101 Expression* compare = NULL; | 3115 Expression* compare = NULL; |
| 3102 // Make compare expression: first == 1. | 3116 // Make compare expression: first == 1. |
| 3103 { | 3117 { |
| 3104 Expression* const1 = factory()->NewSmiLiteral(1, RelocInfo::kNoPosition); | 3118 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) { | 3246 if (peek() != Token::SEMICOLON) { |
| 3233 if (peek() == Token::VAR || | 3247 if (peek() == Token::VAR || |
| 3234 (peek() == Token::CONST && is_sloppy(language_mode()))) { | 3248 (peek() == Token::CONST && is_sloppy(language_mode()))) { |
| 3235 const AstRawString* name = NULL; | 3249 const AstRawString* name = NULL; |
| 3236 VariableDeclarationProperties decl_props = kHasNoInitializers; | 3250 VariableDeclarationProperties decl_props = kHasNoInitializers; |
| 3237 Block* variable_statement = | 3251 Block* variable_statement = |
| 3238 ParseVariableDeclarations(kForStatement, &decl_props, NULL, &name, | 3252 ParseVariableDeclarations(kForStatement, &decl_props, NULL, &name, |
| 3239 CHECK_OK); | 3253 CHECK_OK); |
| 3240 bool accept_OF = decl_props == kHasNoInitializers; | 3254 bool accept_OF = decl_props == kHasNoInitializers; |
| 3241 ForEachStatement::VisitMode mode; | 3255 ForEachStatement::VisitMode mode; |
| 3242 int each_pos = position(); | 3256 int each_beg_pos = scanner()->location().beg_pos; |
| 3257 int each_end_pos = scanner()->location().end_pos; |
| 3243 | 3258 |
| 3244 if (name != NULL && CheckInOrOf(accept_OF, &mode, ok)) { | 3259 if (name != NULL && CheckInOrOf(accept_OF, &mode, ok)) { |
| 3245 if (!*ok) return nullptr; | 3260 if (!*ok) return nullptr; |
| 3246 ForEachStatement* loop = | 3261 ForEachStatement* loop = |
| 3247 factory()->NewForEachStatement(mode, labels, stmt_pos); | 3262 factory()->NewForEachStatement(mode, labels, stmt_pos); |
| 3248 Target target(&this->target_stack_, loop); | 3263 Target target(&this->target_stack_, loop); |
| 3249 | 3264 |
| 3250 Expression* enumerable = ParseExpression(true, CHECK_OK); | 3265 Expression* enumerable = ParseExpression(true, CHECK_OK); |
| 3251 Expect(Token::RPAREN, CHECK_OK); | 3266 Expect(Token::RPAREN, CHECK_OK); |
| 3252 | 3267 |
| 3253 VariableProxy* each = scope_->NewUnresolved(factory(), name, each_pos); | 3268 VariableProxy* each = |
| 3269 scope_->NewUnresolved(factory(), name, each_beg_pos, each_end_pos); |
| 3254 Statement* body = ParseSubStatement(NULL, CHECK_OK); | 3270 Statement* body = ParseSubStatement(NULL, CHECK_OK); |
| 3255 InitializeForEachStatement(loop, each, enumerable, body); | 3271 InitializeForEachStatement(loop, each, enumerable, body); |
| 3256 Block* result = | 3272 Block* result = |
| 3257 factory()->NewBlock(NULL, 2, false, RelocInfo::kNoPosition); | 3273 factory()->NewBlock(NULL, 2, false, RelocInfo::kNoPosition); |
| 3258 result->AddStatement(variable_statement, zone()); | 3274 result->AddStatement(variable_statement, zone()); |
| 3259 result->AddStatement(loop, zone()); | 3275 result->AddStatement(loop, zone()); |
| 3260 scope_ = saved_scope; | 3276 scope_ = saved_scope; |
| 3261 for_scope->set_end_position(scanner()->location().end_pos); | 3277 for_scope->set_end_position(scanner()->location().end_pos); |
| 3262 for_scope = for_scope->FinalizeBlockScope(); | 3278 for_scope = for_scope->FinalizeBlockScope(); |
| 3263 DCHECK(for_scope == NULL); | 3279 DCHECK(for_scope == NULL); |
| 3264 // Parsed for-in loop w/ variable/const declaration. | 3280 // Parsed for-in loop w/ variable/const declaration. |
| 3265 return result; | 3281 return result; |
| 3266 } else { | 3282 } else { |
| 3267 init = variable_statement; | 3283 init = variable_statement; |
| 3268 } | 3284 } |
| 3269 } else if ((peek() == Token::LET || peek() == Token::CONST) && | 3285 } else if ((peek() == Token::LET || peek() == Token::CONST) && |
| 3270 is_strict(language_mode())) { | 3286 is_strict(language_mode())) { |
| 3271 bool is_const = peek() == Token::CONST; | 3287 bool is_const = peek() == Token::CONST; |
| 3272 const AstRawString* name = NULL; | 3288 const AstRawString* name = NULL; |
| 3273 VariableDeclarationProperties decl_props = kHasNoInitializers; | 3289 VariableDeclarationProperties decl_props = kHasNoInitializers; |
| 3274 Block* variable_statement = | 3290 Block* variable_statement = |
| 3275 ParseVariableDeclarations(kForStatement, &decl_props, &let_bindings, | 3291 ParseVariableDeclarations(kForStatement, &decl_props, &let_bindings, |
| 3276 &name, CHECK_OK); | 3292 &name, CHECK_OK); |
| 3277 bool accept_IN = name != NULL && decl_props != kHasInitializers; | 3293 bool accept_IN = name != NULL && decl_props != kHasInitializers; |
| 3278 bool accept_OF = decl_props == kHasNoInitializers; | 3294 bool accept_OF = decl_props == kHasNoInitializers; |
| 3279 ForEachStatement::VisitMode mode; | 3295 ForEachStatement::VisitMode mode; |
| 3280 int each_pos = position(); | 3296 int each_beg_pos = scanner()->location().beg_pos; |
| 3297 int each_end_pos = scanner()->location().end_pos; |
| 3281 | 3298 |
| 3282 if (accept_IN && CheckInOrOf(accept_OF, &mode, ok)) { | 3299 if (accept_IN && CheckInOrOf(accept_OF, &mode, ok)) { |
| 3283 if (!*ok) return nullptr; | 3300 if (!*ok) return nullptr; |
| 3284 | 3301 |
| 3285 // Rewrite a for-in statement of the form | 3302 // Rewrite a for-in statement of the form |
| 3286 // | 3303 // |
| 3287 // for (let/const x in e) b | 3304 // for (let/const x in e) b |
| 3288 // | 3305 // |
| 3289 // into | 3306 // into |
| 3290 // | 3307 // |
| 3291 // <let x' be a temporary variable> | 3308 // <let x' be a temporary variable> |
| 3292 // for (x' in e) { | 3309 // for (x' in e) { |
| 3293 // let/const x; | 3310 // let/const x; |
| 3294 // x = x'; | 3311 // x = x'; |
| 3295 // b; | 3312 // b; |
| 3296 // } | 3313 // } |
| 3297 | 3314 |
| 3298 // TODO(keuchel): Move the temporary variable to the block scope, after | 3315 // TODO(keuchel): Move the temporary variable to the block scope, after |
| 3299 // implementing stack allocated block scoped variables. | 3316 // implementing stack allocated block scoped variables. |
| 3300 Variable* temp = scope_->DeclarationScope()->NewTemporary( | 3317 Variable* temp = scope_->DeclarationScope()->NewTemporary( |
| 3301 ast_value_factory()->dot_for_string()); | 3318 ast_value_factory()->dot_for_string()); |
| 3302 VariableProxy* temp_proxy = factory()->NewVariableProxy(temp, each_pos); | 3319 VariableProxy* temp_proxy = |
| 3320 factory()->NewVariableProxy(temp, each_beg_pos, each_end_pos); |
| 3303 ForEachStatement* loop = | 3321 ForEachStatement* loop = |
| 3304 factory()->NewForEachStatement(mode, labels, stmt_pos); | 3322 factory()->NewForEachStatement(mode, labels, stmt_pos); |
| 3305 Target target(&this->target_stack_, loop); | 3323 Target target(&this->target_stack_, loop); |
| 3306 | 3324 |
| 3307 // The expression does not see the loop variable. | 3325 // The expression does not see the loop variable. |
| 3308 scope_ = saved_scope; | 3326 scope_ = saved_scope; |
| 3309 Expression* enumerable = ParseExpression(true, CHECK_OK); | 3327 Expression* enumerable = ParseExpression(true, CHECK_OK); |
| 3310 scope_ = for_scope; | 3328 scope_ = for_scope; |
| 3311 Expect(Token::RPAREN, CHECK_OK); | 3329 Expect(Token::RPAREN, CHECK_OK); |
| 3312 | 3330 |
| 3313 VariableProxy* each = scope_->NewUnresolved(factory(), name, each_pos); | 3331 VariableProxy* each = |
| 3332 scope_->NewUnresolved(factory(), name, each_beg_pos, each_end_pos); |
| 3314 Statement* body = ParseSubStatement(NULL, CHECK_OK); | 3333 Statement* body = ParseSubStatement(NULL, CHECK_OK); |
| 3315 Block* body_block = | 3334 Block* body_block = |
| 3316 factory()->NewBlock(NULL, 3, false, RelocInfo::kNoPosition); | 3335 factory()->NewBlock(NULL, 3, false, RelocInfo::kNoPosition); |
| 3317 Token::Value init_op = is_const ? Token::INIT_CONST : Token::ASSIGN; | 3336 Token::Value init_op = is_const ? Token::INIT_CONST : Token::ASSIGN; |
| 3318 Assignment* assignment = factory()->NewAssignment( | 3337 Assignment* assignment = factory()->NewAssignment( |
| 3319 init_op, each, temp_proxy, RelocInfo::kNoPosition); | 3338 init_op, each, temp_proxy, RelocInfo::kNoPosition); |
| 3320 Statement* assignment_statement = factory()->NewExpressionStatement( | 3339 Statement* assignment_statement = factory()->NewExpressionStatement( |
| 3321 assignment, RelocInfo::kNoPosition); | 3340 assignment, RelocInfo::kNoPosition); |
| 3322 body_block->AddStatement(variable_statement, zone()); | 3341 body_block->AddStatement(variable_statement, zone()); |
| 3323 body_block->AddStatement(assignment_statement, zone()); | 3342 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); | 4106 block_scope->set_start_position(scanner()->location().end_pos); |
| 4088 } | 4107 } |
| 4089 | 4108 |
| 4090 | 4109 |
| 4091 ClassLiteralChecker checker(this); | 4110 ClassLiteralChecker checker(this); |
| 4092 ZoneList<ObjectLiteral::Property*>* properties = NewPropertyList(4, zone()); | 4111 ZoneList<ObjectLiteral::Property*>* properties = NewPropertyList(4, zone()); |
| 4093 FunctionLiteral* constructor = NULL; | 4112 FunctionLiteral* constructor = NULL; |
| 4094 bool has_seen_constructor = false; | 4113 bool has_seen_constructor = false; |
| 4095 | 4114 |
| 4096 Expect(Token::LBRACE, CHECK_OK); | 4115 Expect(Token::LBRACE, CHECK_OK); |
| 4116 int body_beg_pos = scanner()->location().beg_pos; |
| 4117 |
| 4097 const bool has_extends = extends != nullptr; | 4118 const bool has_extends = extends != nullptr; |
| 4098 while (peek() != Token::RBRACE) { | 4119 while (peek() != Token::RBRACE) { |
| 4099 if (Check(Token::SEMICOLON)) continue; | 4120 if (Check(Token::SEMICOLON)) continue; |
| 4100 if (fni_ != NULL) fni_->Enter(); | 4121 if (fni_ != NULL) fni_->Enter(); |
| 4101 const bool in_class = true; | 4122 const bool in_class = true; |
| 4102 const bool is_static = false; | 4123 const bool is_static = false; |
| 4103 bool is_computed_name = false; // Classes do not care about computed | 4124 bool is_computed_name = false; // Classes do not care about computed |
| 4104 // property names here. | 4125 // property names here. |
| 4105 ObjectLiteral::Property* property = ParsePropertyDefinition( | 4126 ObjectLiteral::Property* property = ParsePropertyDefinition( |
| 4106 &checker, in_class, has_extends, is_static, &is_computed_name, | 4127 &checker, in_class, has_extends, is_static, &is_computed_name, |
| (...skipping 19 matching lines...) Expand all Loading... |
| 4126 constructor = | 4147 constructor = |
| 4127 DefaultConstructor(extends != NULL, block_scope, pos, end_pos); | 4148 DefaultConstructor(extends != NULL, block_scope, pos, end_pos); |
| 4128 } | 4149 } |
| 4129 | 4150 |
| 4130 block_scope->set_end_position(end_pos); | 4151 block_scope->set_end_position(end_pos); |
| 4131 block_scope = block_scope->FinalizeBlockScope(); | 4152 block_scope = block_scope->FinalizeBlockScope(); |
| 4132 | 4153 |
| 4133 if (name != NULL) { | 4154 if (name != NULL) { |
| 4134 DCHECK_NOT_NULL(proxy); | 4155 DCHECK_NOT_NULL(proxy); |
| 4135 DCHECK_NOT_NULL(block_scope); | 4156 DCHECK_NOT_NULL(block_scope); |
| 4136 proxy->var()->set_initializer_position(end_pos); | 4157 proxy->var()->set_initializer_position(body_beg_pos); |
| 4137 } | 4158 } |
| 4138 | 4159 |
| 4139 return factory()->NewClassLiteral(name, block_scope, proxy, extends, | 4160 return factory()->NewClassLiteral(name, block_scope, proxy, extends, |
| 4140 constructor, properties, pos, end_pos); | 4161 constructor, properties, pos, end_pos); |
| 4141 } | 4162 } |
| 4142 | 4163 |
| 4143 | 4164 |
| 4144 Expression* Parser::ParseV8Intrinsic(bool* ok) { | 4165 Expression* Parser::ParseV8Intrinsic(bool* ok) { |
| 4145 // CallRuntime :: | 4166 // CallRuntime :: |
| 4146 // '%' Identifier Arguments | 4167 // '%' Identifier Arguments |
| (...skipping 1267 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5414 } else { | 5435 } else { |
| 5415 const uc16* data = reinterpret_cast<const uc16*>(raw_string->raw_data()); | 5436 const uc16* data = reinterpret_cast<const uc16*>(raw_string->raw_data()); |
| 5416 running_hash = StringHasher::ComputeRunningHash(running_hash, data, | 5437 running_hash = StringHasher::ComputeRunningHash(running_hash, data, |
| 5417 raw_string->length()); | 5438 raw_string->length()); |
| 5418 } | 5439 } |
| 5419 } | 5440 } |
| 5420 | 5441 |
| 5421 return running_hash; | 5442 return running_hash; |
| 5422 } | 5443 } |
| 5423 } } // namespace v8::internal | 5444 } } // namespace v8::internal |
| OLD | NEW |