From b02279de1473d4278bed16109761d79fc7297c6b Mon Sep 17 00:00:00 2001 From: Zalim Bashorov Date: Fri, 27 Jan 2023 02:27:09 +0100 Subject: [PATCH] [Wasm] Run wasm test using all available VMs: V8 & SpiderMonkey for now Also, add a new directive, `WASM_FAILS_IN`, to specify VMs where a test is expected to fail for now. #KT-56166 Fixed --- .../codegen/boxWasmJsInterop/defaultValues.kt | 1 + .../boxWasmJsInterop/externalTypeOperators.kt | 1 + .../codegen/boxWasmJsInterop/externals.kt | 1 + .../codegen/boxWasmJsInterop/functionTypes.kt | 1 + .../codegen/boxWasmJsInterop/jsExport.kt | 1 + .../boxWasmJsInterop/jsToKotlinAdapters.kt | 1 + .../boxWasmJsInterop/kotlinToJsAdapters.kt | 1 + .../codegen/boxWasmJsInterop/types.kt | 1 + .../codegen/boxWasmJsInterop/vararg.kt | 1 + .../kotlin/js/testOld/BasicWasmBoxTest.kt | 52 ++++++++++++++----- .../kotlin/js/testOld/engines/SpiderMonkey.kt | 50 +++++++++++++----- .../box/native/castToNativeClassChecked.kt | 1 + .../box/native/castToNativeInterface.kt | 1 + ...castToTypeParamBoundedByNativeInterface.kt | 1 + .../box/native/passMemberOrExtFromNative.kt | 1 + .../passTopLevelOrLocalFunctionToNative.kt | 1 + 16 files changed, 89 insertions(+), 27 deletions(-) diff --git a/compiler/testData/codegen/boxWasmJsInterop/defaultValues.kt b/compiler/testData/codegen/boxWasmJsInterop/defaultValues.kt index 00e85d5b899..cc63f371c3c 100644 --- a/compiler/testData/codegen/boxWasmJsInterop/defaultValues.kt +++ b/compiler/testData/codegen/boxWasmJsInterop/defaultValues.kt @@ -1,3 +1,4 @@ +// WASM_FAILS_IN: SM // FILE: defaultValues.js function foo(x1 = "d1", x2 = "d2", x3 = "d3", x4 = "d4", x5 = "d5") { return `${x1} ${x2} ${x3} ${x4} ${x5}`; diff --git a/compiler/testData/codegen/boxWasmJsInterop/externalTypeOperators.kt b/compiler/testData/codegen/boxWasmJsInterop/externalTypeOperators.kt index 690816c07bf..47021a9131d 100644 --- a/compiler/testData/codegen/boxWasmJsInterop/externalTypeOperators.kt +++ b/compiler/testData/codegen/boxWasmJsInterop/externalTypeOperators.kt @@ -1,4 +1,5 @@ // WITH_STDLIB +// WASM_FAILS_IN: SM // FILE: externals.js const primitives1 = [3.14, "Test string 1", true, Symbol("symbol"), 131283889534859707199254740992n]; diff --git a/compiler/testData/codegen/boxWasmJsInterop/externals.kt b/compiler/testData/codegen/boxWasmJsInterop/externals.kt index f93c6b8d197..158ccc2cc38 100644 --- a/compiler/testData/codegen/boxWasmJsInterop/externals.kt +++ b/compiler/testData/codegen/boxWasmJsInterop/externals.kt @@ -1,3 +1,4 @@ +// WASM_FAILS_IN: SM // FILE: externals.js function createObject() { return { diff --git a/compiler/testData/codegen/boxWasmJsInterop/functionTypes.kt b/compiler/testData/codegen/boxWasmJsInterop/functionTypes.kt index ff7cedb0a94..d531ac7812b 100644 --- a/compiler/testData/codegen/boxWasmJsInterop/functionTypes.kt +++ b/compiler/testData/codegen/boxWasmJsInterop/functionTypes.kt @@ -1,5 +1,6 @@ // Char issues // IGNORE_BACKEND: JS_IR +// WASM_FAILS_IN: SM // MODULE: main // FILE: externals.js diff --git a/compiler/testData/codegen/boxWasmJsInterop/jsExport.kt b/compiler/testData/codegen/boxWasmJsInterop/jsExport.kt index 7f2e65d43d8..8bfd33cfd82 100644 --- a/compiler/testData/codegen/boxWasmJsInterop/jsExport.kt +++ b/compiler/testData/codegen/boxWasmJsInterop/jsExport.kt @@ -1,4 +1,5 @@ // IGNORE_BACKEND: JS_IR, JS +// WASM_FAILS_IN: SM // MODULE: main // FILE: externals.kt diff --git a/compiler/testData/codegen/boxWasmJsInterop/jsToKotlinAdapters.kt b/compiler/testData/codegen/boxWasmJsInterop/jsToKotlinAdapters.kt index 3a086ac080d..e3d22b11d9e 100644 --- a/compiler/testData/codegen/boxWasmJsInterop/jsToKotlinAdapters.kt +++ b/compiler/testData/codegen/boxWasmJsInterop/jsToKotlinAdapters.kt @@ -1,4 +1,5 @@ // IGNORE_BACKEND: JS_IR, JS +// WASM_FAILS_IN: SM inline fun checkNPE(body: () -> Unit) { var throwed = false diff --git a/compiler/testData/codegen/boxWasmJsInterop/kotlinToJsAdapters.kt b/compiler/testData/codegen/boxWasmJsInterop/kotlinToJsAdapters.kt index a79f3b1e1ca..aa174ed9571 100644 --- a/compiler/testData/codegen/boxWasmJsInterop/kotlinToJsAdapters.kt +++ b/compiler/testData/codegen/boxWasmJsInterop/kotlinToJsAdapters.kt @@ -1,4 +1,5 @@ // IGNORE_BACKEND: JS_IR, JS +// WASM_FAILS_IN: SM @JsFun("(x) => { if (x !== 'abc') throw 'error' }") external fun notNullString(x: String) diff --git a/compiler/testData/codegen/boxWasmJsInterop/types.kt b/compiler/testData/codegen/boxWasmJsInterop/types.kt index 8ed3f297a4c..ef3764c523f 100644 --- a/compiler/testData/codegen/boxWasmJsInterop/types.kt +++ b/compiler/testData/codegen/boxWasmJsInterop/types.kt @@ -1,3 +1,4 @@ +// WASM_FAILS_IN: SM // FILE: externals.js // -- Strings -- diff --git a/compiler/testData/codegen/boxWasmJsInterop/vararg.kt b/compiler/testData/codegen/boxWasmJsInterop/vararg.kt index 4493d0f177a..1fd9197d4e9 100644 --- a/compiler/testData/codegen/boxWasmJsInterop/vararg.kt +++ b/compiler/testData/codegen/boxWasmJsInterop/vararg.kt @@ -1,4 +1,5 @@ // IGNORE_BACKEND_K2: JS_IR +// WASM_FAILS_IN: SM // Partial copy of js/js.translator/testData/box/native/vararg.kt // With some additions for concrete number types, strings and function references diff --git a/js/js.tests/test/org/jetbrains/kotlin/js/testOld/BasicWasmBoxTest.kt b/js/js.tests/test/org/jetbrains/kotlin/js/testOld/BasicWasmBoxTest.kt index 965b18f26e8..398bfb7d9d3 100644 --- a/js/js.tests/test/org/jetbrains/kotlin/js/testOld/BasicWasmBoxTest.kt +++ b/js/js.tests/test/org/jetbrains/kotlin/js/testOld/BasicWasmBoxTest.kt @@ -24,7 +24,7 @@ import org.jetbrains.kotlin.ir.declarations.impl.IrFactoryImpl import org.jetbrains.kotlin.js.config.JSConfigurationKeys import org.jetbrains.kotlin.js.config.JsConfig import org.jetbrains.kotlin.js.facade.TranslationUnit -import org.jetbrains.kotlin.js.testOld.engines.ExternalTool +import org.jetbrains.kotlin.js.testOld.engines.WasmVM import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.psi.KtFile import org.jetbrains.kotlin.psi.KtNamedFunction @@ -200,7 +200,7 @@ abstract class BasicWasmBoxTest( val testJs = if (debugMode >= DebugMode.DEBUG) testJsVerbose else testJsQuiet - fun writeToFilesAndRunD8Test(name: String, res: WasmCompilerResult) { + fun writeToFilesAndRunTest(name: String, res: WasmCompilerResult) { val dir = File(outputDirBase, name) dir.mkdirs() @@ -249,19 +249,45 @@ abstract class BasicWasmBoxTest( File(dir, mjsFile.name).writeText(mjsFile.readText()) } - ExternalTool(System.getProperty("javascript.engine.path.V8")) - .run( - "--experimental-wasm-gc", - *jsFilesBefore.map { File(it).absolutePath }.toTypedArray(), - "--module", - "./${entryMjs}", - *jsFilesAfter.map { File(it).absolutePath }.toTypedArray(), - workingDirectory = dir - ) + val failsIn = InTextDirectivesUtils.findListWithPrefixes(file.readText(), "// WASM_FAILS_IN: ") + + val exceptions = listOf(WasmVM.V8, WasmVM.SpiderMonkey).mapNotNull map@{ vm -> + try { + if (debugMode >= DebugMode.DEBUG) { + println(" ------ Run in ${vm.name}" + if (vm.shortName in failsIn) " (expected to fail)" else "") + } + vm.run( + "./${entryMjs}", + jsFilesBefore.map { File(it).absolutePath }, + jsFilesAfter.map { File(it).absolutePath }, + workingDirectory = dir + ) + if (vm.shortName in failsIn) { + return@map AssertionError("The test expected to fail in ${vm.name}. Please update the testdata.") + } + } catch (e: Throwable) { + if (vm.shortName !in failsIn) { + return@map e + } + } + null + } + + when (exceptions.size) { + 0 -> {} // Everything OK + 1 -> { + throw exceptions.single() + } + else -> { + throw AssertionError("Failed with several exceptions. Look at suppressed exceptions below.").apply { + exceptions.forEach { addSuppressed(it) } + } + } + } } - writeToFilesAndRunD8Test("d8", compilerResult) - writeToFilesAndRunD8Test("d8-dce", compilerResultWithDCE) + writeToFilesAndRunTest("dev", compilerResult) + writeToFilesAndRunTest("dce", compilerResultWithDCE) } } diff --git a/js/js.tests/test/org/jetbrains/kotlin/js/testOld/engines/SpiderMonkey.kt b/js/js.tests/test/org/jetbrains/kotlin/js/testOld/engines/SpiderMonkey.kt index da972466d00..c776d14f897 100644 --- a/js/js.tests/test/org/jetbrains/kotlin/js/testOld/engines/SpiderMonkey.kt +++ b/js/js.tests/test/org/jetbrains/kotlin/js/testOld/engines/SpiderMonkey.kt @@ -11,14 +11,46 @@ import java.io.InputStreamReader import java.lang.Boolean.getBoolean import kotlin.test.fail +private val toolLogsEnabled: Boolean = getBoolean("kotlin.js.test.verbose") -val toolLogsEnabled: Boolean = getBoolean("kotlin.js.test.verbose") +internal sealed class WasmVM(val shortName: String) { + val name: String = javaClass.simpleName + protected val tool = ExternalTool(System.getProperty("javascript.engine.path.$name")) -class ExternalTool(val path: String) { + abstract fun run(entryMjs: String, jsFilesBefore: List, jsFilesAfter: List, workingDirectory: File?) + + object V8 : WasmVM("V8") { + override fun run(entryMjs: String, jsFilesBefore: List, jsFilesAfter: List, workingDirectory: File?) { + tool.run( + "--experimental-wasm-gc", + *jsFilesBefore.toTypedArray(), + "--module", + entryMjs, + *jsFilesAfter.toTypedArray(), + workingDirectory = workingDirectory + ) + } + } + + object SpiderMonkey : WasmVM("SM") { + override fun run(entryMjs: String, jsFilesBefore: List, jsFilesAfter: List, workingDirectory: File?) { + tool.run( + "--wasm-verbose", + "--wasm-gc", + "--wasm-function-references", + *jsFilesBefore.flatMap { listOf("-f", it) }.toTypedArray(), + "--module=$entryMjs", + *jsFilesAfter.flatMap { listOf("-f", it) }.toTypedArray(), + workingDirectory = workingDirectory + ) + } + } +} + +internal class ExternalTool(val path: String) { fun run(vararg arguments: String, workingDirectory: File? = null) { val command = arrayOf(path, *arguments) - val processBuilder = ProcessBuilder(*command) - .redirectErrorStream(true) + val processBuilder = ProcessBuilder(*command).redirectErrorStream(true) if (workingDirectory != null) { processBuilder.directory(workingDirectory) @@ -51,13 +83,3 @@ class ExternalTool(val path: String) { private fun escapeShellArgument(arg: String): String = "'${arg.replace("'", "'\\''")}'" - -class SpiderMonkeyEngine( - jsShellPath: String = System.getProperty("javascript.engine.path.SpiderMonkey") -) { - private val jsShell = ExternalTool(jsShellPath) - - fun runFile(file: String) { - jsShell.run("--wasm-gc", file) - } -} \ No newline at end of file diff --git a/js/js.translator/testData/box/native/castToNativeClassChecked.kt b/js/js.translator/testData/box/native/castToNativeClassChecked.kt index ce250fc4183..e66a3767a48 100644 --- a/js/js.translator/testData/box/native/castToNativeClassChecked.kt +++ b/js/js.translator/testData/box/native/castToNativeClassChecked.kt @@ -1,3 +1,4 @@ +// WASM_FAILS_IN: SM // EXPECTED_REACHABLE_NODES: 1283 // FILE: castToNativeClassChecked.kt external abstract class S() { diff --git a/js/js.translator/testData/box/native/castToNativeInterface.kt b/js/js.translator/testData/box/native/castToNativeInterface.kt index 862ef4ee181..c3c61ff7519 100644 --- a/js/js.translator/testData/box/native/castToNativeInterface.kt +++ b/js/js.translator/testData/box/native/castToNativeInterface.kt @@ -1,3 +1,4 @@ +// WASM_FAILS_IN: SM // EXPECTED_REACHABLE_NODES: 1282 // FILE: castToNativeInterface.kt external interface I { diff --git a/js/js.translator/testData/box/native/castToTypeParamBoundedByNativeInterface.kt b/js/js.translator/testData/box/native/castToTypeParamBoundedByNativeInterface.kt index b01d19eee5c..e16a84441a6 100644 --- a/js/js.translator/testData/box/native/castToTypeParamBoundedByNativeInterface.kt +++ b/js/js.translator/testData/box/native/castToTypeParamBoundedByNativeInterface.kt @@ -1,3 +1,4 @@ +// WASM_FAILS_IN: SM // EXPECTED_REACHABLE_NODES: 1284 // FILE: castToTypeParamBoundedByNativeInterface.kt external interface I { diff --git a/js/js.translator/testData/box/native/passMemberOrExtFromNative.kt b/js/js.translator/testData/box/native/passMemberOrExtFromNative.kt index 85f256ac4b2..48bfd09bdb3 100644 --- a/js/js.translator/testData/box/native/passMemberOrExtFromNative.kt +++ b/js/js.translator/testData/box/native/passMemberOrExtFromNative.kt @@ -1,3 +1,4 @@ +// WASM_FAILS_IN: SM // EXPECTED_REACHABLE_NODES: 1285 package foo diff --git a/js/js.translator/testData/box/native/passTopLevelOrLocalFunctionToNative.kt b/js/js.translator/testData/box/native/passTopLevelOrLocalFunctionToNative.kt index d94bde8bc62..b401c333082 100644 --- a/js/js.translator/testData/box/native/passTopLevelOrLocalFunctionToNative.kt +++ b/js/js.translator/testData/box/native/passTopLevelOrLocalFunctionToNative.kt @@ -1,3 +1,4 @@ +// WASM_FAILS_IN: SM // EXPECTED_REACHABLE_NODES: 1284 package foo