Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "src/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 2241 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2252 ? CONST | 2252 ? CONST |
| 2253 : (is_strict(language_mode()) || allow_harmony_sloppy_function()) && | 2253 : (is_strict(language_mode()) || allow_harmony_sloppy_function()) && |
| 2254 !scope_->is_declaration_scope() | 2254 !scope_->is_declaration_scope() |
| 2255 ? LET | 2255 ? LET |
| 2256 : VAR; | 2256 : VAR; |
| 2257 VariableProxy* proxy = NewUnresolved(name, mode); | 2257 VariableProxy* proxy = NewUnresolved(name, mode); |
| 2258 Declaration* declaration = | 2258 Declaration* declaration = |
| 2259 factory()->NewFunctionDeclaration(proxy, mode, fun, scope_, pos); | 2259 factory()->NewFunctionDeclaration(proxy, mode, fun, scope_, pos); |
| 2260 Declare(declaration, DeclarationDescriptor::NORMAL, true, CHECK_OK); | 2260 Declare(declaration, DeclarationDescriptor::NORMAL, true, CHECK_OK); |
| 2261 if (names) names->Add(name, zone()); | 2261 if (names) names->Add(name, zone()); |
| 2262 return factory()->NewEmptyStatement(RelocInfo::kNoPosition); | 2262 EmptyStatement* empty = factory()->NewEmptyStatement(RelocInfo::kNoPosition); |
| 2263 if (is_sloppy(language_mode()) && allow_harmony_sloppy_function() && | |
| 2264 !scope_->is_declaration_scope()) { | |
| 2265 DelegateStatement* delegate = | |
| 2266 factory()->NewDelegateStatement(RelocInfo::kNoPosition, empty, scope_); | |
| 2267 scope_->DeclarationScope()->sloppy_block_function_map()->Declare(name, | |
| 2268 delegate); | |
| 2269 return delegate; | |
| 2270 } | |
| 2271 return empty; | |
| 2263 } | 2272 } |
| 2264 | 2273 |
| 2265 | 2274 |
| 2266 Statement* Parser::ParseClassDeclaration(ZoneList<const AstRawString*>* names, | 2275 Statement* Parser::ParseClassDeclaration(ZoneList<const AstRawString*>* names, |
| 2267 bool* ok) { | 2276 bool* ok) { |
| 2268 // ClassDeclaration :: | 2277 // ClassDeclaration :: |
| 2269 // 'class' Identifier ('extends' LeftHandExpression)? '{' ClassBody '}' | 2278 // 'class' Identifier ('extends' LeftHandExpression)? '{' ClassBody '}' |
| 2270 // | 2279 // |
| 2271 // A ClassDeclaration | 2280 // A ClassDeclaration |
| 2272 // | 2281 // |
| (...skipping 1997 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4270 function_name_location, CHECK_OK); | 4279 function_name_location, CHECK_OK); |
| 4271 const bool allow_duplicate_parameters = | 4280 const bool allow_duplicate_parameters = |
| 4272 is_sloppy(language_mode) && formals.is_simple && !IsConciseMethod(kind); | 4281 is_sloppy(language_mode) && formals.is_simple && !IsConciseMethod(kind); |
| 4273 ValidateFormalParameters(&formals_classifier, language_mode, | 4282 ValidateFormalParameters(&formals_classifier, language_mode, |
| 4274 allow_duplicate_parameters, CHECK_OK); | 4283 allow_duplicate_parameters, CHECK_OK); |
| 4275 | 4284 |
| 4276 if (is_strict(language_mode)) { | 4285 if (is_strict(language_mode)) { |
| 4277 CheckStrictOctalLiteral(scope->start_position(), scope->end_position(), | 4286 CheckStrictOctalLiteral(scope->start_position(), scope->end_position(), |
| 4278 CHECK_OK); | 4287 CHECK_OK); |
| 4279 } | 4288 } |
| 4289 if (is_sloppy(language_mode) && allow_harmony_sloppy_function()) { | |
| 4290 InsertSloppyBlockFunctionVarBindings(scope, CHECK_OK); | |
| 4291 } | |
| 4280 if (is_strict(language_mode) || allow_harmony_sloppy()) { | 4292 if (is_strict(language_mode) || allow_harmony_sloppy()) { |
| 4281 CheckConflictingVarDeclarations(scope, CHECK_OK); | 4293 CheckConflictingVarDeclarations(scope, CHECK_OK); |
| 4282 } | 4294 } |
| 4283 } | 4295 } |
| 4284 | 4296 |
| 4285 bool has_duplicate_parameters = | 4297 bool has_duplicate_parameters = |
| 4286 !formals_classifier.is_valid_formal_parameter_list_without_duplicates(); | 4298 !formals_classifier.is_valid_formal_parameter_list_without_duplicates(); |
| 4287 FunctionLiteral::ParameterFlag duplicate_parameters = | 4299 FunctionLiteral::ParameterFlag duplicate_parameters = |
| 4288 has_duplicate_parameters ? FunctionLiteral::kHasDuplicateParameters | 4300 has_duplicate_parameters ? FunctionLiteral::kHasDuplicateParameters |
| 4289 : FunctionLiteral::kNoDuplicateParameters; | 4301 : FunctionLiteral::kNoDuplicateParameters; |
| (...skipping 642 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4932 Scanner::Location location = position == RelocInfo::kNoPosition | 4944 Scanner::Location location = position == RelocInfo::kNoPosition |
| 4933 ? Scanner::Location::invalid() | 4945 ? Scanner::Location::invalid() |
| 4934 : Scanner::Location(position, position + 1); | 4946 : Scanner::Location(position, position + 1); |
| 4935 ParserTraits::ReportMessageAt(location, MessageTemplate::kVarRedeclaration, | 4947 ParserTraits::ReportMessageAt(location, MessageTemplate::kVarRedeclaration, |
| 4936 name); | 4948 name); |
| 4937 *ok = false; | 4949 *ok = false; |
| 4938 } | 4950 } |
| 4939 } | 4951 } |
| 4940 | 4952 |
| 4941 | 4953 |
| 4954 void Parser::InsertSloppyBlockFunctionVarBindings(Scope* scope, bool* ok) { | |
|
adamk
2015/09/11 15:42:56
Can you add a DCHECK that the passed-in scope is a
Dan Ehrenberg
2015/09/17 17:44:10
Done
| |
| 4955 // For each variable which is used as a function declaration in a sloppy | |
| 4956 // block, | |
| 4957 SloppyBlockFunctionMap* map = scope->sloppy_block_function_map(); | |
| 4958 for (ZoneHashMap::Entry* p = map->Start(); p != NULL; p = map->Next(p)) { | |
|
adamk
2015/09/11 15:42:56
Nit: I think "nullptr" is preferred these days ove
Dan Ehrenberg
2015/09/17 17:44:10
Done
| |
| 4959 AstRawString* name = reinterpret_cast<AstRawString*>(p->key); | |
|
adamk
2015/09/11 15:42:56
Can this just be a static_cast? Also, please re-co
Dan Ehrenberg
2015/09/17 17:44:10
Done
| |
| 4960 // If the variable wouldn't conflict with a lexical declaration, | |
| 4961 Variable* var = scope->LookupLocal(name); | |
| 4962 if (var == NULL || !IsLexicalVariableMode(var->mode())) { | |
|
adamk
2015/09/11 15:42:56
s/NULL/nullptr/
Dan Ehrenberg
2015/09/17 17:44:10
Done
| |
| 4963 // Declare a var-style binding for the function in the outer scope | |
| 4964 VariableProxy* proxy = scope->NewUnresolved(factory(), name); | |
| 4965 Declaration* declaration = factory()->NewVariableDeclaration( | |
| 4966 proxy, VAR, scope, RelocInfo::kNoPosition); | |
| 4967 Declare(declaration, DeclarationDescriptor::NORMAL, true, ok); | |
|
adamk
2015/09/11 15:42:56
I'm a little bit confused: why do you use the pass
Dan Ehrenberg
2015/09/17 17:44:10
It happens to work because this is called when com
adamk
2015/09/17 18:44:36
Thanks, this looks better. A later cleanup (not in
| |
| 4968 DCHECK(ok); // Based on the preceding check, this should not fail | |
| 4969 if (!ok) return; | |
| 4970 | |
| 4971 // Write in assignments to var for each block-scoped function declaration | |
| 4972 auto delegates = | |
| 4973 reinterpret_cast<ZoneVector<DelegateStatement*>*>(p->value); | |
|
adamk
2015/09/11 15:42:56
Same here, please static_cast instead of reinterpr
Dan Ehrenberg
2015/09/17 17:44:09
Done
| |
| 4974 for (auto stmt = delegates->begin(); stmt < delegates->end(); stmt++) { | |
|
adamk
2015/09/11 15:42:56
You can use more C++11 here:
for (auto stmt : del
Dan Ehrenberg
2015/09/17 17:44:09
Done
| |
| 4975 // Read from the local lexical scope and write to the function scope | |
| 4976 VariableProxy* to = scope->NewUnresolved(factory(), name); | |
| 4977 VariableProxy* from = (*stmt)->scope()->NewUnresolved(factory(), name); | |
| 4978 Expression* assignment = factory()->NewAssignment( | |
| 4979 Token::ASSIGN, to, from, RelocInfo::kNoPosition); | |
| 4980 Statement* statement = factory()->NewExpressionStatement( | |
| 4981 assignment, RelocInfo::kNoPosition); | |
| 4982 (*stmt)->set_statement(statement); | |
| 4983 } | |
| 4984 } | |
| 4985 } | |
| 4986 } | |
| 4987 | |
| 4988 | |
| 4942 // ---------------------------------------------------------------------------- | 4989 // ---------------------------------------------------------------------------- |
| 4943 // Parser support | 4990 // Parser support |
| 4944 | 4991 |
| 4945 bool Parser::TargetStackContainsLabel(const AstRawString* label) { | 4992 bool Parser::TargetStackContainsLabel(const AstRawString* label) { |
| 4946 for (Target* t = target_stack_; t != NULL; t = t->previous()) { | 4993 for (Target* t = target_stack_; t != NULL; t = t->previous()) { |
| 4947 if (ContainsLabel(t->statement()->labels(), label)) return true; | 4994 if (ContainsLabel(t->statement()->labels(), label)) return true; |
| 4948 } | 4995 } |
| 4949 return false; | 4996 return false; |
| 4950 } | 4997 } |
| 4951 | 4998 |
| (...skipping 1291 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 6243 | 6290 |
| 6244 Expression* Parser::SpreadCallNew(Expression* function, | 6291 Expression* Parser::SpreadCallNew(Expression* function, |
| 6245 ZoneList<v8::internal::Expression*>* args, | 6292 ZoneList<v8::internal::Expression*>* args, |
| 6246 int pos) { | 6293 int pos) { |
| 6247 args->InsertAt(0, function, zone()); | 6294 args->InsertAt(0, function, zone()); |
| 6248 | 6295 |
| 6249 return factory()->NewCallRuntime(Context::REFLECT_CONSTRUCT_INDEX, args, pos); | 6296 return factory()->NewCallRuntime(Context::REFLECT_CONSTRUCT_INDEX, args, pos); |
| 6250 } | 6297 } |
| 6251 } // namespace internal | 6298 } // namespace internal |
| 6252 } // namespace v8 | 6299 } // namespace v8 |
| OLD | NEW |