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/parser.cc

Issue 2520883002: [parser] Fix scopes in rewriting of for-of and destructuring assignments. (Closed)
Patch Set: Take into account that the scope may have been removed when we get to rewrite. Created 4 years, 1 month 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
OLDNEW
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-expression-rewriter.h" 10 #include "src/ast/ast-expression-rewriter.h"
(...skipping 4727 matching lines...) Expand 10 before | Expand all | Expand 10 after
4738 Expression* condition = factory()->NewCompareOperation( 4738 Expression* condition = factory()->NewCompareOperation(
4739 Token::EQ, factory()->NewVariableProxy(var_throw), 4739 Token::EQ, factory()->NewVariableProxy(var_throw),
4740 factory()->NewNullLiteral(nopos), nopos); 4740 factory()->NewNullLiteral(nopos), nopos);
4741 Expression* call = 4741 Expression* call =
4742 NewThrowTypeError(MessageTemplate::kThrowMethodMissing, 4742 NewThrowTypeError(MessageTemplate::kThrowMethodMissing,
4743 ast_value_factory()->empty_string(), nopos); 4743 ast_value_factory()->empty_string(), nopos);
4744 Statement* throw_call = factory()->NewExpressionStatement(call, nopos); 4744 Statement* throw_call = factory()->NewExpressionStatement(call, nopos);
4745 4745
4746 Block* then = factory()->NewBlock(nullptr, 4 + 1, false, nopos); 4746 Block* then = factory()->NewBlock(nullptr, 4 + 1, false, nopos);
4747 BuildIteratorCloseForCompletion( 4747 BuildIteratorCloseForCompletion(
4748 then->statements(), var_iterator, 4748 scope(), then->statements(), var_iterator,
4749 factory()->NewSmiLiteral(Parser::kNormalCompletion, nopos)); 4749 factory()->NewSmiLiteral(Parser::kNormalCompletion, nopos));
4750 then->statements()->Add(throw_call, zone()); 4750 then->statements()->Add(throw_call, zone());
4751 check_throw = factory()->NewIfStatement( 4751 check_throw = factory()->NewIfStatement(
4752 condition, then, factory()->NewEmptyStatement(nopos), nopos); 4752 condition, then, factory()->NewEmptyStatement(nopos), nopos);
4753 } 4753 }
4754 4754
4755 // output = %_Call(iteratorThrow, iterator, input); 4755 // output = %_Call(iteratorThrow, iterator, input);
4756 Statement* call_throw; 4756 Statement* call_throw;
4757 { 4757 {
4758 auto args = new (zone()) ZoneList<Expression*>(3, zone()); 4758 auto args = new (zone()) ZoneList<Expression*>(3, zone());
(...skipping 347 matching lines...) Expand 10 before | Expand all | Expand 10 after
5106 is_receiver_call, factory()->NewEmptyStatement(nopos), throw_call, 5106 is_receiver_call, factory()->NewEmptyStatement(nopos), throw_call,
5107 nopos); 5107 nopos);
5108 } 5108 }
5109 5109
5110 statements->Add(get_return, zone()); 5110 statements->Add(get_return, zone());
5111 statements->Add(check_return, zone()); 5111 statements->Add(check_return, zone());
5112 statements->Add(call_return, zone()); 5112 statements->Add(call_return, zone());
5113 statements->Add(validate_output, zone()); 5113 statements->Add(validate_output, zone());
5114 } 5114 }
5115 5115
5116 void Parser::FinalizeIteratorUse(Variable* completion, Expression* condition, 5116 void Parser::FinalizeIteratorUse(Scope* use_scope, Variable* completion,
5117 Variable* iter, Block* iterator_use, 5117 Expression* condition, Variable* iter,
5118 Block* target) { 5118 Block* iterator_use, Block* target) {
5119 // 5119 //
5120 // This function adds two statements to [target], corresponding to the 5120 // This function adds two statements to [target], corresponding to the
5121 // following code: 5121 // following code:
5122 // 5122 //
5123 // completion = kNormalCompletion; 5123 // completion = kNormalCompletion;
5124 // try { 5124 // try {
5125 // try { 5125 // try {
5126 // iterator_use 5126 // iterator_use
5127 // } catch(e) { 5127 // } catch(e) {
5128 // if (completion === kAbruptCompletion) completion = kThrowCompletion; 5128 // if (completion === kAbruptCompletion) completion = kThrowCompletion;
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
5164 condition, statement, factory()->NewEmptyStatement(nopos), nopos); 5164 condition, statement, factory()->NewEmptyStatement(nopos), nopos);
5165 } 5165 }
5166 5166
5167 // if (condition) { 5167 // if (condition) {
5168 // #BuildIteratorCloseForCompletion(iter, completion) 5168 // #BuildIteratorCloseForCompletion(iter, completion)
5169 // } 5169 // }
5170 Block* maybe_close; 5170 Block* maybe_close;
5171 { 5171 {
5172 Block* block = factory()->NewBlock(nullptr, 2, true, nopos); 5172 Block* block = factory()->NewBlock(nullptr, 2, true, nopos);
5173 Expression* proxy = factory()->NewVariableProxy(completion); 5173 Expression* proxy = factory()->NewVariableProxy(completion);
5174 BuildIteratorCloseForCompletion(block->statements(), iter, proxy); 5174 BuildIteratorCloseForCompletion(use_scope, block->statements(), iter,
5175 proxy);
5175 DCHECK(block->statements()->length() == 2); 5176 DCHECK(block->statements()->length() == 2);
5176 5177
5177 maybe_close = factory()->NewBlock(nullptr, 1, true, nopos); 5178 maybe_close = factory()->NewBlock(nullptr, 1, true, nopos);
5178 maybe_close->statements()->Add( 5179 maybe_close->statements()->Add(
5179 factory()->NewIfStatement(condition, block, 5180 factory()->NewIfStatement(condition, block,
5180 factory()->NewEmptyStatement(nopos), nopos), 5181 factory()->NewEmptyStatement(nopos), nopos),
5181 zone()); 5182 zone());
5182 } 5183 }
5183 5184
5184 // try { #try_block } 5185 // try { #try_block }
5185 // catch(e) { 5186 // catch(e) {
5186 // #set_completion_throw; 5187 // #set_completion_throw;
5187 // %ReThrow(e); 5188 // %ReThrow(e);
5188 // } 5189 // }
5189 Statement* try_catch; 5190 Statement* try_catch;
5190 { 5191 {
5191 Scope* catch_scope = NewScopeWithParent(scope(), CATCH_SCOPE); 5192 Scope* catch_scope = NewScopeWithParent(use_scope, CATCH_SCOPE);
5192 Variable* catch_variable = 5193 Variable* catch_variable =
5193 catch_scope->DeclareLocal(ast_value_factory()->dot_catch_string(), VAR, 5194 catch_scope->DeclareLocal(ast_value_factory()->dot_catch_string(), VAR,
5194 kCreatedInitialized, NORMAL_VARIABLE); 5195 kCreatedInitialized, NORMAL_VARIABLE);
5195 catch_scope->set_is_hidden(); 5196 catch_scope->set_is_hidden();
5196 5197
5197 Statement* rethrow; 5198 Statement* rethrow;
5198 // We use %ReThrow rather than the ordinary throw because we want to 5199 // We use %ReThrow rather than the ordinary throw because we want to
5199 // preserve the original exception message. This is also why we create a 5200 // preserve the original exception message. This is also why we create a
5200 // TryCatchStatementForReThrow below (which does not clear the pending 5201 // TryCatchStatementForReThrow below (which does not clear the pending
5201 // message), rather than a TryCatchStatement. 5202 // message), rather than a TryCatchStatement.
(...skipping 19 matching lines...) Expand all
5221 try_block->statements()->Add(try_catch, zone()); 5222 try_block->statements()->Add(try_catch, zone());
5222 5223
5223 try_finally = 5224 try_finally =
5224 factory()->NewTryFinallyStatement(try_block, maybe_close, nopos); 5225 factory()->NewTryFinallyStatement(try_block, maybe_close, nopos);
5225 } 5226 }
5226 5227
5227 target->statements()->Add(initialize_completion, zone()); 5228 target->statements()->Add(initialize_completion, zone());
5228 target->statements()->Add(try_finally, zone()); 5229 target->statements()->Add(try_finally, zone());
5229 } 5230 }
5230 5231
5231 void Parser::BuildIteratorCloseForCompletion(ZoneList<Statement*>* statements, 5232 void Parser::BuildIteratorCloseForCompletion(Scope* scope,
5233 ZoneList<Statement*>* statements,
5232 Variable* iterator, 5234 Variable* iterator,
5233 Expression* completion) { 5235 Expression* completion) {
5234 // 5236 //
5235 // This function adds two statements to [statements], corresponding to the 5237 // This function adds two statements to [statements], corresponding to the
5236 // following code: 5238 // following code:
5237 // 5239 //
5238 // let iteratorReturn = iterator.return; 5240 // let iteratorReturn = iterator.return;
5239 // if (!IS_NULL_OR_UNDEFINED(iteratorReturn)) { 5241 // if (!IS_NULL_OR_UNDEFINED(iteratorReturn)) {
5240 // if (completion === kThrowCompletion) { 5242 // if (completion === kThrowCompletion) {
5241 // if (!IS_CALLABLE(iteratorReturn)) { 5243 // if (!IS_CALLABLE(iteratorReturn)) {
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
5287 5289
5288 Expression* call = 5290 Expression* call =
5289 factory()->NewCallRuntime(Runtime::kInlineCall, args, nopos); 5291 factory()->NewCallRuntime(Runtime::kInlineCall, args, nopos);
5290 5292
5291 Block* try_block = factory()->NewBlock(nullptr, 1, false, nopos); 5293 Block* try_block = factory()->NewBlock(nullptr, 1, false, nopos);
5292 try_block->statements()->Add(factory()->NewExpressionStatement(call, nopos), 5294 try_block->statements()->Add(factory()->NewExpressionStatement(call, nopos),
5293 zone()); 5295 zone());
5294 5296
5295 Block* catch_block = factory()->NewBlock(nullptr, 0, false, nopos); 5297 Block* catch_block = factory()->NewBlock(nullptr, 0, false, nopos);
5296 5298
5297 Scope* catch_scope = NewScope(CATCH_SCOPE); 5299 Scope* catch_scope = NewScopeWithParent(scope, CATCH_SCOPE);
5298 Variable* catch_variable = 5300 Variable* catch_variable =
5299 catch_scope->DeclareLocal(ast_value_factory()->dot_catch_string(), VAR, 5301 catch_scope->DeclareLocal(ast_value_factory()->dot_catch_string(), VAR,
5300 kCreatedInitialized, NORMAL_VARIABLE); 5302 kCreatedInitialized, NORMAL_VARIABLE);
5301 catch_scope->set_is_hidden(); 5303 catch_scope->set_is_hidden();
5302 5304
5303 try_call_return = factory()->NewTryCatchStatement( 5305 try_call_return = factory()->NewTryCatchStatement(
5304 try_block, catch_scope, catch_variable, catch_block, nopos); 5306 try_block, catch_scope, catch_variable, catch_block, nopos);
5305 } 5307 }
5306 5308
5307 // let output = %_Call(iteratorReturn, iterator); 5309 // let output = %_Call(iteratorReturn, iterator);
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after
5424 closing_condition = factory()->NewUnaryOperation( 5426 closing_condition = factory()->NewUnaryOperation(
5425 Token::NOT, factory()->NewBinaryOperation(Token::OR, lhs, rhs, nopos), 5427 Token::NOT, factory()->NewBinaryOperation(Token::OR, lhs, rhs, nopos),
5426 nopos); 5428 nopos);
5427 } 5429 }
5428 5430
5429 Block* final_loop = factory()->NewBlock(nullptr, 2, false, nopos); 5431 Block* final_loop = factory()->NewBlock(nullptr, 2, false, nopos);
5430 { 5432 {
5431 Block* try_block = factory()->NewBlock(nullptr, 1, false, nopos); 5433 Block* try_block = factory()->NewBlock(nullptr, 1, false, nopos);
5432 try_block->statements()->Add(loop, zone()); 5434 try_block->statements()->Add(loop, zone());
5433 5435
5434 FinalizeIteratorUse(var_completion, closing_condition, loop->iterator(), 5436 // The scope in which the parser creates this loop.
5435 try_block, final_loop); 5437 Scope* loop_scope = scope()->outer_scope();
5438 DCHECK_EQ(loop_scope->scope_type(), BLOCK_SCOPE);
5439 DCHECK_EQ(scope()->scope_type(), BLOCK_SCOPE);
5440
5441 FinalizeIteratorUse(loop_scope, var_completion, closing_condition,
5442 loop->iterator(), try_block, final_loop);
5436 } 5443 }
5437 5444
5438 return final_loop; 5445 return final_loop;
5439 } 5446 }
5440 5447
5441 #undef CHECK_OK 5448 #undef CHECK_OK
5442 #undef CHECK_OK_VOID 5449 #undef CHECK_OK_VOID
5443 #undef CHECK_FAILED 5450 #undef CHECK_FAILED
5444 5451
5445 } // namespace internal 5452 } // namespace internal
5446 } // namespace v8 5453 } // namespace v8
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698