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/parser.h" | 5 #include "src/parser.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/ast-literal-reindexer.h" | 9 #include "src/ast-literal-reindexer.h" |
10 #include "src/bailout-reason.h" | 10 #include "src/bailout-reason.h" |
(...skipping 4658 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4669 DCHECK_NOT_NULL(inner_scope); | 4669 DCHECK_NOT_NULL(inner_scope); |
4670 DCHECK_EQ(body, inner_block->statements()); | 4670 DCHECK_EQ(body, inner_block->statements()); |
4671 scope_->SetLanguageMode(inner_scope->language_mode()); | 4671 scope_->SetLanguageMode(inner_scope->language_mode()); |
4672 Block* init_block = BuildParameterInitializationBlock(parameters, CHECK_OK); | 4672 Block* init_block = BuildParameterInitializationBlock(parameters, CHECK_OK); |
4673 DCHECK_NOT_NULL(init_block); | 4673 DCHECK_NOT_NULL(init_block); |
4674 | 4674 |
4675 inner_scope->set_end_position(scanner()->location().end_pos); | 4675 inner_scope->set_end_position(scanner()->location().end_pos); |
4676 inner_scope = inner_scope->FinalizeBlockScope(); | 4676 inner_scope = inner_scope->FinalizeBlockScope(); |
4677 if (inner_scope != nullptr) { | 4677 if (inner_scope != nullptr) { |
4678 CheckConflictingVarDeclarations(inner_scope, CHECK_OK); | 4678 CheckConflictingVarDeclarations(inner_scope, CHECK_OK); |
| 4679 InsertShadowingVarBindingInitializers(inner_block); |
4679 } | 4680 } |
4680 | 4681 |
4681 result->Add(init_block, zone()); | 4682 result->Add(init_block, zone()); |
4682 result->Add(inner_block, zone()); | 4683 result->Add(inner_block, zone()); |
4683 } | 4684 } |
4684 | 4685 |
4685 if (function_type == FunctionLiteral::NAMED_EXPRESSION) { | 4686 if (function_type == FunctionLiteral::NAMED_EXPRESSION) { |
4686 // Now that we know the language mode, we can create the const assignment | 4687 // Now that we know the language mode, we can create the const assignment |
4687 // in the previously reserved spot. | 4688 // in the previously reserved spot. |
4688 // NOTE: We create a proxy and resolve it here so that in the | 4689 // NOTE: We create a proxy and resolve it here so that in the |
(...skipping 240 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4929 | 4930 |
4930 | 4931 |
4931 Literal* Parser::GetLiteralUndefined(int position) { | 4932 Literal* Parser::GetLiteralUndefined(int position) { |
4932 return factory()->NewUndefinedLiteral(position); | 4933 return factory()->NewUndefinedLiteral(position); |
4933 } | 4934 } |
4934 | 4935 |
4935 | 4936 |
4936 void Parser::CheckConflictingVarDeclarations(Scope* scope, bool* ok) { | 4937 void Parser::CheckConflictingVarDeclarations(Scope* scope, bool* ok) { |
4937 Declaration* decl = scope->CheckConflictingVarDeclarations(); | 4938 Declaration* decl = scope->CheckConflictingVarDeclarations(); |
4938 if (decl != NULL) { | 4939 if (decl != NULL) { |
4939 // In harmony mode we treat conflicting variable bindinds as early | 4940 // In ES6, conflicting variable bindings are early errors. |
4940 // errors. See ES5 16 for a definition of early errors. | |
4941 const AstRawString* name = decl->proxy()->raw_name(); | 4941 const AstRawString* name = decl->proxy()->raw_name(); |
4942 int position = decl->proxy()->position(); | 4942 int position = decl->proxy()->position(); |
4943 Scanner::Location location = position == RelocInfo::kNoPosition | 4943 Scanner::Location location = position == RelocInfo::kNoPosition |
4944 ? Scanner::Location::invalid() | 4944 ? Scanner::Location::invalid() |
4945 : Scanner::Location(position, position + 1); | 4945 : Scanner::Location(position, position + 1); |
4946 ParserTraits::ReportMessageAt(location, MessageTemplate::kVarRedeclaration, | 4946 ParserTraits::ReportMessageAt(location, MessageTemplate::kVarRedeclaration, |
4947 name); | 4947 name); |
4948 *ok = false; | 4948 *ok = false; |
4949 } | 4949 } |
4950 } | 4950 } |
4951 | 4951 |
4952 | 4952 |
| 4953 void Parser::InsertShadowingVarBindingInitializers(Block* inner_block) { |
| 4954 // For each var-binding that shadows a parameter, insert an assignment |
| 4955 // initializing the variable with the parameter. |
| 4956 Scope* inner_scope = inner_block->scope(); |
| 4957 DCHECK(inner_scope->is_declaration_scope()); |
| 4958 Scope* function_scope = inner_scope->outer_scope(); |
| 4959 DCHECK(function_scope->is_function_scope()); |
| 4960 ZoneList<Declaration*>* decls = inner_scope->declarations(); |
| 4961 for (int i = 0; i < decls->length(); ++i) { |
| 4962 Declaration* decl = decls->at(i); |
| 4963 if (decl->mode() != VAR || !decl->IsVariableDeclaration()) continue; |
| 4964 const AstRawString* name = decl->proxy()->raw_name(); |
| 4965 Variable* parameter = function_scope->LookupLocal(name); |
| 4966 if (parameter == nullptr) continue; |
| 4967 VariableProxy* to = inner_scope->NewUnresolved(factory(), name); |
| 4968 VariableProxy* from = factory()->NewVariableProxy(parameter); |
| 4969 Expression* assignment = factory()->NewAssignment( |
| 4970 Token::ASSIGN, to, from, RelocInfo::kNoPosition); |
| 4971 Statement* statement = factory()->NewExpressionStatement( |
| 4972 assignment, RelocInfo::kNoPosition); |
| 4973 inner_block->statements()->InsertAt(0, statement, zone()); |
| 4974 } |
| 4975 } |
| 4976 |
| 4977 |
4953 void Parser::InsertSloppyBlockFunctionVarBindings(Scope* scope, bool* ok) { | 4978 void Parser::InsertSloppyBlockFunctionVarBindings(Scope* scope, bool* ok) { |
4954 // For each variable which is used as a function declaration in a sloppy | 4979 // For each variable which is used as a function declaration in a sloppy |
4955 // block, | 4980 // block, |
4956 DCHECK(scope->is_declaration_scope()); | 4981 DCHECK(scope->is_declaration_scope()); |
4957 SloppyBlockFunctionMap* map = scope->sloppy_block_function_map(); | 4982 SloppyBlockFunctionMap* map = scope->sloppy_block_function_map(); |
4958 for (ZoneHashMap::Entry* p = map->Start(); p != nullptr; p = map->Next(p)) { | 4983 for (ZoneHashMap::Entry* p = map->Start(); p != nullptr; p = map->Next(p)) { |
4959 AstRawString* name = static_cast<AstRawString*>(p->key); | 4984 AstRawString* name = static_cast<AstRawString*>(p->key); |
4960 // If the variable wouldn't conflict with a lexical declaration, | 4985 // If the variable wouldn't conflict with a lexical declaration, |
4961 Variable* var = scope->LookupLocal(name); | 4986 Variable* var = scope->LookupLocal(name); |
4962 if (var == nullptr || !IsLexicalVariableMode(var->mode())) { | 4987 if (var == nullptr || !IsLexicalVariableMode(var->mode())) { |
(...skipping 1326 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6289 | 6314 |
6290 Expression* Parser::SpreadCallNew(Expression* function, | 6315 Expression* Parser::SpreadCallNew(Expression* function, |
6291 ZoneList<v8::internal::Expression*>* args, | 6316 ZoneList<v8::internal::Expression*>* args, |
6292 int pos) { | 6317 int pos) { |
6293 args->InsertAt(0, function, zone()); | 6318 args->InsertAt(0, function, zone()); |
6294 | 6319 |
6295 return factory()->NewCallRuntime(Context::REFLECT_CONSTRUCT_INDEX, args, pos); | 6320 return factory()->NewCallRuntime(Context::REFLECT_CONSTRUCT_INDEX, args, pos); |
6296 } | 6321 } |
6297 } // namespace internal | 6322 } // namespace internal |
6298 } // namespace v8 | 6323 } // namespace v8 |
OLD | NEW |