Revert "Reland "[VM] Adds Future.then and Future.catchError stack unwinding."" This reverts commit 9978a246c10c6c6297bc8ac52fd34d3423f6071c. Reason for revert: VM crashes in google3, b/177506826 Original change's description: > Reland "[VM] Adds Future.then and Future.catchError stack unwinding." > > This reverts commit 978b838461ea9757a4ed7d413f85f542e1157861. > > Reason for revert: Fix: https://dart-review.googlesource.com/c/sdk/+/179762 > > TEST=Various 'causal' tests updated below. > > Original change's description: > > Revert "[VM] Adds Future.then and Future.catchError stack unwinding." > > > > This reverts commit 8f2c47f24b6910ad01f7456eb913ca2aa17151a1. > > > > Reason for revert: We suspect this is causing VM crashes: http://b/177506826 > > > > Original change's description: > > > [VM] Adds Future.then and Future.catchError stack unwinding. > > > > > > TEST=Various 'causal' tests updated below. > > > > > > Bug: https://github.com/dart-lang/sdk/issues/40815, https://github.com/dart-lang/sdk/issues/37953 > > > Change-Id: I1420d6163ac2e3b22e0971f7b0ad516895dded70 > > > Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/176662 > > > Commit-Queue: Clement Skau <cskau@google.com> > > > Reviewed-by: Vyacheslav Egorov <vegorov@google.com> > > > > TBR=vegorov@google.com,cskau@google.com > > > > # Not skipping CQ checks because original CL landed > 1 day ago. > > > > Bug: https://github.com/dart-lang/sdk/issues/40815 > > Bug: https://github.com/dart-lang/sdk/issues/37953 > > Change-Id: I870f0202f43588f71a5d2b0f82338978b5a5dda9 > > Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/178998 > > Reviewed-by: Michal Terepeta <michalt@google.com> > > Reviewed-by: Vyacheslav Egorov <vegorov@google.com> > > Commit-Queue: Michal Terepeta <michalt@google.com> > > TBR=vegorov@google.com,cskau@google.com,michalt@google.com > > # Not skipping CQ checks because original CL landed > 1 day ago. > > Bug: https://github.com/dart-lang/sdk/issues/40815 > Bug: https://github.com/dart-lang/sdk/issues/37953 > Change-Id: I8a1eb6679b01571b850499cac2dadc5bf9ef2dcd > Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/179763 > Reviewed-by: Clement Skau <cskau@google.com> > Reviewed-by: Vyacheslav Egorov <vegorov@google.com> > Commit-Queue: Clement Skau <cskau@google.com> TBR=vegorov@google.com,cskau@google.com,michalt@google.com # Not skipping CQ checks because original CL landed > 1 day ago. Bug: https://github.com/dart-lang/sdk/issues/40815 Bug: https://github.com/dart-lang/sdk/issues/37953 Change-Id: I1274bcb375bf6f9cb0609d372b0b451d51eb99c4 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/180147 Reviewed-by: David Morgan <davidmorgan@google.com> Commit-Queue: David Morgan <davidmorgan@google.com>
diff --git a/pkg/vm_service/test/get_stack_test.dart b/pkg/vm_service/test/get_stack_test.dart index 28c5001..f1ba6f1 100644 --- a/pkg/vm_service/test/get_stack_test.dart +++ b/pkg/vm_service/test/get_stack_test.dart
@@ -52,12 +52,11 @@ // Before the first await. hasStoppedAtBreakpoint, stoppedAtLine(LINE_A), - // At LINE_A we're still running sync. so no asyncCausalFrames. (VmService service, IsolateRef isolateRef) async { final result = await service.getStack(isolateRef.id!); expect(result.frames, hasLength(16)); - expect(result.asyncCausalFrames, isNull); + expect(result.asyncCausalFrames, hasLength(16)); expect(result.awaiterFrames, hasLength(16)); expectFrames(result.frames, [ @@ -74,6 +73,20 @@ [equals('Regular'), endsWith(' testMain')], ]); + expectFrames(result.asyncCausalFrames, [ + [equals('Regular'), endsWith(' func10')], + [equals('Regular'), endsWith(' func9')], + [equals('Regular'), endsWith(' func8')], + [equals('Regular'), endsWith(' func7')], + [equals('Regular'), endsWith(' func6')], + [equals('Regular'), endsWith(' func5')], + [equals('Regular'), endsWith(' func4')], + [equals('Regular'), endsWith(' func3')], + [equals('Regular'), endsWith(' func2')], + [equals('Regular'), endsWith(' func1')], + [equals('Regular'), endsWith(' testMain')], + ]); + expectFrames(result.awaiterFrames, [ [equals('AsyncActivation'), endsWith(' func10')], [equals('AsyncActivation'), endsWith(' func9')], @@ -88,10 +101,10 @@ [equals('AsyncActivation'), endsWith(' testMain')], ]); }, + // After resuming the continuation - i.e. running async. resumeIsolate, hasStoppedAtBreakpoint, stoppedAtLine(LINE_B), - // After resuming the continuation - i.e. running async. (VmService service, IsolateRef isolateRef) async { final result = await service.getStack(isolateRef.id!);
diff --git a/runtime/observatory/tests/service/causal_async_stack_presence_test.dart b/runtime/observatory/tests/service/causal_async_stack_presence_test.dart index 01331cd..3a90e4a 100644 --- a/runtime/observatory/tests/service/causal_async_stack_presence_test.dart +++ b/runtime/observatory/tests/service/causal_async_stack_presence_test.dart
@@ -11,8 +11,8 @@ import 'test_helper.dart'; const LINE_C = 19; -const LINE_A = 25; -const LINE_B = 31; +const LINE_A = 24; +const LINE_B = 30; foobar() { debugger(); @@ -20,7 +20,6 @@ } helper() async { - await 0; // Yield. The rest will run async. debugger(); print('helper'); // LINE_A. foobar(); @@ -37,7 +36,6 @@ (Isolate isolate) async { ServiceMap stack = await isolate.getStack(); // No causal frames because we are in a completely synchronous stack. - // Async function hasn't yielded yet. expect(stack['asyncCausalFrames'], isNull); }, resumeIsolate, @@ -45,7 +43,7 @@ stoppedAtLine(LINE_A), (Isolate isolate) async { ServiceMap stack = await isolate.getStack(); - // Async function has yielded once, so it's now running async. + // Has causal frames (we are inside an async function) expect(stack['asyncCausalFrames'], isNotNull); }, resumeIsolate,
diff --git a/runtime/observatory/tests/service/causal_async_star_stack_presence_test.dart b/runtime/observatory/tests/service/causal_async_star_stack_presence_test.dart index 9b605cb..4d3e448 100644 --- a/runtime/observatory/tests/service/causal_async_star_stack_presence_test.dart +++ b/runtime/observatory/tests/service/causal_async_star_stack_presence_test.dart
@@ -39,7 +39,7 @@ (Isolate isolate) async { ServiceMap stack = await isolate.getStack(); // No causal frames because we are in a completely synchronous stack. - expect(stack['asyncCausalFrames'], isNull); + expect(stack['asyncCausalFrames'], isNotNull); }, resumeIsolate, hasStoppedAtBreakpoint,
diff --git a/runtime/observatory_2/tests/service_2/causal_async_stack_presence_test.dart b/runtime/observatory_2/tests/service_2/causal_async_stack_presence_test.dart index cd9ef6a..f52f4a1 100644 --- a/runtime/observatory_2/tests/service_2/causal_async_stack_presence_test.dart +++ b/runtime/observatory_2/tests/service_2/causal_async_stack_presence_test.dart
@@ -11,8 +11,8 @@ import 'test_helper.dart'; const LINE_C = 19; -const LINE_A = 25; -const LINE_B = 31; +const LINE_A = 24; +const LINE_B = 30; foobar() { debugger(); @@ -20,7 +20,6 @@ } helper() async { - await 0; // Yield. The rest will run async. debugger(); print('helper'); // LINE_A. foobar();
diff --git a/runtime/observatory_2/tests/service_2/causal_async_star_stack_presence_test.dart b/runtime/observatory_2/tests/service_2/causal_async_star_stack_presence_test.dart index 8acf40d..7fb385a 100644 --- a/runtime/observatory_2/tests/service_2/causal_async_star_stack_presence_test.dart +++ b/runtime/observatory_2/tests/service_2/causal_async_star_stack_presence_test.dart
@@ -39,7 +39,7 @@ (Isolate isolate) async { ServiceMap stack = await isolate.getStack(); // No causal frames because we are in a completely synchronous stack. - expect(stack['asyncCausalFrames'], isNull); + expect(stack['asyncCausalFrames'], isNotNull); }, resumeIsolate, hasStoppedAtBreakpoint,
diff --git a/runtime/tests/vm/dart/causal_stacks/utils.dart b/runtime/tests/vm/dart/causal_stacks/utils.dart index 8b75f98..73ffe1d 100644 --- a/runtime/tests/vm/dart/causal_stacks/utils.dart +++ b/runtime/tests/vm/dart/causal_stacks/utils.dart
@@ -178,22 +178,12 @@ return Future.sync(throwAsync).whenComplete(() => 'nop'); } -// ---- -// Scenario: Future.then: -// ---- - -Future futureThen() { - return Future.value(0).then((value) { - throwSync(); - }); -} - // Helpers: // We want lines that either start with a frame index or an async gap marker. final _lineRE = RegExp(r'^(?:#(?<number>\d+)|<asynchronous suspension>)'); -Future<void> assertStack(List<String> expects, StackTrace stackTrace, +void assertStack(List<String> expects, StackTrace stackTrace, [String? debugInfoFilename]) async { final original = await Stream.value(stackTrace.toString()) .transform(const LineSplitter()) @@ -263,7 +253,7 @@ await f(); Expect.fail('No exception thrown!'); } on String catch (e, s) { - return assertStack(expectedStack, s, debugInfoFilename); + assertStack(expectedStack, s, debugInfoFilename); } } @@ -277,7 +267,7 @@ await f().then((e) => Expect.fail('No exception thrown!')); Expect.fail('No exception thrown!'); } on String catch (e, s) { - return assertStack(expectedStack, s, debugInfoFilename); + assertStack(expectedStack, s, debugInfoFilename); } } @@ -288,7 +278,7 @@ await f().catchError((e, s) { stackTrace = s; }); - return assertStack(expectedStack, stackTrace, debugInfoFilename); + assertStack(expectedStack, stackTrace, debugInfoFilename); } // ---- @@ -337,32 +327,39 @@ r'^#13 Future._propagateToListeners ', r'^#14 Future._completeWithValue ', r'^#15 _completeOnAsyncReturn ', - r'^#16 assertStack ', + r'^#16 doTestAwaitCatchError ', r'^#17 _RootZone.runUnary ', r'^#18 _FutureListener.handleValue ', r'^#19 Future._propagateToListeners.handleValueCallback ', r'^#20 Future._propagateToListeners ', - r'^#21 Future._complete ', - r'^#22 Stream.toList.<anonymous closure> ', - r'^#23 _RootZone.runGuarded ', - r'^#24 _BufferingStreamSubscription._sendDone.sendDone ', - r'^#25 _BufferingStreamSubscription._sendDone ', - r'^#26 _BufferingStreamSubscription._close ', - r'^#27 _SinkTransformerStreamSubscription._close ', - r'^#28 _EventSinkWrapper.close ', - r'^#29 _StringAdapterSink.close ', - r'^#30 _LineSplitterSink.close ', - r'^#31 _SinkTransformerStreamSubscription._handleDone ', - r'^#32 _RootZone.runGuarded ', - r'^#33 _BufferingStreamSubscription._sendDone.sendDone ', - r'^#34 _BufferingStreamSubscription._sendDone ', - r'^#35 _DelayedDone.perform ', - r'^#36 _StreamImplEvents.handleNext ', - r'^#37 _PendingEvents.schedule.<anonymous closure> ', - r'^#38 _microtaskLoop ', - r'^#39 _startMicrotaskLoop ', - r'^#40 _runPendingImmediateCallback ', - r'^#41 _RawReceivePortImpl._handleMessage ', + r'^#21 Future._completeError ', + r'^#22 _completeOnAsyncError ', + r'^#23 allYield ', + r'^#24 _asyncErrorWrapperHelper.errorCallback ', + r'^#25 _RootZone.runBinary ', + r'^#26 _FutureListener.handleError ', + r'^#27 Future._propagateToListeners.handleError ', + r'^#28 Future._propagateToListeners ', + r'^#29 Future._completeError ', + r'^#30 _completeOnAsyncError ', + r'^#31 allYield2 ', + r'^#32 _asyncErrorWrapperHelper.errorCallback ', + r'^#33 _RootZone.runBinary ', + r'^#34 _FutureListener.handleError ', + r'^#35 Future._propagateToListeners.handleError ', + r'^#36 Future._propagateToListeners ', + r'^#37 Future._completeError ', + r'^#38 _completeOnAsyncError ', + r'^#39 allYield3 ', + r'^#40 _RootZone.runUnary ', + r'^#41 _FutureListener.handleValue ', + r'^#42 Future._propagateToListeners.handleValueCallback ', + r'^#43 Future._propagateToListeners ', + r'^#44 Future._addListener.<anonymous closure> ', + r'^#45 _microtaskLoop ', + r'^#46 _startMicrotaskLoop ', + r'^#47 _runPendingImmediateCallback ', + r'^#48 _RawReceivePortImpl._handleMessage ', ], debugInfoFilename); await doTestAwaitThen( @@ -378,32 +375,34 @@ r'^#13 Future._propagateToListeners ', r'^#14 Future._completeWithValue ', r'^#15 _completeOnAsyncReturn ', - r'^#16 assertStack ', - r'^#17 _RootZone.runUnary ', - r'^#18 _FutureListener.handleValue ', - r'^#19 Future._propagateToListeners.handleValueCallback ', - r'^#20 Future._propagateToListeners ', - r'^#21 Future._complete ', - r'^#22 Stream.toList.<anonymous closure> ', - r'^#23 _RootZone.runGuarded ', - r'^#24 _BufferingStreamSubscription._sendDone.sendDone ', - r'^#25 _BufferingStreamSubscription._sendDone ', - r'^#26 _BufferingStreamSubscription._close ', - r'^#27 _SinkTransformerStreamSubscription._close ', - r'^#28 _EventSinkWrapper.close ', - r'^#29 _StringAdapterSink.close ', - r'^#30 _LineSplitterSink.close ', - r'^#31 _SinkTransformerStreamSubscription._handleDone ', - r'^#32 _RootZone.runGuarded ', - r'^#33 _BufferingStreamSubscription._sendDone.sendDone ', - r'^#34 _BufferingStreamSubscription._sendDone ', - r'^#35 _DelayedDone.perform ', - r'^#36 _StreamImplEvents.handleNext ', - r'^#37 _PendingEvents.schedule.<anonymous closure> ', - r'^#38 _microtaskLoop ', - r'^#39 _startMicrotaskLoop ', - r'^#40 _runPendingImmediateCallback ', - r'^#41 _RawReceivePortImpl._handleMessage ', + r'^#16 doTestAwait ', + r'^#17 _asyncErrorWrapperHelper.errorCallback ', + r'^#18 _RootZone.runBinary ', + r'^#19 _FutureListener.handleError ', + r'^#20 Future._propagateToListeners.handleError ', + r'^#21 Future._propagateToListeners ', + r'^#22 Future._completeError ', + r'^#23 _completeOnAsyncError ', + r'^#24 noYields ', + r'^#25 _asyncErrorWrapperHelper.errorCallback ', + r'^#26 _RootZone.runBinary ', + r'^#27 _FutureListener.handleError ', + r'^#28 Future._propagateToListeners.handleError ', + r'^#29 Future._propagateToListeners ', + r'^#30 Future._completeError ', + r'^#31 _completeOnAsyncError ', + r'^#32 noYields2 ', + r'^#33 _asyncErrorWrapperHelper.errorCallback ', + r'^#34 _RootZone.runBinary ', + r'^#35 _FutureListener.handleError ', + r'^#36 Future._propagateToListeners.handleError ', + r'^#37 Future._propagateToListeners ', + r'^#38 Future._completeError ', + r'^#39 Future._asyncCompleteError.<anonymous closure> ', + r'^#40 _microtaskLoop ', + r'^#41 _startMicrotaskLoop ', + r'^#42 _runPendingImmediateCallback ', + r'^#43 _RawReceivePortImpl._handleMessage ', ], debugInfoFilename); await doTestAwaitCatchError( @@ -419,32 +418,34 @@ r'^#13 Future._propagateToListeners ', r'^#14 Future._completeWithValue ', r'^#15 _completeOnAsyncReturn ', - r'^#16 assertStack ', - r'^#17 _RootZone.runUnary ', - r'^#18 _FutureListener.handleValue ', - r'^#19 Future._propagateToListeners.handleValueCallback ', - r'^#20 Future._propagateToListeners ', - r'^#21 Future._complete ', - r'^#22 Stream.toList.<anonymous closure> ', - r'^#23 _RootZone.runGuarded ', - r'^#24 _BufferingStreamSubscription._sendDone.sendDone ', - r'^#25 _BufferingStreamSubscription._sendDone ', - r'^#26 _BufferingStreamSubscription._close ', - r'^#27 _SinkTransformerStreamSubscription._close ', - r'^#28 _EventSinkWrapper.close ', - r'^#29 _StringAdapterSink.close ', - r'^#30 _LineSplitterSink.close ', - r'^#31 _SinkTransformerStreamSubscription._handleDone ', - r'^#32 _RootZone.runGuarded ', - r'^#33 _BufferingStreamSubscription._sendDone.sendDone ', - r'^#34 _BufferingStreamSubscription._sendDone ', - r'^#35 _DelayedDone.perform ', - r'^#36 _StreamImplEvents.handleNext ', - r'^#37 _PendingEvents.schedule.<anonymous closure> ', - r'^#38 _microtaskLoop ', - r'^#39 _startMicrotaskLoop ', - r'^#40 _runPendingImmediateCallback ', - r'^#41 _RawReceivePortImpl._handleMessage ', + r'^#16 doTestAwaitThen ', + r'^#17 _asyncErrorWrapperHelper.errorCallback ', + r'^#18 _RootZone.runBinary ', + r'^#19 _FutureListener.handleError ', + r'^#20 Future._propagateToListeners.handleError ', + r'^#21 Future._propagateToListeners ', + r'^#22 Future._completeError ', + r'^#23 _completeOnAsyncError ', + r'^#24 noYields ', + r'^#25 _asyncErrorWrapperHelper.errorCallback ', + r'^#26 _RootZone.runBinary ', + r'^#27 _FutureListener.handleError ', + r'^#28 Future._propagateToListeners.handleError ', + r'^#29 Future._propagateToListeners ', + r'^#30 Future._completeError ', + r'^#31 _completeOnAsyncError ', + r'^#32 noYields2 ', + r'^#33 _asyncErrorWrapperHelper.errorCallback ', + r'^#34 _RootZone.runBinary ', + r'^#35 _FutureListener.handleError ', + r'^#36 Future._propagateToListeners.handleError ', + r'^#37 Future._propagateToListeners ', + r'^#38 Future._completeError ', + r'^#39 Future._asyncCompleteError.<anonymous closure> ', + r'^#40 _microtaskLoop ', + r'^#41 _startMicrotaskLoop ', + r'^#42 _runPendingImmediateCallback ', + r'^#43 _RawReceivePortImpl._handleMessage ', ], debugInfoFilename); @@ -641,497 +642,329 @@ await doTestAwaitCatchError( futureSyncWhenComplete, expected, debugInfoFilename); } - - { - final expected = const <String>[ - r'^#0 throwSync \(.*/utils.dart:16(:3)?\)$', - r'^#1 futureThen.<anonymous closure> \(.*/utils.dart:187(:5)?\)$', - r'^#2 _RootZone.runUnary ', - r'^#3 _FutureListener.handleValue ', - r'^#4 Future._propagateToListeners.handleValueCallback ', - r'^#5 Future._propagateToListeners ', - r'^#6 Future._completeWithValue ', - r'^#7 Future._asyncCompleteWithValue.<anonymous closure> ', - r'^#8 _microtaskLoop ', - r'^#9 _startMicrotaskLoop ', - r'^#10 _runPendingImmediateCallback ', - r'^#11 _RawReceivePortImpl._handleMessage ', - ]; - await doTestAwait(futureThen, expected, debugInfoFilename); - await doTestAwaitThen(futureThen, expected, debugInfoFilename); - await doTestAwaitCatchError(futureThen, expected, debugInfoFilename); - } } // For: --lazy-async-stacks Future<void> doTestsLazy([String? debugInfoFilename]) async { - // allYield - { - final allYieldExpected = const <String>[ - r'^#0 throwSync \(.*/utils.dart:16(:3)?\)$', - r'^#1 allYield3 \(.*/utils.dart:39(:3)?\)$', - r'^<asynchronous suspension>$', - r'^#2 allYield2 \(.*/utils.dart:34(:3)?\)$', - r'^<asynchronous suspension>$', - r'^#3 allYield \(.*/utils.dart:29(:3)?\)$', - r'^<asynchronous suspension>$', - ]; - await doTestAwait( - allYield, - allYieldExpected + - const <String>[ - r'^#4 doTestAwait ', - r'^<asynchronous suspension>$', - r'^#5 doTestsLazy ', - r'^<asynchronous suspension>$', - r'^#6 main ', - r'^<asynchronous suspension>$', - ], - debugInfoFilename); - await doTestAwaitThen( - allYield, - allYieldExpected + - const <String>[ - r'^#4 doTestAwaitThen ', - r'^<asynchronous suspension>$', - r'^#5 doTestsLazy ', - r'^<asynchronous suspension>$', - r'^#6 main ', - r'^<asynchronous suspension>$', - ], - debugInfoFilename); - await doTestAwaitCatchError( - allYield, - allYieldExpected + - const <String>[ - r'^#4 doTestAwaitCatchError ', - r'^<asynchronous suspension>$', - r'^#5 doTestsLazy ', - r'^<asynchronous suspension>$', - r'^#6 main ', - r'^<asynchronous suspension>$', - ], - debugInfoFilename); - } + final allYieldExpected = const <String>[ + r'^#0 throwSync \(.*/utils.dart:16(:3)?\)$', + r'^#1 allYield3 \(.*/utils.dart:39(:3)?\)$', + r'^<asynchronous suspension>$', + r'^#2 allYield2 \(.*/utils.dart:34(:3)?\)$', + r'^<asynchronous suspension>$', + r'^#3 allYield \(.*/utils.dart:29(:3)?\)$', + r'^<asynchronous suspension>$', + ]; + await doTestAwait( + allYield, + allYieldExpected + + const <String>[ + r'^#4 doTestAwait ', + r'^<asynchronous suspension>$', + r'^#5 doTestsLazy ', + r'^<asynchronous suspension>$', + r'^#6 main ', + r'^<asynchronous suspension>$', + ], + debugInfoFilename); + await doTestAwaitThen( + allYield, + allYieldExpected + + const <String>[ + r'^#4 doTestAwaitThen.<anonymous closure> ', + r'^<asynchronous suspension>$', + ], + debugInfoFilename); + await doTestAwaitCatchError(allYield, allYieldExpected, debugInfoFilename); - // noYields - { - final noYieldsExpected = const <String>[ - r'^#0 throwSync \(.*/utils.dart:16(:3)?\)$', - r'^#1 noYields3 \(.*/utils.dart:54(:3)?\)$', - r'^#2 noYields2 \(.*/utils.dart:50(:9)?\)$', - r'^#3 noYields \(.*/utils.dart:46(:9)?\)$', - ]; - await doTestAwait( - noYields, - noYieldsExpected + - const <String>[ - r'^#4 doTestAwait ', - r'^#5 doTestsLazy ', - r'^<asynchronous suspension>$', - r'^#6 main ', - r'^<asynchronous suspension>$', - ], - debugInfoFilename); - await doTestAwaitThen( - noYields, - noYieldsExpected + - const <String>[ - r'^#4 doTestAwaitThen ', - r'^#5 doTestsLazy ', - r'^<asynchronous suspension>$', - r'^#6 main ', - r'^<asynchronous suspension>$', - ], - debugInfoFilename); - await doTestAwaitCatchError( - noYields, - noYieldsExpected + - const <String>[ - r'^#4 doTestAwaitCatchError ', - r'^#5 doTestsLazy ', - r'^<asynchronous suspension>$', - r'^#6 main ', - r'^<asynchronous suspension>$', - ], - debugInfoFilename); - } + final noYieldsExpected = const <String>[ + r'^#0 throwSync \(.*/utils.dart:16(:3)?\)$', + r'^#1 noYields3 \(.*/utils.dart:54(:3)?\)$', + r'^#2 noYields2 \(.*/utils.dart:50(:9)?\)$', + r'^#3 noYields \(.*/utils.dart:46(:9)?\)$', + ]; + await doTestAwait( + noYields, + noYieldsExpected + + const <String>[ + r'^#4 doTestAwait ', + r'^#5 doTestsLazy ', + r'^<asynchronous suspension>$', + r'^#6 main ', + r'^<asynchronous suspension>$', + ], + debugInfoFilename); + await doTestAwaitThen( + noYields, + noYieldsExpected + + const <String>[ + r'^#4 doTestAwaitThen ', + r'^#5 doTestsLazy ', + r'^<asynchronous suspension>$', + r'^#6 main ', + r'^<asynchronous suspension>$', + ], + debugInfoFilename); + await doTestAwaitCatchError( + noYields, + noYieldsExpected + + const <String>[ + r'^#4 doTestAwaitCatchError ', + r'^#5 doTestsLazy ', + r'^<asynchronous suspension>$', + r'^#6 main ', + r'^<asynchronous suspension>$', + ], + debugInfoFilename); - // mixedYields - { - final mixedYieldsExpected = const <String>[ - r'^#0 throwAsync \(.*/utils.dart:21(:3)?\)$', - r'^<asynchronous suspension>$', - r'^#1 mixedYields2 \(.*/utils.dart:66(:3)?\)$', - r'^<asynchronous suspension>$', - r'^#2 mixedYields \(.*/utils.dart:61(:3)?\)$', - r'^<asynchronous suspension>$', - ]; - await doTestAwait( - mixedYields, - mixedYieldsExpected + - const <String>[ - r'^#3 doTestAwait ', - r'^<asynchronous suspension>$', - r'^#4 doTestsLazy ', - r'^<asynchronous suspension>$', - r'^#5 main ', - r'^<asynchronous suspension>$', - ], - debugInfoFilename); - await doTestAwaitThen( - mixedYields, - mixedYieldsExpected + - const <String>[ - r'^#3 doTestAwaitThen ', - r'^<asynchronous suspension>$', - r'^#4 doTestsLazy ', - r'^<asynchronous suspension>$', - r'^#5 main ', - r'^<asynchronous suspension>$', - ], - debugInfoFilename); - await doTestAwaitCatchError( - mixedYields, - mixedYieldsExpected + - const <String>[ - r'^#3 doTestAwaitCatchError ', - r'^<asynchronous suspension>$', - r'^#4 doTestsLazy ', - r'^<asynchronous suspension>$', - r'^#5 main ', - r'^<asynchronous suspension>$', - ], - debugInfoFilename); - } + final mixedYieldsExpected = const <String>[ + r'^#0 throwAsync \(.*/utils.dart:21(:3)?\)$', + r'^<asynchronous suspension>$', + r'^#1 mixedYields2 \(.*/utils.dart:66(:3)?\)$', + r'^<asynchronous suspension>$', + r'^#2 mixedYields \(.*/utils.dart:61(:3)?\)$', + r'^<asynchronous suspension>$', + ]; + await doTestAwait( + mixedYields, + mixedYieldsExpected + + const <String>[ + r'^#3 doTestAwait ', + r'^<asynchronous suspension>$', + r'^#4 doTestsLazy ', + r'^<asynchronous suspension>$', + r'^#5 main ', + r'^<asynchronous suspension>$', + ], + debugInfoFilename); + await doTestAwaitThen( + mixedYields, + mixedYieldsExpected + + const <String>[ + r'^#3 doTestAwaitThen.<anonymous closure> ', + r'^<asynchronous suspension>$', + ], + debugInfoFilename); + await doTestAwaitCatchError( + mixedYields, mixedYieldsExpected, debugInfoFilename); - // syncSuffix - { - final syncSuffixExpected = const <String>[ - r'^#0 throwAsync \(.*/utils.dart:21(:3)?\)$', - r'^<asynchronous suspension>$', - r'^#1 syncSuffix2 \(.*/utils.dart:82(:3)?\)$', - r'^<asynchronous suspension>$', - r'^#2 syncSuffix \(.*/utils.dart:77(:3)?\)$', - r'^<asynchronous suspension>$', - ]; - await doTestAwait( - syncSuffix, - syncSuffixExpected + - const <String>[ - r'^#3 doTestAwait ', - r'^<asynchronous suspension>$', - r'^#4 doTestsLazy ', - r'^<asynchronous suspension>$', - r'^#5 main ', - r'^<asynchronous suspension>$', - ], - debugInfoFilename); - await doTestAwaitThen( - syncSuffix, - syncSuffixExpected + - const <String>[ - r'^#3 doTestAwaitThen ', - r'^<asynchronous suspension>$', - r'^#4 doTestsLazy ', - r'^<asynchronous suspension>$', - r'^#5 main ', - r'^<asynchronous suspension>$', - ], - debugInfoFilename); - await doTestAwaitCatchError( - syncSuffix, - syncSuffixExpected + - const <String>[ - r'^#3 doTestAwaitCatchError ', - r'^<asynchronous suspension>$', - r'^#4 doTestsLazy ', - r'^<asynchronous suspension>$', - r'^#5 main ', - r'^<asynchronous suspension>$', - ], - debugInfoFilename); - } + final syncSuffixExpected = const <String>[ + r'^#0 throwAsync \(.*/utils.dart:21(:3)?\)$', + r'^<asynchronous suspension>$', + r'^#1 syncSuffix2 \(.*/utils.dart:82(:3)?\)$', + r'^<asynchronous suspension>$', + r'^#2 syncSuffix \(.*/utils.dart:77(:3)?\)$', + r'^<asynchronous suspension>$', + ]; + await doTestAwait( + syncSuffix, + syncSuffixExpected + + const <String>[ + r'^#3 doTestAwait ', + r'^<asynchronous suspension>$', + r'^#4 doTestsLazy ', + r'^<asynchronous suspension>$', + r'^#5 main ', + r'^<asynchronous suspension>$', + ], + debugInfoFilename); + await doTestAwaitThen( + syncSuffix, + syncSuffixExpected + + const <String>[ + r'^#3 doTestAwaitThen.<anonymous closure> ', + r'^<asynchronous suspension>$', + ], + debugInfoFilename); + await doTestAwaitCatchError( + syncSuffix, syncSuffixExpected, debugInfoFilename); - // nonAsyncNoStack - { - final nonAsyncNoStackExpected = const <String>[ - r'^#0 throwAsync \(.*/utils.dart:21(:3)?\)$', - r'^<asynchronous suspension>$', - r'^#1 nonAsyncNoStack1 \(.*/utils.dart:95(:36)?\)$', - r'^<asynchronous suspension>$', - r'^#2 nonAsyncNoStack \(.*/utils.dart:93(:35)?\)$', - r'^<asynchronous suspension>$', - ]; - await doTestAwait( - nonAsyncNoStack, - nonAsyncNoStackExpected + - const <String>[ - r'^#3 doTestAwait ', - r'^<asynchronous suspension>$', - r'^#4 doTestsLazy ', - r'^<asynchronous suspension>$', - r'^#5 main ', - r'^<asynchronous suspension>$', - ], - debugInfoFilename); - await doTestAwaitThen( - nonAsyncNoStack, - nonAsyncNoStackExpected + - const <String>[ - r'^#3 doTestAwaitThen ', - r'^<asynchronous suspension>$', - r'^#4 doTestsLazy ', - r'^<asynchronous suspension>$', - r'^#5 main ', - r'^<asynchronous suspension>$', - ], - debugInfoFilename); - await doTestAwaitCatchError( - nonAsyncNoStack, - nonAsyncNoStackExpected + - const <String>[ - r'^#3 doTestAwaitCatchError ', - r'^<asynchronous suspension>$', - r'^#4 doTestsLazy ', - r'^<asynchronous suspension>$', - r'^#5 main ', - r'^<asynchronous suspension>$', - ], - debugInfoFilename); - } + final nonAsyncNoStackExpected = const <String>[ + r'^#0 throwAsync \(.*/utils.dart:21(:3)?\)$', + r'^<asynchronous suspension>$', + r'^#1 nonAsyncNoStack1 \(.*/utils.dart:95(:36)?\)$', + r'^<asynchronous suspension>$', + r'^#2 nonAsyncNoStack \(.*/utils.dart:93(:35)?\)$', + r'^<asynchronous suspension>$', + ]; + await doTestAwait( + nonAsyncNoStack, + nonAsyncNoStackExpected + + const <String>[ + r'^#3 doTestAwait ', + r'^<asynchronous suspension>$', + r'^#4 doTestsLazy ', + r'^<asynchronous suspension>$', + r'^#5 main ', + r'^<asynchronous suspension>$', + ], + debugInfoFilename); + await doTestAwaitThen( + nonAsyncNoStack, + nonAsyncNoStackExpected + + const <String>[ + r'^#3 doTestAwaitThen.<anonymous closure> ', + r'^<asynchronous suspension>$', + ], + debugInfoFilename); + await doTestAwaitCatchError( + nonAsyncNoStack, nonAsyncNoStackExpected, debugInfoFilename); - // awaitEveryAsyncStarThrowSync - { - final asyncStarThrowSyncExpected = const <String>[ - r'^#0 throwSync \(.+/utils.dart:16(:3)?\)$', - r'^#1 asyncStarThrowSync \(.+/utils.dart:112(:11)?\)$', - r'^<asynchronous suspension>$', - r'^#2 awaitEveryAsyncStarThrowSync \(.+/utils.dart:104(:3)?\)$', - r'^<asynchronous suspension>$', - ]; - await doTestAwait( - awaitEveryAsyncStarThrowSync, - asyncStarThrowSyncExpected + - const <String>[ - r'^#3 doTestAwait ', - r'^<asynchronous suspension>$', - r'^#4 doTestsLazy ', - r'^<asynchronous suspension>$', - r'^#5 main ', - r'^<asynchronous suspension>$', - ], - debugInfoFilename); - await doTestAwaitThen( - awaitEveryAsyncStarThrowSync, - asyncStarThrowSyncExpected + - const <String>[ - r'^#3 doTestAwaitThen ', - r'^<asynchronous suspension>$', - r'^#4 doTestsLazy ', - r'^<asynchronous suspension>$', - r'^#5 main ', - r'^<asynchronous suspension>$', - ], - debugInfoFilename); - await doTestAwaitCatchError( - awaitEveryAsyncStarThrowSync, - asyncStarThrowSyncExpected + - const <String>[ - r'^#3 doTestAwaitCatchError ', - r'^<asynchronous suspension>$', - r'^#4 doTestsLazy ', - r'^<asynchronous suspension>$', - r'^#5 main ', - r'^<asynchronous suspension>$', - ], - debugInfoFilename); - } + final asyncStarThrowSyncExpected = const <String>[ + r'^#0 throwSync \(.+/utils.dart:16(:3)?\)$', + r'^#1 asyncStarThrowSync \(.+/utils.dart:112(:11)?\)$', + r'^<asynchronous suspension>$', + r'^#2 awaitEveryAsyncStarThrowSync \(.+/utils.dart:104(:3)?\)$', + r'^<asynchronous suspension>$', + ]; + await doTestAwait( + awaitEveryAsyncStarThrowSync, + asyncStarThrowSyncExpected + + const <String>[ + r'^#3 doTestAwait ', + r'^<asynchronous suspension>$', + r'^#4 doTestsLazy ', + r'^<asynchronous suspension>$', + r'^#5 main ', + r'^<asynchronous suspension>$', + ], + debugInfoFilename); + await doTestAwaitThen( + awaitEveryAsyncStarThrowSync, + asyncStarThrowSyncExpected + + const <String>[ + r'^#3 doTestAwaitThen.<anonymous closure> ', + r'^<asynchronous suspension>$', + ], + debugInfoFilename); + await doTestAwaitCatchError(awaitEveryAsyncStarThrowSync, + asyncStarThrowSyncExpected, debugInfoFilename); - // awaitEveryAsyncStarThrowAsync - { - final asyncStarThrowAsyncExpected = const <String>[ - r'^#0 throwAsync \(.*/utils.dart:21(:3)?\)$', - r'^<asynchronous suspension>$', - r'^#1 asyncStarThrowAsync \(.*/utils.dart:126(:5)?\)$', - r'^<asynchronous suspension>$', - r'^#2 awaitEveryAsyncStarThrowAsync \(.+/utils.dart:117(:3)?\)$', - r'^<asynchronous suspension>$', - ]; - await doTestAwait( - awaitEveryAsyncStarThrowAsync, - asyncStarThrowAsyncExpected + - const <String>[ - r'^#3 doTestAwait ', - r'^<asynchronous suspension>$', - r'^#4 doTestsLazy ', - r'^<asynchronous suspension>$', - r'^#5 main ', - r'^<asynchronous suspension>$', - ], - debugInfoFilename); - await doTestAwaitThen( - awaitEveryAsyncStarThrowAsync, - asyncStarThrowAsyncExpected + - const <String>[ - r'^#3 doTestAwaitThen ', - r'^<asynchronous suspension>$', - r'^#4 doTestsLazy ', - r'^<asynchronous suspension>$', - r'^#5 main ', - r'^<asynchronous suspension>$', - ], - debugInfoFilename); - await doTestAwaitCatchError( - awaitEveryAsyncStarThrowAsync, - asyncStarThrowAsyncExpected + - const <String>[ - r'^#3 doTestAwaitCatchError ', - r'^<asynchronous suspension>$', - r'^#4 doTestsLazy ', - r'^<asynchronous suspension>$', - r'^#5 main ', - r'^<asynchronous suspension>$', - ], - debugInfoFilename); - } + final asyncStarThrowAsyncExpected = const <String>[ + r'^#0 throwAsync \(.*/utils.dart:21(:3)?\)$', + r'^<asynchronous suspension>$', + r'^#1 asyncStarThrowAsync \(.*/utils.dart:126(:5)?\)$', + r'^<asynchronous suspension>$', + r'^#2 awaitEveryAsyncStarThrowAsync \(.+/utils.dart:117(:3)?\)$', + r'^<asynchronous suspension>$', + ]; + await doTestAwait( + awaitEveryAsyncStarThrowAsync, + asyncStarThrowAsyncExpected + + const <String>[ + r'^#3 doTestAwait ', + r'^<asynchronous suspension>$', + r'^#4 doTestsLazy ', + r'^<asynchronous suspension>$', + r'^#5 main ', + r'^<asynchronous suspension>$', + ], + debugInfoFilename); + await doTestAwaitThen( + awaitEveryAsyncStarThrowAsync, + asyncStarThrowAsyncExpected + + const <String>[ + r'^#3 doTestAwaitThen.<anonymous closure> ', + r'^<asynchronous suspension>$', + ], + debugInfoFilename); + await doTestAwaitCatchError(awaitEveryAsyncStarThrowAsync, + asyncStarThrowAsyncExpected, debugInfoFilename); - // listenAsyncStarThrowAsync - { - final listenAsyncStartExpected = const <String>[ - r'^#0 throwAsync \(.*/utils.dart:21(:3)?\)$', - r'^<asynchronous suspension>$', - r'^#1 asyncStarThrowAsync \(.*/utils.dart:126(:5)?\)$', - r'^<asynchronous suspension>$', - r'^#2 listenAsyncStarThrowAsync.<anonymous closure> \(.+/utils.dart(:0)?\)$', - r'^<asynchronous suspension>$', - ]; - await doTestAwait( - listenAsyncStarThrowAsync, listenAsyncStartExpected, debugInfoFilename); - await doTestAwaitThen( - listenAsyncStarThrowAsync, listenAsyncStartExpected, debugInfoFilename); - await doTestAwaitCatchError( - listenAsyncStarThrowAsync, listenAsyncStartExpected, debugInfoFilename); - } + final listenAsyncStartExpected = const <String>[ + r'^#0 throwAsync \(.*/utils.dart:21(:3)?\)$', + r'^<asynchronous suspension>$', + r'^#1 asyncStarThrowAsync \(.*/utils.dart:126(:5)?\)$', + r'^<asynchronous suspension>$', + r'^#2 listenAsyncStarThrowAsync.<anonymous closure> \(.+/utils.dart(:0)?\)$', + r'^<asynchronous suspension>$', + ]; + await doTestAwait( + listenAsyncStarThrowAsync, listenAsyncStartExpected, debugInfoFilename); + await doTestAwaitThen( + listenAsyncStarThrowAsync, listenAsyncStartExpected, debugInfoFilename); + await doTestAwaitCatchError( + listenAsyncStarThrowAsync, listenAsyncStartExpected, debugInfoFilename); - // customErrorZone - { - final customErrorZoneExpected = const <String>[ - r'#0 throwSync \(.*/utils.dart:16(:3)?\)$', - r'#1 allYield3 \(.*/utils.dart:39(:3)?\)$', - r'<asynchronous suspension>$', - r'#2 allYield2 \(.*/utils.dart:34(:3)?\)$', - r'<asynchronous suspension>$', - r'#3 allYield \(.*/utils.dart:29(:3)?\)$', - r'<asynchronous suspension>$', - r'#4 customErrorZone.<anonymous closure> \(.*/utils.dart:144(:5)?\)$', - r'<asynchronous suspension>$', - ]; - await doTestAwait( - customErrorZone, customErrorZoneExpected, debugInfoFilename); - await doTestAwaitThen( - customErrorZone, customErrorZoneExpected, debugInfoFilename); - await doTestAwaitCatchError( - customErrorZone, customErrorZoneExpected, debugInfoFilename); - } + final customErrorZoneExpected = const <String>[ + r'#0 throwSync \(.*/utils.dart:16(:3)?\)$', + r'#1 allYield3 \(.*/utils.dart:39(:3)?\)$', + r'<asynchronous suspension>$', + r'#2 allYield2 \(.*/utils.dart:34(:3)?\)$', + r'<asynchronous suspension>$', + r'#3 allYield \(.*/utils.dart:29(:3)?\)$', + r'<asynchronous suspension>$', + r'#4 customErrorZone.<anonymous closure> \(.*/utils.dart:144(:5)?\)$', + r'<asynchronous suspension>$', + ]; + await doTestAwait( + customErrorZone, customErrorZoneExpected, debugInfoFilename); + await doTestAwaitThen( + customErrorZone, customErrorZoneExpected, debugInfoFilename); + await doTestAwaitCatchError( + customErrorZone, customErrorZoneExpected, debugInfoFilename); - // awaitTimeout - { - final awaitTimeoutExpected = const <String>[ - r'^#0 throwAsync \(.*/utils.dart:21(:3)?\)$', - r'^<asynchronous suspension>$', - r'^#1 Future.timeout.<anonymous closure> \(dart:async/future_impl.dart', - r'^<asynchronous suspension>$', - r'^#2 awaitTimeout ', - r'^<asynchronous suspension>$', - ]; - await doTestAwait( - awaitTimeout, - awaitTimeoutExpected + - const <String>[ - r'^#3 doTestAwait ', - r'^<asynchronous suspension>$', - r'^#4 doTestsLazy ', - r'^<asynchronous suspension>$', - r'^#5 main ', - r'^<asynchronous suspension>$', - ], - debugInfoFilename); - await doTestAwaitThen( - awaitTimeout, - awaitTimeoutExpected + - const <String>[ - r'^#3 doTestAwaitThen ', - r'^<asynchronous suspension>$', - r'^#4 doTestsLazy ', - r'^<asynchronous suspension>$', - r'^#5 main ', - r'^<asynchronous suspension>$', - ], - debugInfoFilename); - await doTestAwaitCatchError( - awaitTimeout, - awaitTimeoutExpected + - const <String>[ - r'^#3 doTestAwaitCatchError ', - r'^<asynchronous suspension>$', - r'^#4 doTestsLazy ', - r'^<asynchronous suspension>$', - r'^#5 main ', - r'^<asynchronous suspension>$', - ], - debugInfoFilename); - } + final awaitTimeoutExpected = const <String>[ + r'^#0 throwAsync \(.*/utils.dart:21(:3)?\)$', + r'^<asynchronous suspension>$', + r'^#1 Future.timeout.<anonymous closure> \(dart:async/future_impl.dart', + r'^<asynchronous suspension>$', + r'^#2 awaitTimeout ', + r'^<asynchronous suspension>$', + ]; + await doTestAwait( + awaitTimeout, + awaitTimeoutExpected + + const <String>[ + r'^#3 doTestAwait ', + r'^<asynchronous suspension>$', + r'^#4 doTestsLazy ', + r'^<asynchronous suspension>$', + r'^#5 main ', + r'^<asynchronous suspension>$', + ], + debugInfoFilename); + await doTestAwaitThen( + awaitTimeout, + awaitTimeoutExpected + + const <String>[ + r'^#3 doTestAwaitThen.<anonymous closure> ', + r'^<asynchronous suspension>$', + ], + debugInfoFilename); + await doTestAwaitCatchError( + awaitTimeout, awaitTimeoutExpected, debugInfoFilename); - // awaitWait - { - final awaitWaitExpected = const <String>[ - r'^#0 throwAsync \(.*/utils.dart:21(:3)?\)$', - r'^<asynchronous suspension>$', - r'^#1 Future.wait.<anonymous closure> \(dart:async/future.dart', - r'^<asynchronous suspension>$', - r'^#2 awaitWait ', - r'^<asynchronous suspension>$', - ]; - await doTestAwait( - awaitWait, - awaitWaitExpected + - const <String>[ - r'^#3 doTestAwait ', - r'^<asynchronous suspension>$', - r'^#4 doTestsLazy ', - r'^<asynchronous suspension>$', - r'^#5 main ', - r'^<asynchronous suspension>$', - ], - debugInfoFilename); - await doTestAwaitThen( - awaitWait, - awaitWaitExpected + - const <String>[ - r'^#3 doTestAwaitThen ', - r'^<asynchronous suspension>$', - r'^#4 doTestsLazy ', - r'^<asynchronous suspension>$', - r'^#5 main ', - r'^<asynchronous suspension>$', - ], - debugInfoFilename); - await doTestAwaitCatchError( - awaitWait, - awaitWaitExpected + - const <String>[ - r'^#3 doTestAwaitCatchError ', - r'^<asynchronous suspension>$', - r'^#4 doTestsLazy ', - r'^<asynchronous suspension>$', - r'^#5 main ', - r'^<asynchronous suspension>$', - ], - debugInfoFilename); - } + final awaitWaitExpected = const <String>[ + r'^#0 throwAsync \(.*/utils.dart:21(:3)?\)$', + r'^<asynchronous suspension>$', + r'^#1 Future.wait.<anonymous closure> \(dart:async/future.dart', + r'^<asynchronous suspension>$', + r'^#2 awaitWait ', + r'^<asynchronous suspension>$', + ]; + await doTestAwait( + awaitWait, + awaitWaitExpected + + const <String>[ + r'^#3 doTestAwait ', + r'^<asynchronous suspension>$', + r'^#4 doTestsLazy ', + r'^<asynchronous suspension>$', + r'^#5 main ', + r'^<asynchronous suspension>$', + ], + debugInfoFilename); + await doTestAwaitThen( + awaitWait, + awaitWaitExpected + + const <String>[ + r'^#3 doTestAwaitThen.<anonymous closure> ', + r'^<asynchronous suspension>$', + ], + debugInfoFilename); + await doTestAwaitCatchError(awaitWait, awaitWaitExpected, debugInfoFilename); - // futureSyncWhenComplete { final expected = const <String>[ r'^#0 throwAsync \(.*/utils.dart:21(:3)?\)$', @@ -1153,70 +986,11 @@ futureSyncWhenComplete, expected + const <String>[ - r'^#1 doTestAwaitThen ', - r'^<asynchronous suspension>$', - r'^#2 doTestsLazy ', - r'^<asynchronous suspension>$', - r'^#3 main ', + r'^#1 doTestAwaitThen.<anonymous closure> ', r'^<asynchronous suspension>$', ], debugInfoFilename); await doTestAwaitCatchError( - futureSyncWhenComplete, - expected + - const <String>[ - r'^#1 doTestAwaitCatchError ', - r'^<asynchronous suspension>$', - r'^#2 doTestsLazy ', - r'^<asynchronous suspension>$', - r'^#3 main ', - r'^<asynchronous suspension>$', - ], - debugInfoFilename); - } - - // futureThen - { - final expected = const <String>[ - r'^#0 throwSync \(.*/utils.dart:16(:3)?\)$', - r'^#1 futureThen.<anonymous closure> ', - r'^<asynchronous suspension>$', - ]; - await doTestAwait( - futureThen, - expected + - const <String>[ - r'^#2 doTestAwait ', - r'^<asynchronous suspension>$', - r'^#3 doTestsLazy ', - r'^<asynchronous suspension>$', - r'^#4 main ', - r'^<asynchronous suspension>$', - ], - debugInfoFilename); - await doTestAwaitThen( - futureThen, - expected + - const <String>[ - r'^#2 doTestAwaitThen ', - r'^<asynchronous suspension>$', - r'^#3 doTestsLazy ', - r'^<asynchronous suspension>$', - r'^#4 main ', - r'^<asynchronous suspension>$', - ], - debugInfoFilename); - await doTestAwaitCatchError( - futureThen, - expected + - const <String>[ - r'^#2 doTestAwaitCatchError ', - r'^<asynchronous suspension>$', - r'^#3 doTestsLazy ', - r'^<asynchronous suspension>$', - r'^#4 main ', - r'^<asynchronous suspension>$', - ], - debugInfoFilename); + futureSyncWhenComplete, expected, debugInfoFilename); } }
diff --git a/runtime/tests/vm/dart_2/causal_stacks/utils.dart b/runtime/tests/vm/dart_2/causal_stacks/utils.dart index b7c4e02..192984f 100644 --- a/runtime/tests/vm/dart_2/causal_stacks/utils.dart +++ b/runtime/tests/vm/dart_2/causal_stacks/utils.dart
@@ -178,22 +178,12 @@ return Future.sync(throwAsync).whenComplete(() => 'nop'); } -// ---- -// Scenario: Future.then: -// ---- - -Future futureThen() { - return Future.value(0).then((value) { - throwSync(); - }); -} - // Helpers: // We want lines that either start with a frame index or an async gap marker. final _lineRE = RegExp(r'^(?:#(?<number>\d+)|<asynchronous suspension>)'); -Future<void> assertStack(List<String> expects, StackTrace stackTrace, +void assertStack(List<String> expects, StackTrace stackTrace, [String debugInfoFilename]) async { final original = await Stream.value(stackTrace.toString()) .transform(const LineSplitter()) @@ -263,7 +253,7 @@ await f(); Expect.fail('No exception thrown!'); } on String catch (e, s) { - return assertStack(expectedStack, s, debugInfoFilename); + assertStack(expectedStack, s, debugInfoFilename); } } @@ -277,7 +267,7 @@ await f().then((e) => Expect.fail('No exception thrown!')); Expect.fail('No exception thrown!'); } on String catch (e, s) { - return assertStack(expectedStack, s, debugInfoFilename); + assertStack(expectedStack, s, debugInfoFilename); } } @@ -288,7 +278,7 @@ await f().catchError((e, s) { stackTrace = s; }); - return assertStack(expectedStack, stackTrace, debugInfoFilename); + assertStack(expectedStack, stackTrace, debugInfoFilename); } // ---- @@ -337,32 +327,39 @@ r'^#13 Future._propagateToListeners ', r'^#14 Future._completeWithValue ', r'^#15 _completeOnAsyncReturn ', - r'^#16 assertStack ', + r'^#16 doTestAwaitCatchError ', r'^#17 _RootZone.runUnary ', r'^#18 _FutureListener.handleValue ', r'^#19 Future._propagateToListeners.handleValueCallback ', r'^#20 Future._propagateToListeners ', - r'^#21 Future._complete ', - r'^#22 Stream.toList.<anonymous closure> ', - r'^#23 _RootZone.runGuarded ', - r'^#24 _BufferingStreamSubscription._sendDone.sendDone ', - r'^#25 _BufferingStreamSubscription._sendDone ', - r'^#26 _BufferingStreamSubscription._close ', - r'^#27 _SinkTransformerStreamSubscription._close ', - r'^#28 _EventSinkWrapper.close ', - r'^#29 _StringAdapterSink.close ', - r'^#30 _LineSplitterSink.close ', - r'^#31 _SinkTransformerStreamSubscription._handleDone ', - r'^#32 _RootZone.runGuarded ', - r'^#33 _BufferingStreamSubscription._sendDone.sendDone ', - r'^#34 _BufferingStreamSubscription._sendDone ', - r'^#35 _DelayedDone.perform ', - r'^#36 _StreamImplEvents.handleNext ', - r'^#37 _PendingEvents.schedule.<anonymous closure> ', - r'^#38 _microtaskLoop ', - r'^#39 _startMicrotaskLoop ', - r'^#40 _runPendingImmediateCallback ', - r'^#41 _RawReceivePortImpl._handleMessage ', + r'^#21 Future._completeError ', + r'^#22 _completeOnAsyncError ', + r'^#23 allYield ', + r'^#24 _asyncErrorWrapperHelper.errorCallback ', + r'^#25 _RootZone.runBinary ', + r'^#26 _FutureListener.handleError ', + r'^#27 Future._propagateToListeners.handleError ', + r'^#28 Future._propagateToListeners ', + r'^#29 Future._completeError ', + r'^#30 _completeOnAsyncError ', + r'^#31 allYield2 ', + r'^#32 _asyncErrorWrapperHelper.errorCallback ', + r'^#33 _RootZone.runBinary ', + r'^#34 _FutureListener.handleError ', + r'^#35 Future._propagateToListeners.handleError ', + r'^#36 Future._propagateToListeners ', + r'^#37 Future._completeError ', + r'^#38 _completeOnAsyncError ', + r'^#39 allYield3 ', + r'^#40 _RootZone.runUnary ', + r'^#41 _FutureListener.handleValue ', + r'^#42 Future._propagateToListeners.handleValueCallback ', + r'^#43 Future._propagateToListeners ', + r'^#44 Future._addListener.<anonymous closure> ', + r'^#45 _microtaskLoop ', + r'^#46 _startMicrotaskLoop ', + r'^#47 _runPendingImmediateCallback ', + r'^#48 _RawReceivePortImpl._handleMessage ', ], debugInfoFilename); await doTestAwaitThen( @@ -378,32 +375,34 @@ r'^#13 Future._propagateToListeners ', r'^#14 Future._completeWithValue ', r'^#15 _completeOnAsyncReturn ', - r'^#16 assertStack ', - r'^#17 _RootZone.runUnary ', - r'^#18 _FutureListener.handleValue ', - r'^#19 Future._propagateToListeners.handleValueCallback ', - r'^#20 Future._propagateToListeners ', - r'^#21 Future._complete ', - r'^#22 Stream.toList.<anonymous closure> ', - r'^#23 _RootZone.runGuarded ', - r'^#24 _BufferingStreamSubscription._sendDone.sendDone ', - r'^#25 _BufferingStreamSubscription._sendDone ', - r'^#26 _BufferingStreamSubscription._close ', - r'^#27 _SinkTransformerStreamSubscription._close ', - r'^#28 _EventSinkWrapper.close ', - r'^#29 _StringAdapterSink.close ', - r'^#30 _LineSplitterSink.close ', - r'^#31 _SinkTransformerStreamSubscription._handleDone ', - r'^#32 _RootZone.runGuarded ', - r'^#33 _BufferingStreamSubscription._sendDone.sendDone ', - r'^#34 _BufferingStreamSubscription._sendDone ', - r'^#35 _DelayedDone.perform ', - r'^#36 _StreamImplEvents.handleNext ', - r'^#37 _PendingEvents.schedule.<anonymous closure> ', - r'^#38 _microtaskLoop ', - r'^#39 _startMicrotaskLoop ', - r'^#40 _runPendingImmediateCallback ', - r'^#41 _RawReceivePortImpl._handleMessage ', + r'^#16 doTestAwait ', + r'^#17 _asyncErrorWrapperHelper.errorCallback ', + r'^#18 _RootZone.runBinary ', + r'^#19 _FutureListener.handleError ', + r'^#20 Future._propagateToListeners.handleError ', + r'^#21 Future._propagateToListeners ', + r'^#22 Future._completeError ', + r'^#23 _completeOnAsyncError ', + r'^#24 noYields ', + r'^#25 _asyncErrorWrapperHelper.errorCallback ', + r'^#26 _RootZone.runBinary ', + r'^#27 _FutureListener.handleError ', + r'^#28 Future._propagateToListeners.handleError ', + r'^#29 Future._propagateToListeners ', + r'^#30 Future._completeError ', + r'^#31 _completeOnAsyncError ', + r'^#32 noYields2 ', + r'^#33 _asyncErrorWrapperHelper.errorCallback ', + r'^#34 _RootZone.runBinary ', + r'^#35 _FutureListener.handleError ', + r'^#36 Future._propagateToListeners.handleError ', + r'^#37 Future._propagateToListeners ', + r'^#38 Future._completeError ', + r'^#39 Future._asyncCompleteError.<anonymous closure> ', + r'^#40 _microtaskLoop ', + r'^#41 _startMicrotaskLoop ', + r'^#42 _runPendingImmediateCallback ', + r'^#43 _RawReceivePortImpl._handleMessage ', ], debugInfoFilename); await doTestAwaitCatchError( @@ -419,32 +418,34 @@ r'^#13 Future._propagateToListeners ', r'^#14 Future._completeWithValue ', r'^#15 _completeOnAsyncReturn ', - r'^#16 assertStack ', - r'^#17 _RootZone.runUnary ', - r'^#18 _FutureListener.handleValue ', - r'^#19 Future._propagateToListeners.handleValueCallback ', - r'^#20 Future._propagateToListeners ', - r'^#21 Future._complete ', - r'^#22 Stream.toList.<anonymous closure> ', - r'^#23 _RootZone.runGuarded ', - r'^#24 _BufferingStreamSubscription._sendDone.sendDone ', - r'^#25 _BufferingStreamSubscription._sendDone ', - r'^#26 _BufferingStreamSubscription._close ', - r'^#27 _SinkTransformerStreamSubscription._close ', - r'^#28 _EventSinkWrapper.close ', - r'^#29 _StringAdapterSink.close ', - r'^#30 _LineSplitterSink.close ', - r'^#31 _SinkTransformerStreamSubscription._handleDone ', - r'^#32 _RootZone.runGuarded ', - r'^#33 _BufferingStreamSubscription._sendDone.sendDone ', - r'^#34 _BufferingStreamSubscription._sendDone ', - r'^#35 _DelayedDone.perform ', - r'^#36 _StreamImplEvents.handleNext ', - r'^#37 _PendingEvents.schedule.<anonymous closure> ', - r'^#38 _microtaskLoop ', - r'^#39 _startMicrotaskLoop ', - r'^#40 _runPendingImmediateCallback ', - r'^#41 _RawReceivePortImpl._handleMessage ', + r'^#16 doTestAwaitThen ', + r'^#17 _asyncErrorWrapperHelper.errorCallback ', + r'^#18 _RootZone.runBinary ', + r'^#19 _FutureListener.handleError ', + r'^#20 Future._propagateToListeners.handleError ', + r'^#21 Future._propagateToListeners ', + r'^#22 Future._completeError ', + r'^#23 _completeOnAsyncError ', + r'^#24 noYields ', + r'^#25 _asyncErrorWrapperHelper.errorCallback ', + r'^#26 _RootZone.runBinary ', + r'^#27 _FutureListener.handleError ', + r'^#28 Future._propagateToListeners.handleError ', + r'^#29 Future._propagateToListeners ', + r'^#30 Future._completeError ', + r'^#31 _completeOnAsyncError ', + r'^#32 noYields2 ', + r'^#33 _asyncErrorWrapperHelper.errorCallback ', + r'^#34 _RootZone.runBinary ', + r'^#35 _FutureListener.handleError ', + r'^#36 Future._propagateToListeners.handleError ', + r'^#37 Future._propagateToListeners ', + r'^#38 Future._completeError ', + r'^#39 Future._asyncCompleteError.<anonymous closure> ', + r'^#40 _microtaskLoop ', + r'^#41 _startMicrotaskLoop ', + r'^#42 _runPendingImmediateCallback ', + r'^#43 _RawReceivePortImpl._handleMessage ', ], debugInfoFilename); @@ -641,505 +642,337 @@ await doTestAwaitCatchError( futureSyncWhenComplete, expected, debugInfoFilename); } - - { - final expected = const <String>[ - r'^#0 throwSync \(.*/utils.dart:16(:3)?\)$', - r'^#1 futureThen.<anonymous closure> \(.*/utils.dart:187(:5)?\)$', - r'^#2 _RootZone.runUnary ', - r'^#3 _FutureListener.handleValue ', - r'^#4 Future._propagateToListeners.handleValueCallback ', - r'^#5 Future._propagateToListeners ', - r'^#6 Future._completeWithValue ', - r'^#7 Future._asyncCompleteWithValue.<anonymous closure> ', - r'^#8 _microtaskLoop ', - r'^#9 _startMicrotaskLoop ', - r'^#10 _runPendingImmediateCallback ', - r'^#11 _RawReceivePortImpl._handleMessage ', - ]; - await doTestAwait(futureThen, expected, debugInfoFilename); - await doTestAwaitThen(futureThen, expected, debugInfoFilename); - await doTestAwaitCatchError(futureThen, expected, debugInfoFilename); - } } // For: --lazy-async-stacks Future<void> doTestsLazy([String debugInfoFilename]) async { - // allYield - { - final allYieldExpected = const <String>[ - r'^#0 throwSync \(.*/utils.dart:16(:3)?\)$', - r'^#1 allYield3 \(.*/utils.dart:39(:3)?\)$', - r'^<asynchronous suspension>$', - r'^#2 allYield2 \(.*/utils.dart:34(:3)?\)$', - r'^<asynchronous suspension>$', - r'^#3 allYield \(.*/utils.dart:29(:3)?\)$', - r'^<asynchronous suspension>$', - ]; - await doTestAwait( - allYield, - allYieldExpected + - const <String>[ - r'^#4 doTestAwait ', - r'^<asynchronous suspension>$', - r'^#5 doTestsLazy ', - r'^<asynchronous suspension>$', - r'^#6 main ', - r'^<asynchronous suspension>$', - ], - debugInfoFilename); - await doTestAwaitThen( - allYield, - allYieldExpected + - const <String>[ - r'^#4 doTestAwaitThen ', - r'^<asynchronous suspension>$', - r'^#5 doTestsLazy ', - r'^<asynchronous suspension>$', - r'^#6 main ', - r'^<asynchronous suspension>$', - ], - debugInfoFilename); - await doTestAwaitCatchError( - allYield, - allYieldExpected + - const <String>[ - r'^#4 doTestAwaitCatchError ', - r'^<asynchronous suspension>$', - r'^#5 doTestsLazy ', - r'^<asynchronous suspension>$', - r'^#6 main ', - r'^<asynchronous suspension>$', - ], - debugInfoFilename); - } + final allYieldExpected = const <String>[ + r'^#0 throwSync \(.*/utils.dart:16(:3)?\)$', + r'^#1 allYield3 \(.*/utils.dart:39(:3)?\)$', + r'^<asynchronous suspension>$', + r'^#2 allYield2 \(.*/utils.dart:34(:3)?\)$', + r'^<asynchronous suspension>$', + r'^#3 allYield \(.*/utils.dart:29(:3)?\)$', + r'^<asynchronous suspension>$', + ]; + await doTestAwait( + allYield, + allYieldExpected + + const <String>[ + r'^#4 doTestAwait ', + r'^<asynchronous suspension>$', + r'^#5 doTestsLazy ', + r'^<asynchronous suspension>$', + r'^#6 main ', + r'^<asynchronous suspension>$', + ], + debugInfoFilename); + await doTestAwaitThen( + allYield, + allYieldExpected + + const <String>[ + r'^#4 doTestAwaitThen.<anonymous closure> ', + r'^<asynchronous suspension>$', + ], + debugInfoFilename); + await doTestAwaitCatchError(allYield, allYieldExpected, debugInfoFilename); - // noYields - { - final noYieldsExpected = const <String>[ - r'^#0 throwSync \(.*/utils.dart:16(:3)?\)$', - r'^#1 noYields3 \(.*/utils.dart:54(:3)?\)$', - r'^#2 noYields2 \(.*/utils.dart:50(:9)?\)$', - r'^#3 noYields \(.*/utils.dart:46(:9)?\)$', - ]; - await doTestAwait( - noYields, - noYieldsExpected + - const <String>[ - r'^#4 doTestAwait ', - r'^#5 doTestsLazy ', - r'^<asynchronous suspension>$', - r'^#6 main ', - r'^<asynchronous suspension>$', - ], - debugInfoFilename); - await doTestAwaitThen( - noYields, - noYieldsExpected + - const <String>[ - r'^#4 doTestAwaitThen ', - r'^#5 doTestsLazy ', - r'^<asynchronous suspension>$', - r'^#6 main ', - r'^<asynchronous suspension>$', - ], - debugInfoFilename); - await doTestAwaitCatchError( - noYields, - noYieldsExpected + - const <String>[ - r'^#4 doTestAwaitCatchError ', - r'^#5 doTestsLazy ', - r'^<asynchronous suspension>$', - r'^#6 main ', - r'^<asynchronous suspension>$', - ], - debugInfoFilename); - } + final noYieldsExpected = const <String>[ + r'^#0 throwSync \(.*/utils.dart:16(:3)?\)$', + r'^#1 noYields3 \(.*/utils.dart:54(:3)?\)$', + r'^#2 noYields2 \(.*/utils.dart:50(:9)?\)$', + r'^#3 noYields \(.*/utils.dart:46(:9)?\)$', + ]; + await doTestAwait( + noYields, + noYieldsExpected + + const <String>[ + r'^#4 doTestAwait ', + r'^#5 doTestsLazy ', + r'^<asynchronous suspension>$', + r'^#6 main ', + r'^<asynchronous suspension>$', + ], + debugInfoFilename); + await doTestAwaitThen( + noYields, + noYieldsExpected + + const <String>[ + r'^#4 doTestAwaitThen ', + r'^#5 doTestsLazy ', + r'^<asynchronous suspension>$', + r'^#6 main ', + r'^<asynchronous suspension>$', + ], + debugInfoFilename); + await doTestAwaitCatchError( + noYields, + noYieldsExpected + + const <String>[ + r'^#4 doTestAwaitCatchError ', + r'^#5 doTestsLazy ', + r'^<asynchronous suspension>$', + r'^#6 main ', + r'^<asynchronous suspension>$', + ], + debugInfoFilename); - // mixedYields - { - final mixedYieldsExpected = const <String>[ - r'^#0 throwAsync \(.*/utils.dart:21(:3)?\)$', - r'^<asynchronous suspension>$', - r'^#1 mixedYields2 \(.*/utils.dart:66(:3)?\)$', - r'^<asynchronous suspension>$', - r'^#2 mixedYields \(.*/utils.dart:61(:3)?\)$', - r'^<asynchronous suspension>$', - ]; - await doTestAwait( - mixedYields, - mixedYieldsExpected + - const <String>[ - r'^#3 doTestAwait ', - r'^<asynchronous suspension>$', - r'^#4 doTestsLazy ', - r'^<asynchronous suspension>$', - r'^#5 main ', - r'^<asynchronous suspension>$', - ], - debugInfoFilename); - await doTestAwaitThen( - mixedYields, - mixedYieldsExpected + - const <String>[ - r'^#3 doTestAwaitThen ', - r'^<asynchronous suspension>$', - r'^#4 doTestsLazy ', - r'^<asynchronous suspension>$', - r'^#5 main ', - r'^<asynchronous suspension>$', - ], - debugInfoFilename); - await doTestAwaitCatchError( - mixedYields, - mixedYieldsExpected + - const <String>[ - r'^#3 doTestAwaitCatchError ', - r'^<asynchronous suspension>$', - r'^#4 doTestsLazy ', - r'^<asynchronous suspension>$', - r'^#5 main ', - r'^<asynchronous suspension>$', - ], - debugInfoFilename); - } + final mixedYieldsExpected = const <String>[ + r'^#0 throwAsync \(.*/utils.dart:21(:3)?\)$', + r'^<asynchronous suspension>$', + r'^#1 mixedYields2 \(.*/utils.dart:66(:3)?\)$', + r'^<asynchronous suspension>$', + r'^#2 mixedYields \(.*/utils.dart:61(:3)?\)$', + r'^<asynchronous suspension>$', + ]; + await doTestAwait( + mixedYields, + mixedYieldsExpected + + const <String>[ + r'^#3 doTestAwait ', + r'^<asynchronous suspension>$', + r'^#4 doTestsLazy ', + r'^<asynchronous suspension>$', + r'^#5 main ', + r'^<asynchronous suspension>$', + ], + debugInfoFilename); + await doTestAwaitThen( + mixedYields, + mixedYieldsExpected + + const <String>[ + r'^#3 doTestAwaitThen.<anonymous closure> ', + r'^<asynchronous suspension>$', + ], + debugInfoFilename); + await doTestAwaitCatchError( + mixedYields, mixedYieldsExpected, debugInfoFilename); - // syncSuffix - { - final syncSuffixExpected = const <String>[ - r'^#0 throwAsync \(.*/utils.dart:21(:3)?\)$', - r'^<asynchronous suspension>$', - r'^#1 syncSuffix2 \(.*/utils.dart:82(:3)?\)$', - r'^<asynchronous suspension>$', - r'^#2 syncSuffix \(.*/utils.dart:77(:3)?\)$', - r'^<asynchronous suspension>$', - ]; - await doTestAwait( - syncSuffix, - syncSuffixExpected + - const <String>[ - r'^#3 doTestAwait ', - r'^<asynchronous suspension>$', - r'^#4 doTestsLazy ', - r'^<asynchronous suspension>$', - r'^#5 main ', - r'^<asynchronous suspension>$', - ], - debugInfoFilename); - await doTestAwaitThen( - syncSuffix, - syncSuffixExpected + - const <String>[ - r'^#3 doTestAwaitThen ', - r'^<asynchronous suspension>$', - r'^#4 doTestsLazy ', - r'^<asynchronous suspension>$', - r'^#5 main ', - r'^<asynchronous suspension>$', - ], - debugInfoFilename); - await doTestAwaitCatchError( - syncSuffix, - syncSuffixExpected + - const <String>[ - r'^#3 doTestAwaitCatchError ', - r'^<asynchronous suspension>$', - r'^#4 doTestsLazy ', - r'^<asynchronous suspension>$', - r'^#5 main ', - r'^<asynchronous suspension>$', - ], - debugInfoFilename); - } + final syncSuffixExpected = const <String>[ + r'^#0 throwAsync \(.*/utils.dart:21(:3)?\)$', + r'^<asynchronous suspension>$', + r'^#1 syncSuffix2 \(.*/utils.dart:82(:3)?\)$', + r'^<asynchronous suspension>$', + r'^#2 syncSuffix \(.*/utils.dart:77(:3)?\)$', + r'^<asynchronous suspension>$', + ]; + await doTestAwait( + syncSuffix, + syncSuffixExpected + + const <String>[ + r'^#3 doTestAwait ', + r'^<asynchronous suspension>$', + r'^#4 doTestsLazy ', + r'^<asynchronous suspension>$', + r'^#5 main ', + r'^<asynchronous suspension>$', + ], + debugInfoFilename); + await doTestAwaitThen( + syncSuffix, + syncSuffixExpected + + const <String>[ + r'^#3 doTestAwaitThen.<anonymous closure> ', + r'^<asynchronous suspension>$', + ], + debugInfoFilename); + await doTestAwaitCatchError( + syncSuffix, syncSuffixExpected, debugInfoFilename); - // nonAsyncNoStack - { - final nonAsyncNoStackExpected = const <String>[ - r'^#0 throwAsync \(.*/utils.dart:21(:3)?\)$', - r'^<asynchronous suspension>$', - r'^#1 nonAsyncNoStack1 \(.*/utils.dart:95(:36)?\)$', - r'^<asynchronous suspension>$', - r'^#2 nonAsyncNoStack \(.*/utils.dart:93(:35)?\)$', - r'^<asynchronous suspension>$', - ]; - await doTestAwait( - nonAsyncNoStack, - nonAsyncNoStackExpected + - const <String>[ - r'^#3 doTestAwait ', - r'^<asynchronous suspension>$', - r'^#4 doTestsLazy ', - r'^<asynchronous suspension>$', - r'^#5 main ', - r'^<asynchronous suspension>$', - ], - debugInfoFilename); - await doTestAwaitThen( - nonAsyncNoStack, - nonAsyncNoStackExpected + - const <String>[ - r'^#3 doTestAwaitThen ', - r'^<asynchronous suspension>$', - r'^#4 doTestsLazy ', - r'^<asynchronous suspension>$', - r'^#5 main ', - r'^<asynchronous suspension>$', - ], - debugInfoFilename); - await doTestAwaitCatchError( - nonAsyncNoStack, - nonAsyncNoStackExpected + - const <String>[ - r'^#3 doTestAwaitCatchError ', - r'^<asynchronous suspension>$', - r'^#4 doTestsLazy ', - r'^<asynchronous suspension>$', - r'^#5 main ', - r'^<asynchronous suspension>$', - ], - debugInfoFilename); - } + final nonAsyncNoStackExpected = const <String>[ + r'^#0 throwAsync \(.*/utils.dart:21(:3)?\)$', + r'^<asynchronous suspension>$', + r'^#1 nonAsyncNoStack1 \(.*/utils.dart:95(:36)?\)$', + r'^<asynchronous suspension>$', + r'^#2 nonAsyncNoStack \(.*/utils.dart:93(:35)?\)$', + r'^<asynchronous suspension>$', + ]; + await doTestAwait( + nonAsyncNoStack, + nonAsyncNoStackExpected + + const <String>[ + r'^#3 doTestAwait ', + r'^<asynchronous suspension>$', + r'^#4 doTestsLazy ', + r'^<asynchronous suspension>$', + r'^#5 main ', + r'^<asynchronous suspension>$', + ], + debugInfoFilename); + await doTestAwaitThen( + nonAsyncNoStack, + nonAsyncNoStackExpected + + const <String>[ + r'^#3 doTestAwaitThen.<anonymous closure> ', + r'^<asynchronous suspension>$', + ], + debugInfoFilename); + await doTestAwaitCatchError( + nonAsyncNoStack, nonAsyncNoStackExpected, debugInfoFilename); - // awaitEveryAsyncStarThrowSync - { - final asyncStarThrowSyncExpected = const <String>[ - r'^#0 throwSync \(.+/utils.dart:16(:3)?\)$', - r'^#1 asyncStarThrowSync \(.+/utils.dart:112(:11)?\)$', - r'^<asynchronous suspension>$', - r'^#2 awaitEveryAsyncStarThrowSync \(.+/utils.dart:104(:3)?\)$', - r'^<asynchronous suspension>$', - ]; - await doTestAwait( - awaitEveryAsyncStarThrowSync, - asyncStarThrowSyncExpected + - const <String>[ - r'^#3 doTestAwait ', - r'^<asynchronous suspension>$', - r'^#4 doTestsLazy ', - r'^<asynchronous suspension>$', - r'^#5 main ', - r'^<asynchronous suspension>$', - ], - debugInfoFilename); - await doTestAwaitThen( - awaitEveryAsyncStarThrowSync, - asyncStarThrowSyncExpected + - const <String>[ - r'^#3 doTestAwaitThen ', - r'^<asynchronous suspension>$', - r'^#4 doTestsLazy ', - r'^<asynchronous suspension>$', - r'^#5 main ', - r'^<asynchronous suspension>$', - ], - debugInfoFilename); - await doTestAwaitCatchError( - awaitEveryAsyncStarThrowSync, - asyncStarThrowSyncExpected + - const <String>[ - r'^#3 doTestAwaitCatchError ', - r'^<asynchronous suspension>$', - r'^#4 doTestsLazy ', - r'^<asynchronous suspension>$', - r'^#5 main ', - r'^<asynchronous suspension>$', - ], - debugInfoFilename); - } + final asyncStarThrowSyncExpected = const <String>[ + r'^#0 throwSync \(.+/utils.dart:16(:3)?\)$', + r'^#1 asyncStarThrowSync \(.+/utils.dart:112(:11)?\)$', + r'^<asynchronous suspension>$', + r'^#2 awaitEveryAsyncStarThrowSync \(.+/utils.dart:104(:3)?\)$', + r'^<asynchronous suspension>$', + ]; + await doTestAwait( + awaitEveryAsyncStarThrowSync, + asyncStarThrowSyncExpected + + const <String>[ + r'^#3 doTestAwait ', + r'^<asynchronous suspension>$', + r'^#4 doTestsLazy ', + r'^<asynchronous suspension>$', + r'^#5 main ', + r'^<asynchronous suspension>$', + ], + debugInfoFilename); + await doTestAwaitThen( + awaitEveryAsyncStarThrowSync, + asyncStarThrowSyncExpected + + const <String>[ + r'^#3 doTestAwaitThen.<anonymous closure> ', + r'^<asynchronous suspension>$', + ], + debugInfoFilename); + await doTestAwaitCatchError(awaitEveryAsyncStarThrowSync, + asyncStarThrowSyncExpected, debugInfoFilename); - // awaitEveryAsyncStarThrowAsync - { - final asyncStarThrowAsyncExpected = const <String>[ - r'^#0 throwAsync \(.*/utils.dart:21(:3)?\)$', - r'^<asynchronous suspension>$', - r'^#1 asyncStarThrowAsync \(.*/utils.dart:126(:5)?\)$', - r'^<asynchronous suspension>$', - r'^#2 awaitEveryAsyncStarThrowAsync \(.+/utils.dart:117(:3)?\)$', - r'^<asynchronous suspension>$', - ]; - await doTestAwait( - awaitEveryAsyncStarThrowAsync, - asyncStarThrowAsyncExpected + - const <String>[ - r'^#3 doTestAwait ', - r'^<asynchronous suspension>$', - r'^#4 doTestsLazy ', - r'^<asynchronous suspension>$', - r'^#5 main ', - r'^<asynchronous suspension>$', - ], - debugInfoFilename); - await doTestAwaitThen( - awaitEveryAsyncStarThrowAsync, - asyncStarThrowAsyncExpected + - const <String>[ - r'^#3 doTestAwaitThen ', - r'^<asynchronous suspension>$', - r'^#4 doTestsLazy ', - r'^<asynchronous suspension>$', - r'^#5 main ', - r'^<asynchronous suspension>$', - ], - debugInfoFilename); - await doTestAwaitCatchError( - awaitEveryAsyncStarThrowAsync, - asyncStarThrowAsyncExpected + - const <String>[ - r'^#3 doTestAwaitCatchError ', - r'^<asynchronous suspension>$', - r'^#4 doTestsLazy ', - r'^<asynchronous suspension>$', - r'^#5 main ', - r'^<asynchronous suspension>$', - ], - debugInfoFilename); - } + final asyncStarThrowAsyncExpected = const <String>[ + r'^#0 throwAsync \(.*/utils.dart:21(:3)?\)$', + r'^<asynchronous suspension>$', + r'^#1 asyncStarThrowAsync \(.*/utils.dart:126(:5)?\)$', + r'^<asynchronous suspension>$', + r'^#2 awaitEveryAsyncStarThrowAsync \(.+/utils.dart:117(:3)?\)$', + r'^<asynchronous suspension>$', + ]; + await doTestAwait( + awaitEveryAsyncStarThrowAsync, + asyncStarThrowAsyncExpected + + const <String>[ + r'^#3 doTestAwait ', + r'^<asynchronous suspension>$', + r'^#4 doTestsLazy ', + r'^<asynchronous suspension>$', + r'^#5 main ', + r'^<asynchronous suspension>$', + ], + debugInfoFilename); + await doTestAwaitThen( + awaitEveryAsyncStarThrowAsync, + asyncStarThrowAsyncExpected + + const <String>[ + r'^#3 doTestAwaitThen.<anonymous closure> ', + r'^<asynchronous suspension>$', + ], + debugInfoFilename); + await doTestAwaitCatchError(awaitEveryAsyncStarThrowAsync, + asyncStarThrowAsyncExpected, debugInfoFilename); - // listenAsyncStarThrowAsync - { - final listenAsyncStartExpected = const <String>[ - r'^#0 throwAsync \(.*/utils.dart:21(:3)?\)$', - r'^<asynchronous suspension>$', - r'^#1 asyncStarThrowAsync \(.*/utils.dart:126(:5)?\)$', - r'^<asynchronous suspension>$', - r'^#2 listenAsyncStarThrowAsync.<anonymous closure> \(.+/utils.dart(:0)?\)$', - r'^<asynchronous suspension>$', - ]; - await doTestAwait( - listenAsyncStarThrowAsync, listenAsyncStartExpected, debugInfoFilename); - await doTestAwaitThen( - listenAsyncStarThrowAsync, listenAsyncStartExpected, debugInfoFilename); - await doTestAwaitCatchError( - listenAsyncStarThrowAsync, listenAsyncStartExpected, debugInfoFilename); - } + final listenAsyncStartExpected = const <String>[ + r'^#0 throwAsync \(.*/utils.dart:21(:3)?\)$', + r'^<asynchronous suspension>$', + r'^#1 asyncStarThrowAsync \(.*/utils.dart:126(:5)?\)$', + r'^<asynchronous suspension>$', + r'^#2 listenAsyncStarThrowAsync.<anonymous closure> \(.+/utils.dart(:0)?\)$', + r'^<asynchronous suspension>$', + ]; + await doTestAwait( + listenAsyncStarThrowAsync, listenAsyncStartExpected, debugInfoFilename); + await doTestAwaitThen( + listenAsyncStarThrowAsync, listenAsyncStartExpected, debugInfoFilename); + await doTestAwaitCatchError( + listenAsyncStarThrowAsync, listenAsyncStartExpected, debugInfoFilename); - // customErrorZone - { - final customErrorZoneExpected = const <String>[ - r'#0 throwSync \(.*/utils.dart:16(:3)?\)$', - r'#1 allYield3 \(.*/utils.dart:39(:3)?\)$', - r'<asynchronous suspension>$', - r'#2 allYield2 \(.*/utils.dart:34(:3)?\)$', - r'<asynchronous suspension>$', - r'#3 allYield \(.*/utils.dart:29(:3)?\)$', - r'<asynchronous suspension>$', - r'#4 customErrorZone.<anonymous closure> \(.*/utils.dart:144(:5)?\)$', - r'<asynchronous suspension>$', - ]; - await doTestAwait( - customErrorZone, customErrorZoneExpected, debugInfoFilename); - await doTestAwaitThen( - customErrorZone, customErrorZoneExpected, debugInfoFilename); - await doTestAwaitCatchError( - customErrorZone, customErrorZoneExpected, debugInfoFilename); - } + final customErrorZoneExpected = const <String>[ + r'#0 throwSync \(.*/utils.dart:16(:3)?\)$', + r'#1 allYield3 \(.*/utils.dart:39(:3)?\)$', + r'<asynchronous suspension>$', + r'#2 allYield2 \(.*/utils.dart:34(:3)?\)$', + r'<asynchronous suspension>$', + r'#3 allYield \(.*/utils.dart:29(:3)?\)$', + r'<asynchronous suspension>$', + r'#4 customErrorZone.<anonymous closure> \(.*/utils.dart:144(:5)?\)$', + r'<asynchronous suspension>$', + ]; + await doTestAwait( + customErrorZone, customErrorZoneExpected, debugInfoFilename); + await doTestAwaitThen( + customErrorZone, customErrorZoneExpected, debugInfoFilename); + await doTestAwaitCatchError( + customErrorZone, customErrorZoneExpected, debugInfoFilename); - // awaitTimeout - { - final awaitTimeoutExpected = const <String>[ - r'^#0 throwAsync \(.*/utils.dart:21(:3)?\)$', - r'^<asynchronous suspension>$', - r'^#1 Future.timeout.<anonymous closure> \(dart:async/future_impl.dart', - r'^<asynchronous suspension>$', - r'^#2 awaitTimeout ', - r'^<asynchronous suspension>$', - ]; - await doTestAwait( - awaitTimeout, - awaitTimeoutExpected + - const <String>[ - r'^#3 doTestAwait ', - r'^<asynchronous suspension>$', - r'^#4 doTestsLazy ', - r'^<asynchronous suspension>$', - r'^#5 main ', - r'^<asynchronous suspension>$', - ], - debugInfoFilename); - await doTestAwaitThen( - awaitTimeout, - awaitTimeoutExpected + - const <String>[ - r'^#3 doTestAwaitThen ', - r'^<asynchronous suspension>$', - r'^#4 doTestsLazy ', - r'^<asynchronous suspension>$', - r'^#5 main ', - r'^<asynchronous suspension>$', - ], - debugInfoFilename); - await doTestAwaitCatchError( - awaitTimeout, - awaitTimeoutExpected + - const <String>[ - r'^#3 doTestAwaitCatchError ', - r'^<asynchronous suspension>$', - r'^#4 doTestsLazy ', - r'^<asynchronous suspension>$', - r'^#5 main ', - r'^<asynchronous suspension>$', - ], - debugInfoFilename); - } + final awaitTimeoutExpected = const <String>[ + r'^#0 throwAsync \(.*/utils.dart:21(:3)?\)$', + r'^<asynchronous suspension>$', + r'^#1 Future.timeout.<anonymous closure> \(dart:async/future_impl.dart', + r'^<asynchronous suspension>$', + r'^#2 awaitTimeout ', + r'^<asynchronous suspension>$', + ]; + await doTestAwait( + awaitTimeout, + awaitTimeoutExpected + + const <String>[ + r'^#3 doTestAwait ', + r'^<asynchronous suspension>$', + r'^#4 doTestsLazy ', + r'^<asynchronous suspension>$', + r'^#5 main ', + r'^<asynchronous suspension>$', + ], + debugInfoFilename); + await doTestAwaitThen( + awaitTimeout, + awaitTimeoutExpected + + const <String>[ + r'^#3 doTestAwaitThen.<anonymous closure> ', + r'^<asynchronous suspension>$', + ], + debugInfoFilename); + await doTestAwaitCatchError( + awaitTimeout, awaitTimeoutExpected, debugInfoFilename); - // awaitWait - { - final awaitWaitExpected = const <String>[ - r'^#0 throwAsync \(.*/utils.dart:21(:3)?\)$', - r'^<asynchronous suspension>$', - r'^#1 Future.wait.<anonymous closure> \(dart:async/future.dart', - r'^<asynchronous suspension>$', - r'^#2 awaitWait ', - r'^<asynchronous suspension>$', - ]; - await doTestAwait( - awaitWait, - awaitWaitExpected + - const <String>[ - r'^#3 doTestAwait ', - r'^<asynchronous suspension>$', - r'^#4 doTestsLazy ', - r'^<asynchronous suspension>$', - r'^#5 main ', - r'^<asynchronous suspension>$', - ], - debugInfoFilename); - await doTestAwaitThen( - awaitWait, - awaitWaitExpected + - const <String>[ - r'^#3 doTestAwaitThen ', - r'^<asynchronous suspension>$', - r'^#4 doTestsLazy ', - r'^<asynchronous suspension>$', - r'^#5 main ', - r'^<asynchronous suspension>$', - ], - debugInfoFilename); - await doTestAwaitCatchError( - awaitWait, - awaitWaitExpected + - const <String>[ - r'^#3 doTestAwaitCatchError ', - r'^<asynchronous suspension>$', - r'^#4 doTestsLazy ', - r'^<asynchronous suspension>$', - r'^#5 main ', - r'^<asynchronous suspension>$', - ], - debugInfoFilename); - } + final awaitWaitExpected = const <String>[ + r'^#0 throwAsync \(.*/utils.dart:21(:3)?\)$', + r'^<asynchronous suspension>$', + r'^#1 Future.wait.<anonymous closure> \(dart:async/future.dart', + r'^<asynchronous suspension>$', + r'^#2 awaitWait ', + r'^<asynchronous suspension>$', + ]; + await doTestAwait( + awaitWait, + awaitWaitExpected + + const <String>[ + r'^#3 doTestAwait ', + r'^<asynchronous suspension>$', + r'^#4 doTestsLazy ', + r'^<asynchronous suspension>$', + r'^#5 main ', + r'^<asynchronous suspension>$', + ], + debugInfoFilename); + await doTestAwaitThen( + awaitWait, + awaitWaitExpected + + const <String>[ + r'^#3 doTestAwaitThen.<anonymous closure> ', + r'^<asynchronous suspension>$', + ], + debugInfoFilename); + await doTestAwaitCatchError(awaitWait, awaitWaitExpected, debugInfoFilename); - // futureSyncWhenComplete { - final expected = const <String>[ + final expect = const <String>[ r'^#0 throwAsync \(.*/utils.dart:21(:3)?\)$', r'^<asynchronous suspension>$', ]; await doTestAwait( futureSyncWhenComplete, - expected + + expect + const <String>[ r'^#1 doTestAwait ', r'^<asynchronous suspension>$', @@ -1151,72 +984,13 @@ debugInfoFilename); await doTestAwaitThen( futureSyncWhenComplete, - expected + + expect + const <String>[ - r'^#1 doTestAwaitThen ', - r'^<asynchronous suspension>$', - r'^#2 doTestsLazy ', - r'^<asynchronous suspension>$', - r'^#3 main ', + r'^#1 doTestAwaitThen.<anonymous closure> ', r'^<asynchronous suspension>$', ], debugInfoFilename); await doTestAwaitCatchError( - futureSyncWhenComplete, - expected + - const <String>[ - r'^#1 doTestAwaitCatchError ', - r'^<asynchronous suspension>$', - r'^#2 doTestsLazy ', - r'^<asynchronous suspension>$', - r'^#3 main ', - r'^<asynchronous suspension>$', - ], - debugInfoFilename); - } - - // futureThen - { - final expected = const <String>[ - r'^#0 throwSync \(.*/utils.dart:16(:3)?\)$', - r'^#1 futureThen.<anonymous closure> ', - r'^<asynchronous suspension>$', - ]; - await doTestAwait( - futureThen, - expected + - const <String>[ - r'^#2 doTestAwait ', - r'^<asynchronous suspension>$', - r'^#3 doTestsLazy ', - r'^<asynchronous suspension>$', - r'^#4 main ', - r'^<asynchronous suspension>$', - ], - debugInfoFilename); - await doTestAwaitThen( - futureThen, - expected + - const <String>[ - r'^#2 doTestAwaitThen ', - r'^<asynchronous suspension>$', - r'^#3 doTestsLazy ', - r'^<asynchronous suspension>$', - r'^#4 main ', - r'^<asynchronous suspension>$', - ], - debugInfoFilename); - await doTestAwaitCatchError( - futureThen, - expected + - const <String>[ - r'^#2 doTestAwaitCatchError ', - r'^<asynchronous suspension>$', - r'^#3 doTestsLazy ', - r'^<asynchronous suspension>$', - r'^#4 main ', - r'^<asynchronous suspension>$', - ], - debugInfoFilename); + futureSyncWhenComplete, expect, debugInfoFilename); } }
diff --git a/runtime/vm/compiler/recognized_methods_list.h b/runtime/vm/compiler/recognized_methods_list.h index 6822001..185af0a 100644 --- a/runtime/vm/compiler/recognized_methods_list.h +++ b/runtime/vm/compiler/recognized_methods_list.h
@@ -196,8 +196,6 @@ V(_Utf8Decoder, _scan, Utf8DecoderScan, 0xb35ced99) \ V(_Future, timeout, FutureTimeout, 0x6ad7d1ef) \ V(Future, wait, FutureWait, 0x264aacc2) \ - V(_RootZone, runUnary, RootZoneRunUnary, 0x76e41d34) \ - V(_FutureListener, handleValue, FutureListenerHandleValue, 0x73894d16) \ // List of intrinsics: // (class-name, function-name, intrinsification method, fingerprint).
diff --git a/runtime/vm/debugger.cc b/runtime/vm/debugger.cc index 51975f3..7f6775d 100644 --- a/runtime/vm/debugger.cc +++ b/runtime/vm/debugger.cc
@@ -1848,7 +1848,7 @@ /*skip_frames=*/0, &on_sync_frame, &has_async); - // If the entire stack is sync, return no (async) trace. + // If the entire stack is sync, return no trace. if (!has_async) { return nullptr; }
diff --git a/runtime/vm/stack_frame.cc b/runtime/vm/stack_frame.cc index 96ad60d..5a6c5a9 100644 --- a/runtime/vm/stack_frame.cc +++ b/runtime/vm/stack_frame.cc
@@ -528,19 +528,6 @@ frames_.Unpoison(); } -StackFrameIterator::StackFrameIterator(const StackFrameIterator& orig) - : validate_(orig.validate_), - entry_(orig.thread_), - exit_(orig.thread_), - frames_(orig.thread_), - current_frame_(nullptr), - thread_(orig.thread_) { - frames_.fp_ = orig.frames_.fp_; - frames_.sp_ = orig.frames_.sp_; - frames_.pc_ = orig.frames_.pc_; - frames_.Unpoison(); -} - StackFrame* StackFrameIterator::NextFrame() { // When we are at the start of iteration after having created an // iterator object, current_frame_ will be NULL as we haven't seen
diff --git a/runtime/vm/stack_frame.h b/runtime/vm/stack_frame.h index 6969642..92f864f 100644 --- a/runtime/vm/stack_frame.h +++ b/runtime/vm/stack_frame.h
@@ -236,8 +236,6 @@ Thread* thread, CrossThreadPolicy cross_thread_policy); - StackFrameIterator(const StackFrameIterator& orig); - // Checks if a next frame exists. bool HasNextFrame() const { return frames_.fp_ != 0; } @@ -302,6 +300,7 @@ Thread* thread_; friend class ProfilerDartStackWalker; + DISALLOW_COPY_AND_ASSIGN(StackFrameIterator); }; // Iterator for iterating over all dart frames (skips over exit frames, @@ -340,8 +339,6 @@ thread, cross_thread_policy) {} - DartFrameIterator(const DartFrameIterator& orig) : frames_(orig.frames_) {} - // Get next dart frame. StackFrame* NextFrame() { StackFrame* frame = frames_.NextFrame(); @@ -353,6 +350,8 @@ private: StackFrameIterator frames_; + + DISALLOW_COPY_AND_ASSIGN(DartFrameIterator); }; // Iterator for iterating over all inlined dart functions in an optimized
diff --git a/runtime/vm/stack_trace.cc b/runtime/vm/stack_trace.cc index a231568..ae8849a 100644 --- a/runtime/vm/stack_trace.cc +++ b/runtime/vm/stack_trace.cc
@@ -10,18 +10,11 @@ namespace dart { -// Keep in sync with: -// - sdk/lib/async/stream_controller.dart:_StreamController._STATE_SUBSCRIBED. +// Keep in sync with +// sdk/lib/async/stream_controller.dart:_StreamController._STATE_SUBSCRIBED. const intptr_t k_StreamController__STATE_SUBSCRIBED = 1; -// - sdk/lib/async/future_impl.dart:_FutureListener.stateThen. -const intptr_t k_FutureListener_stateThen = 1; -// - sdk/lib/async/future_impl.dart:_FutureListener.stateCatchError. -const intptr_t k_FutureListener_stateCatchError = 2; -// - sdk/lib/async/future_impl.dart:_FutureListener.stateWhenComplete. -const intptr_t k_FutureListener_stateWhenComplete = 8; - -// Keep in sync with sdk/lib/async/future_impl.dart:_FutureListener.handleValue. -const intptr_t kNumArgsFutureListenerHandleValue = 1; +// sdk/lib/async/future_impl.dart:_FutureListener.stateWhencomplete. +const intptr_t k_FutureListener_stateWhencomplete = 8; // Find current yield index from async closure. // Async closures contains a variable, :await_jump_var that holds the index into @@ -147,19 +140,21 @@ ASSERT(!future.IsNull()); ASSERT(future.GetClassId() == future_impl_class.id()); - // Since this function is recursive, we have to keep a local ref. - auto& listener = Object::Handle( - Instance::Cast(future).GetField(future_result_or_listeners_field)); - if (listener.GetClassId() != future_listener_class.id()) { + listener_ = Instance::Cast(future).GetField(future_result_or_listeners_field); + if (listener_.GetClassId() != future_listener_class.id()) { return Closure::null(); } - callback_ = GetCallerInFutureListener(listener); - if (callback_.IsInstance() && !callback_.IsNull()) { - return Closure::Cast(callback_).ptr(); + // If the _FutureListener is a whenComplete listener, follow the Future being + // completed, `result`, instead of the dangling whenComplete `callback`. + state_ = Instance::Cast(listener_).GetField(future_listener_state_field); + ASSERT(state_.IsSmi()); + if (Smi::Cast(state_).Value() == k_FutureListener_stateWhencomplete) { + future_ = Instance::Cast(listener_).GetField(future_listener_result_field); + return GetCallerInFutureImpl(future_); } - callback_ = Instance::Cast(listener).GetField(callback_field); + callback_ = Instance::Cast(listener_).GetField(callback_field); // This happens for e.g.: await f().catchError(..); if (callback_.IsNull()) { return Closure::null(); @@ -226,46 +221,22 @@ UNREACHABLE(); // If no onData is found we have a bug. } -ClosurePtr CallerClosureFinder::GetCallerInFutureListener( - const Object& future_listener) { - ASSERT(future_listener.GetClassId() == future_listener_class.id()); - - state_ = - Instance::Cast(future_listener).GetField(future_listener_state_field); - - auto value = Smi::Cast(state_).Value(); - // If the _FutureListener is a `then`, `catchError`, or `whenComplete` - // listener, follow the Future being completed, `result`, instead of the - // dangling whenComplete `callback`. - if (value == k_FutureListener_stateThen || - value == k_FutureListener_stateCatchError || - value == k_FutureListener_stateWhenComplete) { - future_ = - Instance::Cast(future_listener).GetField(future_listener_result_field); - return GetCallerInFutureImpl(future_); - } - - return Closure::null(); -} - ClosurePtr CallerClosureFinder::FindCaller(const Closure& receiver_closure) { receiver_function_ = receiver_closure.function(); receiver_context_ = receiver_closure.context(); if (receiver_function_.IsAsyncClosure()) { return FindCallerInAsyncClosure(receiver_context_); - } - if (receiver_function_.IsAsyncGenClosure()) { + } else if (receiver_function_.IsAsyncGenClosure()) { return FindCallerInAsyncGenClosure(receiver_context_); - } - if (receiver_function_.IsLocalFunction()) { + } else if (receiver_function_.IsLocalFunction()) { parent_function_ = receiver_function_.parent_function(); if (parent_function_.recognized_kind() == MethodRecognizer::kFutureTimeout) { context_entry_ = receiver_context_.At(Context::kFutureTimeoutFutureIndex); return GetCallerInFutureImpl(context_entry_); - } - if (parent_function_.recognized_kind() == MethodRecognizer::kFutureWait) { + } else if (parent_function_.recognized_kind() == + MethodRecognizer::kFutureWait) { receiver_context_ = receiver_context_.parent(); ASSERT(!receiver_context_.IsNull()); context_entry_ = receiver_context_.At(Context::kFutureWaitFutureIndex); @@ -329,114 +300,6 @@ UNREACHABLE(); } -ClosurePtr StackTraceUtils::ClosureFromFrameFunction( - Zone* zone, - CallerClosureFinder* caller_closure_finder, - const DartFrameIterator& frames, - StackFrame* frame, - bool* skip_frame, - bool* is_async) { - auto& closure = Closure::Handle(zone); - auto& function = Function::Handle(zone); - - function = frame->LookupDartFunction(); - if (function.IsNull()) { - return Closure::null(); - } - - if (function.IsAsyncClosure() || function.IsAsyncGenClosure()) { - { - NoSafepointScope nsp; - - // Next, look up caller's closure on the stack and walk backwards - // through the yields. - ObjectPtr* last_caller_obj = - reinterpret_cast<ObjectPtr*>(frame->GetCallerSp()); - closure = FindClosureInFrame(last_caller_obj, function); - - // If this async function hasn't yielded yet, we're still dealing with a - // normal stack. Continue to next frame as usual. - if (!caller_closure_finder->IsRunningAsync(closure)) { - return Closure::null(); - } - } - - *is_async = true; - - // Skip: Already handled this as a sync. frame. - return caller_closure_finder->FindCaller(closure); - } - - // May have been called from `_FutureListener.handleValue`, which means its - // receiver holds the Future chain. - if (function.recognized_kind() == MethodRecognizer::kRootZoneRunUnary) { - DartFrameIterator future_frames(frames); - frame = future_frames.NextFrame(); - function = frame->LookupDartFunction(); - if (function.recognized_kind() != - MethodRecognizer::kFutureListenerHandleValue) { - return Closure::null(); - } - } - if (function.recognized_kind() == - MethodRecognizer::kFutureListenerHandleValue) { - *is_async = true; - *skip_frame = true; - - // The _FutureListener receiver is at the top of the previous frame, right - // before the arguments to the call. - Object& receiver = - Object::Handle(*(reinterpret_cast<ObjectPtr*>(frame->GetCallerSp()) + - kNumArgsFutureListenerHandleValue)); - - return caller_closure_finder->GetCallerInFutureListener(receiver); - } - - return Closure::null(); -} - -void StackTraceUtils::UnwindAwaiterChain( - Zone* zone, - const GrowableObjectArray& code_array, - const GrowableObjectArray& pc_offset_array, - CallerClosureFinder* caller_closure_finder, - ClosurePtr leaf_closure) { - auto& code = Code::Handle(zone); - auto& function = Function::Handle(zone); - auto& closure = Closure::Handle(zone, leaf_closure); - auto& pc_descs = PcDescriptors::Handle(zone); - auto& offset = Smi::Handle(zone); - - // Inject async suspension marker. - code_array.Add(StubCode::AsynchronousGapMarker()); - offset = Smi::New(0); - pc_offset_array.Add(offset); - - // Traverse the trail of async futures all the way up. - for (; !closure.IsNull(); - closure = caller_closure_finder->FindCaller(closure)) { - function = closure.function(); - if (function.IsNull()) { - continue; - } - // In hot-reload-test-mode we sometimes have to do this: - code = function.EnsureHasCode(); - RELEASE_ASSERT(!code.IsNull()); - code_array.Add(code); - pc_descs = code.pc_descriptors(); - offset = Smi::New(FindPcOffset(pc_descs, GetYieldIndex(closure))); - // Unlike other sources of PC offsets, the offset may be 0 here if we - // reach a non-async closure receiving the yielded value. - ASSERT(offset.Value() >= 0); - pc_offset_array.Add(offset); - - // Inject async suspension marker. - code_array.Add(StubCode::AsynchronousGapMarker()); - offset = Smi::New(0); - pc_offset_array.Add(offset); - } -} - void StackTraceUtils::CollectFramesLazy( Thread* thread, const GrowableObjectArray& code_array, @@ -457,10 +320,13 @@ return; } + auto& function = Function::Handle(zone); auto& code = Code::Handle(zone); auto& offset = Smi::Handle(zone); + auto& closure = Closure::Handle(zone); CallerClosureFinder caller_closure_finder(zone); + auto& pc_descs = PcDescriptors::Handle(); // Start by traversing the sync. part of the stack. for (; frame != nullptr; frame = frames.NextFrame()) { @@ -469,36 +335,79 @@ continue; } - // If we encounter a known part of the async/Future mechanism, unwind the - // awaiter chain from the closures. - bool skip_frame = false; - bool is_async = false; - auto closure_ptr = ClosureFromFrameFunction( - zone, &caller_closure_finder, frames, frame, &skip_frame, &is_async); + function = frame->LookupDartFunction(); - // This isn't a special (async) frame we should skip. - if (!skip_frame) { - // Add the current synchronous frame. - code = frame->LookupDartCode(); - code_array.Add(code); - const intptr_t pc_offset = frame->pc() - code.PayloadStart(); - ASSERT(pc_offset > 0 && pc_offset <= code.Size()); - offset = Smi::New(pc_offset); - pc_offset_array.Add(offset); - // Callback for sync frame. - if (on_sync_frames != nullptr) { - (*on_sync_frames)(frame); - } + // Add the current synchronous frame. + code = frame->LookupDartCode(); + ASSERT(function.ptr() == code.function()); + code_array.Add(code); + const intptr_t pc_offset = frame->pc() - code.PayloadStart(); + ASSERT(pc_offset > 0 && pc_offset <= code.Size()); + offset = Smi::New(pc_offset); + pc_offset_array.Add(offset); + if (on_sync_frames != nullptr) { + (*on_sync_frames)(frame); } - // This frame is running async. - // Note: The closure might still be null in case it's an unawaited future. - if (is_async) { - UnwindAwaiterChain(zone, code_array, pc_offset_array, - &caller_closure_finder, closure_ptr); + // Either continue the loop (sync-async case) or find all await'ers and + // return. + if (!function.IsNull() && + (function.IsAsyncClosure() || function.IsAsyncGenClosure())) { if (has_async != nullptr) { *has_async = true; } + + { + NoSafepointScope nsp; + + // Next, look up caller's closure on the stack and walk backwards + // through the yields. + ObjectPtr* last_caller_obj = + reinterpret_cast<ObjectPtr*>(frame->GetCallerSp()); + closure = FindClosureInFrame(last_caller_obj, function); + + // If this async function hasn't yielded yet, we're still dealing with a + // normal stack. Continue to next frame as usual. + if (!caller_closure_finder.IsRunningAsync(closure)) { + continue; + } + } + + // Inject async suspension marker. + code_array.Add(StubCode::AsynchronousGapMarker()); + offset = Smi::New(0); + pc_offset_array.Add(offset); + + // Skip: Already handled this frame's function above. + closure = caller_closure_finder.FindCaller(closure); + + // Traverse the trail of async futures all the way up. + for (; !closure.IsNull(); + closure = caller_closure_finder.FindCaller(closure)) { + function = closure.function(); + // In hot-reload-test-mode we sometimes have to do this: + if (!function.HasCode()) { + function.EnsureHasCode(); + } + if (function.HasCode()) { + code = function.CurrentCode(); + code_array.Add(code); + pc_descs = code.pc_descriptors(); + offset = Smi::New(FindPcOffset(pc_descs, GetYieldIndex(closure))); + } else { + UNREACHABLE(); + } + // Unlike other sources of PC offsets, the offset may be 0 here if we + // reach a non-async closure receiving the yielded value. + ASSERT(offset.Value() >= 0); + pc_offset_array.Add(offset); + + // Inject async suspension marker. + code_array.Add(StubCode::AsynchronousGapMarker()); + offset = Smi::New(0); + pc_offset_array.Add(offset); + } + // Ignore the rest of the stack; already unwound all async calls. return; }
diff --git a/runtime/vm/stack_trace.h b/runtime/vm/stack_trace.h index 75ba724..215da83 100644 --- a/runtime/vm/stack_trace.h +++ b/runtime/vm/stack_trace.h
@@ -21,8 +21,6 @@ ClosurePtr GetCallerInFutureImpl(const Object& future_); - ClosurePtr GetCallerInFutureListener(const Object& future_listener); - ClosurePtr FindCallerInAsyncClosure(const Context& receiver_context); ClosurePtr FindCallerInAsyncGenClosure(const Context& receiver_context); @@ -63,8 +61,6 @@ Field& state_field; Field& on_data_field; Field& state_data_field; - - DISALLOW_COPY_AND_ASSIGN(CallerClosureFinder); }; class StackTraceUtils : public AllStatic { @@ -73,20 +69,6 @@ static ClosurePtr FindClosureInFrame(ObjectPtr* last_object_in_caller, const Function& function); - static ClosurePtr ClosureFromFrameFunction( - Zone* zone, - CallerClosureFinder* caller_closure_finder, - const DartFrameIterator& frames, - StackFrame* frame, - bool* skip_frame, - bool* is_async); - - static void UnwindAwaiterChain(Zone* zone, - const GrowableObjectArray& code_array, - const GrowableObjectArray& pc_offset_array, - CallerClosureFinder* caller_closure_finder, - ClosurePtr leaf_closure); - /// Collects all frames on the current stack until an async/async* frame is /// hit which has yielded before (i.e. is not in sync-async case). ///
diff --git a/sdk/lib/async/future_impl.dart b/sdk/lib/async/future_impl.dart index a9f2b80..df8a347 100644 --- a/sdk/lib/async/future_impl.dart +++ b/sdk/lib/async/future_impl.dart
@@ -63,19 +63,18 @@ } class _FutureListener<S, T> { - // Keep in sync with sdk/runtime/vm/stack_trace.cc. static const int maskValue = 1; static const int maskError = 2; static const int maskTestError = 4; - static const int maskWhenComplete = 8; + static const int maskWhencomplete = 8; static const int stateChain = 0; static const int stateThen = maskValue; static const int stateThenOnerror = maskValue | maskError; - static const int stateCatchError = maskError; - static const int stateCatchErrorTest = maskError | maskTestError; - static const int stateWhenComplete = maskWhenComplete; + static const int stateCatcherror = maskError; + static const int stateCatcherrorTest = maskError | maskTestError; + static const int stateWhencomplete = maskWhencomplete; static const int maskType = - maskValue | maskError | maskTestError | maskWhenComplete; + maskValue | maskError | maskTestError | maskWhencomplete; static const int stateIsAwait = 16; // Listeners on the same future are linked through this link. @@ -110,18 +109,18 @@ stateIsAwait; _FutureListener.catchError(this.result, this.errorCallback, this.callback) - : state = (callback == null) ? stateCatchError : stateCatchErrorTest; + : state = (callback == null) ? stateCatcherror : stateCatcherrorTest; _FutureListener.whenComplete(this.result, this.callback) : errorCallback = null, - state = stateWhenComplete; + state = stateWhencomplete; _Zone get _zone => result._zone; bool get handlesValue => (state & maskValue != 0); bool get handlesError => (state & maskError != 0); - bool get hasErrorTest => (state & maskType == stateCatchErrorTest); - bool get handlesComplete => (state & maskType == stateWhenComplete); + bool get hasErrorTest => (state & maskType == stateCatcherrorTest); + bool get handlesComplete => (state & maskType == stateWhencomplete); bool get isAwait => (state & stateIsAwait != 0); FutureOr<T> Function(S) get _onValue { @@ -149,8 +148,6 @@ return _onError != null; } - @pragma("vm:recognized", "other") - @pragma("vm:never-inline") FutureOr<T> handleValue(S sourceResult) { return _zone.runUnary<FutureOr<T>, S>(_onValue, sourceResult); }
diff --git a/sdk/lib/async/zone.dart b/sdk/lib/async/zone.dart index 5400814..4f0873d 100644 --- a/sdk/lib/async/zone.dart +++ b/sdk/lib/async/zone.dart
@@ -1608,7 +1608,6 @@ return _rootRun(null, null, this, f); } - @pragma("vm:recognized", "other") R runUnary<R, T>(R f(T arg), T arg) { if (identical(Zone._current, _rootZone)) return f(arg); return _rootRunUnary(null, null, this, f, arg);