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 2965 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2976 int pos = position(); | 2976 int pos = position(); |
2977 | 2977 |
2978 Block* try_block; | 2978 Block* try_block; |
2979 { | 2979 { |
2980 ReturnExprScope no_tail_calls(function_state_, | 2980 ReturnExprScope no_tail_calls(function_state_, |
2981 ReturnExprContext::kInsideTryBlock); | 2981 ReturnExprContext::kInsideTryBlock); |
2982 try_block = ParseBlock(NULL, CHECK_OK); | 2982 try_block = ParseBlock(NULL, CHECK_OK); |
2983 } | 2983 } |
2984 | 2984 |
2985 Token::Value tok = peek(); | 2985 Token::Value tok = peek(); |
2986 bool catch_for_promise_reject = false; | |
2986 if (tok != Token::CATCH && tok != Token::FINALLY) { | 2987 if (tok != Token::CATCH && tok != Token::FINALLY) { |
2987 ReportMessage(MessageTemplate::kNoCatchOrFinally); | 2988 if (allow_natives() && tok == Token::MOD) { |
2988 *ok = false; | 2989 Consume(Token::MOD); |
2989 return NULL; | 2990 catch_for_promise_reject = true; |
2991 tok = peek(); | |
2992 DCHECK_EQ(Token::CATCH, tok); | |
Dan Ehrenberg
2016/07/21 21:07:33
Nit: I wonder if we should use CHECK here; if it w
| |
2993 } else { | |
2994 ReportMessage(MessageTemplate::kNoCatchOrFinally); | |
2995 *ok = false; | |
2996 return NULL; | |
2997 } | |
2990 } | 2998 } |
2991 | 2999 |
2992 Scope* catch_scope = NULL; | 3000 Scope* catch_scope = NULL; |
2993 Variable* catch_variable = NULL; | 3001 Variable* catch_variable = NULL; |
2994 Block* catch_block = NULL; | 3002 Block* catch_block = NULL; |
2995 TailCallExpressionList tail_call_expressions_in_catch_block(zone()); | 3003 TailCallExpressionList tail_call_expressions_in_catch_block(zone()); |
2996 if (tok == Token::CATCH) { | 3004 if (tok == Token::CATCH) { |
2997 Consume(Token::CATCH); | 3005 Consume(Token::CATCH); |
2998 | 3006 |
2999 Expect(Token::LPAREN, CHECK_OK); | 3007 Expect(Token::LPAREN, CHECK_OK); |
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3097 } | 3105 } |
3098 | 3106 |
3099 // Simplify the AST nodes by converting: | 3107 // Simplify the AST nodes by converting: |
3100 // 'try B0 catch B1 finally B2' | 3108 // 'try B0 catch B1 finally B2' |
3101 // to: | 3109 // to: |
3102 // 'try { try B0 catch B1 } finally B2' | 3110 // 'try { try B0 catch B1 } finally B2' |
3103 | 3111 |
3104 if (catch_block != NULL && finally_block != NULL) { | 3112 if (catch_block != NULL && finally_block != NULL) { |
3105 // If we have both, create an inner try/catch. | 3113 // If we have both, create an inner try/catch. |
3106 DCHECK(catch_scope != NULL && catch_variable != NULL); | 3114 DCHECK(catch_scope != NULL && catch_variable != NULL); |
3107 TryCatchStatement* statement = factory()->NewTryCatchStatement( | 3115 TryCatchStatement* statement; |
3108 try_block, catch_scope, catch_variable, catch_block, kNoSourcePosition); | 3116 if (catch_for_promise_reject) { |
3117 statement = factory()->NewTryCatchStatementForPromiseReject( | |
3118 try_block, catch_scope, catch_variable, catch_block, | |
3119 kNoSourcePosition); | |
3120 } else { | |
3121 statement = factory()->NewTryCatchStatement(try_block, catch_scope, | |
3122 catch_variable, catch_block, | |
3123 kNoSourcePosition); | |
3124 } | |
3125 | |
3109 try_block = factory()->NewBlock(NULL, 1, false, kNoSourcePosition); | 3126 try_block = factory()->NewBlock(NULL, 1, false, kNoSourcePosition); |
3110 try_block->statements()->Add(statement, zone()); | 3127 try_block->statements()->Add(statement, zone()); |
3111 catch_block = NULL; // Clear to indicate it's been handled. | 3128 catch_block = NULL; // Clear to indicate it's been handled. |
3112 } | 3129 } |
3113 | 3130 |
3114 TryStatement* result = NULL; | 3131 TryStatement* result = NULL; |
3115 if (catch_block != NULL) { | 3132 if (catch_block != NULL) { |
3116 // For a try-catch construct append return expressions from the catch block | 3133 // For a try-catch construct append return expressions from the catch block |
3117 // to the list of return expressions. | 3134 // to the list of return expressions. |
3118 function_state_->tail_call_expressions().Append( | 3135 function_state_->tail_call_expressions().Append( |
(...skipping 3943 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
7062 node->Print(Isolate::Current()); | 7079 node->Print(Isolate::Current()); |
7063 } | 7080 } |
7064 #endif // DEBUG | 7081 #endif // DEBUG |
7065 | 7082 |
7066 #undef CHECK_OK | 7083 #undef CHECK_OK |
7067 #undef CHECK_OK_CUSTOM | 7084 #undef CHECK_OK_CUSTOM |
7068 #undef CHECK_FAILED | 7085 #undef CHECK_FAILED |
7069 | 7086 |
7070 } // namespace internal | 7087 } // namespace internal |
7071 } // namespace v8 | 7088 } // namespace v8 |
OLD | NEW |