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/class_finalizer.h" | 10 #include "vm/class_finalizer.h" |
(...skipping 1437 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1448 } | 1448 } |
1449 return new(I) AssertAssignableInstr(token_pos, | 1449 return new(I) AssertAssignableInstr(token_pos, |
1450 value, | 1450 value, |
1451 instantiator, | 1451 instantiator, |
1452 instantiator_type_arguments, | 1452 instantiator_type_arguments, |
1453 dst_type, | 1453 dst_type, |
1454 dst_name); | 1454 dst_name); |
1455 } | 1455 } |
1456 | 1456 |
1457 | 1457 |
1458 void EffectGraphVisitor::BuildAwaitJump(LocalScope* lookup_scope, | 1458 void EffectGraphVisitor::BuildAwaitJump(LocalVariable* old_context, |
| 1459 LocalVariable* continuation_result, |
| 1460 LocalVariable* continuation_error, |
1459 const intptr_t old_ctx_level, | 1461 const intptr_t old_ctx_level, |
1460 JoinEntryInstr* target) { | 1462 JoinEntryInstr* target) { |
1461 // Building a jump consists of the following actions: | 1463 // Building a jump consists of the following actions: |
1462 // * Record the current continuation result in a temporary. | 1464 // * Record the current continuation result in a temporary. |
1463 // * Restore the old context. | 1465 // * Restore the old context. |
1464 // * Overwrite the old context's continuation result with the temporary. | 1466 // * Overwrite the old context's continuation result with the temporary. |
1465 // * Append a Goto to the target's join. | 1467 // * Append a Goto to the target's join. |
1466 LocalVariable* old_ctx = lookup_scope->LookupVariable( | |
1467 Symbols::AwaitContextVar(), false); | |
1468 LocalVariable* continuation_result = lookup_scope->LookupVariable( | |
1469 Symbols::AsyncOperationParam(), false); | |
1470 LocalVariable* continuation_error = lookup_scope->LookupVariable( | |
1471 Symbols::AsyncOperationErrorParam(), false); | |
1472 ASSERT((continuation_result != NULL) && continuation_result->is_captured()); | 1468 ASSERT((continuation_result != NULL) && continuation_result->is_captured()); |
1473 ASSERT((continuation_error != NULL) && continuation_error->is_captured()); | 1469 ASSERT((continuation_error != NULL) && continuation_error->is_captured()); |
1474 ASSERT((old_ctx != NULL) && old_ctx->is_captured()); | 1470 ASSERT((old_context != NULL) && old_context->is_captured()); |
1475 // Before restoring the continuation context we need to temporary save the | 1471 // Before restoring the continuation context we need to temporary save the |
1476 // result and error parameter. | 1472 // result and error parameter. |
1477 LocalVariable* temp_result_var = EnterTempLocalScope( | 1473 LocalVariable* temp_result_var = EnterTempLocalScope( |
1478 Bind(BuildLoadLocal(*continuation_result))); | 1474 Bind(BuildLoadLocal(*continuation_result))); |
1479 LocalVariable* temp_error_var = EnterTempLocalScope( | 1475 LocalVariable* temp_error_var = EnterTempLocalScope( |
1480 Bind(BuildLoadLocal(*continuation_error))); | 1476 Bind(BuildLoadLocal(*continuation_error))); |
1481 // Restore the saved continuation context. | 1477 // Restore the saved continuation context. |
1482 BuildRestoreContext(*old_ctx); | 1478 BuildRestoreContext(*old_context); |
1483 | 1479 |
1484 // Pass over the continuation result. | 1480 // Pass over the continuation result. |
1485 | 1481 |
1486 // FlowGraphBuilder is at top context level, but the await target has possibly | 1482 // FlowGraphBuilder is at top context level, but the await target has possibly |
1487 // been recorded in a nested context (old_ctx_level). We need to unroll | 1483 // been recorded in a nested context (old_ctx_level). We need to unroll |
1488 // manually here. | 1484 // manually here. |
1489 intptr_t delta = old_ctx_level - | 1485 intptr_t delta = old_ctx_level - |
1490 continuation_result->owner()->context_level(); | 1486 continuation_result->owner()->context_level(); |
1491 ASSERT(delta >= 0); | 1487 ASSERT(delta >= 0); |
1492 Value* context = Bind(new(I) CurrentContextInstr()); | 1488 Value* context = Bind(new(I) CurrentContextInstr()); |
(...skipping 2382 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3875 | 3871 |
3876 Instruction* saved_entry = entry_; | 3872 Instruction* saved_entry = entry_; |
3877 Instruction* saved_exit = exit_; | 3873 Instruction* saved_exit = exit_; |
3878 entry_ = NULL; | 3874 entry_ = NULL; |
3879 exit_ = NULL; | 3875 exit_ = NULL; |
3880 | 3876 |
3881 LoadLocalNode* load_jump_cnt = new(I) LoadLocalNode( | 3877 LoadLocalNode* load_jump_cnt = new(I) LoadLocalNode( |
3882 Scanner::kNoSourcePos, jump_var); | 3878 Scanner::kNoSourcePos, jump_var); |
3883 ComparisonNode* check_jump_cnt; | 3879 ComparisonNode* check_jump_cnt; |
3884 const intptr_t num_await_states = owner()->await_joins()->length(); | 3880 const intptr_t num_await_states = owner()->await_joins()->length(); |
| 3881 LocalVariable* old_context = top_scope->LookupVariable( |
| 3882 Symbols::AwaitContextVar(), false); |
| 3883 LocalVariable* continuation_result = top_scope->LookupVariable( |
| 3884 Symbols::AsyncOperationParam(), false); |
| 3885 LocalVariable* continuation_error = top_scope->LookupVariable( |
| 3886 Symbols::AsyncOperationErrorParam(), false); |
3885 for (intptr_t i = 0; i < num_await_states; i++) { | 3887 for (intptr_t i = 0; i < num_await_states; i++) { |
3886 check_jump_cnt = new(I) ComparisonNode( | 3888 check_jump_cnt = new(I) ComparisonNode( |
3887 Scanner::kNoSourcePos, | 3889 Scanner::kNoSourcePos, |
3888 Token::kEQ, | 3890 Token::kEQ, |
3889 load_jump_cnt, | 3891 load_jump_cnt, |
3890 new(I) LiteralNode( | 3892 new(I) LiteralNode( |
3891 Scanner::kNoSourcePos, Smi::ZoneHandle(I, Smi::New(i)))); | 3893 Scanner::kNoSourcePos, Smi::ZoneHandle(I, Smi::New(i)))); |
3892 TestGraphVisitor for_test(owner(), Scanner::kNoSourcePos); | 3894 TestGraphVisitor for_test(owner(), Scanner::kNoSourcePos); |
3893 check_jump_cnt->Visit(&for_test); | 3895 check_jump_cnt->Visit(&for_test); |
3894 EffectGraphVisitor for_true(owner()); | 3896 EffectGraphVisitor for_true(owner()); |
3895 EffectGraphVisitor for_false(owner()); | 3897 EffectGraphVisitor for_false(owner()); |
3896 | 3898 |
3897 for_true.BuildAwaitJump(top_scope, | 3899 for_true.BuildAwaitJump(old_context, |
| 3900 continuation_result, |
| 3901 continuation_error, |
3898 (*owner()->await_levels())[i], | 3902 (*owner()->await_levels())[i], |
3899 (*owner()->await_joins())[i]); | 3903 (*owner()->await_joins())[i]); |
3900 Join(for_test, for_true, for_false); | 3904 Join(for_test, for_true, for_false); |
3901 | 3905 |
3902 if (i == 0) { | 3906 if (i == 0) { |
3903 // Manually link up the preamble start. | 3907 // Manually link up the preamble start. |
3904 preamble_start->previous()->set_next(for_test.entry()); | 3908 preamble_start->previous()->set_next(for_test.entry()); |
3905 for_test.entry()->set_previous(preamble_start->previous()); | 3909 for_test.entry()->set_previous(preamble_start->previous()); |
3906 } | 3910 } |
3907 if (i == (num_await_states - 1)) { | 3911 if (i == (num_await_states - 1)) { |
(...skipping 377 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4285 Report::MessageF(Report::kBailout, | 4289 Report::MessageF(Report::kBailout, |
4286 Script::Handle(function.script()), | 4290 Script::Handle(function.script()), |
4287 function.token_pos(), | 4291 function.token_pos(), |
4288 "FlowGraphBuilder Bailout: %s %s", | 4292 "FlowGraphBuilder Bailout: %s %s", |
4289 String::Handle(function.name()).ToCString(), | 4293 String::Handle(function.name()).ToCString(), |
4290 reason); | 4294 reason); |
4291 UNREACHABLE(); | 4295 UNREACHABLE(); |
4292 } | 4296 } |
4293 | 4297 |
4294 } // namespace dart | 4298 } // namespace dart |
OLD | NEW |