diff --git a/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/K2JSCompilerArguments.kt b/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/K2JSCompilerArguments.kt index f54975cd360..aba055ff0da 100644 --- a/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/K2JSCompilerArguments.kt +++ b/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/K2JSCompilerArguments.kt @@ -256,6 +256,9 @@ class K2JSCompilerArguments : CommonCompilerArguments() { @Argument(value = "-Xwasm-enable-array-range-checks", description = "Turn on range checks for the array access functions") var wasmEnableArrayRangeChecks: Boolean by FreezableVar(false) + @Argument(value = "-Xwasm-enable-asserts", description = "Turn on asserts") + var wasmEnableAsserts: Boolean by FreezableVar(false) + override fun configureAnalysisFlags(collector: MessageCollector, languageVersion: LanguageVersion): MutableMap, Any> { return super.configureAnalysisFlags(collector, languageVersion).also { it[allowFullyQualifiedNameInKClass] = wasm && wasmKClassFqn //Only enabled WASM BE supports this flag diff --git a/compiler/cli/cli-js/src/org/jetbrains/kotlin/cli/js/K2JsIrCompiler.kt b/compiler/cli/cli-js/src/org/jetbrains/kotlin/cli/js/K2JsIrCompiler.kt index 8aa0d50ba48..b6d531ddbc2 100644 --- a/compiler/cli/cli-js/src/org/jetbrains/kotlin/cli/js/K2JsIrCompiler.kt +++ b/compiler/cli/cli-js/src/org/jetbrains/kotlin/cli/js/K2JsIrCompiler.kt @@ -136,6 +136,7 @@ class K2JsIrCompiler : CLICompiler() { configuration.put(JSConfigurationKeys.PARTIAL_LINKAGE, arguments.partialLinkage) configuration.put(JSConfigurationKeys.WASM_ENABLE_ARRAY_RANGE_CHECKS, arguments.wasmEnableArrayRangeChecks) + configuration.put(JSConfigurationKeys.WASM_ENABLE_ASSERTS, arguments.wasmEnableAsserts) val commonSourcesArray = arguments.commonSources val commonSources = commonSourcesArray?.toSet() ?: emptySet() diff --git a/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/WasmSymbols.kt b/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/WasmSymbols.kt index 78f9aeb4c1b..478d78bbbaa 100644 --- a/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/WasmSymbols.kt +++ b/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/WasmSymbols.kt @@ -31,6 +31,8 @@ class WasmSymbols( private val symbolTable: SymbolTable ) : Symbols(context, context.irBuiltIns, symbolTable) { + private val kotlinTopLevelPackage: PackageViewDescriptor = + context.module.getPackage(FqName("kotlin")) private val wasmInternalPackage: PackageViewDescriptor = context.module.getPackage(FqName("kotlin.wasm.internal")) private val collectionsPackage: PackageViewDescriptor = @@ -157,6 +159,7 @@ class WasmSymbols( val wasmRefCast = getInternalFunction("wasm_ref_cast") val rangeCheck = getInternalFunction("rangeCheck") + val assertFuncs = findFunctions(kotlinTopLevelPackage.memberScope, Name.identifier("assert")) val boxIntrinsic: IrSimpleFunctionSymbol = getInternalFunction("boxIntrinsic") val unboxIntrinsic: IrSimpleFunctionSymbol = getInternalFunction("unboxIntrinsic") diff --git a/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/ir2wasm/BodyGenerator.kt b/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/ir2wasm/BodyGenerator.kt index 66815144cb6..94a32be82cd 100644 --- a/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/ir2wasm/BodyGenerator.kt +++ b/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/ir2wasm/BodyGenerator.kt @@ -259,9 +259,15 @@ class BodyGenerator(val context: WasmFunctionCodegenContext) : IrElementVisitorV return } - // Range check intrinsic is a special case because it doesn't require arguments on the stack. - if (call.symbol == wasmSymbols.rangeCheck && - backendContext.configuration.getNotNull(JSConfigurationKeys.WASM_ENABLE_ARRAY_RANGE_CHECKS) == false) { + // Some intrinsics are a special case because we want to remove them completely, including their arguments. + val removableIntrinsics = buildList { + if (backendContext.configuration.getNotNull(JSConfigurationKeys.WASM_ENABLE_ARRAY_RANGE_CHECKS) == false) + add(wasmSymbols.rangeCheck) + if (backendContext.configuration.getNotNull(JSConfigurationKeys.WASM_ENABLE_ASSERTS) == false) + addAll(wasmSymbols.assertFuncs) + } + + if (call.symbol in removableIntrinsics) { body.buildGetUnit() return } diff --git a/compiler/testData/cli/js/jsExtraHelp.out b/compiler/testData/cli/js/jsExtraHelp.out index 7b87fd07b89..1a980c45652 100644 --- a/compiler/testData/cli/js/jsExtraHelp.out +++ b/compiler/testData/cli/js/jsExtraHelp.out @@ -41,6 +41,7 @@ where advanced options include: -Xwasm-debug-info Add debug info to WebAssembly compiled module -Xwasm-enable-array-range-checks Turn on range checks for the array access functions + -Xwasm-enable-asserts Turn on asserts -Xwasm-kclass-fqn Enable support for FQ names in KClass -Xwasm-launcher=esm|nodejs|d8 Picks flavor for the wasm launcher. Default is ESM. -Xallow-kotlin-package Allow compiling code in package 'kotlin' and allow not requiring kotlin.stdlib in module-info diff --git a/js/js.frontend/src/org/jetbrains/kotlin/js/config/JSConfigurationKeys.java b/js/js.frontend/src/org/jetbrains/kotlin/js/config/JSConfigurationKeys.java index fdddd23a301..024d7356cba 100644 --- a/js/js.frontend/src/org/jetbrains/kotlin/js/config/JSConfigurationKeys.java +++ b/js/js.frontend/src/org/jetbrains/kotlin/js/config/JSConfigurationKeys.java @@ -102,4 +102,7 @@ public class JSConfigurationKeys { public static final CompilerConfigurationKey WASM_ENABLE_ARRAY_RANGE_CHECKS = CompilerConfigurationKey.create("enable array range checks"); + + public static final CompilerConfigurationKey WASM_ENABLE_ASSERTS = + CompilerConfigurationKey.create("enable asserts"); } 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 d0f062c585d..a396eddbfac 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 @@ -236,7 +236,8 @@ abstract class BasicWasmBoxTest( private fun createConfig(languageVersionSettings: LanguageVersionSettings?): JsConfig { val configuration = environment.configuration.copy() configuration.put(CommonConfigurationKeys.MODULE_NAME, TEST_MODULE) - configuration.put(JSConfigurationKeys.WASM_ENABLE_ARRAY_RANGE_CHECKS, false) + configuration.put(JSConfigurationKeys.WASM_ENABLE_ARRAY_RANGE_CHECKS, true) + configuration.put(JSConfigurationKeys.WASM_ENABLE_ASSERTS, true) configuration.languageVersionSettings = languageVersionSettings ?: LanguageVersionSettingsImpl(LanguageVersion.LATEST_STABLE, ApiVersion.LATEST_STABLE) return JsConfig(project, configuration, CompilerEnvironment, null, null) diff --git a/libraries/stdlib/wasm/build.gradle.kts b/libraries/stdlib/wasm/build.gradle.kts index 402aa6c1dcb..f05f9ecca71 100644 --- a/libraries/stdlib/wasm/build.gradle.kts +++ b/libraries/stdlib/wasm/build.gradle.kts @@ -143,7 +143,7 @@ val compileTestKotlinWasm by tasks.existing(KotlinCompile::class) { } tasks.named("compileTestDevelopmentExecutableKotlinWasm") { - (this as KotlinCompile<*>).kotlinOptions.freeCompilerArgs += "-Xwasm-enable-array-range-checks" + (this as KotlinCompile<*>).kotlinOptions.freeCompilerArgs += listOf("-Xwasm-enable-array-range-checks", "-Xwasm-enable-asserts") } val runtimeElements by configurations.creating {} diff --git a/libraries/stdlib/wasm/src/kotlin/Assertions.kt b/libraries/stdlib/wasm/src/kotlin/Assertions.kt index fca88b71234..53c90178aad 100644 --- a/libraries/stdlib/wasm/src/kotlin/Assertions.kt +++ b/libraries/stdlib/wasm/src/kotlin/Assertions.kt @@ -5,13 +5,11 @@ package kotlin -// TODO: Make this dependant on the compiler flag (like -ea on JVM) - /** * Throws an [AssertionError] if the [value] is false. */ @kotlin.internal.InlineOnly -public inline fun assert(value: Boolean) { +public fun assert(value: Boolean) { assert(value) { "Assertion failed" } } @@ -19,7 +17,7 @@ public inline fun assert(value: Boolean) { * Throws an [AssertionError] calculated by [lazyMessage] if the [value] is false. */ @kotlin.internal.InlineOnly -public inline fun assert(value: Boolean, lazyMessage: () -> Any) { +public fun assert(value: Boolean, lazyMessage: () -> Any) { if (!value) { val message = lazyMessage() throw AssertionError(message)