Skip to content

Commit

Permalink
Fix build web compilers wasm issue (#3748)
Browse files Browse the repository at this point in the history
This fixes three issues from the dart2js+dart2wasm PR:

1. Since `YamlMap` is not a `Map<String, dynamic>`, `.cast()` doesn't work. Tests didn't catch this because we weren't reading from yaml.
2. The loader script had multiple issues - it referenced an undefined function and assumes that `WebAssembly` is defined. Tests didn't catch this because this was only exercised in the fallback path, and we were only testing on Chrome. I've fixed the loader script and added a custom browser platform that disables WebAssembly in Chrome to make sure the fallback path is working.
3. We've stopped emitting dart2js archives because we expected them to look like `main.dart.js*`. When using a custom build extension for dart2js, they are actually named `main.dart2js.js*` - I've fixed that, this is tested by the deferred imports hello world test in `_test`.

Sorry for the mess!

Closes #3746.
Closes #3747.
  • Loading branch information
simolus3 committed Sep 11, 2024
1 parent 49d83f4 commit 1b95352
Show file tree
Hide file tree
Showing 8 changed files with 42 additions and 27 deletions.
7 changes: 7 additions & 0 deletions _test/dart_test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,13 @@ tags:
# moment, but want to avoid warnings from the test runner about using undefined
# targets.

define_platforms:
chrome_without_wasm:
name: chrome_without_wasm
extends: chrome
settings:
arguments: "--js-flags=--noexpose_wasm"

override_platforms:
chrome:
settings:
Expand Down
2 changes: 1 addition & 1 deletion _test/test/configurable_uri_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ void main() {
test('exports', () {
expect(exported.message, contains('WebAssembly'));
});
}, testOn: 'dart2wasm');
}, testOn: 'dart2wasm && !chrome_without_wasm');

