mirror of
https://github.com/dart-lang/sdk
synced 2024-09-05 00:13:50 +00:00
[vm] Cleanup more async-related code
This change continues cleanup of async implementation in the VM. TEST=ci Issue: https://github.com/dart-lang/sdk/issues/48378 Change-Id: Icdaeab18bcdc0d6974bc45841b630822cd1ac114 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/251441 Reviewed-by: Martin Kustermann <kustermann@google.com> Commit-Queue: Alexander Markov <alexmarkov@google.com>
This commit is contained in:
parent
9391343387
commit
2ad557a892
|
@ -698,22 +698,14 @@ Fragment StreamingFlowGraphBuilder::BuildFunctionBody(
|
|||
return body;
|
||||
}
|
||||
|
||||
Fragment StreamingFlowGraphBuilder::BuildEveryTimePrologue(
|
||||
Fragment StreamingFlowGraphBuilder::BuildRegularFunctionPrologue(
|
||||
const Function& dart_function,
|
||||
TokenPosition token_position,
|
||||
intptr_t type_parameters_offset) {
|
||||
LocalVariable* first_parameter) {
|
||||
Fragment F;
|
||||
F += CheckStackOverflowInPrologue(dart_function);
|
||||
F += DebugStepCheckInPrologue(dart_function, token_position);
|
||||
F += B->InitConstantParameters();
|
||||
return F;
|
||||
}
|
||||
|
||||
Fragment StreamingFlowGraphBuilder::BuildFirstTimePrologue(
|
||||
const Function& dart_function,
|
||||
LocalVariable* first_parameter,
|
||||
intptr_t type_parameters_offset) {
|
||||
Fragment F;
|
||||
F += SetupCapturedParameters(dart_function);
|
||||
F += ShortcutForUserDefinedEquals(dart_function, first_parameter);
|
||||
return F;
|
||||
|
@ -747,8 +739,7 @@ Fragment StreamingFlowGraphBuilder::ClearRawParameters(
|
|||
UncheckedEntryPointStyle StreamingFlowGraphBuilder::ChooseEntryPointStyle(
|
||||
const Function& dart_function,
|
||||
const Fragment& implicit_type_checks,
|
||||
const Fragment& first_time_prologue,
|
||||
const Fragment& every_time_prologue,
|
||||
const Fragment& regular_function_prologue,
|
||||
const Fragment& type_args_handling) {
|
||||
ASSERT(!dart_function.IsImplicitClosureFunction());
|
||||
if (!dart_function.MayHaveUncheckedEntryPoint() ||
|
||||
|
@ -761,17 +752,21 @@ UncheckedEntryPointStyle StreamingFlowGraphBuilder::ChooseEntryPointStyle(
|
|||
//
|
||||
// 1. There is a non-empty PrologueBuilder-prologue.
|
||||
//
|
||||
// 2. There is a non-empty "first-time" prologue.
|
||||
// 2. The regular function prologue has more than two instructions
|
||||
// (DebugStepCheck and CheckStackOverflow).
|
||||
//
|
||||
// 3. The "every-time" prologue has more than two instructions (DebugStepCheck
|
||||
// and CheckStackOverflow).
|
||||
//
|
||||
// TODO(#34162): For regular closures we can often avoid the
|
||||
// PrologueBuilder-prologue on non-dynamic invocations.
|
||||
if (!PrologueBuilder::HasEmptyPrologue(dart_function) ||
|
||||
!type_args_handling.is_empty() || !first_time_prologue.is_empty() ||
|
||||
!(every_time_prologue.entry == every_time_prologue.current ||
|
||||
every_time_prologue.current->previous() == every_time_prologue.entry)) {
|
||||
!type_args_handling.is_empty()) {
|
||||
return UncheckedEntryPointStyle::kSharedWithVariable;
|
||||
}
|
||||
Instruction* instr = regular_function_prologue.entry;
|
||||
if (instr != nullptr && instr->IsCheckStackOverflow()) {
|
||||
instr = instr->next();
|
||||
}
|
||||
if (instr != nullptr && instr->IsDebugStepCheck()) {
|
||||
instr = instr->next();
|
||||
}
|
||||
if (instr != nullptr) {
|
||||
return UncheckedEntryPointStyle::kSharedWithVariable;
|
||||
}
|
||||
|
||||
|
@ -782,15 +777,11 @@ FlowGraph* StreamingFlowGraphBuilder::BuildGraphOfFunction(
|
|||
bool is_constructor) {
|
||||
const Function& dart_function = parsed_function()->function();
|
||||
|
||||
intptr_t type_parameters_offset = 0;
|
||||
LocalVariable* first_parameter = nullptr;
|
||||
TokenPosition token_position = TokenPosition::kNoSource;
|
||||
{
|
||||
AlternativeReadingScope alt(&reader_);
|
||||
FunctionNodeHelper function_node_helper(this);
|
||||
function_node_helper.ReadUntilExcluding(
|
||||
FunctionNodeHelper::kTypeParameters);
|
||||
type_parameters_offset = ReaderOffset();
|
||||
function_node_helper.ReadUntilExcluding(
|
||||
FunctionNodeHelper::kPositionalParameters);
|
||||
intptr_t list_length = ReadListLength(); // read number of positionals.
|
||||
|
@ -811,15 +802,8 @@ FlowGraph* StreamingFlowGraphBuilder::BuildGraphOfFunction(
|
|||
BlockEntryInstr* instruction_cursor =
|
||||
flow_graph_builder_->BuildPrologue(normal_entry, &prologue_info);
|
||||
|
||||
// The 'every_time_prologue' runs first and is run when resuming from yield
|
||||
// points.
|
||||
const Fragment every_time_prologue = BuildEveryTimePrologue(
|
||||
dart_function, token_position, type_parameters_offset);
|
||||
|
||||
// The 'first_time_prologue' run after 'every_time_prologue' and is *not* run
|
||||
// when resuming from yield points.
|
||||
const Fragment first_time_prologue = BuildFirstTimePrologue(
|
||||
dart_function, first_parameter, type_parameters_offset);
|
||||
const Fragment regular_prologue = BuildRegularFunctionPrologue(
|
||||
dart_function, token_position, first_parameter);
|
||||
|
||||
// TODO(#34162): We can remove the default type handling (and
|
||||
// shorten the prologue type handling sequence) for non-dynamic invocations of
|
||||
|
@ -847,30 +831,28 @@ FlowGraph* StreamingFlowGraphBuilder::BuildGraphOfFunction(
|
|||
InitSuspendableFunction(dart_function) +
|
||||
BuildFunctionBody(dart_function, first_parameter, is_constructor);
|
||||
|
||||
auto extra_entry_point_style = ChooseEntryPointStyle(
|
||||
dart_function, implicit_type_checks, first_time_prologue,
|
||||
every_time_prologue, type_args_handling);
|
||||
auto extra_entry_point_style =
|
||||
ChooseEntryPointStyle(dart_function, implicit_type_checks,
|
||||
regular_prologue, type_args_handling);
|
||||
|
||||
Fragment function(instruction_cursor);
|
||||
FunctionEntryInstr* extra_entry = nullptr;
|
||||
switch (extra_entry_point_style) {
|
||||
case UncheckedEntryPointStyle::kNone: {
|
||||
function += every_time_prologue + first_time_prologue +
|
||||
type_args_handling + implicit_type_checks +
|
||||
function += regular_prologue + type_args_handling + implicit_type_checks +
|
||||
explicit_type_checks + body;
|
||||
break;
|
||||
}
|
||||
case UncheckedEntryPointStyle::kSeparate: {
|
||||
ASSERT(instruction_cursor == normal_entry);
|
||||
ASSERT(first_time_prologue.is_empty());
|
||||
ASSERT(type_args_handling.is_empty());
|
||||
|
||||
const Fragment prologue_copy = BuildEveryTimePrologue(
|
||||
dart_function, token_position, type_parameters_offset);
|
||||
const Fragment prologue_copy = BuildRegularFunctionPrologue(
|
||||
dart_function, token_position, first_parameter);
|
||||
|
||||
extra_entry = B->BuildSeparateUncheckedEntryPoint(
|
||||
normal_entry,
|
||||
/*normal_prologue=*/every_time_prologue + implicit_type_checks,
|
||||
/*normal_prologue=*/regular_prologue + implicit_type_checks,
|
||||
/*extra_prologue=*/prologue_copy,
|
||||
/*shared_prologue=*/explicit_type_checks,
|
||||
/*body=*/body);
|
||||
|
@ -878,8 +860,7 @@ FlowGraph* StreamingFlowGraphBuilder::BuildGraphOfFunction(
|
|||
}
|
||||
case UncheckedEntryPointStyle::kSharedWithVariable: {
|
||||
Fragment prologue(normal_entry, instruction_cursor);
|
||||
prologue += every_time_prologue;
|
||||
prologue += first_time_prologue;
|
||||
prologue += regular_prologue;
|
||||
prologue += type_args_handling;
|
||||
prologue += explicit_type_checks;
|
||||
extra_entry = B->BuildSharedUncheckedEntryPoint(
|
||||
|
|
|
@ -82,16 +82,12 @@ class StreamingFlowGraphBuilder : public KernelReaderHelper {
|
|||
bool constructor);
|
||||
|
||||
// Pieces of the prologue. They are all agnostic to the current Kernel offset.
|
||||
Fragment BuildEveryTimePrologue(const Function& dart_function,
|
||||
TokenPosition token_position,
|
||||
intptr_t type_parameters_offset);
|
||||
Fragment BuildFirstTimePrologue(const Function& dart_function,
|
||||
LocalVariable* first_parameter,
|
||||
intptr_t type_parameters_offset);
|
||||
Fragment BuildRegularFunctionPrologue(const Function& dart_function,
|
||||
TokenPosition token_position,
|
||||
LocalVariable* first_parameter);
|
||||
Fragment ClearRawParameters(const Function& dart_function);
|
||||
Fragment DebugStepCheckInPrologue(const Function& dart_function,
|
||||
TokenPosition position);
|
||||
Fragment SetAsyncStackTrace(const Function& dart_function);
|
||||
Fragment CheckStackOverflowInPrologue(const Function& dart_function);
|
||||
Fragment SetupCapturedParameters(const Function& dart_function);
|
||||
Fragment InitSuspendableFunction(const Function& dart_function);
|
||||
|
@ -102,8 +98,7 @@ class StreamingFlowGraphBuilder : public KernelReaderHelper {
|
|||
static UncheckedEntryPointStyle ChooseEntryPointStyle(
|
||||
const Function& dart_function,
|
||||
const Fragment& implicit_type_checks,
|
||||
const Fragment& first_time_prologue,
|
||||
const Fragment& every_time_prologue,
|
||||
const Fragment& regular_function_prologue,
|
||||
const Fragment& type_args_handling);
|
||||
|
||||
void loop_depth_inc();
|
||||
|
|
|
@ -148,7 +148,6 @@ ScopeBuildingResult* ScopeBuilder::BuildScopes() {
|
|||
helper_.ReadUntilFunctionNode();
|
||||
function_node_helper.ReadUntilExcluding(
|
||||
FunctionNodeHelper::kPositionalParameters);
|
||||
current_function_async_marker_ = function_node_helper.async_marker_;
|
||||
// NOTE: FunctionNode is read further below the if.
|
||||
|
||||
intptr_t pos = 0;
|
||||
|
@ -368,7 +367,6 @@ ScopeBuildingResult* ScopeBuilder::BuildScopes() {
|
|||
scope_->InsertParameterAt(pos++, parsed_function_->receiver_var());
|
||||
|
||||
// Create all positional and named parameters.
|
||||
current_function_async_marker_ = FunctionNodeHelper::kSync;
|
||||
AddPositionalAndNamedParameters(
|
||||
pos, kTypeCheckEverythingNotCheckedInNonDynamicallyInvokedMethod,
|
||||
attrs);
|
||||
|
@ -393,7 +391,6 @@ ScopeBuildingResult* ScopeBuilder::BuildScopes() {
|
|||
// Callbacks and calls with handles need try/catch variables.
|
||||
if ((function.FfiCallbackTarget() != Function::null() ||
|
||||
function.FfiCSignatureContainsHandles())) {
|
||||
current_function_async_marker_ = FunctionNodeHelper::kSync;
|
||||
++depth_.try_;
|
||||
AddTryVariables();
|
||||
--depth_.try_;
|
||||
|
@ -1462,13 +1459,10 @@ void ScopeBuilder::HandleLocalFunction(intptr_t parent_kernel_offset) {
|
|||
function_node_helper.ReadUntilExcluding(FunctionNodeHelper::kTypeParameters);
|
||||
|
||||
LocalScope* saved_function_scope = current_function_scope_;
|
||||
FunctionNodeHelper::AsyncMarker saved_function_async_marker =
|
||||
current_function_async_marker_;
|
||||
DepthState saved_depth_state = depth_;
|
||||
depth_ = DepthState(depth_.function_ + 1);
|
||||
EnterScope(parent_kernel_offset);
|
||||
current_function_scope_ = scope_;
|
||||
current_function_async_marker_ = function_node_helper.async_marker_;
|
||||
if (depth_.function_ == 1) {
|
||||
FunctionScope function_scope = {offset, scope_};
|
||||
result_->function_scopes.Add(function_scope);
|
||||
|
@ -1516,7 +1510,6 @@ void ScopeBuilder::HandleLocalFunction(intptr_t parent_kernel_offset) {
|
|||
ExitScope(function_node_helper.position_, function_node_helper.end_position_);
|
||||
depth_ = saved_depth_state;
|
||||
current_function_scope_ = saved_function_scope;
|
||||
current_function_async_marker_ = saved_function_async_marker;
|
||||
}
|
||||
|
||||
void ScopeBuilder::EnterScope(intptr_t kernel_offset) {
|
||||
|
|
|
@ -154,7 +154,6 @@ class ScopeBuilder {
|
|||
TranslationHelper translation_helper_;
|
||||
Zone* zone_;
|
||||
|
||||
FunctionNodeHelper::AsyncMarker current_function_async_marker_;
|
||||
LocalScope* current_function_scope_;
|
||||
LocalScope* scope_;
|
||||
DepthState depth_;
|
||||
|
|
|
@ -97,9 +97,9 @@ namespace dart {
|
|||
0xc40903ac) \
|
||||
V(_SuspendState, _clone, SuspendState_clone, 0xae1a40a0) \
|
||||
V(_SuspendState, _createAsyncCallbacks, SuspendState_createAsyncCallbacks, \
|
||||
0x68be1bf3) \
|
||||
0x967521b1) \
|
||||
V(_SuspendState, _createAsyncStarCallback, \
|
||||
SuspendState_createAsyncStarCallback, 0xfa7537e4) \
|
||||
SuspendState_createAsyncStarCallback, 0xa50f923c) \
|
||||
V(_SuspendState, _resume, SuspendState_resume, 0x5d7a8489) \
|
||||
V(_IntegerImplementation, toDouble, IntegerToDouble, 0x97728b46) \
|
||||
V(_Double, _add, DoubleAdd, 0xea666327) \
|
||||
|
|
|
@ -306,7 +306,7 @@ ActivationFrame::ActivationFrame(const Closure& async_activation,
|
|||
pc_desc_(PcDescriptors::ZoneHandle()) {
|
||||
// Extract the function and the code from the asynchronous activation.
|
||||
function_ = async_activation.function();
|
||||
if (caller_closure_finder->IsCompactAsyncCallback(function_)) {
|
||||
if (caller_closure_finder->IsAsyncCallback(function_)) {
|
||||
const auto& suspend_state = SuspendState::Handle(
|
||||
caller_closure_finder->GetSuspendStateFromAsyncCallback(
|
||||
async_activation));
|
||||
|
@ -2944,16 +2944,6 @@ Breakpoint* Debugger::SetBreakpointAtActivation(const Instance& closure,
|
|||
return bpt_location->AddPerClosure(this, closure, for_over_await);
|
||||
}
|
||||
|
||||
Breakpoint* Debugger::SetBreakpointAtAsyncOp(const Function& async_op) {
|
||||
const Script& script = Script::Handle(async_op.script());
|
||||
BreakpointLocation* bpt_location =
|
||||
SetBreakpoint(script, async_op.token_pos(), async_op.end_token_pos(), -1,
|
||||
-1 /* no line/col */, async_op);
|
||||
auto bpt = bpt_location->AddSingleShot(this);
|
||||
bpt->set_is_synthetic_async(true);
|
||||
return bpt;
|
||||
}
|
||||
|
||||
Breakpoint* Debugger::BreakpointAtActivation(const Instance& closure) {
|
||||
if (!closure.IsClosure()) {
|
||||
return NULL;
|
||||
|
@ -4422,7 +4412,7 @@ void Debugger::MaybeAsyncStepInto(const Closure& async_op) {
|
|||
void Debugger::AsyncStepInto(const Closure& async_op) {
|
||||
Zone* zone = Thread::Current()->zone();
|
||||
CallerClosureFinder caller_closure_finder(zone);
|
||||
if (caller_closure_finder.IsCompactAsyncCallback(
|
||||
if (caller_closure_finder.IsAsyncCallback(
|
||||
Function::Handle(zone, async_op.function()))) {
|
||||
const auto& suspend_state = SuspendState::Handle(
|
||||
zone, caller_closure_finder.GetSuspendStateFromAsyncCallback(async_op));
|
||||
|
|
|
@ -719,10 +719,6 @@ class Debugger {
|
|||
intptr_t line_number,
|
||||
intptr_t column_number);
|
||||
|
||||
// Sets synthetic breakpoint at async_op to step over the synthetic part of
|
||||
// the stack trace.
|
||||
Breakpoint* SetBreakpointAtAsyncOp(const Function& async_op);
|
||||
|
||||
BreakpointLocation* BreakpointLocationAtLineCol(const String& script_url,
|
||||
intptr_t line_number,
|
||||
intptr_t column_number);
|
||||
|
|
|
@ -6996,13 +6996,6 @@ class Context : public Object {
|
|||
static const intptr_t kBytesPerElement = kCompressedWordSize;
|
||||
static const intptr_t kMaxElements = kSmiMax / kBytesPerElement;
|
||||
|
||||
static const intptr_t kAwaitJumpVarIndex = 0;
|
||||
static const intptr_t kAsyncFutureIndex = 1;
|
||||
static const intptr_t kControllerIndex = 1;
|
||||
// Expected context index of chained futures in recognized async functions.
|
||||
// These are used to unwind async stacks.
|
||||
static const intptr_t kIsSyncIndex = 2;
|
||||
|
||||
struct ArrayTraits {
|
||||
static intptr_t elements_start_offset() { return sizeof(UntaggedContext); }
|
||||
static constexpr intptr_t kElementSize = kBytesPerElement;
|
||||
|
|
|
@ -133,13 +133,6 @@ ClosurePtr CallerClosureFinder::GetCallerInFutureImpl(const Object& future) {
|
|||
return GetCallerInFutureListener(listener);
|
||||
}
|
||||
|
||||
ClosurePtr CallerClosureFinder::FindCallerInAsyncGenClosure(
|
||||
const Context& receiver_context) {
|
||||
// Get the async* _AsyncStarStreamController.
|
||||
context_entry_ = receiver_context.At(Context::kControllerIndex);
|
||||
return FindCallerInAsyncStarStreamController(context_entry_);
|
||||
}
|
||||
|
||||
ClosurePtr CallerClosureFinder::FindCallerInAsyncStarStreamController(
|
||||
const Object& async_star_stream_controller) {
|
||||
ASSERT(async_star_stream_controller.IsInstance());
|
||||
|
@ -246,7 +239,7 @@ ClosurePtr CallerClosureFinder::FindCallerFromSuspendState(
|
|||
}
|
||||
}
|
||||
|
||||
bool CallerClosureFinder::IsCompactAsyncCallback(const Function& function) {
|
||||
bool CallerClosureFinder::IsAsyncCallback(const Function& function) {
|
||||
parent_function_ = function.parent_function();
|
||||
auto kind = parent_function_.recognized_kind();
|
||||
return (kind == MethodRecognizer::kSuspendState_createAsyncCallbacks) ||
|
||||
|
@ -255,7 +248,7 @@ bool CallerClosureFinder::IsCompactAsyncCallback(const Function& function) {
|
|||
|
||||
SuspendStatePtr CallerClosureFinder::GetSuspendStateFromAsyncCallback(
|
||||
const Closure& closure) {
|
||||
ASSERT(IsCompactAsyncCallback(Function::Handle(closure.function())));
|
||||
ASSERT(IsAsyncCallback(Function::Handle(closure.function())));
|
||||
// Async/async* handler only captures the receiver (SuspendState).
|
||||
receiver_context_ = closure.context();
|
||||
RELEASE_ASSERT(receiver_context_.num_variables() == 1);
|
||||
|
@ -266,7 +259,7 @@ ClosurePtr CallerClosureFinder::FindCaller(const Closure& receiver_closure) {
|
|||
receiver_function_ = receiver_closure.function();
|
||||
receiver_context_ = receiver_closure.context();
|
||||
|
||||
if (IsCompactAsyncCallback(receiver_function_)) {
|
||||
if (IsAsyncCallback(receiver_function_)) {
|
||||
suspend_state_ = GetSuspendStateFromAsyncCallback(receiver_closure);
|
||||
return FindCallerFromSuspendState(suspend_state_);
|
||||
}
|
||||
|
@ -302,12 +295,6 @@ ClosurePtr CallerClosureFinder::FindCaller(const Closure& receiver_closure) {
|
|||
return Closure::null();
|
||||
}
|
||||
|
||||
ObjectPtr CallerClosureFinder::GetAsyncFuture(const Closure& receiver_closure) {
|
||||
// Closure -> Context -> _Future.
|
||||
receiver_context_ = receiver_closure.context();
|
||||
return receiver_context_.At(Context::kAsyncFutureIndex);
|
||||
}
|
||||
|
||||
ObjectPtr CallerClosureFinder::GetFutureFutureListener(const Object& future) {
|
||||
ASSERT(future.GetClassId() == future_impl_class.id());
|
||||
auto& listener = Object::Handle(
|
||||
|
@ -462,7 +449,7 @@ void StackTraceUtils::UnwindAwaiterChain(
|
|||
if (function.IsNull()) {
|
||||
continue;
|
||||
}
|
||||
if (caller_closure_finder->IsCompactAsyncCallback(function)) {
|
||||
if (caller_closure_finder->IsAsyncCallback(function)) {
|
||||
suspend_state =
|
||||
caller_closure_finder->GetSuspendStateFromAsyncCallback(closure);
|
||||
const uword pc = suspend_state.pc();
|
||||
|
|
|
@ -27,10 +27,6 @@ class CallerClosureFinder {
|
|||
// Returns closure found either via the `result` Future, or the `callback`.
|
||||
ClosurePtr GetCallerInFutureListener(const Object& future_listener);
|
||||
|
||||
// Find caller closure from an async* function receiver context.
|
||||
// Returns either the `onData` or the Future awaiter.
|
||||
ClosurePtr FindCallerInAsyncGenClosure(const Context& receiver_context);
|
||||
|
||||
// Find caller closure from an _AsyncStarStreamController instance
|
||||
// corresponding to async* function.
|
||||
// Returns either the `onData` or the Future awaiter.
|
||||
|
@ -47,15 +43,12 @@ class CallerClosureFinder {
|
|||
|
||||
// Returns true if given closure function is a Future callback
|
||||
// corresponding to an async/async* function or async* body callback.
|
||||
bool IsCompactAsyncCallback(const Function& function);
|
||||
bool IsAsyncCallback(const Function& function);
|
||||
|
||||
// Returns SuspendState from the given callback which corresponds
|
||||
// to an async/async* function.
|
||||
SuspendStatePtr GetSuspendStateFromAsyncCallback(const Closure& closure);
|
||||
|
||||
// Finds the awaited Future from an async function receiver closure.
|
||||
ObjectPtr GetAsyncFuture(const Closure& receiver_closure);
|
||||
|
||||
// Get sdk/lib/async/future_impl.dart:_FutureListener.state.
|
||||
intptr_t GetFutureListenerState(const Object& future_listener);
|
||||
|
||||
|
|
|
@ -235,7 +235,6 @@ class ObjectPointerVisitor;
|
|||
V(SpaceOfSpace, " of ") \
|
||||
V(SpaceWhereNewLine, " where\n") \
|
||||
V(StackOverflowError, "StackOverflowError") \
|
||||
V(StackTraceParameter, ":stack_trace") \
|
||||
V(Stream, "Stream") \
|
||||
V(StringBase, "_StringBase") \
|
||||
V(Struct, "Struct") \
|
||||
|
@ -436,7 +435,6 @@ class ObjectPointerVisitor;
|
|||
V(_returnAsync, "_returnAsync") \
|
||||
V(_returnAsyncNotFuture, "_returnAsyncNotFuture") \
|
||||
V(_returnAsyncStar, "_returnAsyncStar") \
|
||||
V(_returnSyncStar, "_returnSyncStar") \
|
||||
V(_runExtension, "_runExtension") \
|
||||
V(_runPendingImmediateCallback, "_runPendingImmediateCallback") \
|
||||
V(_scanFlags, "_scanFlags") \
|
||||
|
|
|
@ -39,7 +39,7 @@ class _AsyncStarStreamController<T> {
|
|||
@pragma("vm:entry-point")
|
||||
StreamController<T> controller;
|
||||
@pragma("vm:entry-point")
|
||||
Function? asyncStarBody;
|
||||
void Function(Object?)? asyncStarBody;
|
||||
bool isAdding = false;
|
||||
bool onListenReceived = false;
|
||||
bool isScheduled = false;
|
||||
|
@ -66,7 +66,7 @@ class _AsyncStarStreamController<T> {
|
|||
isSuspendedAtYield = false;
|
||||
final bool? argument = continuationArgument;
|
||||
continuationArgument = null;
|
||||
asyncStarBody!(argument, null);
|
||||
asyncStarBody!(argument);
|
||||
}
|
||||
|
||||
void scheduleGenerator() {
|
||||
|
@ -169,8 +169,7 @@ class _AsyncStarStreamController<T> {
|
|||
controller.close();
|
||||
}
|
||||
|
||||
_AsyncStarStreamController(this.asyncStarBody)
|
||||
: controller = new StreamController(sync: true) {
|
||||
_AsyncStarStreamController() : controller = new StreamController(sync: true) {
|
||||
controller.onListen = this.onListen;
|
||||
controller.onResume = this.onResume;
|
||||
controller.onCancel = this.onCancel;
|
||||
|
@ -217,32 +216,22 @@ external void _moveNextDebuggerStepCheck(Function async_op);
|
|||
|
||||
@pragma("vm:entry-point")
|
||||
class _SuspendState {
|
||||
static const bool _trace = false;
|
||||
|
||||
@pragma("vm:entry-point", "call")
|
||||
@pragma("vm:invisible")
|
||||
static Object? _initAsync<T>() {
|
||||
if (_trace) print('_initAsync<$T>');
|
||||
return _Future<T>();
|
||||
}
|
||||
|
||||
@pragma("vm:invisible")
|
||||
@pragma("vm:recognized", "other")
|
||||
void _createAsyncCallbacks() {
|
||||
if (_trace) print('_createAsyncCallbacks');
|
||||
|
||||
@pragma("vm:invisible")
|
||||
thenCallback(value) {
|
||||
if (_trace) print('thenCallback (this=$this, value=$value)');
|
||||
_resume(value, null, null);
|
||||
}
|
||||
|
||||
@pragma("vm:invisible")
|
||||
errorCallback(Object exception, StackTrace stackTrace) {
|
||||
if (_trace) {
|
||||
print('errorCallback (this=$this, '
|
||||
'exception=$exception, stackTrace=$stackTrace)');
|
||||
}
|
||||
_resume(null, exception, stackTrace);
|
||||
}
|
||||
|
||||
|
@ -335,7 +324,6 @@ class _SuspendState {
|
|||
@pragma("vm:entry-point", "call")
|
||||
@pragma("vm:invisible")
|
||||
Object? _await(Object? object) {
|
||||
if (_trace) print('_await (object=$object)');
|
||||
if (_thenCallback == null) {
|
||||
_createAsyncCallbacks();
|
||||
}
|
||||
|
@ -358,10 +346,6 @@ class _SuspendState {
|
|||
@pragma("vm:entry-point", "call")
|
||||
@pragma("vm:invisible")
|
||||
static Future _returnAsync(Object suspendState, Object? returnValue) {
|
||||
if (_trace) {
|
||||
print('_returnAsync (suspendState=$suspendState, '
|
||||
'returnValue=$returnValue)');
|
||||
}
|
||||
_Future future;
|
||||
if (suspendState is _SuspendState) {
|
||||
future = unsafeCast<_Future>(suspendState._functionData);
|
||||
|
@ -380,10 +364,6 @@ class _SuspendState {
|
|||
@pragma("vm:invisible")
|
||||
static Future _returnAsyncNotFuture(
|
||||
Object suspendState, Object? returnValue) {
|
||||
if (_trace) {
|
||||
print('_returnAsyncNotFuture (suspendState=$suspendState, '
|
||||
'returnValue=$returnValue)');
|
||||
}
|
||||
_Future future;
|
||||
if (suspendState is _SuspendState) {
|
||||
future = unsafeCast<_Future>(suspendState._functionData);
|
||||
|
@ -397,15 +377,13 @@ class _SuspendState {
|
|||
@pragma("vm:entry-point", "call")
|
||||
@pragma("vm:invisible")
|
||||
static Object? _initAsyncStar<T>() {
|
||||
if (_trace) print('_initAsyncStar<$T>');
|
||||
return _AsyncStarStreamController<T>(null);
|
||||
return _AsyncStarStreamController<T>();
|
||||
}
|
||||
|
||||
@pragma("vm:invisible")
|
||||
@pragma("vm:recognized", "other")
|
||||
_createAsyncStarCallback(_AsyncStarStreamController controller) {
|
||||
controller.asyncStarBody = (value, _) {
|
||||
if (_trace) print('asyncStarBody callback (value=$value)');
|
||||
controller.asyncStarBody = (value) {
|
||||
_resume(value, null, null);
|
||||
};
|
||||
}
|
||||
|
@ -424,10 +402,6 @@ class _SuspendState {
|
|||
@pragma("vm:entry-point", "call")
|
||||
@pragma("vm:invisible")
|
||||
static void _returnAsyncStar(Object suspendState, Object? returnValue) {
|
||||
if (_trace) {
|
||||
print('_returnAsyncStar (suspendState=$suspendState, '
|
||||
'returnValue=$returnValue)');
|
||||
}
|
||||
final controller = unsafeCast<_AsyncStarStreamController>(
|
||||
unsafeCast<_SuspendState>(suspendState)._functionData);
|
||||
controller.close();
|
||||
|
@ -437,10 +411,6 @@ class _SuspendState {
|
|||
@pragma("vm:invisible")
|
||||
static Object? _handleException(
|
||||
Object suspendState, Object exception, StackTrace stackTrace) {
|
||||
if (_trace) {
|
||||
print('_handleException (suspendState=$suspendState, '
|
||||
'exception=$exception, stackTrace=$stackTrace)');
|
||||
}
|
||||
Object? functionData;
|
||||
bool isSync = true;
|
||||
if (suspendState is _SuspendState) {
|
||||
|
@ -469,14 +439,12 @@ class _SuspendState {
|
|||
@pragma("vm:entry-point", "call")
|
||||
@pragma("vm:invisible")
|
||||
static Object? _initSyncStar<T>() {
|
||||
if (_trace) print('_initSyncStar<$T>');
|
||||
return _SyncStarIterable<T>();
|
||||
}
|
||||
|
||||
@pragma("vm:entry-point", "call")
|
||||
@pragma("vm:invisible")
|
||||
Object? _suspendSyncStarAtStart(Object? object) {
|
||||
if (_trace) print('_suspendSyncStarAtStart($object)');
|
||||
final data = _functionData;
|
||||
unsafeCast<_SyncStarIterable>(data)._stateAtStart = this;
|
||||
return data;
|
||||
|
|
Loading…
Reference in a new issue