Skip to content

Commit 847c356

Browse files
mkustermannCommit Queue
authored andcommitted
[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 #55948 Issue flutter/flutter#149984 Change-Id: I70a775278ab701d1fd2596521e378cb6364edac2 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/370580 Commit-Queue: Martin Kustermann <[email protected]> Reviewed-by: Srujan Gaddam <[email protected]>
1 parent 324ba0c commit 847c356

File tree

12 files changed

+71
-11
lines changed

12 files changed

+71
-11
lines changed

pkg/_js_interop_checks/lib/js_interop_checks.dart

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,8 @@ class JsInteropChecks extends RecursiveVisitor {
8585
final ExportChecker exportChecker;
8686
final bool isDart2Wasm;
8787

88+
final List<String> _disallowedInteropLibrariesInDart2Wasm;
89+
8890
/// Native tests to exclude from checks on external.
8991
// TODO(rileyporter): Use ExternalName from CFE to exclude native tests.
9092
static final List<Pattern> _allowedNativeTestPatterns = [
@@ -107,7 +109,7 @@ class JsInteropChecks extends RecursiveVisitor {
107109
// Negative lookahead to test the violation.
108110
RegExp(
109111
r'(?<!generated_)tests/lib/js/static_interop_test(?!/disallowed_interop_libraries_test.dart)'),
110-
RegExp(r'(?<!generated_)tests/web/wasm'),
112+
RegExp(r'(?<!generated_)tests/web/wasm/(?!ffi/).*'),
111113
// Flutter tests.
112114
RegExp(r'flutter/lib/web_ui/test'),
113115
];
@@ -131,7 +133,7 @@ class JsInteropChecks extends RecursiveVisitor {
131133
];
132134

133135
/// Interop libraries that cannot be used in dart2wasm.
134-
static const _disallowedInteropLibrariesInDart2Wasm = [
136+
static const _disallowedInteropLibrariesInDart2WasmByDefault = [
135137
'package:js/js.dart',
136138
'package:js/js_util.dart',
137139
'dart:js_util',
@@ -163,12 +165,16 @@ class JsInteropChecks extends RecursiveVisitor {
163165

164166
JsInteropChecks(this._coreTypes, ClassHierarchy hierarchy, this._reporter,
165167
this._nativeClasses,
166-
{this.isDart2Wasm = false})
168+
{this.isDart2Wasm = false, bool enableExperimentalFfi = false})
167169
: exportChecker = ExportChecker(_reporter, _coreTypes.objectClass),
168170
_functionToJSTarget = _coreTypes.index.getTopLevelProcedure(
169171
'dart:js_interop', 'FunctionToJSExportedDartFunction|get#toJS'),
170172
_staticTypeContext = StatefulStaticTypeContext.stacked(
171-
TypeEnvironment(_coreTypes, hierarchy)) {
173+
TypeEnvironment(_coreTypes, hierarchy)),
174+
_disallowedInteropLibrariesInDart2Wasm = [
175+
for (final entry in _disallowedInteropLibrariesInDart2WasmByDefault)
176+
if (!(entry == 'dart:ffi' && enableExperimentalFfi)) entry
177+
] {
172178
extensionIndex =
173179
ExtensionIndex(_coreTypes, _staticTypeContext.typeEnvironment);
174180
}

pkg/dart2wasm/lib/compile.dart

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,9 @@ Future<CompilerOutput?> compileToModule(compiler.WasmCompilerOptions options,
8181
mode = wasm.Mode.regular;
8282
}
8383
final WasmTarget target = WasmTarget(
84-
removeAsserts: !options.translatorOptions.enableAsserts, mode: mode);
84+
enableExperimentalFfi: options.translatorOptions.enableExperimentalFfi,
85+
removeAsserts: !options.translatorOptions.enableAsserts,
86+
mode: mode);
8587
CompilerOptions compilerOptions = CompilerOptions()
8688
..target = target
8789
// This is a dummy directory that always exists. This option should be

pkg/dart2wasm/lib/dart2wasm.dart

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,9 @@ final List<Option> options = [
8888
StringOption(
8989
"dump-kernel-after-tfa", (o, value) => o.dumpKernelAfterTfa = value,
9090
hide: true),
91+
Flag("enable-experimental-ffi",
92+
(o, value) => o.translatorOptions.enableExperimentalFfi = value,
93+
defaultsTo: _d.translatorOptions.enableExperimentalFfi),
9194
];
9295

9396
Map<fe.ExperimentalFlag, bool> processFeExperimentalFlags(

pkg/dart2wasm/lib/target.dart

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -89,10 +89,14 @@ class ConstantResolver extends Transformer {
8989
}
9090

9191
class WasmTarget extends Target {
92-
WasmTarget({this.removeAsserts = false, this.mode = Mode.regular});
93-
94-
bool removeAsserts;
95-
Mode mode;
92+
WasmTarget(
93+
{this.enableExperimentalFfi = true,
94+
this.removeAsserts = false,
95+
this.mode = Mode.regular});
96+
97+
final bool removeAsserts;
98+
final Mode mode;
99+
final bool enableExperimentalFfi;
96100
Class? _growableList;
97101
Class? _immutableList;
98102
Class? _wasmDefaultMap;
@@ -206,7 +210,7 @@ class WasmTarget extends Target {
206210
diagnosticReporter as DiagnosticReporter<Message, LocatedMessage>);
207211
final jsInteropChecks = JsInteropChecks(
208212
coreTypes, hierarchy, jsInteropReporter, _nativeClasses!,
209-
isDart2Wasm: true);
213+
isDart2Wasm: true, enableExperimentalFfi: enableExperimentalFfi);
210214
// Process and validate first before doing anything with exports.
211215
for (Library library in interopDependentLibraries) {
212216
jsInteropChecks.visitLibrary(library);
@@ -497,6 +501,10 @@ class WasmTarget extends Target {
497501
@override
498502
Class concreteDoubleLiteralClass(CoreTypes coreTypes, double value) =>
499503
_boxedDouble ??= coreTypes.index.getClass("dart:core", "_BoxedDouble");
504+
505+
@override
506+
DartLibrarySupport get dartLibrarySupport => CustomizedDartLibrarySupport(
507+
unsupported: {if (!enableExperimentalFfi) 'ffi'});
500508
}
501509

502510
class WasmVerification extends Verification {

pkg/dart2wasm/lib/translator.dart

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ class TranslatorOptions {
4444
bool minify = false;
4545
bool verifyTypeChecks = false;
4646
bool verbose = false;
47+
bool enableExperimentalFfi = false;
4748
int inliningLimit = 0;
4849
int? sharedMemoryMaxPages;
4950
List<int> watchPoints = [];
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
// Copyright (c) 2024, the Dart project authors. Please see the AUTHORS file
2+
// for details. All rights reserved. Use of this source code is governed by a
3+
// BSD-style license that can be found in the LICENSE file.
4+
5+
String tryAccessFfi() => 'Have no dart:ffi support';
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
// Copyright (c) 2024, the Dart project authors. Please see the AUTHORS file
2+
// for details. All rights reserved. Use of this source code is governed by a
3+
// BSD-style license that can be found in the LICENSE file.
4+
5+
import 'package:expect/expect.dart';
6+
7+
import 'disabled_helper.dart' if (dart.library.ffi) 'enabled_helper.dart';
8+
9+
void main() {
10+
Expect.isFalse(const bool.fromEnvironment('dart.library.ffi'));
11+
Expect.equals('Have no dart:ffi support', tryAccessFfi());
12+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
// Copyright (c) 2024, the Dart project authors. Please see the AUTHORS file
2+
// for details. All rights reserved. Use of this source code is governed by a
3+
// BSD-style license that can be found in the LICENSE file.
4+
5+
import 'dart:ffi';
6+
7+
String tryAccessFfi() =>
8+
'Have dart:ffi support (${Pointer<Int8>.fromAddress(int.parse('10')).address})';
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
// Copyright (c) 2024, the Dart project authors. Please see the AUTHORS file
2+
// for details. All rights reserved. Use of this source code is governed by a
3+
// BSD-style license that can be found in the LICENSE file.
4+
5+
// dart2wasmOptions=--extra-compiler-option=--enable-experimental-ffi
6+
7+
import 'package:expect/expect.dart';
8+
9+
import 'disabled_helper.dart' if (dart.library.ffi) 'enabled_helper.dart';
10+
11+
void main() {
12+
Expect.isTrue(const bool.fromEnvironment('dart.library.ffi'));
13+
Expect.equals('Have dart:ffi support (10)', tryAccessFfi());
14+
}

tests/web/wasm/ffi_native_test.dart renamed to tests/web/wasm/ffi/ffi_native_test.dart

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
// for details. All rights reserved. Use of this source code is governed by a
33
// BSD-style license that can be found in the LICENSE file.
44

5+
// dart2wasmOptions=--extra-compiler-option=--enable-experimental-ffi
56
// SharedObjects=ffi_native_test_module
67

78
import 'dart:ffi';

0 commit comments

Comments
 (0)