Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(217)

Side by Side Diff: runtime/vm/flow_graph_builder.cc

Issue 944893005: Implement async* functions in VM (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 5 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « runtime/vm/flow_graph_builder.h ('k') | runtime/vm/object.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 1093 matching lines...) Expand 10 before | Expand all | Expand 10 after
1104 } 1104 }
1105 1105
1106 intptr_t current_context_level = owner()->context_level(); 1106 intptr_t current_context_level = owner()->context_level();
1107 ASSERT(current_context_level >= 0); 1107 ASSERT(current_context_level >= 0);
1108 if (HasContextScope()) { 1108 if (HasContextScope()) {
1109 UnchainContexts(current_context_level); 1109 UnchainContexts(current_context_level);
1110 } 1110 }
1111 1111
1112 AddReturnExit(node->token_pos(), return_value); 1112 AddReturnExit(node->token_pos(), return_value);
1113 1113
1114 if ((function.IsAsyncClosure() || function.IsSyncGenClosure()) && 1114 if ((function.IsAsyncClosure() ||
1115 function.IsSyncGenClosure() ||
1116 function.IsAsyncGenClosure()) &&
1115 (node->return_type() == ReturnNode::kContinuationTarget)) { 1117 (node->return_type() == ReturnNode::kContinuationTarget)) {
1116 JoinEntryInstr* const join = new(I) JoinEntryInstr( 1118 JoinEntryInstr* const join = new(I) JoinEntryInstr(
1117 owner()->AllocateBlockId(), owner()->try_index()); 1119 owner()->AllocateBlockId(), owner()->try_index());
1118 owner()->await_joins()->Add(join); 1120 owner()->await_joins()->Add(join);
1119 exit_ = join; 1121 exit_ = join;
1120 } 1122 }
1121 } 1123 }
1122 1124
1123 1125
1124 // <Expression> ::= Literal { literal: Instance } 1126 // <Expression> ::= Literal { literal: Instance }
(...skipping 351 matching lines...) Expand 10 before | Expand all | Expand 10 after
1476 return new(I) AssertAssignableInstr(token_pos, 1478 return new(I) AssertAssignableInstr(token_pos,
1477 value, 1479 value,
1478 instantiator, 1480 instantiator,
1479 instantiator_type_arguments, 1481 instantiator_type_arguments,
1480 dst_type, 1482 dst_type,
1481 dst_name, 1483 dst_name,
1482 deopt_id); 1484 deopt_id);
1483 } 1485 }
1484 1486
1485 1487
1486 void EffectGraphVisitor::BuildYieldJump(LocalVariable* old_context, 1488 void EffectGraphVisitor::BuildSyncYieldJump(LocalVariable* old_context,
1487 LocalVariable* iterator_param, 1489 LocalVariable* iterator_param,
1488 const intptr_t old_ctx_level, 1490 const intptr_t old_ctx_level,
1489 JoinEntryInstr* target) { 1491 JoinEntryInstr* target) {
1490 // Building a jump consists of the following actions: 1492 // Building a jump consists of the following actions:
1491 // * Load the generator body's iterator parameter (:iterator) 1493 // * Load the generator body's iterator parameter (:iterator)
1492 // from the current context into a temporary. 1494 // from the current context into a temporary.
1493 // * Restore the old context from :await_cxt_var. 1495 // * Restore the old context from :await_cxt_var.
1494 // * Copy the iterator saved above into the restored context. 1496 // * Copy the iterator saved above into the restored context.
1495 // * Append a Goto to the target's join. 1497 // * Append a Goto to the target's join.
1496 ASSERT((iterator_param != NULL) && iterator_param->is_captured()); 1498 ASSERT((iterator_param != NULL) && iterator_param->is_captured());
1497 ASSERT((old_context != NULL) && old_context->is_captured()); 1499 ASSERT((old_context != NULL) && old_context->is_captured());
1498 // Before restoring the context we need to temporarily save the 1500 // Before restoring the context we need to temporarily save the
1499 // iterator parameter. 1501 // iterator parameter.
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
1532 Do(store); 1534 Do(store);
1533 1535
1534 Do(ExitTempLocalScope(temp_context_var)); 1536 Do(ExitTempLocalScope(temp_context_var));
1535 Do(ExitTempLocalScope(temp_iterator_var)); 1537 Do(ExitTempLocalScope(temp_iterator_var));
1536 1538
1537 // Goto saved join. 1539 // Goto saved join.
1538 Goto(target); 1540 Goto(target);
1539 } 1541 }
1540 1542
1541 1543
1542 void EffectGraphVisitor::BuildAwaitJump(LocalVariable* old_context, 1544 void EffectGraphVisitor::BuildAsyncJump(LocalVariable* old_context,
1543 LocalVariable* continuation_result, 1545 LocalVariable* continuation_result,
1544 LocalVariable* continuation_error, 1546 LocalVariable* continuation_error,
1545 LocalVariable* continuation_stack_trace, 1547 LocalVariable* continuation_stack_trace,
1546 const intptr_t old_ctx_level, 1548 const intptr_t old_ctx_level,
1547 JoinEntryInstr* target) { 1549 JoinEntryInstr* target) {
1548 // Building a jump consists of the following actions: 1550 // Building a jump consists of the following actions:
1549 // * Load the current continuation result parameter (:async_result) 1551 // * Load the current continuation result parameter (:async_result)
1550 // and continuation error parameter (:async_error_param) from 1552 // and continuation error parameter (:async_error_param) from
1551 // the current context into temporaries. 1553 // the current context into temporaries.
1552 // * Restore the old context from :await_cxt_var. 1554 // * Restore the old context from :await_cxt_var.
(...skipping 2322 matching lines...) Expand 10 before | Expand all | Expand 10 after
3875 pos++; 3877 pos++;
3876 } 3878 }
3877 } 3879 }
3878 3880
3879 // Continuation part: 3881 // Continuation part:
3880 // If this node sequence is the body of a function with continuations, 3882 // If this node sequence is the body of a function with continuations,
3881 // leave room for a preamble. 3883 // leave room for a preamble.
3882 // The preamble is generated after visiting the body. 3884 // The preamble is generated after visiting the body.
3883 GotoInstr* preamble_start = NULL; 3885 GotoInstr* preamble_start = NULL;
3884 if (is_top_level_sequence && 3886 if (is_top_level_sequence &&
3885 (function.IsAsyncClosure() || function.IsSyncGenClosure())) { 3887 (function.IsAsyncClosure() ||
3888 function.IsSyncGenClosure() ||
3889 function.IsAsyncGenClosure())) {
3886 JoinEntryInstr* preamble_end = new(I) JoinEntryInstr( 3890 JoinEntryInstr* preamble_end = new(I) JoinEntryInstr(
3887 owner()->AllocateBlockId(), owner()->try_index()); 3891 owner()->AllocateBlockId(), owner()->try_index());
3888 ASSERT(exit() != NULL); 3892 ASSERT(exit() != NULL);
3889 exit()->Goto(preamble_end); 3893 exit()->Goto(preamble_end);
3890 ASSERT(exit()->next()->IsGoto()); 3894 ASSERT(exit()->next()->IsGoto());
3891 preamble_start = exit()->next()->AsGoto(); 3895 preamble_start = exit()->next()->AsGoto();
3892 ASSERT(preamble_start->IsGoto()); 3896 ASSERT(preamble_start->IsGoto());
3893 exit_ = preamble_end; 3897 exit_ = preamble_end;
3894 } 3898 }
3895 3899
3896 intptr_t i = 0; 3900 intptr_t i = 0;
3897 while (is_open() && (i < node->length())) { 3901 while (is_open() && (i < node->length())) {
3898 EffectGraphVisitor for_effect(owner()); 3902 EffectGraphVisitor for_effect(owner());
3899 node->NodeAt(i++)->Visit(&for_effect); 3903 node->NodeAt(i++)->Visit(&for_effect);
3900 Append(for_effect); 3904 Append(for_effect);
3901 if (!is_open()) { 3905 if (!is_open()) {
3902 // E.g., because of a JumpNode. 3906 // E.g., because of a JumpNode.
3903 break; 3907 break;
3904 } 3908 }
3905 } 3909 }
3906 3910
3907 // Continuation part: 3911 // Continuation part:
3908 // After generating the CFG for the body we can create the preamble 3912 // After generating the CFG for the body we can create the preamble
3909 // because we know exactly how many continuation states we need. 3913 // because we know exactly how many continuation states we need.
3910 if (is_top_level_sequence && 3914 if (is_top_level_sequence &&
3911 (function.IsAsyncClosure() || function.IsSyncGenClosure())) { 3915 (function.IsAsyncClosure() ||
3916 function.IsSyncGenClosure() ||
3917 function.IsAsyncGenClosure())) {
3912 ASSERT(preamble_start != NULL); 3918 ASSERT(preamble_start != NULL);
3913 // We are at the top level. Fetch the corresponding scope. 3919 // We are at the top level. Fetch the corresponding scope.
3914 LocalScope* top_scope = node->scope(); 3920 LocalScope* top_scope = node->scope();
3915 LocalVariable* jump_var = top_scope->LookupVariable( 3921 LocalVariable* jump_var = top_scope->LookupVariable(
3916 Symbols::AwaitJumpVar(), false); 3922 Symbols::AwaitJumpVar(), false);
3917 ASSERT(jump_var != NULL && jump_var->is_captured()); 3923 ASSERT(jump_var != NULL && jump_var->is_captured());
3918 Instruction* saved_entry = entry_; 3924 Instruction* saved_entry = entry_;
3919 Instruction* saved_exit = exit_; 3925 Instruction* saved_exit = exit_;
3920 entry_ = NULL; 3926 entry_ = NULL;
3921 exit_ = NULL; 3927 exit_ = NULL;
(...skipping 10 matching lines...) Expand all
3932 Scanner::kNoSourcePos, 3938 Scanner::kNoSourcePos,
3933 Token::kEQ, 3939 Token::kEQ,
3934 load_jump_count, 3940 load_jump_count,
3935 new(I) LiteralNode( 3941 new(I) LiteralNode(
3936 Scanner::kNoSourcePos, Smi::ZoneHandle(I, Smi::New(i)))); 3942 Scanner::kNoSourcePos, Smi::ZoneHandle(I, Smi::New(i))));
3937 TestGraphVisitor for_test(owner(), Scanner::kNoSourcePos); 3943 TestGraphVisitor for_test(owner(), Scanner::kNoSourcePos);
3938 check_jump_count->Visit(&for_test); 3944 check_jump_count->Visit(&for_test);
3939 EffectGraphVisitor for_true(owner()); 3945 EffectGraphVisitor for_true(owner());
3940 EffectGraphVisitor for_false(owner()); 3946 EffectGraphVisitor for_false(owner());
3941 3947
3942 if (function.IsAsyncClosure()) { 3948 if (function.IsAsyncClosure() || function.IsAsyncGenClosure()) {
3943 LocalVariable* result_param = 3949 LocalVariable* result_param =
3944 top_scope->LookupVariable(Symbols::AsyncOperationParam(), false); 3950 top_scope->LookupVariable(Symbols::AsyncOperationParam(), false);
3945 LocalVariable* error_param = 3951 LocalVariable* error_param =
3946 top_scope->LookupVariable(Symbols::AsyncOperationErrorParam(), 3952 top_scope->LookupVariable(Symbols::AsyncOperationErrorParam(),
3947 false); 3953 false);
3948 LocalVariable* stack_trace_param = 3954 LocalVariable* stack_trace_param =
3949 top_scope->LookupVariable(Symbols::AsyncOperationStackTraceParam(), 3955 top_scope->LookupVariable(Symbols::AsyncOperationStackTraceParam(),
3950 false); 3956 false);
3951 for_true.BuildAwaitJump(old_context, 3957 for_true.BuildAsyncJump(old_context,
3952 result_param, 3958 result_param,
3953 error_param, 3959 error_param,
3954 stack_trace_param, 3960 stack_trace_param,
3955 (*owner()->await_levels())[i], 3961 (*owner()->await_levels())[i],
3956 (*owner()->await_joins())[i]); 3962 (*owner()->await_joins())[i]);
3957 } else { 3963 } else {
3958 ASSERT(function.IsSyncGenClosure()); 3964 ASSERT(function.IsSyncGenClosure());
3959 LocalVariable* iterator_param = 3965 LocalVariable* iterator_param =
3960 top_scope->LookupVariable(Symbols::IteratorParameter(), false); 3966 top_scope->LookupVariable(Symbols::IteratorParameter(), false);
3961 for_true.BuildYieldJump(old_context, 3967 for_true.BuildSyncYieldJump(old_context,
3962 iterator_param, 3968 iterator_param,
3963 (*owner()->await_levels())[i], 3969 (*owner()->await_levels())[i],
3964 (*owner()->await_joins())[i]); 3970 (*owner()->await_joins())[i]);
3965 } 3971 }
3966 3972
3967 Join(for_test, for_true, for_false); 3973 Join(for_test, for_true, for_false);
3968 if (i == 0) { 3974 if (i == 0) {
3969 // Manually link up the preamble start. 3975 // Manually link up the preamble start.
3970 preamble_start->previous()->set_next(for_test.entry()); 3976 preamble_start->previous()->set_next(for_test.entry());
3971 for_test.entry()->set_previous(preamble_start->previous()); 3977 for_test.entry()->set_previous(preamble_start->previous());
3972 } 3978 }
3973 if (i == (num_await_states - 1)) { 3979 if (i == (num_await_states - 1)) {
3974 // Link up preamble end. 3980 // Link up preamble end.
(...skipping 383 matching lines...) Expand 10 before | Expand all | Expand 10 after
4358 Report::MessageF(Report::kBailout, 4364 Report::MessageF(Report::kBailout,
4359 Script::Handle(function.script()), 4365 Script::Handle(function.script()),
4360 function.token_pos(), 4366 function.token_pos(),
4361 "FlowGraphBuilder Bailout: %s %s", 4367 "FlowGraphBuilder Bailout: %s %s",
4362 String::Handle(function.name()).ToCString(), 4368 String::Handle(function.name()).ToCString(),
4363 reason); 4369 reason);
4364 UNREACHABLE(); 4370 UNREACHABLE();
4365 } 4371 }
4366 4372
4367 } // namespace dart 4373 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/flow_graph_builder.h ('k') | runtime/vm/object.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698