[dart2wasm] Make dart compile wasm compiled apps disable dart.library.ffi

This is a follow-up to [0]. That CL changed dart2wasm's modular
transformer to issue an error if `dart:ffi` is imported.

Users of packages that have specialized code for the VM (which supports
FFI) use conditional imports based on `dart.library.ffi`. We don't want
the VM-specific code to be used for web in dart2wasm (as dart2wasm
doesn't support the entirety of `dart:ffi`).

As a result we're going to make `dart.library.ffi` be false in
coditional imports (as well as in
`const bool.fromEnvironment('dart.library.ffi')`).

[0] https://dart-review.googlesource.com/c/sdk/+/368568

Issue https://github.com/dart-lang/sdk/issues/55948
Issue https://github.com/flutter/flutter/issues/149984

Change-Id: I70a775278ab701d1fd2596521e378cb6364edac2
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/370580
Commit-Queue: Martin Kustermann <kustermann@google.com>
Reviewed-by: Srujan Gaddam <srujzs@google.com>
This commit is contained in:
Martin Kustermann
2024-06-11 09:28:40 +00:00
committed by Commit Queue
parent 324ba0c11f
commit 847c35612a
12 changed files with 70 additions and 10 deletions
@@ -85,6 +85,8 @@ class JsInteropChecks extends RecursiveVisitor {
final ExportChecker exportChecker;
final bool isDart2Wasm;
final List<String> _disallowedInteropLibrariesInDart2Wasm;
/// Native tests to exclude from checks on external.
// TODO(rileyporter): Use ExternalName from CFE to exclude native tests.
static final List<Pattern> _allowedNativeTestPatterns = [
@@ -107,7 +109,7 @@ class JsInteropChecks extends RecursiveVisitor {
// Negative lookahead to test the violation.
RegExp(
r'(?<!generated_)tests/lib/js/static_interop_test(?!/disallowed_interop_libraries_test.dart)'),
RegExp(r'(?<!generated_)tests/web/wasm'),
RegExp(r'(?<!generated_)tests/web/wasm/(?!ffi/).*'),
// Flutter tests.
RegExp(r'flutter/lib/web_ui/test'),
];
@@ -131,7 +133,7 @@ class JsInteropChecks extends RecursiveVisitor {
];
/// Interop libraries that cannot be used in dart2wasm.
static const _disallowedInteropLibrariesInDart2Wasm = [
static const _disallowedInteropLibrariesInDart2WasmByDefault = [
'package:js/js.dart',
'package:js/js_util.dart',
'dart:js_util',
@@ -163,12 +165,16 @@ class JsInteropChecks extends RecursiveVisitor {
JsInteropChecks(this._coreTypes, ClassHierarchy hierarchy, this._reporter,
this._nativeClasses,
{this.isDart2Wasm = false})
{this.isDart2Wasm = false, bool enableExperimentalFfi = false})
: exportChecker = ExportChecker(_reporter, _coreTypes.objectClass),
_functionToJSTarget = _coreTypes.index.getTopLevelProcedure(
'dart:js_interop', 'FunctionToJSExportedDartFunction|get#toJS'),
_staticTypeContext = StatefulStaticTypeContext.stacked(
TypeEnvironment(_coreTypes, hierarchy)) {
TypeEnvironment(_coreTypes, hierarchy)),
_disallowedInteropLibrariesInDart2Wasm = [
for (final entry in _disallowedInteropLibrariesInDart2WasmByDefault)
if (!(entry == 'dart:ffi' && enableExperimentalFfi)) entry
] {
extensionIndex =
ExtensionIndex(_coreTypes, _staticTypeContext.typeEnvironment);
}
+3 -1
View File
@@ -81,7 +81,9 @@ Future<CompilerOutput?> compileToModule(compiler.WasmCompilerOptions options,
mode = wasm.Mode.regular;
}
final WasmTarget target = WasmTarget(
removeAsserts: !options.translatorOptions.enableAsserts, mode: mode);
enableExperimentalFfi: options.translatorOptions.enableExperimentalFfi,
removeAsserts: !options.translatorOptions.enableAsserts,
mode: mode);
CompilerOptions compilerOptions = CompilerOptions()
..target = target
// This is a dummy directory that always exists. This option should be
+3
View File
@@ -88,6 +88,9 @@ final List<Option> options = [
StringOption(
"dump-kernel-after-tfa", (o, value) => o.dumpKernelAfterTfa = value,
hide: true),
Flag("enable-experimental-ffi",
(o, value) => o.translatorOptions.enableExperimentalFfi = value,
defaultsTo: _d.translatorOptions.enableExperimentalFfi),
];
Map<fe.ExperimentalFlag, bool> processFeExperimentalFlags(
+12 -4
View File
@@ -89,10 +89,14 @@ class ConstantResolver extends Transformer {
}
class WasmTarget extends Target {
WasmTarget({this.removeAsserts = false, this.mode = Mode.regular});
WasmTarget(
{this.enableExperimentalFfi = true,
this.removeAsserts = false,
this.mode = Mode.regular});
bool removeAsserts;
Mode mode;
final bool removeAsserts;
final Mode mode;
final bool enableExperimentalFfi;
Class? _growableList;
Class? _immutableList;
Class? _wasmDefaultMap;
@@ -206,7 +210,7 @@ class WasmTarget extends Target {
diagnosticReporter as DiagnosticReporter<Message, LocatedMessage>);
final jsInteropChecks = JsInteropChecks(
coreTypes, hierarchy, jsInteropReporter, _nativeClasses!,
isDart2Wasm: true);
isDart2Wasm: true, enableExperimentalFfi: enableExperimentalFfi);
// Process and validate first before doing anything with exports.
for (Library library in interopDependentLibraries) {
jsInteropChecks.visitLibrary(library);
@@ -497,6 +501,10 @@ class WasmTarget extends Target {
@override
Class concreteDoubleLiteralClass(CoreTypes coreTypes, double value) =>
_boxedDouble ??= coreTypes.index.getClass("dart:core", "_BoxedDouble");
@override
DartLibrarySupport get dartLibrarySupport => CustomizedDartLibrarySupport(
unsupported: {if (!enableExperimentalFfi) 'ffi'});
}
class WasmVerification extends Verification {
+1
View File
@@ -44,6 +44,7 @@ class TranslatorOptions {
bool minify = false;
bool verifyTypeChecks = false;
bool verbose = false;
bool enableExperimentalFfi = false;
int inliningLimit = 0;
int? sharedMemoryMaxPages;
List<int> watchPoints = [];
+5
View File
@@ -0,0 +1,5 @@
// Copyright (c) 2024, 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.
String tryAccessFfi() => 'Have no dart:ffi support';
+12
View File
@@ -0,0 +1,12 @@
// Copyright (c) 2024, 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 'package:expect/expect.dart';
import 'disabled_helper.dart' if (dart.library.ffi) 'enabled_helper.dart';
void main() {
Expect.isFalse(const bool.fromEnvironment('dart.library.ffi'));
Expect.equals('Have no dart:ffi support', tryAccessFfi());
}
+8
View File
@@ -0,0 +1,8 @@
// Copyright (c) 2024, 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:ffi';
String tryAccessFfi() =>
'Have dart:ffi support (${Pointer<Int8>.fromAddress(int.parse('10')).address})';
+14
View File
@@ -0,0 +1,14 @@
// Copyright (c) 2024, 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.
// dart2wasmOptions=--extra-compiler-option=--enable-experimental-ffi
import 'package:expect/expect.dart';
import 'disabled_helper.dart' if (dart.library.ffi) 'enabled_helper.dart';
void main() {
Expect.isTrue(const bool.fromEnvironment('dart.library.ffi'));
Expect.equals('Have dart:ffi support (10)', tryAccessFfi());
}
@@ -2,6 +2,7 @@
// 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.
// dart2wasmOptions=--extra-compiler-option=--enable-experimental-ffi
// SharedObjects=ffi_native_test_module
import 'dart:ffi';
+1 -1
View File
@@ -14,7 +14,7 @@ template("wasm_module") {
"compiled_action",
rebase_path("//third_party/emsdk/upstream/emscripten/emcc"),
"--no-entry",
rebase_path("//tests/web/wasm/${invoker.module_name}.c"),
rebase_path("//tests/web/wasm/ffi/${invoker.module_name}.c"),
"-o",
rebase_path("$root_out_dir/wasm/${invoker.module_name}.wasm"),
"-O",