Version 2.12.0-70.0.dev
Merge commit '2149369ffde332a585c274ec50565f92fa6fd03e' into 'dev'
diff --git a/pkg/analyzer/lib/src/dart/micro/cider_byte_store.dart b/pkg/analyzer/lib/src/dart/micro/cider_byte_store.dart
index 9fd158d..2d4c16b 100644
--- a/pkg/analyzer/lib/src/dart/micro/cider_byte_store.dart
+++ b/pkg/analyzer/lib/src/dart/micro/cider_byte_store.dart
@@ -35,10 +35,17 @@
void release(Iterable<int> ids);
}
+class CiderByteStoreTestView {
+ int length = 0;
+}
+
class CiderCachedByteStore implements CiderByteStore {
final Cache<String, CiderCacheEntry> _cache;
int idCounter = 0;
+ /// This field gets value only during testing.
+ CiderByteStoreTestView testView;
+
CiderCachedByteStore(int maxCacheSize)
: _cache = Cache<String, CiderCacheEntry>(
maxCacheSize, (v) => v.data.bytes.length);
@@ -59,6 +66,7 @@
idCounter++;
var entry = CiderCacheEntry(signature, CacheData(idCounter, bytes));
_cache.put(key, entry);
+ testView?.length++;
return entry.data;
}
diff --git a/pkg/analyzer/lib/src/dart/micro/library_graph.dart b/pkg/analyzer/lib/src/dart/micro/library_graph.dart
index 96b4548..b9b4b8e 100644
--- a/pkg/analyzer/lib/src/dart/micro/library_graph.dart
+++ b/pkg/analyzer/lib/src/dart/micro/library_graph.dart
@@ -519,6 +519,13 @@
}
}
+ /// Clears all the cached files. Returns the list of ids of all the removed
+ /// files.
+ Set<int> collectSharedDataIdentifiers() {
+ var files = _pathToFile.values.map((file) => file.id).toSet();
+ return files;
+ }
+
FeatureSet contextFeatureSet(
String path,
Uri uri,
diff --git a/pkg/analyzer/lib/src/dart/micro/resolve_file.dart b/pkg/analyzer/lib/src/dart/micro/resolve_file.dart
index 26bed2a..82e250c 100644
--- a/pkg/analyzer/lib/src/dart/micro/resolve_file.dart
+++ b/pkg/analyzer/lib/src/dart/micro/resolve_file.dart
@@ -147,6 +147,13 @@
}
}
+ /// Collects all the cached artifacts and add all the cache id's for the
+ /// removed artifacts to [removedCacheIds].
+ void collectSharedDataIdentifiers() {
+ removedCacheIds.addAll(fsState.collectSharedDataIdentifiers());
+ removedCacheIds.addAll(libraryContext.collectSharedDataIdentifiers());
+ }
+
@deprecated
void dispose() {}
@@ -631,6 +638,14 @@
);
}
+ /// Clears all the loaded libraries. Returns the cache ids for the removed
+ /// artifacts.
+ Set<int> collectSharedDataIdentifiers() {
+ var ids = loadedBundles.map((cycle) => cycle.id).toSet();
+ loadedBundles.clear();
+ return ids;
+ }
+
/// Load data required to access elements of the given [targetLibrary].
void load2({
@required FileState targetLibrary,
diff --git a/pkg/analyzer/test/src/dart/micro/file_resolution.dart b/pkg/analyzer/test/src/dart/micro/file_resolution.dart
index b03a488..1cf1d10 100644
--- a/pkg/analyzer/test/src/dart/micro/file_resolution.dart
+++ b/pkg/analyzer/test/src/dart/micro/file_resolution.dart
@@ -22,7 +22,7 @@
class FileResolutionTest with ResourceProviderMixin, ResolutionTest {
static final String _testFile = '/workspace/dart/test/lib/test.dart';
- final CiderByteStore byteStore =
+ final CiderCachedByteStore byteStore =
CiderCachedByteStore(20 * 1024 * 1024 /* 20 MB */);
final StringBuffer logBuffer = StringBuffer();
@@ -45,6 +45,7 @@
convertPath(_testFile),
);
+ byteStore.testView = CiderByteStoreTestView();
fileResolver = FileResolver.from(
logger: logger,
resourceProvider: resourceProvider,
diff --git a/pkg/analyzer/test/src/dart/micro/simple_file_resolver_test.dart b/pkg/analyzer/test/src/dart/micro/simple_file_resolver_test.dart
index 082445b..b462f39 100644
--- a/pkg/analyzer/test/src/dart/micro/simple_file_resolver_test.dart
+++ b/pkg/analyzer/test/src/dart/micro/simple_file_resolver_test.dart
@@ -3,6 +3,7 @@
// BSD-style license that can be found in the LICENSE file.
import 'package:analyzer/src/dart/error/syntactic_errors.dart';
+import 'package:analyzer/src/dart/micro/cider_byte_store.dart';
import 'package:analyzer/src/error/codes.dart';
import 'package:analyzer/src/lint/registry.dart';
import 'package:matcher/matcher.dart';
@@ -309,6 +310,19 @@
assertType(findElement.topVar('b').type, 'int');
}
+ test_collectSharedDataIdentifiers() async {
+ var aPath = convertPath('/workspace/third_party/dart/aaa/lib/a.dart');
+
+ newFile(aPath, content: r'''
+class A {}
+''');
+
+ await resolveFile(aPath);
+ fileResolver.collectSharedDataIdentifiers();
+ expect(fileResolver.removedCacheIds.length,
+ (fileResolver.byteStore as CiderCachedByteStore).testView.length);
+ }
+
test_getErrors() {
addTestFile(r'''
var a = b;
diff --git a/runtime/tests/vm/dart/causal_stacks/utils.dart b/runtime/tests/vm/dart/causal_stacks/utils.dart
index a0fbb82..c77ce92 100644
--- a/runtime/tests/vm/dart/causal_stacks/utils.dart
+++ b/runtime/tests/vm/dart/causal_stacks/utils.dart
@@ -13,12 +13,12 @@
// Test functions:
Future<void> throwSync() {
- throw '';
+ throw 'throw from throwSync';
}
Future<void> throwAsync() async {
await 0;
- throw '';
+ throw 'throw from throwAsync';
}
// ----
@@ -170,6 +170,14 @@
]);
}
+// ----
+// Scenario: Future.whenComplete:
+// ----
+
+Future futureSyncWhenComplete() {
+ return Future.sync(throwAsync).whenComplete(() => 'nop');
+}
+
// Helpers:
// We want lines that either start with a frame index or an async gap marker.
@@ -664,7 +672,7 @@
final awaitTimeoutExpected = const <String>[
r'^#0 throwAsync \(.*/utils.dart:21(:3)?\)$',
- r'^^<asynchronous suspension>$',
+ r'^<asynchronous suspension>$',
r'^#1 awaitTimeout ',
];
await doTestAwait(
@@ -706,7 +714,7 @@
final awaitWaitExpected = const <String>[
r'^#0 throwAsync \(.*/utils.dart:21(:3)?\)$',
- r'^^<asynchronous suspension>$',
+ r'^<asynchronous suspension>$',
r'^#1 awaitWait ',
];
await doTestAwait(
@@ -745,6 +753,49 @@
r'^#6 _RawReceivePortImpl._handleMessage ',
],
debugInfoFilename);
+
+ final futureSyncWhenCompleteExpected = const <String>[
+ r'^#0 throwAsync \(.*/utils.dart:21(:3)?\)$',
+ r'^<asynchronous suspension>$',
+ r'^#1 new Future.sync ',
+ r'^#2 futureSyncWhenComplete ',
+ ];
+ await doTestAwait(
+ futureSyncWhenComplete,
+ futureSyncWhenCompleteExpected +
+ const <String>[
+ r'^#3 doTestAwait ',
+ r'^#4 doTestsCausal ',
+ r'^<asynchronous suspension>$',
+ r'^#5 main \(.+\)$',
+ r'^#6 _delayEntrypointInvocation.<anonymous closure> ',
+ r'^#7 _RawReceivePortImpl._handleMessage ',
+ ],
+ debugInfoFilename);
+ await doTestAwaitThen(
+ futureSyncWhenComplete,
+ futureSyncWhenCompleteExpected +
+ const <String>[
+ r'^#3 doTestAwaitThen ',
+ r'^#4 doTestsCausal ',
+ r'^<asynchronous suspension>$',
+ r'^#5 main \(.+\)$',
+ r'^#6 _delayEntrypointInvocation.<anonymous closure> ',
+ r'^#7 _RawReceivePortImpl._handleMessage ',
+ ],
+ debugInfoFilename);
+ await doTestAwaitCatchError(
+ futureSyncWhenComplete,
+ futureSyncWhenCompleteExpected +
+ const <String>[
+ r'^#3 doTestAwaitCatchError ',
+ r'^#4 doTestsCausal ',
+ r'^<asynchronous suspension>$',
+ r'^#5 main \(.+\)$',
+ r'^#6 _delayEntrypointInvocation.<anonymous closure> ',
+ r'^#7 _RawReceivePortImpl._handleMessage ',
+ ],
+ debugInfoFilename);
}
// For: --no-causal-async-stacks --no-lazy-async-stacks
@@ -1065,12 +1116,10 @@
r'^#8 _runPendingImmediateCallback ',
r'^#9 _RawReceivePortImpl._handleMessage ',
];
- await doTestAwait(
- awaitTimeout, awaitTimeoutExpected + const <String>[], debugInfoFilename);
- await doTestAwaitThen(
- awaitTimeout, awaitTimeoutExpected + const <String>[], debugInfoFilename);
+ await doTestAwait(awaitTimeout, awaitTimeoutExpected, debugInfoFilename);
+ await doTestAwaitThen(awaitTimeout, awaitTimeoutExpected, debugInfoFilename);
await doTestAwaitCatchError(
- awaitTimeout, awaitTimeoutExpected + const <String>[], debugInfoFilename);
+ awaitTimeout, awaitTimeoutExpected, debugInfoFilename);
final awaitWaitExpected = const <String>[
r'#0 throwAsync \(.*/utils.dart:21(:3)?\)$',
@@ -1084,12 +1133,28 @@
r'^#8 _runPendingImmediateCallback ',
r'^#9 _RawReceivePortImpl._handleMessage ',
];
- await doTestAwait(
- awaitWait, awaitWaitExpected + const <String>[], debugInfoFilename);
- await doTestAwaitThen(
- awaitWait, awaitWaitExpected + const <String>[], debugInfoFilename);
- await doTestAwaitCatchError(
- awaitWait, awaitWaitExpected + const <String>[], debugInfoFilename);
+ await doTestAwait(awaitWait, awaitWaitExpected, debugInfoFilename);
+ await doTestAwaitThen(awaitWait, awaitWaitExpected, debugInfoFilename);
+ await doTestAwaitCatchError(awaitWait, awaitWaitExpected, debugInfoFilename);
+
+ {
+ final expected = const <String>[
+ r'^#0 throwAsync \(.*/utils.dart:21(:3)?\)$',
+ r'^#1 _RootZone.runUnary ',
+ r'^#2 _FutureListener.handleValue ',
+ r'^#3 Future._propagateToListeners.handleValueCallback ',
+ r'^#4 Future._propagateToListeners ',
+ r'^#5 Future.(_addListener|_prependListeners).<anonymous closure> ',
+ r'^#6 _microtaskLoop ',
+ r'^#7 _startMicrotaskLoop ',
+ r'^#8 _runPendingImmediateCallback ',
+ r'^#9 _RawReceivePortImpl._handleMessage ',
+ ];
+ await doTestAwait(futureSyncWhenComplete, expected, debugInfoFilename);
+ await doTestAwaitThen(futureSyncWhenComplete, expected, debugInfoFilename);
+ await doTestAwaitCatchError(
+ futureSyncWhenComplete, expected, debugInfoFilename);
+ }
}
// For: --lazy-async-stacks
@@ -1381,7 +1446,7 @@
],
debugInfoFilename);
await doTestAwaitCatchError(
- awaitTimeout, awaitTimeoutExpected + const <String>[], debugInfoFilename);
+ awaitTimeout, awaitTimeoutExpected, debugInfoFilename);
final awaitWaitExpected = const <String>[
r'^#0 throwAsync \(.*/utils.dart:21(:3)?\)$',
@@ -1411,6 +1476,34 @@
r'^<asynchronous suspension>$',
],
debugInfoFilename);
- await doTestAwaitCatchError(
- awaitWait, awaitWaitExpected + const <String>[], debugInfoFilename);
+ await doTestAwaitCatchError(awaitWait, awaitWaitExpected, debugInfoFilename);
+
+ {
+ final expected = const <String>[
+ r'^#0 throwAsync \(.*/utils.dart:21(:3)?\)$',
+ r'^<asynchronous suspension>$',
+ ];
+ await doTestAwait(
+ futureSyncWhenComplete,
+ expected +
+ const <String>[
+ r'^#1 doTestAwait ',
+ r'^<asynchronous suspension>$',
+ r'^#2 doTestsLazy ',
+ r'^<asynchronous suspension>$',
+ r'^#3 main ',
+ r'^<asynchronous suspension>$',
+ ],
+ debugInfoFilename);
+ await doTestAwaitThen(
+ futureSyncWhenComplete,
+ expected +
+ const <String>[
+ r'^#1 doTestAwaitThen.<anonymous closure> ',
+ r'^<asynchronous suspension>$',
+ ],
+ debugInfoFilename);
+ await doTestAwaitCatchError(
+ 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 3b6facb..f511d4c 100644
--- a/runtime/tests/vm/dart_2/causal_stacks/utils.dart
+++ b/runtime/tests/vm/dart_2/causal_stacks/utils.dart
@@ -13,12 +13,12 @@
// Test functions:
Future<void> throwSync() {
- throw '';
+ throw 'throw from throwSync';
}
Future<void> throwAsync() async {
await 0;
- throw '';
+ throw 'throw from throwAsync';
}
// ----
@@ -170,6 +170,14 @@
]);
}
+// ----
+// Scenario: Future.whenComplete:
+// ----
+
+Future futureSyncWhenComplete() {
+ return Future.sync(throwAsync).whenComplete(() => 'nop');
+}
+
// Helpers:
// We want lines that either start with a frame index or an async gap marker.
@@ -664,7 +672,7 @@
final awaitTimeoutExpected = const <String>[
r'^#0 throwAsync \(.*/utils.dart:21(:3)?\)$',
- r'^^<asynchronous suspension>$',
+ r'^<asynchronous suspension>$',
r'^#1 awaitTimeout ',
];
await doTestAwait(
@@ -706,7 +714,7 @@
final awaitWaitExpected = const <String>[
r'^#0 throwAsync \(.*/utils.dart:21(:3)?\)$',
- r'^^<asynchronous suspension>$',
+ r'^<asynchronous suspension>$',
r'^#1 awaitWait ',
];
await doTestAwait(
@@ -745,6 +753,49 @@
r'^#6 _RawReceivePortImpl._handleMessage ',
],
debugInfoFilename);
+
+ final futureSyncWhenCompleteExpected = const <String>[
+ r'^#0 throwAsync \(.*/utils.dart:21(:3)?\)$',
+ r'^<asynchronous suspension>$',
+ r'^#1 new Future.sync ',
+ r'^#2 futureSyncWhenComplete ',
+ ];
+ await doTestAwait(
+ futureSyncWhenComplete,
+ futureSyncWhenCompleteExpected +
+ const <String>[
+ r'^#3 doTestAwait ',
+ r'^#4 doTestsCausal ',
+ r'^<asynchronous suspension>$',
+ r'^#5 main \(.+\)$',
+ r'^#6 _delayEntrypointInvocation.<anonymous closure> ',
+ r'^#7 _RawReceivePortImpl._handleMessage ',
+ ],
+ debugInfoFilename);
+ await doTestAwaitThen(
+ futureSyncWhenComplete,
+ futureSyncWhenCompleteExpected +
+ const <String>[
+ r'^#3 doTestAwaitThen ',
+ r'^#4 doTestsCausal ',
+ r'^<asynchronous suspension>$',
+ r'^#5 main \(.+\)$',
+ r'^#6 _delayEntrypointInvocation.<anonymous closure> ',
+ r'^#7 _RawReceivePortImpl._handleMessage ',
+ ],
+ debugInfoFilename);
+ await doTestAwaitCatchError(
+ futureSyncWhenComplete,
+ futureSyncWhenCompleteExpected +
+ const <String>[
+ r'^#3 doTestAwaitCatchError ',
+ r'^#4 doTestsCausal ',
+ r'^<asynchronous suspension>$',
+ r'^#5 main \(.+\)$',
+ r'^#6 _delayEntrypointInvocation.<anonymous closure> ',
+ r'^#7 _RawReceivePortImpl._handleMessage ',
+ ],
+ debugInfoFilename);
}
// For: --no-causal-async-stacks --no-lazy-async-stacks
@@ -1065,12 +1116,10 @@
r'^#8 _runPendingImmediateCallback ',
r'^#9 _RawReceivePortImpl._handleMessage ',
];
- await doTestAwait(
- awaitTimeout, awaitTimeoutExpected + const <String>[], debugInfoFilename);
- await doTestAwaitThen(
- awaitTimeout, awaitTimeoutExpected + const <String>[], debugInfoFilename);
+ await doTestAwait(awaitTimeout, awaitTimeoutExpected, debugInfoFilename);
+ await doTestAwaitThen(awaitTimeout, awaitTimeoutExpected, debugInfoFilename);
await doTestAwaitCatchError(
- awaitTimeout, awaitTimeoutExpected + const <String>[], debugInfoFilename);
+ awaitTimeout, awaitTimeoutExpected, debugInfoFilename);
final awaitWaitExpected = const <String>[
r'#0 throwAsync \(.*/utils.dart:21(:3)?\)$',
@@ -1084,12 +1133,28 @@
r'^#8 _runPendingImmediateCallback ',
r'^#9 _RawReceivePortImpl._handleMessage ',
];
- await doTestAwait(
- awaitWait, awaitWaitExpected + const <String>[], debugInfoFilename);
- await doTestAwaitThen(
- awaitWait, awaitWaitExpected + const <String>[], debugInfoFilename);
- await doTestAwaitCatchError(
- awaitWait, awaitWaitExpected + const <String>[], debugInfoFilename);
+ await doTestAwait(awaitWait, awaitWaitExpected, debugInfoFilename);
+ await doTestAwaitThen(awaitWait, awaitWaitExpected, debugInfoFilename);
+ await doTestAwaitCatchError(awaitWait, awaitWaitExpected, debugInfoFilename);
+
+ {
+ final expected = const <String>[
+ r'^#0 throwAsync \(.*/utils.dart:21(:3)?\)$',
+ r'^#1 _RootZone.runUnary ',
+ r'^#2 _FutureListener.handleValue ',
+ r'^#3 Future._propagateToListeners.handleValueCallback ',
+ r'^#4 Future._propagateToListeners ',
+ r'^#5 Future.(_addListener|_prependListeners).<anonymous closure> ',
+ r'^#6 _microtaskLoop ',
+ r'^#7 _startMicrotaskLoop ',
+ r'^#8 _runPendingImmediateCallback ',
+ r'^#9 _RawReceivePortImpl._handleMessage ',
+ ];
+ await doTestAwait(futureSyncWhenComplete, expected, debugInfoFilename);
+ await doTestAwaitThen(futureSyncWhenComplete, expected, debugInfoFilename);
+ await doTestAwaitCatchError(
+ futureSyncWhenComplete, expected, debugInfoFilename);
+ }
}
// For: --lazy-async-stacks
@@ -1381,7 +1446,7 @@
],
debugInfoFilename);
await doTestAwaitCatchError(
- awaitTimeout, awaitTimeoutExpected + const <String>[], debugInfoFilename);
+ awaitTimeout, awaitTimeoutExpected, debugInfoFilename);
final awaitWaitExpected = const <String>[
r'^#0 throwAsync \(.*/utils.dart:21(:3)?\)$',
@@ -1411,6 +1476,34 @@
r'^<asynchronous suspension>$',
],
debugInfoFilename);
- await doTestAwaitCatchError(
- awaitWait, awaitWaitExpected + const <String>[], debugInfoFilename);
+ await doTestAwaitCatchError(awaitWait, awaitWaitExpected, debugInfoFilename);
+
+ {
+ final expect = const <String>[
+ r'^#0 throwAsync \(.*/utils.dart:21(:3)?\)$',
+ r'^<asynchronous suspension>$',
+ ];
+ await doTestAwait(
+ futureSyncWhenComplete,
+ expect +
+ const <String>[
+ r'^#1 doTestAwait ',
+ r'^<asynchronous suspension>$',
+ r'^#2 doTestsLazy ',
+ r'^<asynchronous suspension>$',
+ r'^#3 main ',
+ r'^<asynchronous suspension>$',
+ ],
+ debugInfoFilename);
+ await doTestAwaitThen(
+ futureSyncWhenComplete,
+ expect +
+ const <String>[
+ r'^#1 doTestAwaitThen.<anonymous closure> ',
+ r'^<asynchronous suspension>$',
+ ],
+ debugInfoFilename);
+ await doTestAwaitCatchError(
+ futureSyncWhenComplete, expect, debugInfoFilename);
+ }
}
diff --git a/runtime/vm/regexp_assembler_ir.cc b/runtime/vm/regexp_assembler_ir.cc
index 0111496..003ceb7 100644
--- a/runtime/vm/regexp_assembler_ir.cc
+++ b/runtime/vm/regexp_assembler_ir.cc
@@ -166,7 +166,7 @@
char_in_capture_ = Local(Symbols::char_in_capture());
char_in_match_ = Local(Symbols::char_in_match());
index_temp_ = Local(Symbols::index_temp());
- result_ = Local(Symbols::result());
+ result_ = Local(Symbols::c_result());
string_param_ = Parameter(Symbols::string_param(),
RegExpMacroAssembler::kParamStringIndex);
diff --git a/runtime/vm/stack_trace.cc b/runtime/vm/stack_trace.cc
index 5b146ff..502a4f9 100644
--- a/runtime/vm/stack_trace.cc
+++ b/runtime/vm/stack_trace.cc
@@ -12,7 +12,9 @@
// Keep in sync with
// sdk/lib/async/stream_controller.dart:_StreamController._STATE_SUBSCRIBED.
-const intptr_t kStreamController_StateSubscribed = 1;
+const intptr_t k_StreamController__STATE_SUBSCRIBED = 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
@@ -66,6 +68,8 @@
stream_iterator_class(Class::Handle(zone)),
future_result_or_listeners_field(Field::Handle(zone)),
callback_field(Field::Handle(zone)),
+ future_listener_state_field(Field::Handle(zone)),
+ future_listener_result_field(Field::Handle(zone)),
controller_controller_field(Field::Handle(zone)),
var_data_field(Field::Handle(zone)),
state_field(Field::Handle(zone)),
@@ -107,6 +111,12 @@
callback_field =
future_listener_class.LookupFieldAllowPrivate(Symbols::callback());
ASSERT(!callback_field.IsNull());
+ future_listener_state_field =
+ future_listener_class.LookupFieldAllowPrivate(Symbols::state());
+ ASSERT(!future_listener_state_field.IsNull());
+ future_listener_result_field =
+ future_listener_class.LookupFieldAllowPrivate(Symbols::result());
+ ASSERT(!future_listener_result_field.IsNull());
// - async*:
controller_controller_field =
async_start_stream_controller_class.LookupFieldAllowPrivate(
@@ -126,16 +136,24 @@
ASSERT(!state_data_field.IsNull());
}
-ClosurePtr CallerClosureFinder::GetCallerInFutureImpl(const Object& future_) {
- ASSERT(!future_.IsNull());
- ASSERT(future_.GetClassId() == future_impl_class.id());
+ClosurePtr CallerClosureFinder::GetCallerInFutureImpl(const Object& future) {
+ ASSERT(!future.IsNull());
+ ASSERT(future.GetClassId() == future_impl_class.id());
- listener_ =
- Instance::Cast(future_).GetField(future_result_or_listeners_field);
+ listener_ = Instance::Cast(future).GetField(future_result_or_listeners_field);
if (listener_.GetClassId() != future_listener_class.id()) {
return Closure::null();
}
+ // 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);
// This happens for e.g.: await f().catchError(..);
if (callback_.IsNull()) {
@@ -166,7 +184,7 @@
state_ = Instance::Cast(controller_).GetField(state_field);
ASSERT(state_.IsSmi());
- if (Smi::Cast(state_).Value() != kStreamController_StateSubscribed) {
+ if (Smi::Cast(state_).Value() != k_StreamController__STATE_SUBSCRIBED) {
return Closure::null();
}
diff --git a/runtime/vm/stack_trace.h b/runtime/vm/stack_trace.h
index 660746a..460074b 100644
--- a/runtime/vm/stack_trace.h
+++ b/runtime/vm/stack_trace.h
@@ -54,6 +54,8 @@
Field& future_result_or_listeners_field;
Field& callback_field;
+ Field& future_listener_state_field;
+ Field& future_listener_result_field;
Field& controller_controller_field;
Field& var_data_field;
Field& state_field;
diff --git a/runtime/vm/symbols.h b/runtime/vm/symbols.h
index bbee27e..6e408a0 100644
--- a/runtime/vm/symbols.h
+++ b/runtime/vm/symbols.h
@@ -481,10 +481,12 @@
V(position_registers, ":position_registers") \
V(print, "print") \
V(removeLast, "removeLast") \
- V(result, ":result") \
+ V(c_result, ":result") \
+ V(result, "result") \
V(stack, ":stack") \
V(stack_pointer, ":stack_pointer") \
V(start_index_param, ":start_index_param") \
+ V(state, "state") \
V(string_param, ":string_param") \
V(string_param_length, ":string_param_length") \
V(toString, "toString") \
diff --git a/sdk/lib/async/future_impl.dart b/sdk/lib/async/future_impl.dart
index 1b3e02f..862c871 100644
--- a/sdk/lib/async/future_impl.dart
+++ b/sdk/lib/async/future_impl.dart
@@ -74,15 +74,22 @@
static const int maskType =
maskValue | maskError | maskTestError | maskWhencomplete;
static const int stateIsAwait = 16;
+
// Listeners on the same future are linked through this link.
_FutureListener? _nextListener;
+
// The future to complete when this listener is activated.
+ @pragma("vm:entry-point")
final _Future<T> result;
+
// Which fields means what.
+ @pragma("vm:entry-point")
final int state;
+
// Used for then/whenDone callback and error test
@pragma("vm:entry-point")
final Function? callback;
+
// Used for error callbacks.
final Function? errorCallback;
diff --git a/tools/VERSION b/tools/VERSION
index d025231..da26c81 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
MAJOR 2
MINOR 12
PATCH 0
-PRERELEASE 69
+PRERELEASE 70
PRERELEASE_PATCH 0
\ No newline at end of file