mirror of
https://github.com/dart-lang/sdk
synced 2024-10-14 16:55:08 +00:00
Avoid type checks in Future.wait
CoreLibraryReviewExempt: Bypassing because Wasm-approver is OOO. Change-Id: I484e900c14f181f56083b6e90a0d1f34546c85e1 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/341504 Commit-Queue: Lasse Nielsen <lrn@google.com> Reviewed-by: Nate Bosch <nbosch@google.com> Reviewed-by: Martin Kustermann <kustermann@google.com> Reviewed-by: Stephen Adams <sra@google.com>
This commit is contained in:
parent
a261196ea7
commit
712df96202
|
@ -480,34 +480,39 @@ abstract interface class Future<T> {
|
|||
final _Future<List<T>> _future = _Future<List<T>>();
|
||||
List<T?>? values; // Collects the values. Set to null on error.
|
||||
int remaining = 0; // How many futures are we waiting for.
|
||||
late Object error; // The first error from a future.
|
||||
late StackTrace stackTrace; // The stackTrace that came with the error.
|
||||
Object? error; // The first error from a future.
|
||||
StackTrace? stackTrace; // The stackTrace that came with the error.
|
||||
|
||||
// Handle an error from any of the futures.
|
||||
void handleError(Object theError, StackTrace theStackTrace) {
|
||||
remaining--;
|
||||
var remainingResults = --remaining;
|
||||
List<T?>? valueList = values;
|
||||
if (valueList != null) {
|
||||
// First error, set state to represent error having already happened.
|
||||
values = null;
|
||||
error = theError;
|
||||
stackTrace = theStackTrace;
|
||||
// Then clean up any already successfully produced results.
|
||||
if (cleanUp != null) {
|
||||
for (var value in valueList) {
|
||||
if (value != null) {
|
||||
// Ensure errors from cleanUp are uncaught.
|
||||
// Ensure errors from `cleanUp` are uncaught.
|
||||
T cleanUpValue = value;
|
||||
new Future.sync(() {
|
||||
Future.sync(() {
|
||||
cleanUp(cleanUpValue);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
values = null;
|
||||
if (remaining == 0 || eagerError) {
|
||||
if (remainingResults == 0 || eagerError) {
|
||||
_future._completeError(theError, theStackTrace);
|
||||
} else {
|
||||
error = theError;
|
||||
stackTrace = theStackTrace;
|
||||
}
|
||||
} else if (remaining == 0 && !eagerError) {
|
||||
_future._completeError(error, stackTrace);
|
||||
} else {
|
||||
// Not the first error.
|
||||
if (remainingResults == 0 && !eagerError) {
|
||||
// Last future completed, non-eagerly report the first error.
|
||||
_future._completeError(error!, stackTrace!);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -517,24 +522,27 @@ abstract interface class Future<T> {
|
|||
for (var future in futures) {
|
||||
int pos = remaining;
|
||||
future.then((T value) {
|
||||
remaining--;
|
||||
var remainingResults = --remaining;
|
||||
List<T?>? valueList = values;
|
||||
if (valueList != null) {
|
||||
// No errors yet.
|
||||
assert(valueList[pos] == null);
|
||||
valueList[pos] = value;
|
||||
if (remaining == 0) {
|
||||
_future._completeWithValue(List<T>.from(valueList));
|
||||
if (remainingResults == 0) {
|
||||
_future._completeWithValue(
|
||||
[for (var value in valueList) value as T]);
|
||||
}
|
||||
} else {
|
||||
// Prior error, clean-up this value if necessary.
|
||||
if (cleanUp != null && value != null) {
|
||||
// Ensure errors from cleanUp are uncaught.
|
||||
new Future.sync(() {
|
||||
Future.sync(() {
|
||||
cleanUp(value);
|
||||
});
|
||||
}
|
||||
if (remaining == 0 && !eagerError) {
|
||||
// If eagerError is false, and valueList is null, then
|
||||
// error and stackTrace have been set in handleError above.
|
||||
_future._completeError(error, stackTrace);
|
||||
if (remainingResults == 0 && !eagerError) {
|
||||
// Last future completed, non-eagerly report the first error.
|
||||
_future._completeError(error!, stackTrace!);
|
||||
}
|
||||
}
|
||||
}, onError: handleError);
|
||||
|
@ -544,9 +552,10 @@ abstract interface class Future<T> {
|
|||
remaining++;
|
||||
}
|
||||
if (remaining == 0) {
|
||||
// No elements in iterable.
|
||||
return _future.._completeWithValue(<T>[]);
|
||||
}
|
||||
values = new List<T?>.filled(remaining, null);
|
||||
values = List<T?>.filled(remaining, null);
|
||||
} catch (e, st) {
|
||||
// The error must have been thrown while iterating over the futures
|
||||
// list, or while installing a callback handler on the future.
|
||||
|
@ -1338,8 +1347,5 @@ void _asyncCompleteWithErrorCallback(
|
|||
} else {
|
||||
stackTrace ??= AsyncError.defaultStackTrace(error);
|
||||
}
|
||||
if (stackTrace == null) {
|
||||
throw "unreachable"; // TODO(lrn): Remove when type promotion works.
|
||||
}
|
||||
result._asyncCompleteError(error, stackTrace);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue