[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:
committed by
Commit Queue
parent
324ba0c11f
commit
847c35612a
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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 = [];
|
||||
|
||||
@@ -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';
|
||||
@@ -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());
|
||||
}
|
||||
@@ -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})';
|
||||
@@ -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';
|
||||
@@ -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",
|
||||
|
||||
Reference in New Issue
Block a user