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 1842953003: Preserve exception message in iterator finalization. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 4 years, 8 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
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 "src/api.h" 7 #include "src/api.h"
8 #include "src/ast/ast.h" 8 #include "src/ast/ast.h"
9 #include "src/ast/ast-expression-rewriter.h" 9 #include "src/ast/ast-expression-rewriter.h"
10 #include "src/ast/ast-expression-visitor.h" 10 #include "src/ast/ast-expression-visitor.h"
(...skipping 2989 matching lines...) Expand 10 before | Expand all | Expand 10 after
3000 } 3000 }
3001 3001
3002 // Simplify the AST nodes by converting: 3002 // Simplify the AST nodes by converting:
3003 // 'try B0 catch B1 finally B2' 3003 // 'try B0 catch B1 finally B2'
3004 // to: 3004 // to:
3005 // 'try { try B0 catch B1 } finally B2' 3005 // 'try { try B0 catch B1 } finally B2'
3006 3006
3007 if (catch_block != NULL && finally_block != NULL) { 3007 if (catch_block != NULL && finally_block != NULL) {
3008 // If we have both, create an inner try/catch. 3008 // If we have both, create an inner try/catch.
3009 DCHECK(catch_scope != NULL && catch_variable != NULL); 3009 DCHECK(catch_scope != NULL && catch_variable != NULL);
3010 TryCatchStatement* statement = 3010 TryCatchStatement* statement = factory()->NewTryCatchStatement(
3011 factory()->NewTryCatchStatement(try_block, catch_scope, catch_variable, 3011 try_block, catch_scope, catch_variable, catch_block, true,
3012 catch_block, RelocInfo::kNoPosition); 3012 RelocInfo::kNoPosition);
3013 try_block = factory()->NewBlock(NULL, 1, false, RelocInfo::kNoPosition); 3013 try_block = factory()->NewBlock(NULL, 1, false, RelocInfo::kNoPosition);
3014 try_block->statements()->Add(statement, zone()); 3014 try_block->statements()->Add(statement, zone());
3015 catch_block = NULL; // Clear to indicate it's been handled. 3015 catch_block = NULL; // Clear to indicate it's been handled.
3016 } 3016 }
3017 3017
3018 TryStatement* result = NULL; 3018 TryStatement* result = NULL;
3019 if (catch_block != NULL) { 3019 if (catch_block != NULL) {
3020 // For a try-catch construct append return expressions from the catch block 3020 // For a try-catch construct append return expressions from the catch block
3021 // to the list of return expressions. 3021 // to the list of return expressions.
3022 function_state_->expressions_in_tail_position().AddAll( 3022 function_state_->expressions_in_tail_position().AddAll(
3023 expressions_in_tail_position_in_catch_block); 3023 expressions_in_tail_position_in_catch_block);
3024 3024
3025 DCHECK(finally_block == NULL); 3025 DCHECK(finally_block == NULL);
3026 DCHECK(catch_scope != NULL && catch_variable != NULL); 3026 DCHECK(catch_scope != NULL && catch_variable != NULL);
3027 result = factory()->NewTryCatchStatement(try_block, catch_scope, 3027 result = factory()->NewTryCatchStatement(
3028 catch_variable, catch_block, pos); 3028 try_block, catch_scope, catch_variable, catch_block, true, pos);
3029 } else { 3029 } else {
3030 DCHECK(finally_block != NULL); 3030 DCHECK(finally_block != NULL);
3031 result = factory()->NewTryFinallyStatement(try_block, finally_block, pos); 3031 result = factory()->NewTryFinallyStatement(try_block, finally_block, pos);
3032 } 3032 }
3033 3033
3034 return result; 3034 return result;
3035 } 3035 }
3036 3036
3037 3037
3038 DoWhileStatement* Parser::ParseDoWhileStatement( 3038 DoWhileStatement* Parser::ParseDoWhileStatement(
(...skipping 3012 matching lines...) Expand 10 before | Expand all | Expand 10 after
6051 Block* catch_block = factory->NewBlock(nullptr, 1, false, nopos); 6051 Block* catch_block = factory->NewBlock(nullptr, 1, false, nopos);
6052 catch_block->statements()->Add(set_mode_throw, zone); 6052 catch_block->statements()->Add(set_mode_throw, zone);
6053 6053
6054 Scope* catch_scope = NewScope(scope, CATCH_SCOPE); 6054 Scope* catch_scope = NewScope(scope, CATCH_SCOPE);
6055 const AstRawString* name = avfactory->dot_catch_string(); 6055 const AstRawString* name = avfactory->dot_catch_string();
6056 Variable* catch_variable = 6056 Variable* catch_variable =
6057 catch_scope->DeclareLocal(name, VAR, kCreatedInitialized, 6057 catch_scope->DeclareLocal(name, VAR, kCreatedInitialized,
6058 Variable::NORMAL); 6058 Variable::NORMAL);
6059 6059
6060 try_catch = factory->NewTryCatchStatement( 6060 try_catch = factory->NewTryCatchStatement(
6061 try_block, catch_scope, catch_variable, catch_block, nopos); 6061 try_block, catch_scope, catch_variable, catch_block, true, nopos);
6062 } 6062 }
6063 6063
6064 6064
6065 // try { ... } finally { ... } 6065 // try { ... } finally { ... }
6066 Statement* try_finally; 6066 Statement* try_finally;
6067 { 6067 {
6068 Block* try_block = factory->NewBlock(nullptr, 1, false, nopos); 6068 Block* try_block = factory->NewBlock(nullptr, 1, false, nopos);
6069 try_block->statements()->Add(try_catch, zone); 6069 try_block->statements()->Add(try_catch, zone);
6070 6070
6071 Block* finally = factory->NewBlock(nullptr, 2, false, nopos); 6071 Block* finally = factory->NewBlock(nullptr, 2, false, nopos);
(...skipping 385 matching lines...) Expand 10 before | Expand all | Expand 10 after
6457 // 6457 //
6458 // This function adds two statements to [target], corresponding to the 6458 // This function adds two statements to [target], corresponding to the
6459 // following code: 6459 // following code:
6460 // 6460 //
6461 // completion = kNormalCompletion; 6461 // completion = kNormalCompletion;
6462 // try { 6462 // try {
6463 // try { 6463 // try {
6464 // iterator_use 6464 // iterator_use
6465 // } catch(e) { 6465 // } catch(e) {
6466 // if (completion === kAbruptCompletion) completion = kThrowCompletion; 6466 // if (completion === kAbruptCompletion) completion = kThrowCompletion;
6467 // throw e; 6467 // %ReThrow(e);
6468 // } 6468 // }
6469 // } finally { 6469 // } finally {
6470 // if (condition) { 6470 // if (condition) {
6471 // #BuildIteratorCloseForCompletion(iter, completion) 6471 // #BuildIteratorCloseForCompletion(iter, completion)
6472 // } 6472 // }
6473 // } 6473 // }
6474 // 6474 //
6475 6475
6476 const int nopos = RelocInfo::kNoPosition; 6476 const int nopos = RelocInfo::kNoPosition;
6477 auto factory = parser_->factory(); 6477 auto factory = parser_->factory();
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
6518 maybe_close = factory->NewBlock(nullptr, 1, true, nopos); 6518 maybe_close = factory->NewBlock(nullptr, 1, true, nopos);
6519 maybe_close->statements()->Add( 6519 maybe_close->statements()->Add(
6520 factory->NewIfStatement(condition, block, 6520 factory->NewIfStatement(condition, block,
6521 factory->NewEmptyStatement(nopos), nopos), 6521 factory->NewEmptyStatement(nopos), nopos),
6522 zone); 6522 zone);
6523 } 6523 }
6524 6524
6525 // try { #try_block } 6525 // try { #try_block }
6526 // catch(e) { 6526 // catch(e) {
6527 // #set_completion_throw; 6527 // #set_completion_throw;
6528 // throw e; 6528 // %ReThrow(e);
6529 // } 6529 // }
6530 Statement* try_catch; 6530 Statement* try_catch;
6531 { 6531 {
6532 Scope* catch_scope = parser_->NewScope(scope, CATCH_SCOPE); 6532 Scope* catch_scope = parser_->NewScope(scope, CATCH_SCOPE);
6533 Variable* catch_variable = 6533 Variable* catch_variable =
6534 catch_scope->DeclareLocal(avfactory->dot_catch_string(), VAR, 6534 catch_scope->DeclareLocal(avfactory->dot_catch_string(), VAR,
6535 kCreatedInitialized, Variable::NORMAL); 6535 kCreatedInitialized, Variable::NORMAL);
6536 6536
6537 Statement* rethrow; 6537 Statement* rethrow;
6538 // We use %ReThrow rather than the ordinary throw because we want to
6539 // keep the original exception message. This is also why we create the
6540 // TryCatchStatement below with clear_pending_message set to false.
6538 { 6541 {
6539 Expression* proxy = factory->NewVariableProxy(catch_variable); 6542 auto args = new (zone) ZoneList<Expression*>(1, zone);
6540 rethrow = factory->NewExpressionStatement(factory->NewThrow(proxy, nopos), 6543 args->Add(factory->NewVariableProxy(catch_variable), zone);
6541 nopos); 6544 rethrow = factory->NewExpressionStatement(
6545 factory->NewCallRuntime(Runtime::kReThrow, args, nopos), nopos);
6542 } 6546 }
6543 6547
6544 Block* catch_block = factory->NewBlock(nullptr, 2, false, nopos); 6548 Block* catch_block = factory->NewBlock(nullptr, 2, false, nopos);
6545 catch_block->statements()->Add(set_completion_throw, zone); 6549 catch_block->statements()->Add(set_completion_throw, zone);
6546 catch_block->statements()->Add(rethrow, zone); 6550 catch_block->statements()->Add(rethrow, zone);
6547 6551
6548 try_catch = factory->NewTryCatchStatement( 6552 try_catch = factory->NewTryCatchStatement(
6549 iterator_use, catch_scope, catch_variable, catch_block, nopos); 6553 iterator_use, catch_scope, catch_variable, catch_block, false, nopos);
6550 } 6554 }
6551 6555
6552 // try { #try_catch } finally { #maybe_close } 6556 // try { #try_catch } finally { #maybe_close }
6553 Statement* try_finally; 6557 Statement* try_finally;
6554 { 6558 {
6555 Block* try_block = factory->NewBlock(nullptr, 1, false, nopos); 6559 Block* try_block = factory->NewBlock(nullptr, 1, false, nopos);
6556 try_block->statements()->Add(try_catch, zone); 6560 try_block->statements()->Add(try_catch, zone);
6557 6561
6558 try_finally = 6562 try_finally =
6559 factory->NewTryFinallyStatement(try_block, maybe_close, nopos); 6563 factory->NewTryFinallyStatement(try_block, maybe_close, nopos);
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
6634 zone); 6638 zone);
6635 6639
6636 Block* catch_block = factory->NewBlock(nullptr, 0, false, nopos); 6640 Block* catch_block = factory->NewBlock(nullptr, 0, false, nopos);
6637 6641
6638 Scope* catch_scope = NewScope(scope, CATCH_SCOPE); 6642 Scope* catch_scope = NewScope(scope, CATCH_SCOPE);
6639 Variable* catch_variable = catch_scope->DeclareLocal( 6643 Variable* catch_variable = catch_scope->DeclareLocal(
6640 avfactory->dot_catch_string(), VAR, kCreatedInitialized, 6644 avfactory->dot_catch_string(), VAR, kCreatedInitialized,
6641 Variable::NORMAL); 6645 Variable::NORMAL);
6642 6646
6643 try_call_return = factory->NewTryCatchStatement( 6647 try_call_return = factory->NewTryCatchStatement(
6644 try_block, catch_scope, catch_variable, catch_block, nopos); 6648 try_block, catch_scope, catch_variable, catch_block, true, nopos);
6645 } 6649 }
6646 6650
6647 // let output = %_Call(iteratorReturn, iterator); 6651 // let output = %_Call(iteratorReturn, iterator);
6648 // if (!IS_RECEIVER(output)) { 6652 // if (!IS_RECEIVER(output)) {
6649 // %ThrowIteratorResultNotAnObject(output); 6653 // %ThrowIteratorResultNotAnObject(output);
6650 // } 6654 // }
6651 Block* validate_return; 6655 Block* validate_return;
6652 { 6656 {
6653 Variable* var_output = scope->NewTemporary(avfactory->empty_string()); 6657 Variable* var_output = scope->NewTemporary(avfactory->empty_string());
6654 Statement* call_return; 6658 Statement* call_return;
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
6734 // 6738 //
6735 // This function replaces the loop with the following wrapping: 6739 // This function replaces the loop with the following wrapping:
6736 // 6740 //
6737 // let each; 6741 // let each;
6738 // let completion = kNormalCompletion; 6742 // let completion = kNormalCompletion;
6739 // try { 6743 // try {
6740 // try { 6744 // try {
6741 // #loop; 6745 // #loop;
6742 // } catch(e) { 6746 // } catch(e) {
6743 // if (completion === kAbruptCompletion) completion = kThrowCompletion; 6747 // if (completion === kAbruptCompletion) completion = kThrowCompletion;
6744 // throw e; 6748 // %ReThrow(e);
6745 // } 6749 // }
6746 // } finally { 6750 // } finally {
6747 // if (!(completion === kNormalCompletion || IS_UNDEFINED(#iterator))) { 6751 // if (!(completion === kNormalCompletion || IS_UNDEFINED(#iterator))) {
6748 // #BuildIteratorCloseForCompletion(#iterator, completion) 6752 // #BuildIteratorCloseForCompletion(#iterator, completion)
6749 // } 6753 // }
6750 // } 6754 // }
6751 // 6755 //
6752 // where the loop's body is wrapped as follows: 6756 // where the loop's body is wrapped as follows:
6753 // 6757 //
6754 // { 6758 // {
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
6859 try_block, target); 6863 try_block, target);
6860 final_loop = target; 6864 final_loop = target;
6861 } 6865 }
6862 6866
6863 return final_loop; 6867 return final_loop;
6864 } 6868 }
6865 6869
6866 6870
6867 } // namespace internal 6871 } // namespace internal
6868 } // namespace v8 6872 } // namespace v8
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698