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

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, 10 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
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::BuildAsyncYieldJump(LocalVariable* old_context,
1487 LocalVariable* iterator_param, 1489 const intptr_t old_ctx_level,
Ivan Posva 2015/02/23 08:23:36 old_ctx_level is not used in this function. Why is
hausner 2015/02/23 17:12:01 Copy-paste error. I think I will need it though si
1488 const intptr_t old_ctx_level, 1490 JoinEntryInstr* target) {
1489 JoinEntryInstr* target) { 1491 // Building a jump consists of the following actions:
1492 // * Restore the old context from :await_cxt_var.
1493 // * Append a Goto to the target's join.
1494 ASSERT((old_context != NULL) && old_context->is_captured());
1495
1496 // Restore the saved continuation context, i.e. the context that was
1497 // saved into :await_ctx_var before the closure suspended.
1498 BuildRestoreContext(*old_context);
1499
1500 // Goto saved join.
1501 Goto(target);
1502 }
1503
1504
1505 void EffectGraphVisitor::BuildSyncYieldJump(LocalVariable* old_context,
1506 LocalVariable* iterator_param,
1507 const intptr_t old_ctx_level,
1508 JoinEntryInstr* target) {
1490 // Building a jump consists of the following actions: 1509 // Building a jump consists of the following actions:
1491 // * Load the generator body's iterator parameter (:iterator) 1510 // * Load the generator body's iterator parameter (:iterator)
1492 // from the current context into a temporary. 1511 // from the current context into a temporary.
1493 // * Restore the old context from :await_cxt_var. 1512 // * Restore the old context from :await_cxt_var.
1494 // * Copy the iterator saved above into the restored context. 1513 // * Copy the iterator saved above into the restored context.
1495 // * Append a Goto to the target's join. 1514 // * Append a Goto to the target's join.
1496 ASSERT((iterator_param != NULL) && iterator_param->is_captured()); 1515 ASSERT((iterator_param != NULL) && iterator_param->is_captured());
1497 ASSERT((old_context != NULL) && old_context->is_captured()); 1516 ASSERT((old_context != NULL) && old_context->is_captured());
1498 // Before restoring the context we need to temporarily save the 1517 // Before restoring the context we need to temporarily save the
1499 // iterator parameter. 1518 // iterator parameter.
(...skipping 2375 matching lines...) Expand 10 before | Expand all | Expand 10 after
3875 pos++; 3894 pos++;
3876 } 3895 }
3877 } 3896 }
3878 3897
3879 // Continuation part: 3898 // Continuation part:
3880 // If this node sequence is the body of a function with continuations, 3899 // If this node sequence is the body of a function with continuations,
3881 // leave room for a preamble. 3900 // leave room for a preamble.
3882 // The preamble is generated after visiting the body. 3901 // The preamble is generated after visiting the body.
3883 GotoInstr* preamble_start = NULL; 3902 GotoInstr* preamble_start = NULL;
3884 if (is_top_level_sequence && 3903 if (is_top_level_sequence &&
3885 (function.IsAsyncClosure() || function.IsSyncGenClosure())) { 3904 (function.IsAsyncClosure() ||
3905 function.IsSyncGenClosure() ||
3906 function.IsAsyncGenClosure())) {
3886 JoinEntryInstr* preamble_end = new(I) JoinEntryInstr( 3907 JoinEntryInstr* preamble_end = new(I) JoinEntryInstr(
3887 owner()->AllocateBlockId(), owner()->try_index()); 3908 owner()->AllocateBlockId(), owner()->try_index());
3888 ASSERT(exit() != NULL); 3909 ASSERT(exit() != NULL);
3889 exit()->Goto(preamble_end); 3910 exit()->Goto(preamble_end);
3890 ASSERT(exit()->next()->IsGoto()); 3911 ASSERT(exit()->next()->IsGoto());
3891 preamble_start = exit()->next()->AsGoto(); 3912 preamble_start = exit()->next()->AsGoto();
3892 ASSERT(preamble_start->IsGoto()); 3913 ASSERT(preamble_start->IsGoto());
3893 exit_ = preamble_end; 3914 exit_ = preamble_end;
3894 } 3915 }
3895 3916
3896 intptr_t i = 0; 3917 intptr_t i = 0;
3897 while (is_open() && (i < node->length())) { 3918 while (is_open() && (i < node->length())) {
3898 EffectGraphVisitor for_effect(owner()); 3919 EffectGraphVisitor for_effect(owner());
3899 node->NodeAt(i++)->Visit(&for_effect); 3920 node->NodeAt(i++)->Visit(&for_effect);
3900 Append(for_effect); 3921 Append(for_effect);
3901 if (!is_open()) { 3922 if (!is_open()) {
3902 // E.g., because of a JumpNode. 3923 // E.g., because of a JumpNode.
3903 break; 3924 break;
3904 } 3925 }
3905 } 3926 }
3906 3927
3907 // Continuation part: 3928 // Continuation part:
3908 // After generating the CFG for the body we can create the preamble 3929 // After generating the CFG for the body we can create the preamble
3909 // because we know exactly how many continuation states we need. 3930 // because we know exactly how many continuation states we need.
3910 if (is_top_level_sequence && 3931 if (is_top_level_sequence &&
3911 (function.IsAsyncClosure() || function.IsSyncGenClosure())) { 3932 (function.IsAsyncClosure() ||
3933 function.IsSyncGenClosure() ||
3934 function.IsAsyncGenClosure())) {
3912 ASSERT(preamble_start != NULL); 3935 ASSERT(preamble_start != NULL);
3913 // We are at the top level. Fetch the corresponding scope. 3936 // We are at the top level. Fetch the corresponding scope.
3914 LocalScope* top_scope = node->scope(); 3937 LocalScope* top_scope = node->scope();
3915 LocalVariable* jump_var = top_scope->LookupVariable( 3938 LocalVariable* jump_var = top_scope->LookupVariable(
3916 Symbols::AwaitJumpVar(), false); 3939 Symbols::AwaitJumpVar(), false);
3917 ASSERT(jump_var != NULL && jump_var->is_captured()); 3940 ASSERT(jump_var != NULL && jump_var->is_captured());
3918 Instruction* saved_entry = entry_; 3941 Instruction* saved_entry = entry_;
3919 Instruction* saved_exit = exit_; 3942 Instruction* saved_exit = exit_;
3920 entry_ = NULL; 3943 entry_ = NULL;
3921 exit_ = NULL; 3944 exit_ = NULL;
(...skipping 25 matching lines...) Expand all
3947 false); 3970 false);
3948 LocalVariable* stack_trace_param = 3971 LocalVariable* stack_trace_param =
3949 top_scope->LookupVariable(Symbols::AsyncOperationStackTraceParam(), 3972 top_scope->LookupVariable(Symbols::AsyncOperationStackTraceParam(),
3950 false); 3973 false);
3951 for_true.BuildAwaitJump(old_context, 3974 for_true.BuildAwaitJump(old_context,
3952 result_param, 3975 result_param,
3953 error_param, 3976 error_param,
3954 stack_trace_param, 3977 stack_trace_param,
3955 (*owner()->await_levels())[i], 3978 (*owner()->await_levels())[i],
3956 (*owner()->await_joins())[i]); 3979 (*owner()->await_joins())[i]);
3980 } else if (function.IsAsyncGenClosure()) {
3981 for_true.BuildAsyncYieldJump(old_context,
3982 (*owner()->await_levels())[i],
3983 (*owner()->await_joins())[i]);
3984
3957 } else { 3985 } else {
3958 ASSERT(function.IsSyncGenClosure()); 3986 ASSERT(function.IsSyncGenClosure());
3959 LocalVariable* iterator_param = 3987 LocalVariable* iterator_param =
3960 top_scope->LookupVariable(Symbols::IteratorParameter(), false); 3988 top_scope->LookupVariable(Symbols::IteratorParameter(), false);
3961 for_true.BuildYieldJump(old_context, 3989 for_true.BuildSyncYieldJump(old_context,
3962 iterator_param, 3990 iterator_param,
3963 (*owner()->await_levels())[i], 3991 (*owner()->await_levels())[i],
3964 (*owner()->await_joins())[i]); 3992 (*owner()->await_joins())[i]);
3965 } 3993 }
3966 3994
3967 Join(for_test, for_true, for_false); 3995 Join(for_test, for_true, for_false);
3968 if (i == 0) { 3996 if (i == 0) {
3969 // Manually link up the preamble start. 3997 // Manually link up the preamble start.
3970 preamble_start->previous()->set_next(for_test.entry()); 3998 preamble_start->previous()->set_next(for_test.entry());
3971 for_test.entry()->set_previous(preamble_start->previous()); 3999 for_test.entry()->set_previous(preamble_start->previous());
3972 } 4000 }
3973 if (i == (num_await_states - 1)) { 4001 if (i == (num_await_states - 1)) {
3974 // Link up preamble end. 4002 // Link up preamble end.
(...skipping 381 matching lines...) Expand 10 before | Expand all | Expand 10 after
4356 Report::MessageF(Report::kBailout, 4384 Report::MessageF(Report::kBailout,
4357 Script::Handle(function.script()), 4385 Script::Handle(function.script()),
4358 function.token_pos(), 4386 function.token_pos(),
4359 "FlowGraphBuilder Bailout: %s %s", 4387 "FlowGraphBuilder Bailout: %s %s",
4360 String::Handle(function.name()).ToCString(), 4388 String::Handle(function.name()).ToCString(),
4361 reason); 4389 reason);
4362 UNREACHABLE(); 4390 UNREACHABLE();
4363 } 4391 }
4364 4392
4365 } // namespace dart 4393 } // namespace dart
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698