[dart2wasm] Make test runner use pkg/dart2wasm/tool/run_benchmark (just as golem does)

* We make the test runner use the same runner script as golem uses
* We make the runner script work for different JS shells

=> The runner script encapsulates how to invoke different JS shells, the
   commandline format, environment variables, ...

=> Golem can then continue to use same runner script, but also with new
   shells

Change-Id: Iad63fe6c0563cfeac28cbfb25eb41ee1b7c13f3a
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/365740
Reviewed-by: Slava Egorov <vegorov@google.com>
Commit-Queue: Martin Kustermann <kustermann@google.com>
diff --git a/pkg/dart2wasm/bin/run_wasm.js b/pkg/dart2wasm/bin/run_wasm.js
index 1162e1e..139f965 100644
--- a/pkg/dart2wasm/bin/run_wasm.js
+++ b/pkg/dart2wasm/bin/run_wasm.js
@@ -16,7 +16,7 @@
 // $> export JSC_useWebAssemblyTypedFunctionReferences=1
 // $> export JSC_useWebAssemblyExtendedConstantExpressions=1
 // $> export JSC_useWebAssemblyGC=1
-// $> jsc run_wasm.js -- <dart_module>.ms <dart_module>.wasm  \
+// $> jsc run_wasm.js -- <dart_module>.mjs <dart_module>.wasm [<ffi_module>.wasm] \
 //       [-- Dart commandline arguments...]
 //
 // Run as follows on JSShell:
@@ -137,7 +137,8 @@
     ms = Math.max(0, ms);
     var id = timerIdCounter++;
     // A callback can be scheduled at most once.
-    console.assert(f.$timerId === undefined);
+    // (console.assert is only available on D8)
+    if (isD8) console.assert(f.$timerId === undefined);
     f.$timerId = id;
     timerIds[id] = f;
     if (ms == 0 && !isNextTimerDue()) {
diff --git a/pkg/dart2wasm/tool/run_benchmark b/pkg/dart2wasm/tool/run_benchmark
index ef11ffe..4f8ce71 100755
--- a/pkg/dart2wasm/tool/run_benchmark
+++ b/pkg/dart2wasm/tool/run_benchmark
@@ -24,10 +24,66 @@
 PROG_DIR="$(cd "${PROG_NAME%/*}" ; pwd -P)"
 SDK_DIR="$(cd "${PROG_DIR}/../../.." ; pwd -P)"
 
-# Hardcoded to x64 Linux for now.
-D8="$SDK_DIR/third_party/d8/linux/x64/d8"
-
 RUN_WASM="$SDK_DIR/pkg/dart2wasm/bin/run_wasm.js"
 
-# We locate the JS runtime based on the input wasm file.
-exec "$D8" "$RUN_WASM" -- "$(realpath -- "${1%.*}.mjs")" "$1" -- "${@:2}"
+# Hardcoded to x64 Linux for now.
+D8_BIN="$SDK_DIR/third_party/d8/linux/x64/d8"
+JSSHELL_BIN="$SDK_DIR/third_party/firefox_jsshell/js"
+JSC_BIN="$SDK_DIR/third_party/jsc/jsc"
+
+SHELL_BIN="$D8_BIN"
+SHELL_OPTIONS=()
+SHELL_ARG_SEPERATOR="--"
+MJS_FILE=""
+WASM_FILE=""
+LINEAR_WASM_FILES=()
+ARGS=()
+while [ $# -gt 0 ]; do
+  case "$1" in
+    --d8)
+      SHELL_BIN="$D8_BIN"
+      SHELL_ARG_SEPERATOR="--"
+      shift
+      ;;
+
+    --jsshell)
+      SHELL_BIN="$JSSHELL_BIN"
+      SHELL_ARG_SEPERATOR=""
+      shift
+      ;;
+
+    --jsc)
+      SHELL_BIN="$JSC_BIN"
+      SHELL_ARG_SEPERATOR="--"
+      export JSC_useWebAssemblyTypedFunctionReferences=1
+      export JSC_useWebAssemblyExtendedConstantExpression=1
+      export JSC_useWebAssemblyGC=1
+      shift
+      ;;
+
+    --shell-option=*)
+      SHELL_OPTIONS+=("${1#--shell-option=}")
+      shift
+      ;;
+
+    *.wasm)
+      if [ -z "$WASM_FILE" ]; then
+        # First wasm file is the actual dart program
+        WASM_FILE="$(realpath "$1")"
+        MJS_FILE="${WASM_FILE%.wasm}.mjs"
+      else
+        # Following wasm files are imported linear memory modules
+        LINEAR_WASM_FILES+=("$1")
+      fi
+      shift
+      ;;
+
+    *)
+      # Any arguments that are not the above will be arguments to the dart's
+      # main function.
+      break
+      ;;
+  esac
+done
+
+exec "$SHELL_BIN" "$RUN_WASM" $SHELL_ARG_SEPERATOR "$MJS_FILE" "$WASM_FILE" "${LINEAR_WASM_FILES[@]}" -- "$@"
diff --git a/pkg/test_runner/lib/src/compiler_configuration.dart b/pkg/test_runner/lib/src/compiler_configuration.dart
index 7499c68..d4c141c 100644
--- a/pkg/test_runner/lib/src/compiler_configuration.dart
+++ b/pkg/test_runner/lib/src/compiler_configuration.dart
@@ -601,20 +601,17 @@
       List<String> vmOptions,
       List<String> originalArguments,
       CommandArtifact? artifact) {
-    final filename = artifact!.filename;
+    final wasmFilename = 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 || isJSC) '--',
-      '${filename.substring(0, filename.lastIndexOf('.'))}.mjs',
-      filename,
+      if (isD8) ...[
+        '--shell-option=turboshaft-wasm',
+        '--shell-option=experimental-wasm-imported-strings',
+      ],
+      wasmFilename,
       ...testFile.sharedObjects
           .map((obj) => '${_configuration.buildDirectory}/wasm/$obj.wasm'),
-      if (args.isNotEmpty) '--',
       ...args,
     ];
   }
diff --git a/pkg/test_runner/lib/src/runtime_configuration.dart b/pkg/test_runner/lib/src/runtime_configuration.dart
index cdf944a..ea633f7 100644
--- a/pkg/test_runner/lib/src/runtime_configuration.dart
+++ b/pkg/test_runner/lib/src/runtime_configuration.dart
@@ -209,8 +209,8 @@
     checkArtifact(artifact!);
     if (compiler == Compiler.dart2wasm) {
       return [
-        Dart2WasmCommandLineCommand(
-            moniker, d8FileName, arguments, environmentOverrides)
+        Dart2WasmCommandLineCommand(moniker, 'pkg/dart2wasm/tool/run_benchmark',
+            ['--d8', ...arguments], environmentOverrides)
       ];
     } else {
       return [
@@ -246,14 +246,9 @@
     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)
+      Dart2WasmCommandLineCommand(moniker, 'pkg/dart2wasm/tool/run_benchmark',
+          ['--jsc', ...arguments], environmentOverrides)
     ];
   }
 }
@@ -274,8 +269,8 @@
     checkArtifact(artifact!);
     if (compiler == Compiler.dart2wasm) {
       return [
-        Dart2WasmCommandLineCommand(
-            moniker, jsShellFileName, arguments, environmentOverrides)
+        Dart2WasmCommandLineCommand(moniker, 'pkg/dart2wasm/tool/run_benchmark',
+            ['--jsshell', ...arguments], environmentOverrides)
       ];
     } else {
       return [