| 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/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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 |
| OLD | NEW |