OLD | NEW |
---|---|
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 #include "vm/flow_graph_builder.h" | 5 #include "vm/flow_graph_builder.h" |
6 | 6 |
7 #include "lib/invocation_mirror.h" | 7 #include "lib/invocation_mirror.h" |
8 #include "vm/ast_printer.h" | 8 #include "vm/ast_printer.h" |
9 #include "vm/bit_vector.h" | 9 #include "vm/bit_vector.h" |
10 #include "vm/compiler.h" | 10 #include "vm/compiler.h" |
(...skipping 4207 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4218 BuildRestoreContext(node->context_var(), node->token_pos()); | 4218 BuildRestoreContext(node->context_var(), node->token_pos()); |
4219 | 4219 |
4220 EffectGraphVisitor for_catch(owner()); | 4220 EffectGraphVisitor for_catch(owner()); |
4221 node->VisitChildren(&for_catch); | 4221 node->VisitChildren(&for_catch); |
4222 Append(for_catch); | 4222 Append(for_catch); |
4223 } | 4223 } |
4224 | 4224 |
4225 | 4225 |
4226 void EffectGraphVisitor::VisitTryCatchNode(TryCatchNode* node) { | 4226 void EffectGraphVisitor::VisitTryCatchNode(TryCatchNode* node) { |
4227 InlineBailout("EffectGraphVisitor::VisitTryCatchNode (exception)"); | 4227 InlineBailout("EffectGraphVisitor::VisitTryCatchNode (exception)"); |
4228 CatchClauseNode* catch_block = node->catch_block(); | |
4229 SequenceNode* finally_block = node->finally_block(); | |
4230 if ((finally_block != NULL) && (finally_block->length() == 0)) { | |
rmacnak
2016/09/08 22:02:37
finally_block == NULL || finally_block->length() =
Florian Schneider
2016/09/09 00:51:48
Yes, the only issue is that when 'catch' is parsed
| |
4231 SequenceNode* catch_sequence = catch_block->sequence(); | |
4232 if (catch_sequence->length() == 1) { | |
4233 ThrowNode* throw_node = catch_sequence-> NodeAt(0)->AsThrowNode(); | |
rmacnak
2016/09/08 22:02:37
->NodeAt
Florian Schneider
2016/09/09 00:51:48
Done.
| |
4234 if ((throw_node != NULL) && (throw_node->exception() != NULL)) { | |
Florian Schneider
2016/09/09 00:51:48
Actually, I have to check (throw_node->stack_trace
| |
4235 // Empty finally-block in a try-finally can be optimized away. | |
4236 EffectGraphVisitor for_try(owner()); | |
4237 node->try_block()->Visit(&for_try); | |
4238 Append(for_try); | |
4239 return; | |
4240 } | |
4241 } | |
4242 } | |
4243 | |
4228 const intptr_t original_handler_index = owner()->try_index(); | 4244 const intptr_t original_handler_index = owner()->try_index(); |
4229 const intptr_t try_handler_index = node->try_index(); | 4245 const intptr_t try_handler_index = node->try_index(); |
4230 ASSERT(try_handler_index != original_handler_index); | 4246 ASSERT(try_handler_index != original_handler_index); |
4231 owner()->set_try_index(try_handler_index); | 4247 owner()->set_try_index(try_handler_index); |
4232 | 4248 |
4233 // Preserve current context into local variable ':saved_try_context_var'. | 4249 // Preserve current context into local variable ':saved_try_context_var'. |
4234 BuildSaveContext(node->context_var(), ST(node->token_pos())); | 4250 BuildSaveContext(node->context_var(), ST(node->token_pos())); |
4235 | 4251 |
4236 EffectGraphVisitor for_try(owner()); | 4252 EffectGraphVisitor for_try(owner()); |
4237 node->try_block()->Visit(&for_try); | 4253 node->try_block()->Visit(&for_try); |
4238 | 4254 |
4239 if (for_try.is_open()) { | 4255 if (for_try.is_open()) { |
4240 JoinEntryInstr* after_try = | 4256 JoinEntryInstr* after_try = |
4241 new(Z) JoinEntryInstr(owner()->AllocateBlockId(), | 4257 new(Z) JoinEntryInstr(owner()->AllocateBlockId(), |
4242 original_handler_index); | 4258 original_handler_index); |
4243 for_try.Goto(after_try); | 4259 for_try.Goto(after_try); |
4244 for_try.exit_ = after_try; | 4260 for_try.exit_ = after_try; |
4245 } | 4261 } |
4246 | 4262 |
4247 JoinEntryInstr* try_entry = | 4263 JoinEntryInstr* try_entry = |
4248 new(Z) JoinEntryInstr(owner()->AllocateBlockId(), try_handler_index); | 4264 new(Z) JoinEntryInstr(owner()->AllocateBlockId(), try_handler_index); |
4249 | 4265 |
4250 Goto(try_entry); | 4266 Goto(try_entry); |
4251 AppendFragment(try_entry, for_try); | 4267 AppendFragment(try_entry, for_try); |
4252 exit_ = for_try.exit_; | 4268 exit_ = for_try.exit_; |
4253 | 4269 |
4254 // We are done generating code for the try block. | 4270 // We are done generating code for the try block. |
4255 owner()->set_try_index(original_handler_index); | 4271 owner()->set_try_index(original_handler_index); |
4256 | 4272 |
4257 CatchClauseNode* catch_block = node->catch_block(); | |
4258 SequenceNode* finally_block = node->finally_block(); | |
4259 | |
4260 // If there is a finally block, it is the handler for code in the catch | 4273 // If there is a finally block, it is the handler for code in the catch |
4261 // block. | 4274 // block. |
4262 const intptr_t catch_handler_index = (finally_block == NULL) | 4275 const intptr_t catch_handler_index = (finally_block == NULL) |
4263 ? original_handler_index | 4276 ? original_handler_index |
4264 : catch_block->catch_handler_index(); | 4277 : catch_block->catch_handler_index(); |
4265 | 4278 |
4266 const intptr_t prev_catch_try_index = owner()->catch_try_index(); | 4279 const intptr_t prev_catch_try_index = owner()->catch_try_index(); |
4267 | 4280 |
4268 owner()->set_try_index(catch_handler_index); | 4281 owner()->set_try_index(catch_handler_index); |
4269 owner()->set_catch_try_index(try_handler_index); | 4282 owner()->set_catch_try_index(try_handler_index); |
(...skipping 328 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4598 block_marks); | 4611 block_marks); |
4599 ASSERT(found); | 4612 ASSERT(found); |
4600 } | 4613 } |
4601 | 4614 |
4602 | 4615 |
4603 void FlowGraphBuilder::Bailout(const char* reason) const { | 4616 void FlowGraphBuilder::Bailout(const char* reason) const { |
4604 parsed_function_.Bailout("FlowGraphBuilder", reason); | 4617 parsed_function_.Bailout("FlowGraphBuilder", reason); |
4605 } | 4618 } |
4606 | 4619 |
4607 } // namespace dart | 4620 } // namespace dart |
OLD | NEW |