diff --git a/chasm/build.gradle.kts b/chasm/build.gradle.kts index 0b219441..53476b40 100644 --- a/chasm/build.gradle.kts +++ b/chasm/build.gradle.kts @@ -69,12 +69,12 @@ configure { } configure { - wabtVersion = "1.0.36" + wasmToolsVersion = "1.216.0" testSuiteCommit = "7c3ec23ab19b37c68976b555f9491752cbda6d5f" scriptRunner = "io.github.charlietap.chasm.script.ChasmScriptRunner" testPackageName = "io.github.charlietap.chasm" proposals = listOf("tail-call", "extended-const", "multi-memory") - excludes = listOf("simd_*/**", "**/simd_*", "align.wast", "binary.wast", "global.wast", "imports.wast", "memory.wast") + excludes = listOf("simd_*/**", "**/simd_*", "align.wast", "binary.wast", "global.wast", "imports.wast", "memory.wast", "comments.wast") } tasks.withType().configureEach { diff --git a/chasm/src/commonTest/kotlin/io/github/charlietap/chasm/script/command/ActionCommandRunner.kt b/chasm/src/commonTest/kotlin/io/github/charlietap/chasm/script/command/ActionCommandRunner.kt index fafb7bcf..92fb14e3 100644 --- a/chasm/src/commonTest/kotlin/io/github/charlietap/chasm/script/command/ActionCommandRunner.kt +++ b/chasm/src/commonTest/kotlin/io/github/charlietap/chasm/script/command/ActionCommandRunner.kt @@ -3,8 +3,6 @@ package io.github.charlietap.chasm.script.command import io.github.charlietap.chasm.script.ScriptContext import io.github.charlietap.chasm.script.action.ActionResult import io.github.charlietap.chasm.script.action.ActionRunner -import io.github.charlietap.chasm.script.ext.mismatchTemplate -import io.github.charlietap.chasm.script.value.ValueMapper import io.github.charlietap.sweet.lib.command.ActionCommand typealias ActionCommandRunner = (ScriptContext, ActionCommand) -> CommandResult @@ -16,24 +14,16 @@ fun ActionCommandRunner( context = context, command = command, actionRunner = ::ActionRunner, - valueMapper = ::ValueMapper, ) private fun ActionCommandRunner( context: ScriptContext, command: ActionCommand, actionRunner: ActionRunner, - valueMapper: ValueMapper, ): CommandResult { return when (val result = actionRunner(context, command, command.action)) { is ActionResult.Success -> { - val expected = command.expected.map(valueMapper) - if (result.value == expected) { - CommandResult.Success - } else { - val mismatch = mismatchTemplate(expected, result.value) - CommandResult.Failure(command, mismatch) - } + CommandResult.Success } is ActionResult.Failure -> { CommandResult.Failure(command, result.reason) diff --git a/sweet/lib/src/commonMain/kotlin/io/github/charlietap/sweet/lib/command/ActionCommand.kt b/sweet/lib/src/commonMain/kotlin/io/github/charlietap/sweet/lib/command/ActionCommand.kt index 52146afc..82e38c82 100644 --- a/sweet/lib/src/commonMain/kotlin/io/github/charlietap/sweet/lib/command/ActionCommand.kt +++ b/sweet/lib/src/commonMain/kotlin/io/github/charlietap/sweet/lib/command/ActionCommand.kt @@ -1,7 +1,6 @@ package io.github.charlietap.sweet.lib.command import io.github.charlietap.sweet.lib.action.Action -import io.github.charlietap.sweet.lib.value.Value import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable @@ -10,5 +9,4 @@ import kotlinx.serialization.Serializable data class ActionCommand( override val line: Int, val action: Action, - val expected: List, ): Command diff --git a/sweet/lib/src/commonMain/kotlin/io/github/charlietap/sweet/lib/command/AssertExhaustionCommand.kt b/sweet/lib/src/commonMain/kotlin/io/github/charlietap/sweet/lib/command/AssertExhaustionCommand.kt index be664d4e..7d960489 100644 --- a/sweet/lib/src/commonMain/kotlin/io/github/charlietap/sweet/lib/command/AssertExhaustionCommand.kt +++ b/sweet/lib/src/commonMain/kotlin/io/github/charlietap/sweet/lib/command/AssertExhaustionCommand.kt @@ -1,7 +1,6 @@ package io.github.charlietap.sweet.lib.command import io.github.charlietap.sweet.lib.action.Action -import io.github.charlietap.sweet.lib.value.Value import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable @@ -10,6 +9,5 @@ import kotlinx.serialization.Serializable data class AssertExhaustionCommand( override val line: Int, val action: Action, - val expected: List, val text: String, ): Command diff --git a/sweet/lib/src/commonMain/kotlin/io/github/charlietap/sweet/lib/command/AssertTrapCommand.kt b/sweet/lib/src/commonMain/kotlin/io/github/charlietap/sweet/lib/command/AssertTrapCommand.kt index 0afe9881..a2deffa0 100644 --- a/sweet/lib/src/commonMain/kotlin/io/github/charlietap/sweet/lib/command/AssertTrapCommand.kt +++ b/sweet/lib/src/commonMain/kotlin/io/github/charlietap/sweet/lib/command/AssertTrapCommand.kt @@ -1,7 +1,6 @@ package io.github.charlietap.sweet.lib.command import io.github.charlietap.sweet.lib.action.Action -import io.github.charlietap.sweet.lib.value.Value import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable @@ -10,6 +9,5 @@ import kotlinx.serialization.Serializable data class AssertTrapCommand( override val line: Int, val action: Action, - val expected: List, val text: String, ): Command diff --git a/sweet/plugin/src/main/kotlin/io/github/charlietap/sweet/plugin/WasmTestSuiteGenPlugin.kt b/sweet/plugin/src/main/kotlin/io/github/charlietap/sweet/plugin/WasmTestSuiteGenPlugin.kt index 80050fb3..7a1547bb 100644 --- a/sweet/plugin/src/main/kotlin/io/github/charlietap/sweet/plugin/WasmTestSuiteGenPlugin.kt +++ b/sweet/plugin/src/main/kotlin/io/github/charlietap/sweet/plugin/WasmTestSuiteGenPlugin.kt @@ -1,9 +1,9 @@ package io.github.charlietap.sweet.plugin -import io.github.charlietap.sweet.plugin.task.DownloadWabtTask +import io.github.charlietap.sweet.plugin.task.DownloadWasmToolsTask import io.github.charlietap.sweet.plugin.task.GenerateTestsTask import io.github.charlietap.sweet.plugin.task.PrepareTestSuiteTask -import io.github.charlietap.sweet.plugin.task.ResolveWast2JsonTask +import io.github.charlietap.sweet.plugin.task.ResolveWasmToolsTask import io.github.charlietap.sweet.plugin.task.SyncRepositoryTask import org.gradle.api.Plugin import org.gradle.api.Project @@ -29,26 +29,26 @@ class WasmTestSuiteGenPlugin : Plugin { outputDirectory.set(extension.testSuiteDirectory) } - val downloadWabtTask = project.tasks.register( - TASK_NAME_DOWNLOAD_WABT, + val downloadWasmToolsTask = project.tasks.register( + TASK_NAME_DOWNLOAD_WASM_TOOLS, ) { description = TASK_DESCRIPTION_DOWNLOAD_WABT group = GROUP - wabtVersion.set(extension.wabtVersion) - outputDirectory.set(project.layout.buildDirectory.dir("wabt")) + wasmToolsVersion.set(extension.wasmToolsVersion) + outputDirectory.set(project.layout.buildDirectory.dir("wasm-tools")) } - val resolveWast2JsonTask = project.tasks.register( - TASK_NAME_RESOLVE_W2J, + val resolveWasmToolsTask = project.tasks.register( + TASK_NAME_RESOLVE_WASM_TOOLS, ) { description = TASK_DESCRIPTION_RESOLVE_W2J group = GROUP - wabtVersion.set(extension.wabtVersion) - wabtDirectory.set(downloadWabtTask.flatMap { it.outputDirectory }) - outputFile.set(wabtVersion.zip(wabtDirectory) { version, dir -> - dir.dir(version).file("wast2json") + wasmToolsVersion.set(extension.wasmToolsVersion) + wasmToolsDirectory.set(downloadWasmToolsTask.flatMap { it.outputDirectory }) + outputFile.set(wasmToolsVersion.zip(wasmToolsDirectory) { version, dir -> + dir.dir(version).file("wasm-tools") }) } @@ -70,7 +70,7 @@ class WasmTestSuiteGenPlugin : Plugin { excludes.set(extension.excludes) proposals.set(extension.proposals) - wast2Json.set(resolveWast2JsonTask.flatMap { it.outputFile }) + wast2Json.set(resolveWasmToolsTask.flatMap { it.outputFile }) outputDirectory.set(extension.testSuiteIntermediateDirectory) } @@ -111,8 +111,8 @@ class WasmTestSuiteGenPlugin : Plugin { const val GROUP = "testsuite" const val TASK_NAME_SYNC_SUITE = "syncWasmTestSuite" - const val TASK_NAME_DOWNLOAD_WABT = "downloadWabt" - const val TASK_NAME_RESOLVE_W2J = "resolveWast2Json" + const val TASK_NAME_DOWNLOAD_WASM_TOOLS = "downloadWasmTools" + const val TASK_NAME_RESOLVE_WASM_TOOLS = "resolveWasmTools" const val TASK_NAME_PREPARE_SUITE = "prepareTestSuite" const val TASK_NAME_GENERATE_TESTS = "generateTests" diff --git a/sweet/plugin/src/main/kotlin/io/github/charlietap/sweet/plugin/WasmTestSuiteGenPluginExtension.kt b/sweet/plugin/src/main/kotlin/io/github/charlietap/sweet/plugin/WasmTestSuiteGenPluginExtension.kt index 4919a07a..c49097de 100644 --- a/sweet/plugin/src/main/kotlin/io/github/charlietap/sweet/plugin/WasmTestSuiteGenPluginExtension.kt +++ b/sweet/plugin/src/main/kotlin/io/github/charlietap/sweet/plugin/WasmTestSuiteGenPluginExtension.kt @@ -11,7 +11,7 @@ open class WasmTestSuiteGenPluginExtension @Inject constructor( layout: ProjectLayout, objects: ObjectFactory, ) { - val wabtVersion: Property = objects.property(String::class.java) + val wasmToolsVersion: Property = objects.property(String::class.java) val testSuiteCommit: Property = objects.property(String::class.java) diff --git a/sweet/plugin/src/main/kotlin/io/github/charlietap/sweet/plugin/action/Wast2JsonAction.kt b/sweet/plugin/src/main/kotlin/io/github/charlietap/sweet/plugin/action/WasmToolsAction.kt similarity index 57% rename from sweet/plugin/src/main/kotlin/io/github/charlietap/sweet/plugin/action/Wast2JsonAction.kt rename to sweet/plugin/src/main/kotlin/io/github/charlietap/sweet/plugin/action/WasmToolsAction.kt index d8b24f02..40e59ee7 100644 --- a/sweet/plugin/src/main/kotlin/io/github/charlietap/sweet/plugin/action/Wast2JsonAction.kt +++ b/sweet/plugin/src/main/kotlin/io/github/charlietap/sweet/plugin/action/WasmToolsAction.kt @@ -1,19 +1,20 @@ package io.github.charlietap.sweet.plugin.action +import java.io.File +import javax.inject.Inject import org.gradle.api.file.DirectoryProperty import org.gradle.api.file.RegularFileProperty import org.gradle.process.ExecOperations import org.gradle.workers.WorkAction import org.gradle.workers.WorkParameters -import javax.inject.Inject -interface Wast2JsonParams: WorkParameters { - val wast2JsonFile: RegularFileProperty +interface WasmToolsParams: WorkParameters { + val wasmToolsFile: RegularFileProperty val inputFile: RegularFileProperty val outputDirectory: DirectoryProperty } -abstract class Wast2JsonAction : WorkAction { +abstract class WasmToolsAction : WorkAction { @get:Inject abstract val cli: ExecOperations @@ -27,18 +28,20 @@ abstract class Wast2JsonAction : WorkAction { cli.exec { workingDir = outputDir - executable = parameters.wast2JsonFile.get().asFile.absolutePath + executable = parameters.wasmToolsFile.get().asFile.absolutePath args = listOf( + CLI_ARG_J2W, + CLI_OPTION_DIR, outputDir.absolutePath, + CLI_OPTION_OUTPUT, outputDir.absolutePath + File.separator + outputDir.nameWithoutExtension + ".json", parameters.inputFile.get().asFile.absolutePath, - ) + ADDITIONAL_FLAGS + ) } } private companion object { - val ADDITIONAL_FLAGS = setOf( - "--enable-tail-call", - "--enable-extended-const", - "--enable-multi-memory", - ) + const val CLI_ARG_J2W = "json-from-wast" + + const val CLI_OPTION_DIR = "--wasm-dir" + const val CLI_OPTION_OUTPUT = "-o" } } diff --git a/sweet/plugin/src/main/kotlin/io/github/charlietap/sweet/plugin/task/DownloadWabtTask.kt b/sweet/plugin/src/main/kotlin/io/github/charlietap/sweet/plugin/task/DownloadWabtTask.kt deleted file mode 100644 index e8ab8f6c..00000000 --- a/sweet/plugin/src/main/kotlin/io/github/charlietap/sweet/plugin/task/DownloadWabtTask.kt +++ /dev/null @@ -1,93 +0,0 @@ -package io.github.charlietap.sweet.plugin.task - -import java.io.File -import java.net.URI -import java.net.URL -import javax.inject.Inject -import org.gradle.api.DefaultTask -import org.gradle.api.GradleException -import org.gradle.api.file.ArchiveOperations -import org.gradle.api.file.DirectoryProperty -import org.gradle.api.file.FileSystemOperations -import org.gradle.api.provider.Property -import org.gradle.api.tasks.CacheableTask -import org.gradle.api.tasks.Input -import org.gradle.api.tasks.OutputDirectory -import org.gradle.api.tasks.TaskAction - -@CacheableTask -abstract class DownloadWabtTask : DefaultTask() { - - @get:Input - abstract val wabtVersion: Property - - @get:OutputDirectory - abstract val outputDirectory: DirectoryProperty - - @get:Inject - abstract val archive: ArchiveOperations - - @get:Inject - abstract val fs: FileSystemOperations - - @TaskAction - fun downloadAndExtract() { - val osName = System.getProperty("os.name").lowercase() - val osArch = System.getProperty("os.arch").lowercase() - val tarFile = outputDirectory.file("${wabtVersion.get()}.tar.gz").get().asFile - - val releaseUrl = when { - osName.contains("mac") -> { - when (osArch) { - "x86_64" -> "https://github.com/WebAssembly/wabt/releases/download/${wabtVersion.get()}/wabt-${wabtVersion.get()}-macos-12.tar.gz" - "aarch64" -> "https://github.com/WebAssembly/wabt/releases/download/${wabtVersion.get()}/wabt-${wabtVersion.get()}-macos-14.tar.gz" - else -> throw GradleException("Unsupported macOS architecture: $osArch") - } - } - osName.contains("nux") -> { - "https://github.com/WebAssembly/wabt/releases/download/${wabtVersion.get()}/wabt-${wabtVersion.get()}-ubuntu-20.04.tar.gz" - } - osName.contains("win") -> { - "https://github.com/WebAssembly/wabt/releases/download/${wabtVersion.get()}/wabt-${wabtVersion.get()}-windows.tar.gz" - } - else -> throw GradleException("Unsupported OS: ${System.getProperty("os.name")}") - } - - wipeDirectory() - downloadRelease(URI(releaseUrl).toURL(), tarFile) - - fs.copy { - from(archive.tarTree(archive.gzip(tarFile))) { - include("*/bin/**") - eachFile { - path = path - .replace("wabt-${wabtVersion.get()}", wabtVersion.get()) - .replace("bin", "") - .replace(".exe", "") - includeEmptyDirs = false - } - } - into(outputDirectory) - } - - val extractedDirectory = outputDirectory.dir("wabt-" + wabtVersion.get()).get() - val extractedBinDirectory = outputDirectory.dir(wabtVersion.get()).get().dir("bin") - extractedDirectory.asFile.deleteRecursively() - extractedBinDirectory.asFile.deleteRecursively() - tarFile.delete() - } - - private fun downloadRelease(url: URL, destination: File) { - url.openStream().use { input -> - destination.outputStream().use { output -> - input.copyTo(output) - } - } - } - - private fun wipeDirectory() { - outputDirectory.get().asFile.listFiles()?.forEach { - it.deleteRecursively() - } - } -} diff --git a/sweet/plugin/src/main/kotlin/io/github/charlietap/sweet/plugin/task/DownloadWasmToolsTask.kt b/sweet/plugin/src/main/kotlin/io/github/charlietap/sweet/plugin/task/DownloadWasmToolsTask.kt new file mode 100644 index 00000000..8019a569 --- /dev/null +++ b/sweet/plugin/src/main/kotlin/io/github/charlietap/sweet/plugin/task/DownloadWasmToolsTask.kt @@ -0,0 +1,121 @@ +package io.github.charlietap.sweet.plugin.task + +import java.io.File +import java.net.URI +import java.net.URL +import javax.inject.Inject +import org.gradle.api.DefaultTask +import org.gradle.api.GradleException +import org.gradle.api.file.ArchiveOperations +import org.gradle.api.file.DirectoryProperty +import org.gradle.api.file.FileSystemOperations +import org.gradle.api.provider.Property +import org.gradle.api.tasks.CacheableTask +import org.gradle.api.tasks.Input +import org.gradle.api.tasks.OutputDirectory +import org.gradle.api.tasks.TaskAction + +@CacheableTask +abstract class DownloadWasmToolsTask : DefaultTask() { + + @get:Input + abstract val wasmToolsVersion: Property + + @get:OutputDirectory + abstract val outputDirectory: DirectoryProperty + + @get:Inject + abstract val archive: ArchiveOperations + + @get:Inject + abstract val fs: FileSystemOperations + + @TaskAction + fun download() { + + val version = wasmToolsVersion.get() + val osArch = System.getProperty("os.arch").lowercase() + val osName = System.getProperty("os.name").lowercase() + + + val (os, extension) = when { + osName.contains("mac") -> OS_MAC to FILE_EXTENSION_TAR + osName.contains("nux") -> OS_LINUX to FILE_EXTENSION_TAR + osName.contains("win") -> OS_WINDOWS to FILE_EXTENSION_ZIP + else -> throw GradleException("Unsupported OS: $osName") + } + val arch = when { + osArch.contains(ARCH_ARM) -> ARCH_ARM + x86.contains(osArch) -> ARCH_X8664 + else -> throw GradleException("Unsupported cpu architecture: $osArch") + } + + val filename = filename(version, arch, os) + val url = "${RELEASE_URL}v${version}/${filename}${extension}" + + val compressed = if(os == OS_WINDOWS) { + outputDirectory.file("${version}${FILE_EXTENSION_ZIP}").get().asFile + } else { + outputDirectory.file("${version}${FILE_EXTENSION_TAR}").get().asFile + } + + wipeDirectory() + downloadRelease(URI(url).toURL(), compressed) + + val tree = if(os == OS_WINDOWS) { + archive.zipTree(compressed) + } else { + archive.tarTree(archive.gzip(compressed)) + } + + fs.copy { + from(tree) { + include("**/wasm-tools*") + eachFile { + path = path + .replace(filename, version) + .replace(".exe", "") + includeEmptyDirs = false + } + } + into(outputDirectory) + } + + val extractedDirectory = outputDirectory.dir(filename).get() + extractedDirectory.asFile.deleteRecursively() + compressed.delete() + } + + private fun downloadRelease(url: URL, destination: File) { + url.openStream().use { input -> + destination.outputStream().use { output -> + input.copyTo(output) + } + } + } + + private fun wipeDirectory() { + outputDirectory.get().asFile.listFiles()?.forEach { + it.deleteRecursively() + } + } + + private companion object { + const val RELEASE_URL = "https://github.com/bytecodealliance/wasm-tools/releases/download/" + + const val ARCH_X8664 = "x86_64" + const val ARCH_AMD64 = "amd64" + const val ARCH_ARM = "aarch64" + + const val OS_LINUX = "linux" + const val OS_MAC = "macos" + const val OS_WINDOWS = "windows" + + const val FILE_EXTENSION_TAR = ".tar.gz" + const val FILE_EXTENSION_ZIP = ".zip" + + val x86 = arrayOf(ARCH_AMD64, ARCH_X8664) + + fun filename(version: String, arch: String, os: String) = "wasm-tools-$version-$arch-$os" + } +} diff --git a/sweet/plugin/src/main/kotlin/io/github/charlietap/sweet/plugin/task/PrepareTestSuiteTask.kt b/sweet/plugin/src/main/kotlin/io/github/charlietap/sweet/plugin/task/PrepareTestSuiteTask.kt index 3bc68628..01e58338 100644 --- a/sweet/plugin/src/main/kotlin/io/github/charlietap/sweet/plugin/task/PrepareTestSuiteTask.kt +++ b/sweet/plugin/src/main/kotlin/io/github/charlietap/sweet/plugin/task/PrepareTestSuiteTask.kt @@ -1,6 +1,6 @@ package io.github.charlietap.sweet.plugin.task -import io.github.charlietap.sweet.plugin.action.Wast2JsonAction +import io.github.charlietap.sweet.plugin.action.WasmToolsAction import javax.inject.Inject import org.gradle.api.DefaultTask import org.gradle.api.file.ConfigurableFileTree @@ -67,24 +67,24 @@ abstract class PrepareTestSuiteTask : DefaultTask() { } ChangeType.MODIFIED -> { generatedDirectory.get().asFile.deleteRecursively() - queueJobToRunWast2Json(change, generatedDirectory) + queueJobToRunWasmTools(change, generatedDirectory) } ChangeType.ADDED -> { - queueJobToRunWast2Json(change, generatedDirectory) + queueJobToRunWasmTools(change, generatedDirectory) } } } } - private fun queueJobToRunWast2Json( + private fun queueJobToRunWasmTools( change: FileChange, generatedDirectory: Provider, ) { val queue = workerExecutor.noIsolation() - queue.submit(Wast2JsonAction::class.java) { + queue.submit(WasmToolsAction::class.java) { inputFile.set(change.file) outputDirectory.set(generatedDirectory) - wast2JsonFile.set(wast2Json) + wasmToolsFile.set(wast2Json) } } } diff --git a/sweet/plugin/src/main/kotlin/io/github/charlietap/sweet/plugin/task/ResolveWast2JsonTask.kt b/sweet/plugin/src/main/kotlin/io/github/charlietap/sweet/plugin/task/ResolveWasmToolsTask.kt similarity index 70% rename from sweet/plugin/src/main/kotlin/io/github/charlietap/sweet/plugin/task/ResolveWast2JsonTask.kt rename to sweet/plugin/src/main/kotlin/io/github/charlietap/sweet/plugin/task/ResolveWasmToolsTask.kt index b482a817..2b874eb5 100644 --- a/sweet/plugin/src/main/kotlin/io/github/charlietap/sweet/plugin/task/ResolveWast2JsonTask.kt +++ b/sweet/plugin/src/main/kotlin/io/github/charlietap/sweet/plugin/task/ResolveWasmToolsTask.kt @@ -17,14 +17,14 @@ import org.gradle.api.tasks.TaskAction import org.gradle.process.ExecOperations @CacheableTask -abstract class ResolveWast2JsonTask : DefaultTask() { +abstract class ResolveWasmToolsTask : DefaultTask() { @get:Input - abstract val wabtVersion: Property + abstract val wasmToolsVersion: Property @get:InputDirectory @get:PathSensitive(PathSensitivity.RELATIVE) - abstract val wabtDirectory: DirectoryProperty + abstract val wasmToolsDirectory: DirectoryProperty @get:OutputFile abstract val outputFile: RegularFileProperty @@ -35,10 +35,10 @@ abstract class ResolveWast2JsonTask : DefaultTask() { @TaskAction fun resolve() { - val wast2JsonFile = outputFile.get().asFile + val wasmToolsFile = outputFile.get().asFile - if(!wast2JsonFile.exists()) { - throw GradleException("wast2json file does not exist: ${wast2JsonFile.absolutePath}") + if(!wasmToolsFile.exists()) { + throw GradleException("wasm-tools file does not exist: ${wasmToolsFile.absolutePath}") } val versionBytes = ByteArrayOutputStream() @@ -50,8 +50,8 @@ abstract class ResolveWast2JsonTask : DefaultTask() { val version = versionBytes.toString().trim() - if(version != wabtVersion.get()) { - throw GradleException("Wast2JsonTask does not support version $wabtVersion") + if(!version.contains(wasmToolsVersion.get())) { + throw GradleException("wasm-tools does not support version $wasmToolsVersion") } } }