237ba8de01
Change-Id: I13ecd6339afd62cb5ebeb29c29d80470bcc22671 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/425146 Auto-Submit: Bob Nystrom <rnystrom@google.com> Commit-Queue: Lasse Nielsen <lrn@google.com> Reviewed-by: Lasse Nielsen <lrn@google.com>
129 lines
3.5 KiB
Dart
129 lines
3.5 KiB
Dart
// Copyright (c) 2025, the Dart project authors. Please see the AUTHORS file
|
|
// for details. All rights reserved. Use of this source code is governed by a
|
|
// BSD-style license that can be found in the LICENSE file.
|
|
|
|
import 'dart:async';
|
|
import 'dart:ffi';
|
|
|
|
void main() async {
|
|
print(
|
|
'returnRegularFuture returns: '
|
|
'${await returnRegularFuture(5)}',
|
|
);
|
|
print(
|
|
'sumIntStream(useAsyncStar = false) returns: '
|
|
'${await sumIntStream(5, 1, false)}',
|
|
);
|
|
print(
|
|
'sumIntStream(useAsyncStar = true) returns: '
|
|
'${await sumIntStream(5, 1, true)}',
|
|
);
|
|
}
|
|
|
|
Future<int> returnRegularFuture(int delayMs) async {
|
|
await Future.delayed(Duration(milliseconds: 5));
|
|
return 256;
|
|
}
|
|
|
|
Future<int> returnMicrotaskFuture(int delayMs) => Future.microtask(() async {
|
|
await Future.delayed(Duration(milliseconds: delayMs));
|
|
return 256;
|
|
});
|
|
|
|
Stream<int> produceIntStreamWithAsyncStar(int count, int delayMs) async* {
|
|
final delay = Duration(milliseconds: delayMs);
|
|
|
|
for (var i = 0; i < count; i++) {
|
|
await Future.delayed(delay);
|
|
yield i;
|
|
}
|
|
}
|
|
|
|
Stream<int> produceIntStreamWithController(int count, int delayMs) {
|
|
final delay = Duration(milliseconds: delayMs);
|
|
|
|
final sc = StreamController<int>();
|
|
(() async {
|
|
for (var i = 0; i < count; i++) {
|
|
await Future.delayed(delay);
|
|
sc.add(i);
|
|
}
|
|
sc.close();
|
|
})();
|
|
return sc.stream;
|
|
}
|
|
|
|
Future<int> sumIntStream(int count, int delayMs, bool useAsyncStar) async {
|
|
final stream = useAsyncStar
|
|
? produceIntStreamWithAsyncStar(count, delayMs)
|
|
: produceIntStreamWithController(count, delayMs);
|
|
var sum = 0;
|
|
await for (var value in stream) {
|
|
sum += value;
|
|
}
|
|
return sum;
|
|
}
|
|
|
|
Future<int> awaitAndMultiply(Future<int> a, Future<int> b) async =>
|
|
(await a) * (await b);
|
|
|
|
class AwaitAndMultiplyCall {
|
|
final _a = Completer<int>();
|
|
final _b = Completer<int>();
|
|
|
|
Future<int> getA() => _a.future;
|
|
Future<int> getB() => _b.future;
|
|
|
|
@pragma('vm:entry-point', 'call')
|
|
void setA(int value) => _a.complete(value);
|
|
@pragma('vm:entry-point', 'call')
|
|
void setB(int value) => _b.complete(value);
|
|
}
|
|
|
|
@pragma('vm:entry-point', 'call')
|
|
AwaitAndMultiplyCall awaitAndMultiplyC(int callbackPtr, int contextPtr) {
|
|
final call = AwaitAndMultiplyCall();
|
|
() async {
|
|
Pointer<NativeFunction<Void Function(Pointer<Opaque>, Int64)>>.fromAddress(
|
|
callbackPtr,
|
|
).asFunction<void Function(Pointer<Opaque>, int)>()(
|
|
Pointer<Opaque>.fromAddress(contextPtr),
|
|
await awaitAndMultiply(call.getA(), call.getB()),
|
|
);
|
|
}();
|
|
return call;
|
|
}
|
|
|
|
@pragma('vm:entry-point', 'call')
|
|
// C-friendly wrapper over [returnRegularFuture].
|
|
void returnRegularFutureC(
|
|
int delayMs,
|
|
bool useMicrotask,
|
|
int callbackPtr,
|
|
int contextPtr,
|
|
) async =>
|
|
Pointer<NativeFunction<Void Function(Pointer<Opaque>, Int64)>>.fromAddress(
|
|
callbackPtr,
|
|
).asFunction<void Function(Pointer<Opaque>, int)>()(
|
|
Pointer<Opaque>.fromAddress(contextPtr),
|
|
await (useMicrotask
|
|
? returnMicrotaskFuture(delayMs)
|
|
: returnRegularFuture(delayMs)),
|
|
);
|
|
|
|
@pragma('vm:entry-point', 'call')
|
|
// C-friendly wrapper over [sumIntStream].
|
|
void sumIntStreamC(
|
|
int count,
|
|
int delayMs,
|
|
bool useAsyncStar,
|
|
int callbackPtr,
|
|
int contextPtr,
|
|
) async =>
|
|
Pointer<NativeFunction<Void Function(Pointer<Opaque>, Int64)>>.fromAddress(
|
|
callbackPtr,
|
|
).asFunction<void Function(Pointer<Opaque>, int)>()(
|
|
Pointer<Opaque>.fromAddress(contextPtr),
|
|
await sumIntStream(count, delayMs, useAsyncStar),
|
|
);
|