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/code_descriptors.h" | 10 #include "vm/code_descriptors.h" |
(...skipping 3226 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3237 BuildLoadContext(node->context_var()); | 3237 BuildLoadContext(node->context_var()); |
3238 | 3238 |
3239 EffectGraphVisitor for_catch(owner(), temp_index()); | 3239 EffectGraphVisitor for_catch(owner(), temp_index()); |
3240 node->VisitChildren(&for_catch); | 3240 node->VisitChildren(&for_catch); |
3241 Append(for_catch); | 3241 Append(for_catch); |
3242 } | 3242 } |
3243 | 3243 |
3244 | 3244 |
3245 void EffectGraphVisitor::VisitTryCatchNode(TryCatchNode* node) { | 3245 void EffectGraphVisitor::VisitTryCatchNode(TryCatchNode* node) { |
3246 InlineBailout("EffectGraphVisitor::VisitTryCatchNode (exception)"); | 3246 InlineBailout("EffectGraphVisitor::VisitTryCatchNode (exception)"); |
3247 intptr_t old_try_index = owner()->try_index(); | 3247 intptr_t original_handler_index = owner()->try_index(); |
Kevin Millikin (Google)
2013/06/26 14:27:04
The name 'try_index' isn't quite right. There can
| |
3248 intptr_t try_index = owner()->AllocateTryIndex(); | 3248 intptr_t try_handler_index = owner()->AllocateTryIndex(); |
3249 owner()->set_try_index(try_index); | 3249 owner()->set_try_index(try_handler_index); |
3250 | 3250 |
3251 // Preserve CTX into local variable '%saved_context'. | 3251 // Preserve CTX into local variable '%saved_context'. |
3252 BuildStoreContext(node->context_var()); | 3252 BuildStoreContext(node->context_var()); |
3253 | 3253 |
3254 EffectGraphVisitor for_try_block(owner(), temp_index()); | 3254 EffectGraphVisitor for_try(owner(), temp_index()); |
3255 node->try_block()->Visit(&for_try_block); | 3255 node->try_block()->Visit(&for_try); |
3256 | 3256 |
3257 if (for_try_block.is_open()) { | 3257 if (for_try.is_open()) { |
3258 JoinEntryInstr* after_try = | 3258 JoinEntryInstr* after_try = |
3259 new JoinEntryInstr(owner()->AllocateBlockId(), old_try_index); | 3259 new JoinEntryInstr(owner()->AllocateBlockId(), original_handler_index); |
3260 for_try_block.Goto(after_try); | 3260 for_try.Goto(after_try); |
3261 for_try_block.exit_ = after_try; | 3261 for_try.exit_ = after_try; |
3262 } | 3262 } |
3263 | 3263 |
3264 JoinEntryInstr* try_entry = | 3264 JoinEntryInstr* try_entry = |
3265 new JoinEntryInstr(owner()->AllocateBlockId(), try_index); | 3265 new JoinEntryInstr(owner()->AllocateBlockId(), try_handler_index); |
3266 | 3266 |
3267 Goto(try_entry); | 3267 Goto(try_entry); |
3268 AppendFragment(try_entry, for_try_block); | 3268 AppendFragment(try_entry, for_try); |
3269 exit_ = for_try_block.exit_; | 3269 exit_ = for_try.exit_; |
3270 | 3270 |
3271 // We are done generating code for the try block. | 3271 // We are done generating code for the try block. |
3272 owner()->set_try_index(old_try_index); | 3272 owner()->set_try_index(original_handler_index); |
3273 | 3273 |
3274 CatchClauseNode* catch_block = node->catch_block(); | 3274 CatchClauseNode* catch_block = node->catch_block(); |
3275 SequenceNode* finally_block = node->finally_block(); | |
3275 if (catch_block != NULL) { | 3276 if (catch_block != NULL) { |
3276 EffectGraphVisitor for_catch_block(owner(), temp_index()); | 3277 // If there is a finally block, it is the handler for code in the catch |
3277 catch_block->Visit(&for_catch_block); | 3278 // block. |
3279 intptr_t catch_handler_index = (finally_block == NULL) | |
3280 ? original_handler_index | |
3281 : owner()->AllocateTryIndex(); | |
3282 owner()->set_try_index(catch_handler_index); | |
3283 EffectGraphVisitor for_catch(owner(), temp_index()); | |
3284 catch_block->Visit(&for_catch); | |
3278 CatchBlockEntryInstr* catch_entry = | 3285 CatchBlockEntryInstr* catch_entry = |
3279 new CatchBlockEntryInstr(owner()->AllocateBlockId(), | 3286 new CatchBlockEntryInstr(owner()->AllocateBlockId(), |
3280 old_try_index, | 3287 catch_handler_index, |
3281 catch_block->handler_types(), | 3288 catch_block->handler_types(), |
3282 try_index); | 3289 try_handler_index); |
3283 owner()->AddCatchEntry(catch_entry); | 3290 owner()->AddCatchEntry(catch_entry); |
3284 ASSERT(!for_catch_block.is_open()); | 3291 ASSERT(!for_catch.is_open()); |
3285 AppendFragment(catch_entry, for_catch_block); | 3292 AppendFragment(catch_entry, for_catch); |
3286 if (node->end_catch_label() != NULL) { | 3293 if (node->end_catch_label() != NULL) { |
3287 JoinEntryInstr* join = node->end_catch_label()->join_for_continue(); | 3294 JoinEntryInstr* join = node->end_catch_label()->join_for_continue(); |
3288 if (join != NULL) { | 3295 if (join != NULL) { |
3289 if (is_open()) Goto(join); | 3296 if (is_open()) Goto(join); |
3290 exit_ = join; | 3297 exit_ = join; |
3291 } | 3298 } |
3292 } | 3299 } |
3300 | |
3301 if (finally_block != NULL) { | |
3302 // Create a handler for the code in the catch block, containing the | |
3303 // code in the finally block. | |
3304 owner()->set_try_index(original_handler_index); | |
3305 EffectGraphVisitor for_finally(owner(), temp_index()); | |
3306 for_finally.AddInstruction( | |
3307 new CatchEntryInstr(catch_block->exception_var(), | |
3308 catch_block->stacktrace_var())); | |
3309 for_finally.BuildLoadContext(catch_block->context_var()); | |
3310 | |
3311 finally_block->Visit(&for_finally); | |
3312 if (for_finally.is_open()) { | |
3313 // Rethrow the exception. Manually build the graph for rethrow. | |
3314 Value* exception = for_finally.Bind( | |
3315 for_finally.BuildLoadLocal(catch_block->exception_var())); | |
3316 for_finally.PushArgument(exception); | |
3317 Value* stacktrace = for_finally.Bind( | |
3318 for_finally.BuildLoadLocal(catch_block->stacktrace_var())); | |
3319 for_finally.PushArgument(stacktrace); | |
3320 for_finally.AddInstruction(new ReThrowInstr(catch_block->token_pos())); | |
3321 for_finally.CloseFragment(); | |
3322 } | |
3323 ASSERT(!for_finally.is_open()); | |
3324 | |
3325 const Array& types = Array::ZoneHandle(Array::New(1, Heap::kOld)); | |
3326 types.SetAt(0, Type::Handle(Type::DynamicType())); | |
3327 CatchBlockEntryInstr* finally_entry = | |
3328 new CatchBlockEntryInstr(owner()->AllocateBlockId(), | |
3329 original_handler_index, | |
3330 types, | |
3331 catch_handler_index); | |
3332 owner()->AddCatchEntry(finally_entry); | |
3333 AppendFragment(finally_entry, for_finally); | |
3334 } | |
3293 } | 3335 } |
3294 | 3336 |
3295 // Generate code for the finally block if one exists. | 3337 // Generate code for the finally block if one exists. |
3296 if ((node->finally_block() != NULL) && is_open()) { | 3338 if ((node->finally_block() != NULL) && is_open()) { |
Florian Schneider
2013/06/27 14:05:59
s/node->finally_block()/finally_block/
Kevin Millikin (Google)
2013/06/28 11:59:08
Well spotted. Done.
| |
3297 EffectGraphVisitor for_finally_block(owner(), temp_index()); | 3339 EffectGraphVisitor for_finally_block(owner(), temp_index()); |
3298 node->finally_block()->Visit(&for_finally_block); | 3340 node->finally_block()->Visit(&for_finally_block); |
Florian Schneider
2013/06/27 14:05:59
s/node->finally_block()/finally_block/
| |
3299 Append(for_finally_block); | 3341 Append(for_finally_block); |
3300 } | 3342 } |
3301 } | 3343 } |
3302 | 3344 |
3303 | 3345 |
3304 // Looks up dynamic method noSuchMethod in target_class | 3346 // Looks up dynamic method noSuchMethod in target_class |
3305 // (including its super class chain) and builds a static call to it. | 3347 // (including its super class chain) and builds a static call to it. |
3306 StaticCallInstr* EffectGraphVisitor::BuildStaticNoSuchMethodCall( | 3348 StaticCallInstr* EffectGraphVisitor::BuildStaticNoSuchMethodCall( |
3307 const Class& target_class, | 3349 const Class& target_class, |
3308 AstNode* receiver, | 3350 AstNode* receiver, |
(...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3510 intptr_t len = OS::SNPrint(NULL, 0, kFormat, function_name, reason) + 1; | 3552 intptr_t len = OS::SNPrint(NULL, 0, kFormat, function_name, reason) + 1; |
3511 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len); | 3553 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len); |
3512 OS::SNPrint(chars, len, kFormat, function_name, reason); | 3554 OS::SNPrint(chars, len, kFormat, function_name, reason); |
3513 const Error& error = Error::Handle( | 3555 const Error& error = Error::Handle( |
3514 LanguageError::New(String::Handle(String::New(chars)))); | 3556 LanguageError::New(String::Handle(String::New(chars)))); |
3515 Isolate::Current()->long_jump_base()->Jump(1, error); | 3557 Isolate::Current()->long_jump_base()->Jump(1, error); |
3516 } | 3558 } |
3517 | 3559 |
3518 | 3560 |
3519 } // namespace dart | 3561 } // namespace dart |
OLD | NEW |