Unverified Commit 3420b9c5 authored by jellynoone's avatar jellynoone Committed by GitHub

Fix `compute` in unsound null safety debug mode (#100544)

parent 613f16c1
......@@ -65,7 +65,6 @@ Future<R> compute<Q, R>(isolates.ComputeCallback<Q, R> callback, Q message, { St
switch (type) {
// success; see _buildSuccessResponse
case 1:
assert(response[0] is R);
return response[0] as R;
// native error; see Isolate.addErrorListener
......@@ -78,10 +77,7 @@ Future<R> compute<Q, R>(isolates.ComputeCallback<Q, R> callback, Q message, { St
// caught error; see _buildErrorResponse
case 3:
default:
assert(type == 3);
assert(response[0] is Object);
assert(response[1] is StackTrace);
assert(response[2] == null);
assert(type == 3 && response[2] == null);
await Future<Never>.error(
response[0] as Object,
......
// Copyright 2014 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// @dart=2.9
// Running in unsound null-safety mode is intended to test for potential miscasts
// or invalid assertions.
import 'package:flutter/src/foundation/_isolates_io.dart';
import 'package:flutter/src/foundation/isolates.dart' as isolates;
int returnInt(int arg) {
return arg;
}
Future<int> returnIntAsync(int arg) {
return Future<int>.value(arg);
}
Future<void> testCompute<T>(isolates.ComputeCallback<T, T> callback, T input) async {
if (input != await compute(callback, input)) {
throw Exception('compute returned bad result');
}
}
void main() async {
await testCompute(returnInt, 10);
await testCompute(returnInt, null);
await testCompute(returnIntAsync, 10);
await testCompute(returnIntAsync, null);
}
// Copyright 2014 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// @dart=2.9
// Running in unsound null-safety mode is intended to test for potential miscasts
// or invalid assertions.
import 'package:flutter/src/foundation/_isolates_io.dart';
int throwNull(int arg) {
throw null;
}
void main() async {
try {
await compute(throwNull, null);
} catch (e) {
if (e is! NullThrownError) {
throw Exception('compute returned bad result');
}
}
}
......@@ -80,7 +80,7 @@ Future<int> test5CallCompute(int value) {
return compute(test5, value);
}
Future<void> expectFileClosesAllPorts(String filename) async {
Future<void> expectFileSuccessfullyCompletes(String filename) async {
// Run a Dart script that calls compute().
// The Dart process will terminate only if the script exits cleanly with
// all isolate ports closed.
......@@ -90,7 +90,9 @@ Future<void> expectFileClosesAllPorts(String filename) async {
final String dartPath = fs.path.join(flutterRoot, 'bin', 'cache', 'dart-sdk', 'bin', 'dart');
final String packageRoot = fs.path.dirname(fs.path.fromUri(platform.script));
final String scriptPath = fs.path.join(packageRoot, 'test', 'foundation', filename);
final ProcessResult result = await Process.run(dartPath, <String>[scriptPath]);
// Enable asserts to also catch potentially invalid assertions.
final ProcessResult result = await Process.run(dartPath, <String>['run', '--enable-asserts', scriptPath]);
expect(result.exitCode, 0);
}
......@@ -159,6 +161,10 @@ String? testDebugName(_) {
return Isolate.current.debugName;
}
int? testReturnNull(_) {
return null;
}
void main() {
test('compute()', () async {
expect(await compute(test1, 0), 1);
......@@ -189,20 +195,30 @@ void main() {
expect(computeInvalidInstanceMethod(10), throwsArgumentError);
expect(await compute(testDebugName, null, debugLabel: 'debug_name'), 'debug_name');
expect(await compute(testReturnNull, null), null);
}, skip: kIsWeb); // [intended] isn't supported on the web.
group('compute closes all ports', () {
group('compute() closes all ports', () {
test('with valid message', () async {
await expectFileClosesAllPorts('_compute_caller.dart');
await expectFileSuccessfullyCompletes('_compute_caller.dart');
});
test('with invalid message', () async {
await expectFileClosesAllPorts('_compute_caller_invalid_message.dart');
await expectFileSuccessfullyCompletes('_compute_caller_invalid_message.dart');
});
test('with valid error', () async {
await expectFileClosesAllPorts('_compute_caller.dart');
await expectFileSuccessfullyCompletes('_compute_caller.dart');
});
test('with invalid error', () async {
await expectFileClosesAllPorts('_compute_caller_invalid_message.dart');
await expectFileSuccessfullyCompletes('_compute_caller_invalid_message.dart');
});
}, skip: kIsWeb); // [intended] isn't supported on the web.
group('compute() works with unsound null safety caller', () {
test('returning', () async {
await expectFileSuccessfullyCompletes('_compute_caller_unsound_null_safety.dart');
});
test('erroring', () async {
await expectFileSuccessfullyCompletes('_compute_caller_unsound_null_safety_error.dart');
});
}, skip: kIsWeb); // [intended] isn't supported on the web.
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment