| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "src/parsing/parser.h" | 5 #include "src/parsing/parser.h" |
| 6 | 6 |
| 7 #include <memory> | 7 #include <memory> |
| 8 | 8 |
| 9 #include "src/api.h" | 9 #include "src/api.h" |
| 10 #include "src/ast/ast.h" | 10 #include "src/ast/ast.h" |
| (...skipping 230 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 241 bool call_super, int pos, | 241 bool call_super, int pos, |
| 242 int end_pos, | 242 int end_pos, |
| 243 LanguageMode language_mode) { | 243 LanguageMode language_mode) { |
| 244 int materialized_literal_count = -1; | 244 int materialized_literal_count = -1; |
| 245 int expected_property_count = -1; | 245 int expected_property_count = -1; |
| 246 int parameter_count = 0; | 246 int parameter_count = 0; |
| 247 if (name == nullptr) name = ast_value_factory()->empty_string(); | 247 if (name == nullptr) name = ast_value_factory()->empty_string(); |
| 248 | 248 |
| 249 FunctionKind kind = call_super ? FunctionKind::kDefaultSubclassConstructor | 249 FunctionKind kind = call_super ? FunctionKind::kDefaultSubclassConstructor |
| 250 : FunctionKind::kDefaultBaseConstructor; | 250 : FunctionKind::kDefaultBaseConstructor; |
| 251 DeclarationScope* function_scope = NewFunctionScope(kind); | 251 Scope* function_scope = NewFunctionScope(kind); |
| 252 SetLanguageMode(function_scope, | 252 SetLanguageMode(function_scope, |
| 253 static_cast<LanguageMode>(language_mode | STRICT)); | 253 static_cast<LanguageMode>(language_mode | STRICT)); |
| 254 // Set start and end position to the same value | 254 // Set start and end position to the same value |
| 255 function_scope->set_start_position(pos); | 255 function_scope->set_start_position(pos); |
| 256 function_scope->set_end_position(pos); | 256 function_scope->set_end_position(pos); |
| 257 ZoneList<Statement*>* body = NULL; | 257 ZoneList<Statement*>* body = NULL; |
| 258 | 258 |
| 259 { | 259 { |
| 260 FunctionState function_state(&function_state_, &scope_state_, | 260 FunctionState function_state(&function_state_, &scope_state_, |
| 261 function_scope, kind); | 261 function_scope, kind); |
| (...skipping 627 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 889 ast_value_factory_ = info->ast_value_factory(); | 889 ast_value_factory_ = info->ast_value_factory(); |
| 890 ast_node_factory_.set_ast_value_factory(ast_value_factory_); | 890 ast_node_factory_.set_ast_value_factory(ast_value_factory_); |
| 891 } | 891 } |
| 892 } | 892 } |
| 893 | 893 |
| 894 void Parser::DeserializeScopeChain( | 894 void Parser::DeserializeScopeChain( |
| 895 ParseInfo* info, Handle<Context> context, | 895 ParseInfo* info, Handle<Context> context, |
| 896 Scope::DeserializationMode deserialization_mode) { | 896 Scope::DeserializationMode deserialization_mode) { |
| 897 // TODO(wingo): Add an outer SCRIPT_SCOPE corresponding to the native | 897 // TODO(wingo): Add an outer SCRIPT_SCOPE corresponding to the native |
| 898 // context, which will have the "this" binding for script scopes. | 898 // context, which will have the "this" binding for script scopes. |
| 899 DeclarationScope* script_scope = NewScriptScope(); | 899 Scope* scope = NewScriptScope(); |
| 900 info->set_script_scope(script_scope); | 900 info->set_script_scope(scope); |
| 901 Scope* scope = script_scope; | |
| 902 if (!context.is_null() && !context->IsNativeContext()) { | 901 if (!context.is_null() && !context->IsNativeContext()) { |
| 903 scope = | 902 scope = |
| 904 Scope::DeserializeScopeChain(info->isolate(), zone(), *context, scope, | 903 Scope::DeserializeScopeChain(info->isolate(), zone(), *context, scope, |
| 905 ast_value_factory(), deserialization_mode); | 904 ast_value_factory(), deserialization_mode); |
| 906 if (info->context().is_null()) { | 905 if (info->context().is_null()) { |
| 907 DCHECK(deserialization_mode == | 906 DCHECK(deserialization_mode == |
| 908 Scope::DeserializationMode::kDeserializeOffHeap); | 907 Scope::DeserializationMode::kDeserializeOffHeap); |
| 909 } else { | 908 } else { |
| 910 // The Scope is backed up by ScopeInfo (which is in the V8 heap); this | 909 // The Scope is backed up by ScopeInfo (which is in the V8 heap); this |
| 911 // means the Parser cannot operate independent of the V8 heap. Tell the | 910 // means the Parser cannot operate independent of the V8 heap. Tell the |
| (...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 998 // background thread. We should not access anything Isolate / heap dependent | 997 // background thread. We should not access anything Isolate / heap dependent |
| 999 // via ParseInfo, and also not pass it forward. | 998 // via ParseInfo, and also not pass it forward. |
| 1000 DCHECK_NULL(scope_state_); | 999 DCHECK_NULL(scope_state_); |
| 1001 DCHECK_NULL(target_stack_); | 1000 DCHECK_NULL(target_stack_); |
| 1002 | 1001 |
| 1003 Mode parsing_mode = FLAG_lazy && allow_lazy() ? PARSE_LAZILY : PARSE_EAGERLY; | 1002 Mode parsing_mode = FLAG_lazy && allow_lazy() ? PARSE_LAZILY : PARSE_EAGERLY; |
| 1004 if (allow_natives() || extension_ != NULL) parsing_mode = PARSE_EAGERLY; | 1003 if (allow_natives() || extension_ != NULL) parsing_mode = PARSE_EAGERLY; |
| 1005 | 1004 |
| 1006 FunctionLiteral* result = NULL; | 1005 FunctionLiteral* result = NULL; |
| 1007 { | 1006 { |
| 1008 Scope* outer = original_scope_; | 1007 Scope* scope = original_scope_; |
| 1009 DCHECK(outer); | 1008 DCHECK(scope); |
| 1010 if (info->is_eval()) { | 1009 if (info->is_eval()) { |
| 1011 if (!outer->is_script_scope() || is_strict(info->language_mode())) { | 1010 if (!scope->is_script_scope() || is_strict(info->language_mode())) { |
| 1012 parsing_mode = PARSE_EAGERLY; | 1011 parsing_mode = PARSE_EAGERLY; |
| 1013 } | 1012 } |
| 1014 outer = NewEvalScope(outer); | 1013 scope = NewScopeWithParent(scope, EVAL_SCOPE); |
| 1015 } else if (info->is_module()) { | 1014 } else if (info->is_module()) { |
| 1016 outer = NewModuleScope(outer); | 1015 scope = NewScopeWithParent(scope, MODULE_SCOPE); |
| 1017 } | 1016 } |
| 1018 | 1017 |
| 1019 DeclarationScope* scope = outer->AsDeclarationScope(); | |
| 1020 | |
| 1021 scope->set_start_position(0); | 1018 scope->set_start_position(0); |
| 1022 | 1019 |
| 1023 // Enter 'scope' with the given parsing mode. | 1020 // Enter 'scope' with the given parsing mode. |
| 1024 ParsingModeScope parsing_mode_scope(this, parsing_mode); | 1021 ParsingModeScope parsing_mode_scope(this, parsing_mode); |
| 1025 FunctionState function_state(&function_state_, &scope_state_, scope, | 1022 FunctionState function_state(&function_state_, &scope_state_, scope, |
| 1026 kNormalFunction); | 1023 kNormalFunction); |
| 1027 | 1024 |
| 1028 ZoneList<Statement*>* body = new(zone()) ZoneList<Statement*>(16, zone()); | 1025 ZoneList<Statement*>* body = new(zone()) ZoneList<Statement*>(16, zone()); |
| 1029 bool ok = true; | 1026 bool ok = true; |
| 1030 int beg_pos = scanner()->location().beg_pos; | 1027 int beg_pos = scanner()->location().beg_pos; |
| 1031 parsing_module_ = info->is_module(); | 1028 parsing_module_ = info->is_module(); |
| 1032 if (parsing_module_) { | 1029 if (parsing_module_) { |
| 1033 ParseModuleItemList(body, &ok); | 1030 ParseModuleItemList(body, &ok); |
| 1034 ok = ok && | 1031 ok = ok && |
| 1035 module()->Validate(this->scope()->AsDeclarationScope(), | 1032 module()->Validate(this->scope(), &pending_error_handler_, zone()); |
| 1036 &pending_error_handler_, zone()); | |
| 1037 } else { | 1033 } else { |
| 1038 // Don't count the mode in the use counters--give the program a chance | 1034 // Don't count the mode in the use counters--give the program a chance |
| 1039 // to enable script-wide strict mode below. | 1035 // to enable script-wide strict mode below. |
| 1040 this->scope()->SetLanguageMode(info->language_mode()); | 1036 this->scope()->SetLanguageMode(info->language_mode()); |
| 1041 ParseStatementList(body, Token::EOS, &ok); | 1037 ParseStatementList(body, Token::EOS, &ok); |
| 1042 } | 1038 } |
| 1043 | 1039 |
| 1044 // The parser will peek but not consume EOS. Our scope logically goes all | 1040 // The parser will peek but not consume EOS. Our scope logically goes all |
| 1045 // the way to the EOS, though. | 1041 // the way to the EOS, though. |
| 1046 scope->set_end_position(scanner()->peek_location().beg_pos); | 1042 scope->set_end_position(scanner()->peek_location().beg_pos); |
| 1047 | 1043 |
| 1048 if (ok && is_strict(language_mode())) { | 1044 if (ok && is_strict(language_mode())) { |
| 1049 CheckStrictOctalLiteral(beg_pos, scanner()->location().end_pos, &ok); | 1045 CheckStrictOctalLiteral(beg_pos, scanner()->location().end_pos, &ok); |
| 1050 CheckDecimalLiteralWithLeadingZero(use_counts_, beg_pos, | 1046 CheckDecimalLiteralWithLeadingZero(use_counts_, beg_pos, |
| 1051 scanner()->location().end_pos); | 1047 scanner()->location().end_pos); |
| 1052 } | 1048 } |
| 1053 if (ok && is_sloppy(language_mode())) { | 1049 if (ok && is_sloppy(language_mode())) { |
| 1054 // TODO(littledan): Function bindings on the global object that modify | 1050 // TODO(littledan): Function bindings on the global object that modify |
| 1055 // pre-existing bindings should be made writable, enumerable and | 1051 // pre-existing bindings should be made writable, enumerable and |
| 1056 // nonconfigurable if possible, whereas this code will leave attributes | 1052 // nonconfigurable if possible, whereas this code will leave attributes |
| 1057 // unchanged if the property already exists. | 1053 // unchanged if the property already exists. |
| 1058 InsertSloppyBlockFunctionVarBindings(scope, nullptr, &ok); | 1054 InsertSloppyBlockFunctionVarBindings(scope, nullptr, &ok); |
| 1059 } | 1055 } |
| 1060 if (ok) { | 1056 if (ok) { |
| 1061 CheckConflictingVarDeclarations(scope, &ok); | 1057 CheckConflictingVarDeclarations(this->scope(), &ok); |
| 1062 } | 1058 } |
| 1063 | 1059 |
| 1064 if (ok && info->parse_restriction() == ONLY_SINGLE_FUNCTION_LITERAL) { | 1060 if (ok && info->parse_restriction() == ONLY_SINGLE_FUNCTION_LITERAL) { |
| 1065 if (body->length() != 1 || | 1061 if (body->length() != 1 || |
| 1066 !body->at(0)->IsExpressionStatement() || | 1062 !body->at(0)->IsExpressionStatement() || |
| 1067 !body->at(0)->AsExpressionStatement()-> | 1063 !body->at(0)->AsExpressionStatement()-> |
| 1068 expression()->IsFunctionLiteral()) { | 1064 expression()->IsFunctionLiteral()) { |
| 1069 ReportMessage(MessageTemplate::kSingleFunctionLiteral); | 1065 ReportMessage(MessageTemplate::kSingleFunctionLiteral); |
| 1070 ok = false; | 1066 ok = false; |
| 1071 } | 1067 } |
| 1072 } | 1068 } |
| 1073 | 1069 |
| 1074 if (ok) { | 1070 if (ok) { |
| 1075 ParserTraits::RewriteDestructuringAssignments(); | 1071 ParserTraits::RewriteDestructuringAssignments(); |
| 1076 result = factory()->NewScriptOrEvalFunctionLiteral( | 1072 result = factory()->NewScriptOrEvalFunctionLiteral( |
| 1077 scope, body, function_state.materialized_literal_count(), | 1073 this->scope(), body, function_state.materialized_literal_count(), |
| 1078 function_state.expected_property_count()); | 1074 function_state.expected_property_count()); |
| 1079 } | 1075 } |
| 1080 } | 1076 } |
| 1081 | 1077 |
| 1082 // Make sure the target stack is empty. | 1078 // Make sure the target stack is empty. |
| 1083 DCHECK(target_stack_ == NULL); | 1079 DCHECK(target_stack_ == NULL); |
| 1084 | 1080 |
| 1085 return result; | 1081 return result; |
| 1086 } | 1082 } |
| 1087 | 1083 |
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1184 CHECK(stack_overflow()); | 1180 CHECK(stack_overflow()); |
| 1185 return nullptr; | 1181 return nullptr; |
| 1186 } | 1182 } |
| 1187 if (!(peek_any_identifier() || peek() == Token::LPAREN)) { | 1183 if (!(peek_any_identifier() || peek() == Token::LPAREN)) { |
| 1188 CHECK(stack_overflow()); | 1184 CHECK(stack_overflow()); |
| 1189 return nullptr; | 1185 return nullptr; |
| 1190 } | 1186 } |
| 1191 } | 1187 } |
| 1192 | 1188 |
| 1193 // TODO(adamk): We should construct this scope from the ScopeInfo. | 1189 // TODO(adamk): We should construct this scope from the ScopeInfo. |
| 1194 DeclarationScope* scope = NewFunctionScope(FunctionKind::kArrowFunction); | 1190 Scope* scope = NewFunctionScope(FunctionKind::kArrowFunction); |
| 1195 | 1191 |
| 1196 // These two bits only need to be explicitly set because we're | 1192 // These two bits only need to be explicitly set because we're |
| 1197 // not passing the ScopeInfo to the Scope constructor. | 1193 // not passing the ScopeInfo to the Scope constructor. |
| 1198 // TODO(adamk): Remove these calls once the above NewScope call | 1194 // TODO(adamk): Remove these calls once the above NewScope call |
| 1199 // passes the ScopeInfo. | 1195 // passes the ScopeInfo. |
| 1200 if (info->calls_eval()) { | 1196 if (info->calls_eval()) { |
| 1201 scope->RecordEvalCall(); | 1197 scope->RecordEvalCall(); |
| 1202 } | 1198 } |
| 1203 SetLanguageMode(scope, info->language_mode()); | 1199 SetLanguageMode(scope, info->language_mode()); |
| 1204 | 1200 |
| (...skipping 755 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1960 | 1956 |
| 1961 | 1957 |
| 1962 VariableProxy* Parser::NewUnresolved(const AstRawString* name, | 1958 VariableProxy* Parser::NewUnresolved(const AstRawString* name, |
| 1963 VariableMode mode) { | 1959 VariableMode mode) { |
| 1964 // If we are inside a function, a declaration of a 'var' variable is a | 1960 // If we are inside a function, a declaration of a 'var' variable is a |
| 1965 // truly local variable, and the scope of the variable is always the function | 1961 // truly local variable, and the scope of the variable is always the function |
| 1966 // scope. | 1962 // scope. |
| 1967 // Let/const variables are always added to the immediately enclosing scope. | 1963 // Let/const variables are always added to the immediately enclosing scope. |
| 1968 Scope* scope = IsLexicalVariableMode(mode) | 1964 Scope* scope = IsLexicalVariableMode(mode) |
| 1969 ? this->scope() | 1965 ? this->scope() |
| 1970 : this->scope()->GetDeclarationScope(); | 1966 : this->scope()->DeclarationScope(); |
| 1971 return scope->NewUnresolved(factory(), name, Variable::NORMAL, | 1967 return scope->NewUnresolved(factory(), name, Variable::NORMAL, |
| 1972 scanner()->location().beg_pos, | 1968 scanner()->location().beg_pos, |
| 1973 scanner()->location().end_pos); | 1969 scanner()->location().end_pos); |
| 1974 } | 1970 } |
| 1975 | 1971 |
| 1976 | 1972 |
| 1977 void Parser::DeclareImport(const AstRawString* local_name, int pos, bool* ok) { | 1973 void Parser::DeclareImport(const AstRawString* local_name, int pos, bool* ok) { |
| 1978 DCHECK_NOT_NULL(local_name); | 1974 DCHECK_NOT_NULL(local_name); |
| 1979 VariableProxy* proxy = NewUnresolved(local_name, IMPORT); | 1975 VariableProxy* proxy = NewUnresolved(local_name, IMPORT); |
| 1980 Declaration* declaration = | 1976 Declaration* declaration = |
| 1981 factory()->NewVariableDeclaration(proxy, IMPORT, scope(), pos); | 1977 factory()->NewVariableDeclaration(proxy, IMPORT, scope(), pos); |
| 1982 Declare(declaration, DeclarationDescriptor::NORMAL, true, CHECK_OK_VOID); | 1978 Declare(declaration, DeclarationDescriptor::NORMAL, true, CHECK_OK_VOID); |
| 1983 } | 1979 } |
| 1984 | 1980 |
| 1985 | 1981 |
| 1986 Variable* Parser::Declare(Declaration* declaration, | 1982 Variable* Parser::Declare(Declaration* declaration, |
| 1987 DeclarationDescriptor::Kind declaration_kind, | 1983 DeclarationDescriptor::Kind declaration_kind, |
| 1988 bool resolve, bool* ok, Scope* scope) { | 1984 bool resolve, bool* ok, Scope* scope) { |
| 1989 VariableProxy* proxy = declaration->proxy(); | 1985 VariableProxy* proxy = declaration->proxy(); |
| 1990 DCHECK(proxy->raw_name() != NULL); | 1986 DCHECK(proxy->raw_name() != NULL); |
| 1991 const AstRawString* name = proxy->raw_name(); | 1987 const AstRawString* name = proxy->raw_name(); |
| 1992 VariableMode mode = declaration->mode(); | 1988 VariableMode mode = declaration->mode(); |
| 1993 DCHECK(IsDeclaredVariableMode(mode) && mode != CONST_LEGACY); | 1989 DCHECK(IsDeclaredVariableMode(mode) && mode != CONST_LEGACY); |
| 1994 bool is_function_declaration = declaration->IsFunctionDeclaration(); | 1990 bool is_function_declaration = declaration->IsFunctionDeclaration(); |
| 1995 if (scope == nullptr) scope = this->scope(); | 1991 if (scope == nullptr) scope = this->scope(); |
| 1996 Scope* declaration_scope = | 1992 Scope* declaration_scope = |
| 1997 IsLexicalVariableMode(mode) ? scope : scope->GetDeclarationScope(); | 1993 IsLexicalVariableMode(mode) ? scope : scope->DeclarationScope(); |
| 1998 Variable* var = NULL; | 1994 Variable* var = NULL; |
| 1999 | 1995 |
| 2000 // If a suitable scope exists, then we can statically declare this | 1996 // If a suitable scope exists, then we can statically declare this |
| 2001 // variable and also set its mode. In any case, a Declaration node | 1997 // variable and also set its mode. In any case, a Declaration node |
| 2002 // will be added to the scope so that the declaration can be added | 1998 // will be added to the scope so that the declaration can be added |
| 2003 // to the corresponding activation frame at runtime if necessary. | 1999 // to the corresponding activation frame at runtime if necessary. |
| 2004 // For instance, var declarations inside a sloppy eval scope need | 2000 // For instance, var declarations inside a sloppy eval scope need |
| 2005 // to be added to the calling function context. Similarly, strict | 2001 // to be added to the calling function context. Similarly, strict |
| 2006 // mode eval scope and lexical eval bindings do not leak variable | 2002 // mode eval scope and lexical eval bindings do not leak variable |
| 2007 // declarations to the caller's scope so we declare all locals, too. | 2003 // declarations to the caller's scope so we declare all locals, too. |
| (...skipping 21 matching lines...) Expand all Loading... |
| 2029 if (is_sloppy(language_mode()) && is_function_declaration && | 2025 if (is_sloppy(language_mode()) && is_function_declaration && |
| 2030 var->is_function()) { | 2026 var->is_function()) { |
| 2031 DCHECK(IsLexicalVariableMode(mode) && | 2027 DCHECK(IsLexicalVariableMode(mode) && |
| 2032 IsLexicalVariableMode(var->mode())); | 2028 IsLexicalVariableMode(var->mode())); |
| 2033 // If the duplication is allowed, then the var will show up | 2029 // If the duplication is allowed, then the var will show up |
| 2034 // in the SloppyBlockFunctionMap and the new FunctionKind | 2030 // in the SloppyBlockFunctionMap and the new FunctionKind |
| 2035 // will be a permitted duplicate. | 2031 // will be a permitted duplicate. |
| 2036 FunctionKind function_kind = | 2032 FunctionKind function_kind = |
| 2037 declaration->AsFunctionDeclaration()->fun()->kind(); | 2033 declaration->AsFunctionDeclaration()->fun()->kind(); |
| 2038 duplicate_allowed = | 2034 duplicate_allowed = |
| 2039 scope->GetDeclarationScope()->sloppy_block_function_map()->Lookup( | 2035 scope->DeclarationScope()->sloppy_block_function_map()->Lookup( |
| 2040 const_cast<AstRawString*>(name), name->hash()) != nullptr && | 2036 const_cast<AstRawString*>(name), name->hash()) != nullptr && |
| 2041 !IsAsyncFunction(function_kind) && | 2037 !IsAsyncFunction(function_kind) && |
| 2042 !(allow_harmony_restrictive_generators() && | 2038 !(allow_harmony_restrictive_generators() && |
| 2043 IsGeneratorFunction(function_kind)); | 2039 IsGeneratorFunction(function_kind)); |
| 2044 } | 2040 } |
| 2045 if (duplicate_allowed) { | 2041 if (duplicate_allowed) { |
| 2046 ++use_counts_[v8::Isolate::kSloppyModeBlockScopedFunctionRedefinition]; | 2042 ++use_counts_[v8::Isolate::kSloppyModeBlockScopedFunctionRedefinition]; |
| 2047 } else { | 2043 } else { |
| 2048 // The name was declared in this scope before; check for conflicting | 2044 // The name was declared in this scope before; check for conflicting |
| 2049 // re-declarations. We have a conflict if either of the declarations | 2045 // re-declarations. We have a conflict if either of the declarations |
| (...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2156 Expect(Token::COMMA, CHECK_OK); | 2152 Expect(Token::COMMA, CHECK_OK); |
| 2157 } | 2153 } |
| 2158 } | 2154 } |
| 2159 Expect(Token::RPAREN, CHECK_OK); | 2155 Expect(Token::RPAREN, CHECK_OK); |
| 2160 Expect(Token::SEMICOLON, CHECK_OK); | 2156 Expect(Token::SEMICOLON, CHECK_OK); |
| 2161 | 2157 |
| 2162 // Make sure that the function containing the native declaration | 2158 // Make sure that the function containing the native declaration |
| 2163 // isn't lazily compiled. The extension structures are only | 2159 // isn't lazily compiled. The extension structures are only |
| 2164 // accessible while parsing the first time not when reparsing | 2160 // accessible while parsing the first time not when reparsing |
| 2165 // because of lazy compilation. | 2161 // because of lazy compilation. |
| 2166 // TODO(adamk): Should this be GetClosureScope()? | 2162 // TODO(adamk): Should this be ClosureScope()? |
| 2167 scope()->GetDeclarationScope()->ForceEagerCompilation(); | 2163 scope()->DeclarationScope()->ForceEagerCompilation(); |
| 2168 | 2164 |
| 2169 // TODO(1240846): It's weird that native function declarations are | 2165 // TODO(1240846): It's weird that native function declarations are |
| 2170 // introduced dynamically when we meet their declarations, whereas | 2166 // introduced dynamically when we meet their declarations, whereas |
| 2171 // other functions are set up when entering the surrounding scope. | 2167 // other functions are set up when entering the surrounding scope. |
| 2172 VariableProxy* proxy = NewUnresolved(name, VAR); | 2168 VariableProxy* proxy = NewUnresolved(name, VAR); |
| 2173 Declaration* declaration = | 2169 Declaration* declaration = |
| 2174 factory()->NewVariableDeclaration(proxy, VAR, scope(), pos); | 2170 factory()->NewVariableDeclaration(proxy, VAR, scope(), pos); |
| 2175 Declare(declaration, DeclarationDescriptor::NORMAL, true, CHECK_OK); | 2171 Declare(declaration, DeclarationDescriptor::NORMAL, true, CHECK_OK); |
| 2176 NativeFunctionLiteral* lit = | 2172 NativeFunctionLiteral* lit = |
| 2177 factory()->NewNativeFunctionLiteral(name, extension_, kNoSourcePosition); | 2173 factory()->NewNativeFunctionLiteral(name, extension_, kNoSourcePosition); |
| (...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2267 EmptyStatement* empty = factory()->NewEmptyStatement(kNoSourcePosition); | 2263 EmptyStatement* empty = factory()->NewEmptyStatement(kNoSourcePosition); |
| 2268 // Async functions don't undergo sloppy mode block scoped hoisting, and don't | 2264 // Async functions don't undergo sloppy mode block scoped hoisting, and don't |
| 2269 // allow duplicates in a block. Both are represented by the | 2265 // allow duplicates in a block. Both are represented by the |
| 2270 // sloppy_block_function_map. Don't add them to the map for async functions. | 2266 // sloppy_block_function_map. Don't add them to the map for async functions. |
| 2271 // Generators are also supposed to be prohibited; currently doing this behind | 2267 // Generators are also supposed to be prohibited; currently doing this behind |
| 2272 // a flag and UseCounting violations to assess web compatibility. | 2268 // a flag and UseCounting violations to assess web compatibility. |
| 2273 if (is_sloppy(language_mode()) && !scope()->is_declaration_scope() && | 2269 if (is_sloppy(language_mode()) && !scope()->is_declaration_scope() && |
| 2274 !is_async && !(allow_harmony_restrictive_generators() && is_generator)) { | 2270 !is_async && !(allow_harmony_restrictive_generators() && is_generator)) { |
| 2275 SloppyBlockFunctionStatement* delegate = | 2271 SloppyBlockFunctionStatement* delegate = |
| 2276 factory()->NewSloppyBlockFunctionStatement(empty, scope()); | 2272 factory()->NewSloppyBlockFunctionStatement(empty, scope()); |
| 2277 scope()->GetDeclarationScope()->sloppy_block_function_map()->Declare( | 2273 scope()->DeclarationScope()->sloppy_block_function_map()->Declare( |
| 2278 variable_name, delegate); | 2274 variable_name, delegate); |
| 2279 return delegate; | 2275 return delegate; |
| 2280 } | 2276 } |
| 2281 return empty; | 2277 return empty; |
| 2282 } | 2278 } |
| 2283 | 2279 |
| 2284 Statement* Parser::ParseClassDeclaration(ZoneList<const AstRawString*>* names, | 2280 Statement* Parser::ParseClassDeclaration(ZoneList<const AstRawString*>* names, |
| 2285 bool default_export, bool* ok) { | 2281 bool default_export, bool* ok) { |
| 2286 // ClassDeclaration :: | 2282 // ClassDeclaration :: |
| 2287 // 'class' Identifier ('extends' LeftHandExpression)? '{' ClassBody '}' | 2283 // 'class' Identifier ('extends' LeftHandExpression)? '{' ClassBody '}' |
| (...skipping 546 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2834 ExpectSemicolon(CHECK_OK); | 2830 ExpectSemicolon(CHECK_OK); |
| 2835 | 2831 |
| 2836 if (is_generator()) { | 2832 if (is_generator()) { |
| 2837 return_value = BuildIteratorResult(return_value, true); | 2833 return_value = BuildIteratorResult(return_value, true); |
| 2838 } else if (is_async_function()) { | 2834 } else if (is_async_function()) { |
| 2839 return_value = BuildPromiseResolve(return_value, return_value->position()); | 2835 return_value = BuildPromiseResolve(return_value, return_value->position()); |
| 2840 } | 2836 } |
| 2841 | 2837 |
| 2842 result = factory()->NewReturnStatement(return_value, loc.beg_pos); | 2838 result = factory()->NewReturnStatement(return_value, loc.beg_pos); |
| 2843 | 2839 |
| 2844 DeclarationScope* decl_scope = scope()->GetDeclarationScope(); | 2840 Scope* decl_scope = scope()->DeclarationScope(); |
| 2845 if (decl_scope->is_script_scope() || decl_scope->is_eval_scope()) { | 2841 if (decl_scope->is_script_scope() || decl_scope->is_eval_scope()) { |
| 2846 ReportMessageAt(loc, MessageTemplate::kIllegalReturn); | 2842 ReportMessageAt(loc, MessageTemplate::kIllegalReturn); |
| 2847 *ok = false; | 2843 *ok = false; |
| 2848 return NULL; | 2844 return NULL; |
| 2849 } | 2845 } |
| 2850 return result; | 2846 return result; |
| 2851 } | 2847 } |
| 2852 | 2848 |
| 2853 | 2849 |
| 2854 Statement* Parser::ParseWithStatement(ZoneList<const AstRawString*>* labels, | 2850 Statement* Parser::ParseWithStatement(ZoneList<const AstRawString*>* labels, |
| (...skipping 912 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3767 bound_names_are_lexical = | 3763 bound_names_are_lexical = |
| 3768 IsLexicalVariableMode(parsing_result.descriptor.mode); | 3764 IsLexicalVariableMode(parsing_result.descriptor.mode); |
| 3769 | 3765 |
| 3770 // special case for legacy for (var ... = ... in ...) | 3766 // special case for legacy for (var ... = ... in ...) |
| 3771 if (!bound_names_are_lexical && decl.pattern->IsVariableProxy() && | 3767 if (!bound_names_are_lexical && decl.pattern->IsVariableProxy() && |
| 3772 decl.initializer != nullptr) { | 3768 decl.initializer != nullptr) { |
| 3773 DCHECK(!allow_harmony_for_in()); | 3769 DCHECK(!allow_harmony_for_in()); |
| 3774 ++use_counts_[v8::Isolate::kForInInitializer]; | 3770 ++use_counts_[v8::Isolate::kForInInitializer]; |
| 3775 const AstRawString* name = | 3771 const AstRawString* name = |
| 3776 decl.pattern->AsVariableProxy()->raw_name(); | 3772 decl.pattern->AsVariableProxy()->raw_name(); |
| 3777 VariableProxy* single_var = NewUnresolved(name, VAR); | 3773 VariableProxy* single_var = scope()->NewUnresolved( |
| 3774 factory(), name, Variable::NORMAL, each_beg_pos, each_end_pos); |
| 3778 init_block = factory()->NewBlock( | 3775 init_block = factory()->NewBlock( |
| 3779 nullptr, 2, true, parsing_result.descriptor.declaration_pos); | 3776 nullptr, 2, true, parsing_result.descriptor.declaration_pos); |
| 3780 init_block->statements()->Add( | 3777 init_block->statements()->Add( |
| 3781 factory()->NewExpressionStatement( | 3778 factory()->NewExpressionStatement( |
| 3782 factory()->NewAssignment(Token::ASSIGN, single_var, | 3779 factory()->NewAssignment(Token::ASSIGN, single_var, |
| 3783 decl.initializer, kNoSourcePosition), | 3780 decl.initializer, kNoSourcePosition), |
| 3784 kNoSourcePosition), | 3781 kNoSourcePosition), |
| 3785 zone()); | 3782 zone()); |
| 3786 } | 3783 } |
| 3787 | 3784 |
| (...skipping 445 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4233 DoExpression* Parser::ParseDoExpression(bool* ok) { | 4230 DoExpression* Parser::ParseDoExpression(bool* ok) { |
| 4234 // AssignmentExpression :: | 4231 // AssignmentExpression :: |
| 4235 // do '{' StatementList '}' | 4232 // do '{' StatementList '}' |
| 4236 int pos = peek_position(); | 4233 int pos = peek_position(); |
| 4237 | 4234 |
| 4238 Expect(Token::DO, CHECK_OK); | 4235 Expect(Token::DO, CHECK_OK); |
| 4239 Variable* result = | 4236 Variable* result = |
| 4240 scope()->NewTemporary(ast_value_factory()->dot_result_string()); | 4237 scope()->NewTemporary(ast_value_factory()->dot_result_string()); |
| 4241 Block* block = ParseBlock(nullptr, CHECK_OK); | 4238 Block* block = ParseBlock(nullptr, CHECK_OK); |
| 4242 DoExpression* expr = factory()->NewDoExpression(block, result, pos); | 4239 DoExpression* expr = factory()->NewDoExpression(block, result, pos); |
| 4243 if (!Rewriter::Rewrite(this, scope()->GetClosureScope(), expr, | 4240 if (!Rewriter::Rewrite(this, scope()->ClosureScope(), expr, |
| 4244 ast_value_factory())) { | 4241 ast_value_factory())) { |
| 4245 *ok = false; | 4242 *ok = false; |
| 4246 return nullptr; | 4243 return nullptr; |
| 4247 } | 4244 } |
| 4248 return expr; | 4245 return expr; |
| 4249 } | 4246 } |
| 4250 | 4247 |
| 4251 void ParserTraits::ParseArrowFunctionFormalParameterList( | 4248 void ParserTraits::ParseArrowFunctionFormalParameterList( |
| 4252 ParserFormalParameters* parameters, Expression* expr, | 4249 ParserFormalParameters* parameters, Expression* expr, |
| 4253 const Scanner::Location& params_loc, Scanner::Location* duplicate_loc, | 4250 const Scanner::Location& params_loc, Scanner::Location* duplicate_loc, |
| (...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4382 // - The function literal shouldn't be hinted to eagerly compile. | 4379 // - The function literal shouldn't be hinted to eagerly compile. |
| 4383 // - For asm.js functions the body needs to be available when module | 4380 // - For asm.js functions the body needs to be available when module |
| 4384 // validation is active, because we examine the entire module at once. | 4381 // validation is active, because we examine the entire module at once. |
| 4385 bool use_temp_zone = | 4382 bool use_temp_zone = |
| 4386 !is_lazily_parsed && FLAG_lazy && !allow_natives() && | 4383 !is_lazily_parsed && FLAG_lazy && !allow_natives() && |
| 4387 extension_ == NULL && allow_lazy() && | 4384 extension_ == NULL && allow_lazy() && |
| 4388 function_type == FunctionLiteral::kDeclaration && | 4385 function_type == FunctionLiteral::kDeclaration && |
| 4389 eager_compile_hint != FunctionLiteral::kShouldEagerCompile && | 4386 eager_compile_hint != FunctionLiteral::kShouldEagerCompile && |
| 4390 !(FLAG_validate_asm && scope()->asm_module()); | 4387 !(FLAG_validate_asm && scope()->asm_module()); |
| 4391 | 4388 |
| 4392 DeclarationScope* main_scope = nullptr; | 4389 Scope* main_scope = nullptr; |
| 4393 if (use_temp_zone) { | 4390 if (use_temp_zone) { |
| 4394 // This Scope lives in the main Zone; we'll migrate data into it later. | 4391 // This Scope lives in the main Zone; we'll migrate data into it later. |
| 4395 main_scope = NewFunctionScope(kind); | 4392 main_scope = NewFunctionScope(kind); |
| 4396 } | 4393 } |
| 4397 | 4394 |
| 4398 ZoneList<Statement*>* body = nullptr; | 4395 ZoneList<Statement*>* body = nullptr; |
| 4399 int arity = -1; | 4396 int arity = -1; |
| 4400 int materialized_literal_count = -1; | 4397 int materialized_literal_count = -1; |
| 4401 int expected_property_count = -1; | 4398 int expected_property_count = -1; |
| 4402 DuplicateFinder duplicate_finder(scanner()->unicode_cache()); | 4399 DuplicateFinder duplicate_finder(scanner()->unicode_cache()); |
| 4403 bool should_be_used_once_hint = false; | 4400 bool should_be_used_once_hint = false; |
| 4404 bool has_duplicate_parameters; | 4401 bool has_duplicate_parameters; |
| 4405 | 4402 |
| 4406 { | 4403 { |
| 4407 // Temporary zones can nest. When we migrate free variables (see below), we | 4404 // Temporary zones can nest. When we migrate free variables (see below), we |
| 4408 // need to recreate them in the previous Zone. | 4405 // need to recreate them in the previous Zone. |
| 4409 AstNodeFactory previous_zone_ast_node_factory(ast_value_factory()); | 4406 AstNodeFactory previous_zone_ast_node_factory(ast_value_factory()); |
| 4410 previous_zone_ast_node_factory.set_zone(zone()); | 4407 previous_zone_ast_node_factory.set_zone(zone()); |
| 4411 | 4408 |
| 4412 // Open a new zone scope, which sets our AstNodeFactory to allocate in the | 4409 // Open a new zone scope, which sets our AstNodeFactory to allocate in the |
| 4413 // new temporary zone if the preconditions are satisfied, and ensures that | 4410 // new temporary zone if the preconditions are satisfied, and ensures that |
| 4414 // the previous zone is always restored after parsing the body. To be able | 4411 // the previous zone is always restored after parsing the body. To be able |
| 4415 // to do scope analysis correctly after full parsing, we migrate needed | 4412 // to do scope analysis correctly after full parsing, we migrate needed |
| 4416 // information from scope into main_scope when the function has been parsed. | 4413 // information from scope into main_scope when the function has been parsed. |
| 4417 Zone temp_zone(zone()->allocator()); | 4414 Zone temp_zone(zone()->allocator()); |
| 4418 DiscardableZoneScope zone_scope(this, &temp_zone, use_temp_zone); | 4415 DiscardableZoneScope zone_scope(this, &temp_zone, use_temp_zone); |
| 4419 | 4416 |
| 4420 DeclarationScope* scope = NewFunctionScope(kind); | 4417 Scope* scope = NewFunctionScope(kind); |
| 4421 SetLanguageMode(scope, language_mode); | 4418 SetLanguageMode(scope, language_mode); |
| 4422 if (!use_temp_zone) { | 4419 if (!use_temp_zone) { |
| 4423 main_scope = scope; | 4420 main_scope = scope; |
| 4424 } else { | 4421 } else { |
| 4425 DCHECK(main_scope->zone() != scope->zone()); | 4422 DCHECK(main_scope->zone() != scope->zone()); |
| 4426 } | 4423 } |
| 4427 | 4424 |
| 4428 FunctionState function_state(&function_state_, &scope_state_, scope, kind); | 4425 FunctionState function_state(&function_state_, &scope_state_, scope, kind); |
| 4429 #ifdef DEBUG | 4426 #ifdef DEBUG |
| 4430 scope->SetScopeName(function_name); | 4427 this->scope()->SetScopeName(function_name); |
| 4431 #endif | 4428 #endif |
| 4432 ExpressionClassifier formals_classifier(this, &duplicate_finder); | 4429 ExpressionClassifier formals_classifier(this, &duplicate_finder); |
| 4433 | 4430 |
| 4434 if (is_generator) { | 4431 if (is_generator) { |
| 4435 // For generators, allocating variables in contexts is currently a win | 4432 // For generators, allocating variables in contexts is currently a win |
| 4436 // because it minimizes the work needed to suspend and resume an | 4433 // because it minimizes the work needed to suspend and resume an |
| 4437 // activation. The machine code produced for generators (by full-codegen) | 4434 // activation. The machine code produced for generators (by full-codegen) |
| 4438 // relies on this forced context allocation, but not in an essential way. | 4435 // relies on this forced context allocation, but not in an essential way. |
| 4439 this->scope()->ForceContextAllocation(); | 4436 this->scope()->ForceContextAllocation(); |
| 4440 | 4437 |
| (...skipping 315 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4756 factory()->NewUndefinedLiteral(kNoSourcePosition), kNoSourcePosition); | 4753 factory()->NewUndefinedLiteral(kNoSourcePosition), kNoSourcePosition); |
| 4757 initial_value = factory()->NewConditional( | 4754 initial_value = factory()->NewConditional( |
| 4758 condition, parameter.initializer, initial_value, kNoSourcePosition); | 4755 condition, parameter.initializer, initial_value, kNoSourcePosition); |
| 4759 descriptor.initialization_pos = parameter.initializer->position(); | 4756 descriptor.initialization_pos = parameter.initializer->position(); |
| 4760 initializer_position = parameter.initializer_end_position; | 4757 initializer_position = parameter.initializer_end_position; |
| 4761 } | 4758 } |
| 4762 | 4759 |
| 4763 Scope* param_scope = scope(); | 4760 Scope* param_scope = scope(); |
| 4764 Block* param_block = init_block; | 4761 Block* param_block = init_block; |
| 4765 if (!parameter.is_simple() && scope()->calls_sloppy_eval()) { | 4762 if (!parameter.is_simple() && scope()->calls_sloppy_eval()) { |
| 4766 param_scope = NewVarblockScope(); | 4763 param_scope = NewScope(BLOCK_SCOPE); |
| 4764 param_scope->set_is_declaration_scope(); |
| 4767 param_scope->set_start_position(descriptor.initialization_pos); | 4765 param_scope->set_start_position(descriptor.initialization_pos); |
| 4768 param_scope->set_end_position(parameter.initializer_end_position); | 4766 param_scope->set_end_position(parameter.initializer_end_position); |
| 4769 param_scope->RecordEvalCall(); | 4767 param_scope->RecordEvalCall(); |
| 4770 param_block = factory()->NewBlock(NULL, 8, true, kNoSourcePosition); | 4768 param_block = factory()->NewBlock(NULL, 8, true, kNoSourcePosition); |
| 4771 param_block->set_scope(param_scope); | 4769 param_block->set_scope(param_scope); |
| 4772 descriptor.hoist_scope = scope(); | 4770 descriptor.hoist_scope = scope(); |
| 4773 // Pass the appropriate scope in so that PatternRewriter can appropriately | 4771 // Pass the appropriate scope in so that PatternRewriter can appropriately |
| 4774 // rewrite inner initializers of the pattern to param_scope | 4772 // rewrite inner initializers of the pattern to param_scope |
| 4775 descriptor.scope = param_scope; | 4773 descriptor.scope = param_scope; |
| 4776 // Rewrite the outer initializer to point to param_scope | 4774 // Rewrite the outer initializer to point to param_scope |
| (...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4862 // If we have a named function expression, we add a local variable | 4860 // If we have a named function expression, we add a local variable |
| 4863 // declaration to the body of the function with the name of the | 4861 // declaration to the body of the function with the name of the |
| 4864 // function and let it refer to the function itself (closure). | 4862 // function and let it refer to the function itself (closure). |
| 4865 // Not having parsed the function body, the language mode may still change, | 4863 // Not having parsed the function body, the language mode may still change, |
| 4866 // so we reserve a spot and create the actual const assignment later. | 4864 // so we reserve a spot and create the actual const assignment later. |
| 4867 DCHECK_EQ(kFunctionNameAssignmentIndex, result->length()); | 4865 DCHECK_EQ(kFunctionNameAssignmentIndex, result->length()); |
| 4868 result->Add(NULL, zone()); | 4866 result->Add(NULL, zone()); |
| 4869 } | 4867 } |
| 4870 | 4868 |
| 4871 ZoneList<Statement*>* body = result; | 4869 ZoneList<Statement*>* body = result; |
| 4872 DeclarationScope* function_scope = scope()->AsDeclarationScope(); | 4870 Scope* inner_scope = scope(); |
| 4873 DeclarationScope* inner_scope = function_scope; | |
| 4874 Block* inner_block = nullptr; | 4871 Block* inner_block = nullptr; |
| 4875 if (!parameters.is_simple) { | 4872 if (!parameters.is_simple) { |
| 4876 inner_scope = NewVarblockScope(); | 4873 inner_scope = NewScope(BLOCK_SCOPE); |
| 4874 inner_scope->set_is_declaration_scope(); |
| 4877 inner_scope->set_start_position(scanner()->location().beg_pos); | 4875 inner_scope->set_start_position(scanner()->location().beg_pos); |
| 4878 inner_block = factory()->NewBlock(NULL, 8, true, kNoSourcePosition); | 4876 inner_block = factory()->NewBlock(NULL, 8, true, kNoSourcePosition); |
| 4879 inner_block->set_scope(inner_scope); | 4877 inner_block->set_scope(inner_scope); |
| 4880 body = inner_block->statements(); | 4878 body = inner_block->statements(); |
| 4881 } | 4879 } |
| 4882 | 4880 |
| 4883 { | 4881 { |
| 4884 BlockState block_state(&scope_state_, inner_scope); | 4882 BlockState block_state(&scope_state_, inner_scope); |
| 4885 | 4883 |
| 4886 if (IsGeneratorFunction(kind)) { | 4884 if (IsGeneratorFunction(kind)) { |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4952 kNoSourcePosition), | 4950 kNoSourcePosition), |
| 4953 zone()); | 4951 zone()); |
| 4954 } | 4952 } |
| 4955 } | 4953 } |
| 4956 | 4954 |
| 4957 Expect(Token::RBRACE, CHECK_OK); | 4955 Expect(Token::RBRACE, CHECK_OK); |
| 4958 scope()->set_end_position(scanner()->location().end_pos); | 4956 scope()->set_end_position(scanner()->location().end_pos); |
| 4959 | 4957 |
| 4960 if (!parameters.is_simple) { | 4958 if (!parameters.is_simple) { |
| 4961 DCHECK_NOT_NULL(inner_scope); | 4959 DCHECK_NOT_NULL(inner_scope); |
| 4962 DCHECK_EQ(function_scope, scope()); | |
| 4963 DCHECK_EQ(function_scope, inner_scope->outer_scope()); | |
| 4964 DCHECK_EQ(body, inner_block->statements()); | 4960 DCHECK_EQ(body, inner_block->statements()); |
| 4965 SetLanguageMode(function_scope, inner_scope->language_mode()); | 4961 SetLanguageMode(scope(), inner_scope->language_mode()); |
| 4966 Block* init_block = BuildParameterInitializationBlock(parameters, CHECK_OK); | 4962 Block* init_block = BuildParameterInitializationBlock(parameters, CHECK_OK); |
| 4967 | 4963 |
| 4968 if (is_sloppy(inner_scope->language_mode())) { | 4964 if (is_sloppy(inner_scope->language_mode())) { |
| 4969 InsertSloppyBlockFunctionVarBindings(inner_scope, function_scope, | 4965 InsertSloppyBlockFunctionVarBindings( |
| 4970 CHECK_OK); | 4966 inner_scope, inner_scope->outer_scope(), CHECK_OK); |
| 4971 } | 4967 } |
| 4972 | 4968 |
| 4973 if (IsAsyncFunction(kind)) { | 4969 if (IsAsyncFunction(kind)) { |
| 4974 init_block = BuildRejectPromiseOnException(init_block); | 4970 init_block = BuildRejectPromiseOnException(init_block); |
| 4975 } | 4971 } |
| 4976 | 4972 |
| 4977 DCHECK_NOT_NULL(init_block); | 4973 DCHECK_NOT_NULL(init_block); |
| 4978 | 4974 |
| 4979 inner_scope->set_end_position(scanner()->location().end_pos); | 4975 inner_scope->set_end_position(scanner()->location().end_pos); |
| 4980 if (inner_scope->FinalizeBlockScope() != nullptr) { | 4976 inner_scope = inner_scope->FinalizeBlockScope(); |
| 4977 if (inner_scope != nullptr) { |
| 4981 CheckConflictingVarDeclarations(inner_scope, CHECK_OK); | 4978 CheckConflictingVarDeclarations(inner_scope, CHECK_OK); |
| 4982 InsertShadowingVarBindingInitializers(inner_block); | 4979 InsertShadowingVarBindingInitializers(inner_block); |
| 4983 } | 4980 } |
| 4984 inner_scope = nullptr; | |
| 4985 | 4981 |
| 4986 result->Add(init_block, zone()); | 4982 result->Add(init_block, zone()); |
| 4987 result->Add(inner_block, zone()); | 4983 result->Add(inner_block, zone()); |
| 4988 } else { | 4984 } else { |
| 4989 DCHECK_EQ(inner_scope, function_scope); | 4985 if (is_sloppy(inner_scope->language_mode())) { |
| 4990 if (is_sloppy(function_scope->language_mode())) { | 4986 InsertSloppyBlockFunctionVarBindings(inner_scope, nullptr, CHECK_OK); |
| 4991 InsertSloppyBlockFunctionVarBindings(function_scope, nullptr, CHECK_OK); | |
| 4992 } | 4987 } |
| 4993 } | 4988 } |
| 4994 | 4989 |
| 4995 if (function_type == FunctionLiteral::kNamedExpression) { | 4990 if (function_type == FunctionLiteral::kNamedExpression) { |
| 4996 // Now that we know the language mode, we can create the const assignment | 4991 // Now that we know the language mode, we can create the const assignment |
| 4997 // in the previously reserved spot. | 4992 // in the previously reserved spot. |
| 4998 // NOTE: We create a proxy and resolve it here so that in the | 4993 // NOTE: We create a proxy and resolve it here so that in the |
| 4999 // future we can change the AST to only refer to VariableProxies | 4994 // future we can change the AST to only refer to VariableProxies |
| 5000 // instead of Variables and Proxies as is the case now. | 4995 // instead of Variables and Proxies as is the case now. |
| 5001 DCHECK_EQ(function_scope, scope()); | |
| 5002 VariableMode fvar_mode = is_strict(language_mode()) ? CONST : CONST_LEGACY; | 4996 VariableMode fvar_mode = is_strict(language_mode()) ? CONST : CONST_LEGACY; |
| 5003 Variable* fvar = new (zone()) | 4997 Variable* fvar = new (zone()) |
| 5004 Variable(scope(), function_name, fvar_mode, Variable::NORMAL, | 4998 Variable(scope(), function_name, fvar_mode, Variable::NORMAL, |
| 5005 kCreatedInitialized, kNotAssigned); | 4999 kCreatedInitialized, kNotAssigned); |
| 5006 VariableProxy* proxy = factory()->NewVariableProxy(fvar); | 5000 VariableProxy* proxy = factory()->NewVariableProxy(fvar); |
| 5007 VariableDeclaration* fvar_declaration = factory()->NewVariableDeclaration( | 5001 VariableDeclaration* fvar_declaration = factory()->NewVariableDeclaration( |
| 5008 proxy, fvar_mode, scope(), kNoSourcePosition); | 5002 proxy, fvar_mode, scope(), kNoSourcePosition); |
| 5009 function_scope->DeclareFunctionVar(fvar_declaration); | 5003 scope()->DeclareFunctionVar(fvar_declaration); |
| 5010 | 5004 |
| 5011 VariableProxy* fproxy = factory()->NewVariableProxy(fvar); | 5005 VariableProxy* fproxy = factory()->NewVariableProxy(fvar); |
| 5012 result->Set(kFunctionNameAssignmentIndex, | 5006 result->Set(kFunctionNameAssignmentIndex, |
| 5013 factory()->NewExpressionStatement( | 5007 factory()->NewExpressionStatement( |
| 5014 factory()->NewAssignment(Token::INIT, fproxy, | 5008 factory()->NewAssignment(Token::INIT, fproxy, |
| 5015 factory()->NewThisFunction(pos), | 5009 factory()->NewThisFunction(pos), |
| 5016 kNoSourcePosition), | 5010 kNoSourcePosition), |
| 5017 kNoSourcePosition)); | 5011 kNoSourcePosition)); |
| 5018 } | 5012 } |
| 5019 | 5013 |
| (...skipping 22 matching lines...) Expand all Loading... |
| 5042 SET_ALLOW(harmony_do_expressions); | 5036 SET_ALLOW(harmony_do_expressions); |
| 5043 SET_ALLOW(harmony_for_in); | 5037 SET_ALLOW(harmony_for_in); |
| 5044 SET_ALLOW(harmony_function_sent); | 5038 SET_ALLOW(harmony_function_sent); |
| 5045 SET_ALLOW(harmony_restrictive_declarations); | 5039 SET_ALLOW(harmony_restrictive_declarations); |
| 5046 SET_ALLOW(harmony_async_await); | 5040 SET_ALLOW(harmony_async_await); |
| 5047 SET_ALLOW(harmony_trailing_commas); | 5041 SET_ALLOW(harmony_trailing_commas); |
| 5048 #undef SET_ALLOW | 5042 #undef SET_ALLOW |
| 5049 } | 5043 } |
| 5050 PreParser::PreParseResult result = reusable_preparser_->PreParseLazyFunction( | 5044 PreParser::PreParseResult result = reusable_preparser_->PreParseLazyFunction( |
| 5051 language_mode(), function_state_->kind(), | 5045 language_mode(), function_state_->kind(), |
| 5052 scope()->AsDeclarationScope()->has_simple_parameters(), parsing_module_, | 5046 scope()->has_simple_parameters(), parsing_module_, logger, bookmark, |
| 5053 logger, bookmark, use_counts_); | 5047 use_counts_); |
| 5054 if (pre_parse_timer_ != NULL) { | 5048 if (pre_parse_timer_ != NULL) { |
| 5055 pre_parse_timer_->Stop(); | 5049 pre_parse_timer_->Stop(); |
| 5056 } | 5050 } |
| 5057 return result; | 5051 return result; |
| 5058 } | 5052 } |
| 5059 | 5053 |
| 5060 Expression* Parser::ParseClassLiteral(ExpressionClassifier* classifier, | 5054 Expression* Parser::ParseClassLiteral(ExpressionClassifier* classifier, |
| 5061 const AstRawString* name, | 5055 const AstRawString* name, |
| 5062 Scanner::Location class_name_location, | 5056 Scanner::Location class_name_location, |
| 5063 bool name_is_strict_reserved, int pos, | 5057 bool name_is_strict_reserved, int pos, |
| (...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5169 scope()->NewTemporary(ast_value_factory()->empty_string()); | 5163 scope()->NewTemporary(ast_value_factory()->empty_string()); |
| 5170 do_block->set_scope(block_state.FinalizedBlockScope()); | 5164 do_block->set_scope(block_state.FinalizedBlockScope()); |
| 5171 DoExpression* do_expr = factory()->NewDoExpression(do_block, result_var, pos); | 5165 DoExpression* do_expr = factory()->NewDoExpression(do_block, result_var, pos); |
| 5172 | 5166 |
| 5173 ClassLiteral* class_literal = factory()->NewClassLiteral( | 5167 ClassLiteral* class_literal = factory()->NewClassLiteral( |
| 5174 proxy, extends, constructor, properties, pos, end_pos); | 5168 proxy, extends, constructor, properties, pos, end_pos); |
| 5175 | 5169 |
| 5176 do_block->statements()->Add( | 5170 do_block->statements()->Add( |
| 5177 factory()->NewExpressionStatement(class_literal, pos), zone()); | 5171 factory()->NewExpressionStatement(class_literal, pos), zone()); |
| 5178 do_expr->set_represented_function(constructor); | 5172 do_expr->set_represented_function(constructor); |
| 5179 Rewriter::Rewrite(this, scope()->GetClosureScope(), do_expr, | 5173 Rewriter::Rewrite(this, scope()->ClosureScope(), do_expr, |
| 5180 ast_value_factory()); | 5174 ast_value_factory()); |
| 5181 | 5175 |
| 5182 return do_expr; | 5176 return do_expr; |
| 5183 } | 5177 } |
| 5184 | 5178 |
| 5185 | 5179 |
| 5186 Expression* Parser::ParseV8Intrinsic(bool* ok) { | 5180 Expression* Parser::ParseV8Intrinsic(bool* ok) { |
| 5187 // CallRuntime :: | 5181 // CallRuntime :: |
| 5188 // '%' Identifier Arguments | 5182 // '%' Identifier Arguments |
| 5189 | 5183 |
| 5190 int pos = peek_position(); | 5184 int pos = peek_position(); |
| 5191 Expect(Token::MOD, CHECK_OK); | 5185 Expect(Token::MOD, CHECK_OK); |
| 5192 // Allow "eval" or "arguments" for backward compatibility. | 5186 // Allow "eval" or "arguments" for backward compatibility. |
| 5193 const AstRawString* name = ParseIdentifier(kAllowRestrictedIdentifiers, | 5187 const AstRawString* name = ParseIdentifier(kAllowRestrictedIdentifiers, |
| 5194 CHECK_OK); | 5188 CHECK_OK); |
| 5195 Scanner::Location spread_pos; | 5189 Scanner::Location spread_pos; |
| 5196 ExpressionClassifier classifier(this); | 5190 ExpressionClassifier classifier(this); |
| 5197 ZoneList<Expression*>* args = | 5191 ZoneList<Expression*>* args = |
| 5198 ParseArguments(&spread_pos, &classifier, CHECK_OK); | 5192 ParseArguments(&spread_pos, &classifier, CHECK_OK); |
| 5199 | 5193 |
| 5200 DCHECK(!spread_pos.IsValid()); | 5194 DCHECK(!spread_pos.IsValid()); |
| 5201 | 5195 |
| 5202 if (extension_ != NULL) { | 5196 if (extension_ != NULL) { |
| 5203 // The extension structures are only accessible while parsing the | 5197 // The extension structures are only accessible while parsing the |
| 5204 // very first time not when reparsing because of lazy compilation. | 5198 // very first time not when reparsing because of lazy compilation. |
| 5205 scope()->GetDeclarationScope()->ForceEagerCompilation(); | 5199 scope()->DeclarationScope()->ForceEagerCompilation(); |
| 5206 } | 5200 } |
| 5207 | 5201 |
| 5208 const Runtime::Function* function = Runtime::FunctionForName(name->string()); | 5202 const Runtime::Function* function = Runtime::FunctionForName(name->string()); |
| 5209 | 5203 |
| 5210 if (function != NULL) { | 5204 if (function != NULL) { |
| 5211 // Check for possible name clash. | 5205 // Check for possible name clash. |
| 5212 DCHECK_EQ(Context::kNotFound, | 5206 DCHECK_EQ(Context::kNotFound, |
| 5213 Context::IntrinsicIndexForName(name->string())); | 5207 Context::IntrinsicIndexForName(name->string())); |
| 5214 // Check for built-in IS_VAR macro. | 5208 // Check for built-in IS_VAR macro. |
| 5215 if (function->function_id == Runtime::kIS_VAR) { | 5209 if (function->function_id == Runtime::kIS_VAR) { |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5272 | 5266 |
| 5273 | 5267 |
| 5274 void Parser::InsertShadowingVarBindingInitializers(Block* inner_block) { | 5268 void Parser::InsertShadowingVarBindingInitializers(Block* inner_block) { |
| 5275 // For each var-binding that shadows a parameter, insert an assignment | 5269 // For each var-binding that shadows a parameter, insert an assignment |
| 5276 // initializing the variable with the parameter. | 5270 // initializing the variable with the parameter. |
| 5277 Scope* inner_scope = inner_block->scope(); | 5271 Scope* inner_scope = inner_block->scope(); |
| 5278 DCHECK(inner_scope->is_declaration_scope()); | 5272 DCHECK(inner_scope->is_declaration_scope()); |
| 5279 Scope* function_scope = inner_scope->outer_scope(); | 5273 Scope* function_scope = inner_scope->outer_scope(); |
| 5280 DCHECK(function_scope->is_function_scope()); | 5274 DCHECK(function_scope->is_function_scope()); |
| 5281 ZoneList<Declaration*>* decls = inner_scope->declarations(); | 5275 ZoneList<Declaration*>* decls = inner_scope->declarations(); |
| 5282 BlockState block_state(&scope_state_, inner_scope); | |
| 5283 for (int i = 0; i < decls->length(); ++i) { | 5276 for (int i = 0; i < decls->length(); ++i) { |
| 5284 Declaration* decl = decls->at(i); | 5277 Declaration* decl = decls->at(i); |
| 5285 if (decl->mode() != VAR || !decl->IsVariableDeclaration()) continue; | 5278 if (decl->mode() != VAR || !decl->IsVariableDeclaration()) continue; |
| 5286 const AstRawString* name = decl->proxy()->raw_name(); | 5279 const AstRawString* name = decl->proxy()->raw_name(); |
| 5287 Variable* parameter = function_scope->LookupLocal(name); | 5280 Variable* parameter = function_scope->LookupLocal(name); |
| 5288 if (parameter == nullptr) continue; | 5281 if (parameter == nullptr) continue; |
| 5289 VariableProxy* to = NewUnresolved(name, VAR); | 5282 VariableProxy* to = inner_scope->NewUnresolved(factory(), name); |
| 5290 VariableProxy* from = factory()->NewVariableProxy(parameter); | 5283 VariableProxy* from = factory()->NewVariableProxy(parameter); |
| 5291 Expression* assignment = | 5284 Expression* assignment = |
| 5292 factory()->NewAssignment(Token::ASSIGN, to, from, kNoSourcePosition); | 5285 factory()->NewAssignment(Token::ASSIGN, to, from, kNoSourcePosition); |
| 5293 Statement* statement = | 5286 Statement* statement = |
| 5294 factory()->NewExpressionStatement(assignment, kNoSourcePosition); | 5287 factory()->NewExpressionStatement(assignment, kNoSourcePosition); |
| 5295 inner_block->statements()->InsertAt(0, statement, zone()); | 5288 inner_block->statements()->InsertAt(0, statement, zone()); |
| 5296 } | 5289 } |
| 5297 } | 5290 } |
| 5298 | 5291 |
| 5299 void Parser::InsertSloppyBlockFunctionVarBindings(DeclarationScope* scope, | 5292 void Parser::InsertSloppyBlockFunctionVarBindings(Scope* scope, |
| 5300 Scope* complex_params_scope, | 5293 Scope* complex_params_scope, |
| 5301 bool* ok) { | 5294 bool* ok) { |
| 5302 // For each variable which is used as a function declaration in a sloppy | 5295 // For each variable which is used as a function declaration in a sloppy |
| 5303 // block, | 5296 // block, |
| 5297 DCHECK(scope->is_declaration_scope()); |
| 5304 SloppyBlockFunctionMap* map = scope->sloppy_block_function_map(); | 5298 SloppyBlockFunctionMap* map = scope->sloppy_block_function_map(); |
| 5305 for (ZoneHashMap::Entry* p = map->Start(); p != nullptr; p = map->Next(p)) { | 5299 for (ZoneHashMap::Entry* p = map->Start(); p != nullptr; p = map->Next(p)) { |
| 5306 AstRawString* name = static_cast<AstRawString*>(p->key); | 5300 AstRawString* name = static_cast<AstRawString*>(p->key); |
| 5307 | 5301 |
| 5308 // If the variable wouldn't conflict with a lexical declaration | 5302 // If the variable wouldn't conflict with a lexical declaration |
| 5309 // or parameter, | 5303 // or parameter, |
| 5310 | 5304 |
| 5311 // Check if there's a conflict with a parameter. | 5305 // Check if there's a conflict with a parameter. |
| 5312 // This depends on the fact that functions always have a scope solely to | 5306 // This depends on the fact that functions always have a scope solely to |
| 5313 // hold complex parameters, and the names local to that scope are | 5307 // hold complex parameters, and the names local to that scope are |
| 5314 // precisely the names of the parameters. IsDeclaredParameter(name) does | 5308 // precisely the names of the parameters. IsDeclaredParameter(name) does |
| 5315 // not hold for names declared by complex parameters, nor are those | 5309 // not hold for names declared by complex parameters, nor are those |
| 5316 // bindings necessarily declared lexically, so we have to check for them | 5310 // bindings necessarily declared lexically, so we have to check for them |
| 5317 // explicitly. On the other hand, if there are not complex parameters, | 5311 // explicitly. On the other hand, if there are not complex parameters, |
| 5318 // it is sufficient to just check IsDeclaredParameter. | 5312 // it is sufficient to just check IsDeclaredParameter. |
| 5319 if (complex_params_scope != nullptr) { | 5313 if (complex_params_scope != nullptr) { |
| 5320 if (complex_params_scope->LookupLocal(name) != nullptr) { | 5314 if (complex_params_scope->LookupLocal(name) != nullptr) { |
| 5321 continue; | 5315 continue; |
| 5322 } | 5316 } |
| 5323 } else { | 5317 } else { |
| 5324 if (scope->IsDeclaredParameter(name)) { | 5318 if (scope->IsDeclaredParameter(name)) { |
| 5325 continue; | 5319 continue; |
| 5326 } | 5320 } |
| 5327 } | 5321 } |
| 5328 | 5322 |
| 5329 bool var_created = false; | 5323 bool var_created = false; |
| 5330 | 5324 |
| 5331 // Write in assignments to var for each block-scoped function declaration | 5325 // Write in assignments to var for each block-scoped function declaration |
| 5332 auto delegates = static_cast<SloppyBlockFunctionMap::Vector*>(p->value); | 5326 auto delegates = static_cast<SloppyBlockFunctionMap::Vector*>(p->value); |
| 5333 | |
| 5334 DeclarationScope* decl_scope = scope; | |
| 5335 while (decl_scope->is_eval_scope()) { | |
| 5336 decl_scope = decl_scope->outer_scope()->GetDeclarationScope(); | |
| 5337 } | |
| 5338 Scope* outer_scope = decl_scope->outer_scope(); | |
| 5339 | |
| 5340 for (SloppyBlockFunctionStatement* delegate : *delegates) { | 5327 for (SloppyBlockFunctionStatement* delegate : *delegates) { |
| 5341 // Check if there's a conflict with a lexical declaration | 5328 // Check if there's a conflict with a lexical declaration |
| 5329 Scope* decl_scope = scope; |
| 5330 while (decl_scope->is_eval_scope()) { |
| 5331 decl_scope = decl_scope->outer_scope()->DeclarationScope(); |
| 5332 } |
| 5333 Scope* outer_scope = decl_scope->outer_scope(); |
| 5342 Scope* query_scope = delegate->scope()->outer_scope(); | 5334 Scope* query_scope = delegate->scope()->outer_scope(); |
| 5343 Variable* var = nullptr; | 5335 Variable* var = nullptr; |
| 5344 bool should_hoist = true; | 5336 bool should_hoist = true; |
| 5345 | 5337 |
| 5346 // Note that we perform this loop for each delegate named 'name', | 5338 // Note that we perform this loop for each delegate named 'name', |
| 5347 // which may duplicate work if those delegates share scopes. | 5339 // which may duplicate work if those delegates share scopes. |
| 5348 // It is not sufficient to just do a Lookup on query_scope: for | 5340 // It is not sufficient to just do a Lookup on query_scope: for |
| 5349 // example, that does not prevent hoisting of the function in | 5341 // example, that does not prevent hoisting of the function in |
| 5350 // `{ let e; try {} catch (e) { function e(){} } }` | 5342 // `{ let e; try {} catch (e) { function e(){} } }` |
| 5351 do { | 5343 do { |
| (...skipping 1331 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6683 do_block_->statements()->Add(validate_iterator, zone); | 6675 do_block_->statements()->Add(validate_iterator, zone); |
| 6684 do_block_->statements()->Add(loop, zone); | 6676 do_block_->statements()->Add(loop, zone); |
| 6685 do_block_->statements()->Add(maybe_return_value, zone); | 6677 do_block_->statements()->Add(maybe_return_value, zone); |
| 6686 | 6678 |
| 6687 Block* do_block = factory->NewBlock(nullptr, 2, false, nopos); | 6679 Block* do_block = factory->NewBlock(nullptr, 2, false, nopos); |
| 6688 do_block->statements()->Add(do_block_, zone); | 6680 do_block->statements()->Add(do_block_, zone); |
| 6689 do_block->statements()->Add(get_value, zone); | 6681 do_block->statements()->Add(get_value, zone); |
| 6690 | 6682 |
| 6691 Variable* dot_result = scope->NewTemporary(avfactory->dot_result_string()); | 6683 Variable* dot_result = scope->NewTemporary(avfactory->dot_result_string()); |
| 6692 yield_star = factory->NewDoExpression(do_block, dot_result, nopos); | 6684 yield_star = factory->NewDoExpression(do_block, dot_result, nopos); |
| 6693 Rewriter::Rewrite(parser_, scope->GetClosureScope(), yield_star, avfactory); | 6685 Rewriter::Rewrite(parser_, scope->ClosureScope(), yield_star, avfactory); |
| 6694 } | 6686 } |
| 6695 | 6687 |
| 6696 return yield_star; | 6688 return yield_star; |
| 6697 } | 6689 } |
| 6698 | 6690 |
| 6699 Statement* ParserTraits::CheckCallable(Variable* var, Expression* error, | 6691 Statement* ParserTraits::CheckCallable(Variable* var, Expression* error, |
| 6700 int pos) { | 6692 int pos) { |
| 6701 auto factory = parser_->factory(); | 6693 auto factory = parser_->factory(); |
| 6702 auto avfactory = parser_->ast_value_factory(); | 6694 auto avfactory = parser_->ast_value_factory(); |
| 6703 const int nopos = kNoSourcePosition; | 6695 const int nopos = kNoSourcePosition; |
| (...skipping 456 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7160 node->Print(Isolate::Current()); | 7152 node->Print(Isolate::Current()); |
| 7161 } | 7153 } |
| 7162 #endif // DEBUG | 7154 #endif // DEBUG |
| 7163 | 7155 |
| 7164 #undef CHECK_OK | 7156 #undef CHECK_OK |
| 7165 #undef CHECK_OK_VOID | 7157 #undef CHECK_OK_VOID |
| 7166 #undef CHECK_FAILED | 7158 #undef CHECK_FAILED |
| 7167 | 7159 |
| 7168 } // namespace internal | 7160 } // namespace internal |
| 7169 } // namespace v8 | 7161 } // namespace v8 |
| OLD | NEW |