group('vm', () {
test('imports', () {
Expand Down
8 changes: 7 additions & 1 deletion _test/test/dart2wasm_integration_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,13 @@ void main() {
'--config=both',
'--output=${d.sandbox}',
],
testArgs: _testArgs,
testArgs: [
..._testArgs,
'-p',
'chrome_without_wasm',
'-p',
'chrome',
],
);
await _expectWasCompiledWithDart2Wasm();

Expand Down
4 changes: 2 additions & 2 deletions build_web_compilers/lib/src/dart2js_bootstrap.dart
Original file line number Diff line number Diff line change
Expand Up @@ -113,8 +113,8 @@ https://github.com/dart-lang/build/blob/master/docs/faq.md#how-can-i-resolve-ski
if (result.exitCode == 0 && await jsOutputFile.exists()) {
log.info('${result.stdout}\n${result.stderr}');
var rootDir = p.dirname(jsOutputFile.path);
var dartFile = p.basename(dartEntrypointId.path);
var fileGlob = Glob('$dartFile.js*');
var baseInputName = p.basenameWithoutExtension(dartEntrypointId.path);
var fileGlob = Glob('$baseInputName$entrypointExtension*');
var archive = Archive();
await for (var jsFile in fileGlob.list(root: rootDir)) {
if (jsFile.path.endsWith(entrypointExtension) ||
Expand Down
16 changes: 6 additions & 10 deletions build_web_compilers/lib/src/web_entrypoint_builder.dart
Original file line number Diff line number Diff line change
Expand Up @@ -163,17 +163,16 @@ final class EntrypointBuilderOptions {
// dart2js + dart2wasm). Since the default builder configuration doesn't
// use the compilers key, we preserve backwards compatibility.
if (config.containsKey(compilersOption)) {
var configuredCompilers = (config[compilersOption] as Map?)
?.cast<String, Map<String, Object?>?>() ??
const {};
var configuredCompilers =
(config[compilersOption] as Map?)?.cast<String, Map?>() ?? const {};
var hasDart2Wasm = false;

for (var MapEntry(:key, :value) in configuredCompilers.entries) {
const extensionOption = 'extension';
const argsOption = 'args';
const supportedOptions = [extensionOption, argsOption];
validateOptions(value ?? const {}, supportedOptions,
'build_web_compilers:entrypoint');
validateOptions(Map<String, dynamic>.from(value ?? const {}),
supportedOptions, 'build_web_compilers:entrypoint');

var compiler = WebCompiler.fromOptionName(key);
compilers.add(EnabledEntrypointCompiler(
Expand Down Expand Up @@ -336,9 +335,6 @@ class WebEntrypointBuilder implements Builder {
options.optionsFor(WebCompiler.DartDevc);

var loaderResult = StringBuffer('''(async () => {
function resolveUrlWithSegments(...segments) {
return new URL(joinPathSegments(...segments), document.baseURI).toString()
}
''');

// If we're compiling to JS, start a feature detection to prefer wasm but
Expand All @@ -351,7 +347,7 @@ function supportsWasmGC() {
//
// Copied from https://github.com/GoogleChromeLabs/wasm-feature-detect/blob/main/src/detectors/gc/index.js
const bytes = [0, 97, 115, 109, 1, 0, 0, 0, 1, 5, 1, 95, 1, 120, 0];
return WebAssembly && WebAssembly.validate(new Uint8Array(bytes));
return 'WebAssembly' in self && WebAssembly.validate(new Uint8Array(bytes));
}
if (supportsWasmGC()) {
Expand All @@ -371,7 +367,7 @@ invoke(instantiated, []);
} else {
const scriptTag = document.createElement("script");
scriptTag.type = "application/javascript";
scriptTag.src = resolveUrlWithSegments("./$basename${jsCompiler.extension}");
scriptTag.src = new URL("./$basename${jsCompiler.extension}", document.baseURI).toString();
document.head.append(scriptTag);
}
''');
Expand Down
1 change: 1 addition & 0 deletions build_web_compilers/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ dev_dependencies:
path: test/fixtures/d
dart_flutter_team_lints: ^3.1.0
test: ^1.16.0
yaml: ^3.1.0

topics:
- build-runner
4 changes: 3 additions & 1 deletion build_web_compilers/test/dart2wasm_bootstrap_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -63,14 +63,15 @@ void main() {
outputs: {
'a|web/index.mjs': anything,
'a|web/index.wasm': anything,
'a|web/index.dart.js.tar.gz': anything,
'a|web/index.dart2js.js': decodedMatches(contains('Hello world!')),
'a|web/index.dart.js': decodedMatches(
stringContainsInOrder(
[
'if (supportsWasmGC())',
'WebAssembly.compileStreaming',
'else',
'scriptTag.src = resolveUrlWithSegments("./index.dart2js.js");'
'scriptTag.src = new URL("./index.dart2js.js", document.baseURI).toString();'
],
),
),
Expand All @@ -96,6 +97,7 @@ void main() {
outputs: {
'a|web/index.mjs': anything,
'a|web/index.wasm': anything,
'a|web/index.dart.js.tar.gz': anything,
'a|web/index.dart2js.js': decodedMatches(contains('Hello world!')),
},
);
Expand Down
27 changes: 15 additions & 12 deletions build_web_compilers/test/entrypoint_options_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import 'package:build/build.dart';
import 'package:build_web_compilers/src/web_entrypoint_builder.dart';
import 'package:test/test.dart';
import 'package:yaml/yaml.dart';

void main() {
test('uses ddc by default', () {
Expand Down Expand Up @@ -67,18 +68,20 @@ void main() {
});

test('can enable multiple compilers', () {
final options = EntrypointBuilderOptions.fromOptions(const BuilderOptions({
'compilers': {
'dart2js': {
'args': ['-O4'],
},
'dart2wasm': {
'extension': '.custom_extension.js',
'args': ['-O3'],
},
},
'loader': '.dart.js',
}));
final yamlOptions = loadYaml('''
compilers:
dart2js:
args:
- "-O4"
dart2wasm:
extension: .custom_extension.js
args:
- "-O3"
loader: .dart.js
''') as Map;

final options = EntrypointBuilderOptions.fromOptions(
BuilderOptions(yamlOptions.cast()));

expect(options.nativeNullAssertions, isNull);
expect(options.loaderExtension, '.dart.js');
Expand Down

0 comments on commit 1b95352

Please sign in to comment.