Chromium Code Reviews| 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 |