mirror of
https://github.com/dart-lang/sdk
synced 2024-10-06 12:57:42 +00:00
[dart2wasm] Add support for testing dart2wasm with JSC
JSC only supports `print()` but not `console.log()`. => The changes to `printToConsole()` are therefore extended to check for `console.log()` as well as `print()`. => This is extending it to a broader subset of dart2js's print Change-Id: I7efa697477aa60e473d01716b104fc1526035c67 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/347283 Commit-Queue: Martin Kustermann <kustermann@google.com> Reviewed-by: Slava Egorov <vegorov@google.com>
This commit is contained in:
parent
f706ff4ee2
commit
3a314331a7
|
@ -11,6 +11,14 @@
|
|||
// -- /abs/path/to/<dart_module>.mjs <dart_module>.wasm [<ffi_module>.wasm] \
|
||||
// [-- Dart commandline arguments...]
|
||||
//
|
||||
// Run as follows on JSC:
|
||||
//
|
||||
// $> export JSC_useWebAssemblyTypedFunctionReferences=1
|
||||
// $> export JSC_useWebAssemblyExtendedConstantExpressions=1
|
||||
// $> export JSC_useWebAssemblyGC=1
|
||||
// $> jsc run_wasm.js -- <dart_module>.ms <dart_module>.wasm \
|
||||
// [-- Dart commandline arguments...]
|
||||
//
|
||||
// Run as follows on JSShell:
|
||||
//
|
||||
// $> js run_wasm.js \
|
||||
|
@ -36,6 +44,19 @@ const jsRuntimeArg = 0;
|
|||
const wasmArg = 1;
|
||||
const ffiArg = 2;
|
||||
|
||||
// This script is intended to be used by D8, JSShell or JSC. We distinguish
|
||||
// them by the functions they offer to read files:
|
||||
//
|
||||
// Engine | Shell | FileRead | Arguments
|
||||
// --------------------------------------------------------------
|
||||
// V8 | D8 | readbuffer | arguments (arg0 arg1)
|
||||
// JavaScriptCore | JSC | readFile | arguments (arg0 arg1)
|
||||
// SpiderMonkey | JSShell | readRelativeToScript | scriptArgs (-- arg0 arg1)
|
||||
//
|
||||
const isD8 = (typeof readbuffer === "function");
|
||||
const isJSC = (typeof readFile === "function");
|
||||
const isJSShell = (typeof readRelativeToScript === "function");
|
||||
|
||||
// d8's `setTimeout` doesn't work as expected (it doesn't wait before calling
|
||||
// the callback), and d8 also doesn't have `setInterval` and `queueMicrotask`.
|
||||
// So we define our own event loop with these functions.
|
||||
|
@ -282,10 +303,16 @@ const ffiArg = 2;
|
|||
}
|
||||
|
||||
async function eventLoop(action) {
|
||||
if (isJSC) asyncTestStart(1);
|
||||
while (action) {
|
||||
try {
|
||||
await action();
|
||||
} catch (e) {
|
||||
// JSC doesn't report/print uncaught async exceptions for some reason.
|
||||
if (isJSC) {
|
||||
print('Error: ' + e);
|
||||
print('Stack: ' + e.stack);
|
||||
}
|
||||
if (typeof onerror == "function") {
|
||||
onerror(e, null, -1);
|
||||
} else {
|
||||
|
@ -294,6 +321,7 @@ const ffiArg = 2;
|
|||
}
|
||||
action = nextEvent();
|
||||
}
|
||||
if (isJSC) asyncTestPassed();
|
||||
}
|
||||
|
||||
// Global properties. "self" refers to the global object, so adding a
|
||||
|
@ -315,17 +343,11 @@ const ffiArg = 2;
|
|||
self.dartUseDateNowForTicks = true;
|
||||
})(this, []);
|
||||
|
||||
|
||||
// This script is intended to be used by either D8 or JSShell. We distinguish
|
||||
// the two by seeing whether the global `arguments` exists (D8 uses `arguments`
|
||||
// and JsShell uses `scriptArgs`).
|
||||
var isD8 = (typeof arguments != "undefined");
|
||||
|
||||
// We would like this itself to be a ES module rather than a script, but
|
||||
// unfortunately d8 does not return a failed error code if an unhandled
|
||||
// exception occurs asynchronously in an ES module.
|
||||
const main = async () => {
|
||||
var args = isD8 ? arguments : scriptArgs;
|
||||
var args = (isD8 || isJSC) ? arguments : scriptArgs;
|
||||
var dartArgs = [];
|
||||
const argsSplit = args.indexOf("--");
|
||||
if (argsSplit != -1) {
|
||||
|
@ -336,7 +358,14 @@ const main = async () => {
|
|||
const dart2wasm = await import(args[jsRuntimeArg]);
|
||||
function compile(filename) {
|
||||
// Create a Wasm module from the binary wasm file.
|
||||
var bytes = isD8 ? readbuffer(filename) : readRelativeToScript(filename, "binary") ;
|
||||
var bytes;
|
||||
if (isJSC) {
|
||||
bytes = readFile(filename, "binary");
|
||||
} else if (isD8) {
|
||||
bytes = readbuffer(filename);
|
||||
} else {
|
||||
bytes = readRelativeToScript(filename, "binary");
|
||||
}
|
||||
return new WebAssembly.Module(bytes);
|
||||
}
|
||||
|
||||
|
|
|
@ -67,6 +67,20 @@ const jsRuntimeBlobPart2JSCM = r'''
|
|||
''';
|
||||
|
||||
const jsRuntimeBlobPart3 = r'''
|
||||
// Prints to the console
|
||||
function printToConsole(value) {
|
||||
if (typeof console == "object" && typeof console.log != "undefined") {
|
||||
console.log(value);
|
||||
return;
|
||||
}
|
||||
if (typeof print == "function") {
|
||||
print(value);
|
||||
return;
|
||||
}
|
||||
|
||||
throw "Unable to print message: " + js;
|
||||
}
|
||||
|
||||
// Converts a Dart List to a JS array. Any Dart objects will be converted, but
|
||||
// this will be cheap for JSValues.
|
||||
function arrayFromDartList(constructor, list) {
|
||||
|
@ -96,7 +110,7 @@ const jsRuntimeBlobPart3 = r'''
|
|||
}
|
||||
|
||||
if (WebAssembly.String === undefined) {
|
||||
console.log("WebAssembly.String is undefined, adding polyfill");
|
||||
printToConsole("WebAssembly.String is undefined, adding polyfill");
|
||||
WebAssembly.String = {
|
||||
"charCodeAt": (s, i) => s.charCodeAt(i),
|
||||
"compare": (s1, s2) => {
|
||||
|
|
|
@ -868,6 +868,7 @@ class Compiler extends NamedEnum {
|
|||
case Compiler.dart2wasm:
|
||||
return const [
|
||||
Runtime.none,
|
||||
Runtime.jsc,
|
||||
Runtime.jsshell,
|
||||
Runtime.d8,
|
||||
Runtime.chrome,
|
||||
|
@ -980,6 +981,7 @@ class Runtime extends NamedEnum {
|
|||
static const flutter = Runtime._('flutter');
|
||||
static const dartPrecompiled = Runtime._('dart_precompiled');
|
||||
static const d8 = Runtime._('d8');
|
||||
static const jsc = Runtime._('jsc');
|
||||
static const jsshell = Runtime._('jsshell');
|
||||
static const firefox = Runtime._('firefox');
|
||||
static const chrome = Runtime._('chrome');
|
||||
|
@ -998,6 +1000,7 @@ class Runtime extends NamedEnum {
|
|||
flutter,
|
||||
dartPrecompiled,
|
||||
d8,
|
||||
jsc,
|
||||
jsshell,
|
||||
firefox,
|
||||
chrome,
|
||||
|
@ -1035,7 +1038,7 @@ class Runtime extends NamedEnum {
|
|||
bool get isSafari => name.startsWith("safari");
|
||||
|
||||
/// Whether this runtime is a command-line JavaScript environment.
|
||||
bool get isJSCommandLine => const [d8, jsshell].contains(this);
|
||||
bool get isJSCommandLine => const [d8, jsc, jsshell].contains(this);
|
||||
|
||||
/// If the runtime doesn't support `Window.open`, we use iframes instead.
|
||||
bool get requiresIFrame => !const [ie11, ie10].contains(this);
|
||||
|
@ -1063,6 +1066,9 @@ class Runtime extends NamedEnum {
|
|||
case chromeOnAndroid:
|
||||
return Compiler.dart2js;
|
||||
|
||||
case jsc:
|
||||
return Compiler.dart2wasm;
|
||||
|
||||
case none:
|
||||
// If we aren't running it, we probably just want to analyze it.
|
||||
return Compiler.dart2analyzer;
|
||||
|
|
|
@ -610,11 +610,12 @@ class Dart2WasmCompilerConfiguration extends CompilerConfiguration {
|
|||
final filename = artifact!.filename;
|
||||
final args = testFile.dartOptions;
|
||||
final isD8 = runtimeConfiguration is D8RuntimeConfiguration;
|
||||
final isJSC = runtimeConfiguration is JSCRuntimeConfiguration;
|
||||
return [
|
||||
if (isD8) '--turboshaft-wasm',
|
||||
if (isD8) '--experimental-wasm-imported-strings',
|
||||
'pkg/dart2wasm/bin/run_wasm.js',
|
||||
if (isD8) '--',
|
||||
if (isD8 || isJSC) '--',
|
||||
'${filename.substring(0, filename.lastIndexOf('.'))}.mjs',
|
||||
filename,
|
||||
...testFile.sharedObjects
|
||||
|
|
|
@ -87,8 +87,9 @@ fasta: Compile using CFE for errors, but do not run.
|
|||
help: '''Where the tests should be run.
|
||||
vm: Run Dart code on the standalone Dart VM.
|
||||
dart_precompiled: Run a precompiled snapshot on the VM without a JIT.
|
||||
d8: Run JavaScript from the command line using v8.
|
||||
jsshell: Run JavaScript from the command line using Firefox js-shell.
|
||||
d8: Run JavaScript from the command line using Chrome's v8.
|
||||
jsc: Run JavaScript from the command line using Safari/WebKit's jsc.
|
||||
jsshell: Run JavaScript from the command line using Firefox's js-shell.
|
||||
|
||||
firefox:
|
||||
chrome:
|
||||
|
|
|
@ -31,6 +31,9 @@ abstract class RuntimeConfiguration {
|
|||
// TODO(ahe): Replace this with one or more browser runtimes.
|
||||
return DummyRuntimeConfiguration();
|
||||
|
||||
case Runtime.jsc:
|
||||
return JSCRuntimeConfiguration(configuration.compiler);
|
||||
|
||||
case Runtime.jsshell:
|
||||
return JsshellRuntimeConfiguration(configuration.compiler);
|
||||
|
||||
|
@ -144,6 +147,15 @@ abstract class RuntimeConfiguration {
|
|||
return d8;
|
||||
}
|
||||
|
||||
String get jscFileName {
|
||||
final d8Dir = Repository.dir.append('third_party/jsc');
|
||||
final d8Path = d8Dir.append(
|
||||
'${Platform.operatingSystem}/${Architecture.host}/jsc$executableExtension');
|
||||
final d8 = d8Path.toNativePath();
|
||||
TestUtils.ensureExists(d8, _configuration);
|
||||
return d8;
|
||||
}
|
||||
|
||||
String get jsShellFileName {
|
||||
var executable = 'jsshell$executableExtension';
|
||||
var jsshellDir = Repository.uri.resolve("tools/testing/bin").path;
|
||||
|
@ -218,6 +230,35 @@ class D8RuntimeConfiguration extends CommandLineJavaScriptRuntime {
|
|||
}
|
||||
}
|
||||
|
||||
/// Safari/WebKit/JavaScriptCore-based development shell (jsc).
|
||||
class JSCRuntimeConfiguration extends CommandLineJavaScriptRuntime {
|
||||
final Compiler compiler;
|
||||
|
||||
JSCRuntimeConfiguration(this.compiler) : super('jsc');
|
||||
|
||||
@override
|
||||
List<Command> computeRuntimeCommands(
|
||||
CommandArtifact? artifact,
|
||||
List<String> arguments,
|
||||
Map<String, String> environmentOverrides,
|
||||
List<String> extraLibs,
|
||||
bool isCrashExpected) {
|
||||
checkArtifact(artifact!);
|
||||
if (compiler != Compiler.dart2wasm) {
|
||||
throw 'No test runner setup for jsc + dart2js yet';
|
||||
}
|
||||
final environment = {
|
||||
...environmentOverrides,
|
||||
'JSC_useWebAssemblyTypedFunctionReferences': '1',
|
||||
'JSC_useWebAssemblyExtendedConstantExpression': '1',
|
||||
'JSC_useWebAssemblyGC': '1',
|
||||
};
|
||||
return [
|
||||
Dart2WasmCommandLineCommand(moniker, jscFileName, arguments, environment)
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
/// Firefox/SpiderMonkey-based development shell (jsshell).
|
||||
class JsshellRuntimeConfiguration extends CommandLineJavaScriptRuntime {
|
||||
final Compiler compiler;
|
||||
|
|
|
@ -6,4 +6,4 @@ part of "internal_patch.dart";
|
|||
|
||||
@patch
|
||||
void printToConsole(String line) =>
|
||||
JS<void>('s => console.log(stringFromDartString(s))');
|
||||
JS<void>('s => printToConsole(stringFromDartString(s))');
|
||||
|
|
|
@ -451,7 +451,7 @@
|
|||
"timeout": 240
|
||||
}
|
||||
},
|
||||
"dart2wasm-(linux|mac|win)-(d8|jsshell|chrome|firefox)": {
|
||||
"dart2wasm-(linux|mac|win)-(d8|jsshell|jsc|chrome|firefox)": {
|
||||
"options": {
|
||||
"host-checked": true,
|
||||
"dart2wasm-options": [
|
||||
|
@ -460,7 +460,7 @@
|
|||
"timeout": 240
|
||||
}
|
||||
},
|
||||
"dart2wasm-(linux|mac|win)-optimized-(d8|jsshell|chrome|firefox)": {
|
||||
"dart2wasm-(linux|mac|win)-optimized-(d8|jsshell|jsc|chrome|firefox)": {
|
||||
"options": {
|
||||
"dart2wasm-options": [
|
||||
"--optimize"
|
||||
|
@ -469,7 +469,7 @@
|
|||
"timeout": 240
|
||||
}
|
||||
},
|
||||
"dart2wasm-(linux|mac|win)-jscm-(d8|jsshell|chrome|firefox)": {
|
||||
"dart2wasm-(linux|mac|win)-jscm-(d8|jsshell|jsc|chrome|firefox)": {
|
||||
"options": {
|
||||
"dart2wasm-options": [
|
||||
"--no-optimize",
|
||||
|
|
Loading…
Reference in a new issue