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 |