Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1)

Side by Side Diff: src/parsing/pattern-rewriter.cc

Issue 2662183002: [parser] Remove hoist_scope from DeclarationDescriptor (Closed)
Patch Set: Factored out helper function Created 3 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/parsing/parser-base.h ('k') | src/parsing/preparser.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2015 the V8 project authors. All rights reserved. 1 // Copyright 2015 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/ast/ast.h" 5 #include "src/ast/ast.h"
6 #include "src/messages.h" 6 #include "src/messages.h"
7 #include "src/objects-inl.h" 7 #include "src/objects-inl.h"
8 #include "src/parsing/parameter-initializer-rewriter.h" 8 #include "src/parsing/parameter-initializer-rewriter.h"
9 #include "src/parsing/parser.h" 9 #include "src/parsing/parser.h"
10 10
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after
130 // when the variable is encountered in the source. But the variable/constant 130 // when the variable is encountered in the source. But the variable/constant
131 // is declared (and set to 'undefined') upon entering the function within 131 // is declared (and set to 'undefined') upon entering the function within
132 // which the variable or constant is declared. Only function variables have 132 // which the variable or constant is declared. Only function variables have
133 // an initial value in the declaration (because they are initialized upon 133 // an initial value in the declaration (because they are initialized upon
134 // entering the function). 134 // entering the function).
135 const AstRawString* name = pattern->raw_name(); 135 const AstRawString* name = pattern->raw_name();
136 VariableProxy* proxy = 136 VariableProxy* proxy =
137 factory()->NewVariableProxy(name, NORMAL_VARIABLE, pattern->position()); 137 factory()->NewVariableProxy(name, NORMAL_VARIABLE, pattern->position());
138 Declaration* declaration = factory()->NewVariableDeclaration( 138 Declaration* declaration = factory()->NewVariableDeclaration(
139 proxy, descriptor_->scope, descriptor_->declaration_pos); 139 proxy, descriptor_->scope, descriptor_->declaration_pos);
140
141 // When an extra declaration scope needs to be inserted to account for
142 // a sloppy eval in a default parameter or function body, the parameter
143 // needs to be declared in the function's scope, not in the varblock
144 // scope which will be used for the initializer expression.
145 Scope* outer_function_scope = nullptr;
146 if (DeclaresParameterContainingSloppyEval()) {
147 outer_function_scope = descriptor_->scope->outer_scope();
neis 2017/02/01 08:55:24 Can you add a DCHECK here saying that it's a funct
adamk 2017/02/01 16:22:15 I could add another one, but it does feel kind of
148 }
140 Variable* var = parser_->Declare( 149 Variable* var = parser_->Declare(
141 declaration, descriptor_->declaration_kind, descriptor_->mode, 150 declaration, descriptor_->declaration_kind, descriptor_->mode,
142 Variable::DefaultInitializationFlag(descriptor_->mode), ok_, 151 Variable::DefaultInitializationFlag(descriptor_->mode), ok_,
143 descriptor_->hoist_scope); 152 outer_function_scope);
144 if (!*ok_) return; 153 if (!*ok_) return;
145 DCHECK_NOT_NULL(var); 154 DCHECK_NOT_NULL(var);
146 DCHECK(proxy->is_resolved()); 155 DCHECK(proxy->is_resolved());
147 DCHECK(initializer_position_ != kNoSourcePosition); 156 DCHECK(initializer_position_ != kNoSourcePosition);
148 var->set_initializer_position(initializer_position_); 157 var->set_initializer_position(initializer_position_);
149 158
150 // TODO(adamk): This should probably be checking hoist_scope. 159 Scope* declaration_scope =
151 // Move it to Parser::Declare() to make it easier to test 160 outer_function_scope != nullptr
152 // the right scope. 161 ? outer_function_scope
153 Scope* declaration_scope = IsLexicalVariableMode(descriptor_->mode) 162 : (IsLexicalVariableMode(descriptor_->mode)
154 ? descriptor_->scope 163 ? descriptor_->scope
155 : descriptor_->scope->GetDeclarationScope(); 164 : descriptor_->scope->GetDeclarationScope());
156 if (declaration_scope->num_var() > kMaxNumFunctionLocals) { 165 if (declaration_scope->num_var() > kMaxNumFunctionLocals) {
157 parser_->ReportMessage(MessageTemplate::kTooManyVariables); 166 parser_->ReportMessage(MessageTemplate::kTooManyVariables);
158 *ok_ = false; 167 *ok_ = false;
159 return; 168 return;
160 } 169 }
161 if (names_) { 170 if (names_) {
162 names_->Add(name, zone()); 171 names_->Add(name, zone());
163 } 172 }
164 173
165 // If there's no initializer, we're done. 174 // If there's no initializer, we're done.
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after
314 Expression* expr = factory()->NewDoExpression(block_, temp, pos); 323 Expression* expr = factory()->NewDoExpression(block_, temp, pos);
315 node->Rewrite(expr); 324 node->Rewrite(expr);
316 block_ = old_block; 325 block_ = old_block;
317 if (block_) { 326 if (block_) {
318 block_->statements()->Add(factory()->NewExpressionStatement(expr, pos), 327 block_->statements()->Add(factory()->NewExpressionStatement(expr, pos),
319 zone()); 328 zone());
320 } 329 }
321 set_context(old_context); 330 set_context(old_context);
322 } 331 }
323 332
333 bool Parser::PatternRewriter::DeclaresParameterContainingSloppyEval() const {
334 // Need to check for a binding context to make sure we have a descriptor.
335 if (IsBindingContext() &&
336 // Only relevant for parameters.
337 descriptor_->declaration_kind == DeclarationDescriptor::PARAMETER &&
338 // And only when scope is a block scope;
339 // without eval, it is a function scope.
340 scope()->is_block_scope()) {
341 DCHECK(scope()->calls_sloppy_eval());
342 DCHECK(scope()->is_declaration_scope());
343 DCHECK(scope()->outer_scope()->is_function_scope());
neis 2017/02/01 08:55:24 Hmm I guess it's already here because scope() is a
adamk 2017/02/01 16:22:15 Another option would be to call this function some
neis 2017/02/01 16:26:41 I prefer the current version. It's okay with me if
344 return true;
345 }
346
347 return false;
348 }
349
324 // When an extra declaration scope needs to be inserted to account for 350 // When an extra declaration scope needs to be inserted to account for
325 // a sloppy eval in a default parameter or function body, the expressions 351 // a sloppy eval in a default parameter or function body, the expressions
326 // needs to be in that new inner scope which was added after initial 352 // needs to be in that new inner scope which was added after initial
327 // parsing. 353 // parsing.
328 void Parser::PatternRewriter::RewriteParameterScopes(Expression* expr) { 354 void Parser::PatternRewriter::RewriteParameterScopes(Expression* expr) {
329 if (!IsBindingContext()) return; 355 if (DeclaresParameterContainingSloppyEval()) {
330 if (descriptor_->declaration_kind != DeclarationDescriptor::PARAMETER) return; 356 ReparentParameterExpressionScope(parser_->stack_limit(), expr, scope());
331 if (!scope()->is_block_scope()) return; 357 }
332
333 DCHECK(scope()->is_declaration_scope());
334 DCHECK(scope()->outer_scope()->is_function_scope());
335 DCHECK(scope()->calls_sloppy_eval());
336
337 ReparentParameterExpressionScope(parser_->stack_limit(), expr, scope());
338 } 358 }
339 359
340 void Parser::PatternRewriter::VisitObjectLiteral(ObjectLiteral* pattern, 360 void Parser::PatternRewriter::VisitObjectLiteral(ObjectLiteral* pattern,
341 Variable** temp_var) { 361 Variable** temp_var) {
342 auto temp = *temp_var = CreateTempVar(current_value_); 362 auto temp = *temp_var = CreateTempVar(current_value_);
343 363
344 ZoneList<Expression*>* rest_runtime_callargs = nullptr; 364 ZoneList<Expression*>* rest_runtime_callargs = nullptr;
345 if (pattern->has_rest_property()) { 365 if (pattern->has_rest_property()) {
346 // non_rest_properties_count = pattern->properties()->length - 1; 366 // non_rest_properties_count = pattern->properties()->length - 1;
347 // args_length = 1 + non_rest_properties_count because we need to 367 // args_length = 1 + non_rest_properties_count because we need to
(...skipping 398 matching lines...) Expand 10 before | Expand all | Expand 10 after
746 NOT_A_PATTERN(TryFinallyStatement) 766 NOT_A_PATTERN(TryFinallyStatement)
747 NOT_A_PATTERN(UnaryOperation) 767 NOT_A_PATTERN(UnaryOperation)
748 NOT_A_PATTERN(VariableDeclaration) 768 NOT_A_PATTERN(VariableDeclaration)
749 NOT_A_PATTERN(WhileStatement) 769 NOT_A_PATTERN(WhileStatement)
750 NOT_A_PATTERN(WithStatement) 770 NOT_A_PATTERN(WithStatement)
751 NOT_A_PATTERN(Yield) 771 NOT_A_PATTERN(Yield)
752 772
753 #undef NOT_A_PATTERN 773 #undef NOT_A_PATTERN
754 } // namespace internal 774 } // namespace internal
755 } // namespace v8 775 } // namespace v8
OLDNEW
« no previous file with comments | « src/parsing/parser-base.h ('k') | src/parsing/preparser.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698