From 3ec4f2e0ee9766092703ec25f74f4ab24f5e6887 Mon Sep 17 00:00:00 2001 From: Alexander Shabalin Date: Mon, 14 Aug 2023 11:16:52 +0200 Subject: [PATCH] [K/N] Remove jsinterop because K/N wasm32 target is removed ^KT-59008 See https://kotl.in/native-targets-tiers for details --- .../JsRuntime/src/main/js/jsinterop.js | 97 ----- .../JsRuntime/src/main/kotlin/jsinterop.kt | 94 ++-- .../native/interop/gen/jvm/CommandLine.kt | 11 - .../kotlin/native/interop/gen/jvm/main.kt | 3 +- .../native/interop/gen/wasm/StubGenerator.kt | 410 ------------------ .../kotlin/native/interop/gen/wasm/idl/dom.kt | 50 --- .../kotlin/native/interop/gen/wasm/idl/idl.kt | 37 -- .../native/interop/gen/wasm/idl/idlMath.kt | 73 ---- kotlin-native/build.gradle | 8 - kotlin-native/runtime/build.gradle.kts | 27 -- .../runtime/src/launcher/js/index.html | 14 - .../runtime/src/launcher/js/launcher.js | 247 ----------- kotlin-native/runtime/src/main/js/math.js | 254 ----------- .../kotlin/cli/utilities/InteropCompiler.kt | 15 +- .../jetbrains/kotlin/cli/utilities/main.kt | 5 +- 15 files changed, 46 insertions(+), 1299 deletions(-) delete mode 100644 kotlin-native/Interop/JsRuntime/src/main/js/jsinterop.js delete mode 100644 kotlin-native/Interop/StubGenerator/src/main/kotlin/org/jetbrains/kotlin/native/interop/gen/wasm/StubGenerator.kt delete mode 100644 kotlin-native/Interop/StubGenerator/src/main/kotlin/org/jetbrains/kotlin/native/interop/gen/wasm/idl/dom.kt delete mode 100644 kotlin-native/Interop/StubGenerator/src/main/kotlin/org/jetbrains/kotlin/native/interop/gen/wasm/idl/idl.kt delete mode 100644 kotlin-native/Interop/StubGenerator/src/main/kotlin/org/jetbrains/kotlin/native/interop/gen/wasm/idl/idlMath.kt delete mode 100644 kotlin-native/runtime/src/launcher/js/index.html delete mode 100644 kotlin-native/runtime/src/launcher/js/launcher.js delete mode 100644 kotlin-native/runtime/src/main/js/math.js diff --git a/kotlin-native/Interop/JsRuntime/src/main/js/jsinterop.js b/kotlin-native/Interop/JsRuntime/src/main/js/jsinterop.js deleted file mode 100644 index 050b4a7bcf7..00000000000 --- a/kotlin-native/Interop/JsRuntime/src/main/js/jsinterop.js +++ /dev/null @@ -1,97 +0,0 @@ -/* - * Copyright 2010-2018 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -konan.libraries.push ({ - arenas: new Map(), - nextArena: 0, - Konan_js_allocateArena: function (array) { - var index = konan_dependencies.env.nextArena++; - konan_dependencies.env.arenas.set(index, array || []); - return index; - - }, - Konan_js_freeArena: function(arenaIndex) { - var arena = konan_dependencies.env.arenas.get(arenaIndex); - arena.forEach(function(element, index) { - arena[index] = null; - }); - konan_dependencies.env.arenas.delete(arenaIndex); - }, - Konan_js_pushIntToArena: function (arenaIndex, value) { - var arena = konan_dependencies.env.arenas.get(arenaIndex); - arena.push(value); - return arena.length - 1; - }, - Konan_js_addObjectToArena: function (arenaIndex, object) { - var arena = konan_dependencies.env.arenas.get(arenaIndex); - arena.push(object); - return arena.length - 1; - }, - Konan_js_wrapLambda: function (functionArenaIndex, index) { - return (function () { - var functionArena = konan_dependencies.env.arenas.get(functionArenaIndex); - - // convert Arguments to an array - // to be provided by launcher.js - var argumentArenaIndex = konan_dependencies.env.Konan_js_allocateArena(Array.prototype.slice.call(arguments)); - - var resultIndex = instance.exports.Konan_js_runLambda(index, argumentArenaIndex, arguments.length); - var result = kotlinObject(argumentArenaIndex, resultIndex); - konan_dependencies.env.Konan_js_freeArena(argumentArenaIndex); - - return result; - }); - }, - Konan_js_getInt: function(arenaIndex, objIndex, propertyNamePtr, propertyNameLength) { - // TODO: The toUTF16String() is to be resolved by launcher.js runtime. - var property = toUTF16String(propertyNamePtr, propertyNameLength); - var value = kotlinObject(arenaIndex, objIndex)[property]; - return value; - }, - Konan_js_getProperty: function(arenaIndex, objIndex, propertyNamePtr, propertyNameLength) { - // TODO: The toUTF16String() is to be resolved by launcher.js runtime. - var property = toUTF16String(propertyNamePtr, propertyNameLength); - var arena = konan_dependencies.env.arenas.get(arenaIndex); - var value = arena[objIndex][property]; - arena.push(value); - return arena.length - 1; - }, - Konan_js_setFunction: function (arena, obj, propertyName, propertyNameLength, func) { - var name = toUTF16String(propertyName, propertyNameLength); - kotlinObject(arena, obj)[name] = konan_dependencies.env.Konan_js_wrapLambda(arena, func); - }, - - Konan_js_setString: function (arena, obj, propertyName, propertyNameLength, stringPtr, stringLength) { - var name = toUTF16String(propertyName, propertyNameLength); - var string = toUTF16String(stringPtr, stringLength); - kotlinObject(arena, obj)[name] = string; - }, -}); - -// TODO: This is just a shorthand notation. -function kotlinObject(arenaIndex, objectIndex) { - var arena = konan_dependencies.env.arenas.get(arenaIndex); - if (typeof arena == "undefined") { - console.log("No arena index " + arenaIndex + "for object" + objectIndex); - console.trace() - } - return arena[objectIndex] -} - -function toArena(arenaIndex, object) { - return konan_dependencies.env.Konan_js_addObjectToArena(arenaIndex, object); -} - diff --git a/kotlin-native/Interop/JsRuntime/src/main/kotlin/jsinterop.kt b/kotlin-native/Interop/JsRuntime/src/main/kotlin/jsinterop.kt index 6610ffa6ba5..44193880d84 100644 --- a/kotlin-native/Interop/JsRuntime/src/main/kotlin/jsinterop.kt +++ b/kotlin-native/Interop/JsRuntime/src/main/kotlin/jsinterop.kt @@ -14,7 +14,7 @@ * limitations under the License. */ -@file:Suppress("DEPRECATION", "TYPEALIAS_EXPANSION_DEPRECATION") // Everything is scheduled for removal +@file:Suppress("DEPRECATION_ERROR", "TYPEALIAS_EXPANSION_DEPRECATION_ERROR", "UNUSED_PARAMETER") // Everything is scheduled for removal @file:OptIn(ExperimentalForeignApi::class) package kotlinx.wasm.jsinterop @@ -23,74 +23,60 @@ import kotlin.native.* import kotlin.native.internal.* import kotlinx.cinterop.* -@Deprecated(WASM_TARGET_IS_DEPRECATED, level = DeprecationLevel.WARNING) +@Deprecated(WASM_TARGET_IS_DEPRECATED, level = DeprecationLevel.ERROR) typealias Arena = Int -@Deprecated(WASM_TARGET_IS_DEPRECATED, level = DeprecationLevel.WARNING) +@Deprecated(WASM_TARGET_IS_DEPRECATED, level = DeprecationLevel.ERROR) typealias Object = Int -@Deprecated(WASM_TARGET_IS_DEPRECATED, level = DeprecationLevel.WARNING) +@Deprecated(WASM_TARGET_IS_DEPRECATED, level = DeprecationLevel.ERROR) typealias Pointer = Int -private const val WASM_TARGET_IS_DEPRECATED = "K/N WASM target and all related API is deprecated for removal. " + +private const val WASM_TARGET_IS_DEPRECATED = "K/N WASM target was removed and all related API is deprecated for removal. " + "See https://blog.jetbrains.com/kotlin/2023/02/update-regarding-kotlin-native-targets for additional details" /** * @Retain annotation is required to preserve functions from internalization and DCE. */ -@RetainForTarget("wasm32") -@GCUnsafeCall("Konan_js_allocateArena") -@Deprecated(WASM_TARGET_IS_DEPRECATED, level = DeprecationLevel.WARNING) -external public fun allocateArena(): Arena +@Deprecated(WASM_TARGET_IS_DEPRECATED, level = DeprecationLevel.ERROR) +public fun allocateArena(): Arena = error(WASM_TARGET_IS_DEPRECATED) -@RetainForTarget("wasm32") -@GCUnsafeCall("Konan_js_freeArena") -@Deprecated(WASM_TARGET_IS_DEPRECATED, level = DeprecationLevel.WARNING) -external public fun freeArena(arena: Arena) +@Deprecated(WASM_TARGET_IS_DEPRECATED, level = DeprecationLevel.ERROR) +public fun freeArena(arena: Arena) { error(WASM_TARGET_IS_DEPRECATED) } -@RetainForTarget("wasm32") -@GCUnsafeCall("Konan_js_pushIntToArena") -@Deprecated(WASM_TARGET_IS_DEPRECATED, level = DeprecationLevel.WARNING) -external public fun pushIntToArena(arena: Arena, value: Int) +@Deprecated(WASM_TARGET_IS_DEPRECATED, level = DeprecationLevel.ERROR) +public fun pushIntToArena(arena: Arena, value: Int) { error(WASM_TARGET_IS_DEPRECATED) } -@Deprecated(WASM_TARGET_IS_DEPRECATED, level = DeprecationLevel.WARNING) +@Deprecated(WASM_TARGET_IS_DEPRECATED, level = DeprecationLevel.ERROR) const val upperWord = 0xffffffff.toLong() shl 32 -@ExportForCppRuntime -@Deprecated(WASM_TARGET_IS_DEPRECATED, level = DeprecationLevel.WARNING) +@Deprecated(WASM_TARGET_IS_DEPRECATED, level = DeprecationLevel.ERROR) fun doubleUpper(value: Double): Int = ((value.toBits() and upperWord) ushr 32) .toInt() -@ExportForCppRuntime -@Deprecated(WASM_TARGET_IS_DEPRECATED, level = DeprecationLevel.WARNING) +@Deprecated(WASM_TARGET_IS_DEPRECATED, level = DeprecationLevel.ERROR) fun doubleLower(value: Double): Int = (value.toBits() and 0x00000000ffffffff) .toInt() -@RetainForTarget("wasm32") -@GCUnsafeCall("ReturnSlot_getDouble") -@Deprecated(WASM_TARGET_IS_DEPRECATED, level = DeprecationLevel.WARNING) -external public fun ReturnSlot_getDouble(): Double +@Deprecated(WASM_TARGET_IS_DEPRECATED, level = DeprecationLevel.ERROR) +public fun ReturnSlot_getDouble(): Double = error(WASM_TARGET_IS_DEPRECATED) -@RetainForTarget("wasm32") @GCUnsafeCall("Kotlin_String_utf16pointer") -@Deprecated(WASM_TARGET_IS_DEPRECATED, level = DeprecationLevel.WARNING) +@Deprecated(WASM_TARGET_IS_DEPRECATED, level = DeprecationLevel.ERROR) external public fun stringPointer(message: String): Pointer -@RetainForTarget("wasm32") -@Deprecated(WASM_TARGET_IS_DEPRECATED, level = DeprecationLevel.WARNING) +@Deprecated(WASM_TARGET_IS_DEPRECATED, level = DeprecationLevel.ERROR) @GCUnsafeCall("Kotlin_String_utf16length") external public fun stringLengthBytes(message: String): Int -@Deprecated(WASM_TARGET_IS_DEPRECATED, level = DeprecationLevel.WARNING) +@Deprecated(WASM_TARGET_IS_DEPRECATED, level = DeprecationLevel.ERROR) typealias KtFunction = ((ArrayList)->R) -@Deprecated(WASM_TARGET_IS_DEPRECATED, level = DeprecationLevel.WARNING) +@Deprecated(WASM_TARGET_IS_DEPRECATED, level = DeprecationLevel.ERROR) fun wrapFunction(func: KtFunction): Int { val ptr: Long = StableRef.create(func).asCPointer().toLong() return ptr.toInt() // TODO: LP64 unsafe. } -@RetainForTarget("wasm32") -@ExportForCppRuntime("Konan_js_runLambda") -@Deprecated(WASM_TARGET_IS_DEPRECATED, level = DeprecationLevel.WARNING) +@Deprecated(WASM_TARGET_IS_DEPRECATED, level = DeprecationLevel.ERROR) fun runLambda(pointer: Int, argumentsArena: Arena, argumentsArenaSize: Int): Int { val arguments = arrayListOf() for (i in 0 until argumentsArenaSize) { @@ -106,7 +92,7 @@ fun runLambda(pointer: Int, argumentsArena: Arena, argumentsArenaSize: Int): Int return result.index } -@Deprecated(WASM_TARGET_IS_DEPRECATED, level = DeprecationLevel.WARNING) +@Deprecated(WASM_TARGET_IS_DEPRECATED, level = DeprecationLevel.ERROR) open class JsValue(val arena: Arena, val index: Object) { fun getInt(property: String): Int { return getInt(ArenaManager.currentArena, index, stringPointer(property), stringLengthBytes(property)) @@ -116,7 +102,7 @@ open class JsValue(val arena: Arena, val index: Object) { } } -@Deprecated(WASM_TARGET_IS_DEPRECATED, level = DeprecationLevel.WARNING) +@Deprecated(WASM_TARGET_IS_DEPRECATED, level = DeprecationLevel.ERROR) open class JsArray(arena: Arena, index: Object): JsValue(arena, index) { constructor(jsValue: JsValue): this(jsValue.arena, jsValue.index) operator fun get(index: Int): JsValue { @@ -127,48 +113,40 @@ open class JsArray(arena: Arena, index: Object): JsValue(arena, index) { get() = this.getInt("length") } -@RetainForTarget("wasm32") -@GCUnsafeCall("Konan_js_getInt") -@Deprecated(WASM_TARGET_IS_DEPRECATED, level = DeprecationLevel.WARNING) -external public fun getInt(arena: Arena, obj: Object, propertyPtr: Pointer, propertyLen: Int): Int; +@Deprecated(WASM_TARGET_IS_DEPRECATED, level = DeprecationLevel.ERROR) +public fun getInt(arena: Arena, obj: Object, propertyPtr: Pointer, propertyLen: Int): Int = error(WASM_TARGET_IS_DEPRECATED) -@RetainForTarget("wasm32") -@GCUnsafeCall("Konan_js_getProperty") -@Deprecated(WASM_TARGET_IS_DEPRECATED, level = DeprecationLevel.WARNING) -external public fun Konan_js_getProperty(arena: Arena, obj: Object, propertyPtr: Pointer, propertyLen: Int): Int; +@Deprecated(WASM_TARGET_IS_DEPRECATED, level = DeprecationLevel.ERROR) +public fun Konan_js_getProperty(arena: Arena, obj: Object, propertyPtr: Pointer, propertyLen: Int): Int = error(WASM_TARGET_IS_DEPRECATED) -@RetainForTarget("wasm32") -@GCUnsafeCall("Konan_js_setFunction") -@Deprecated(WASM_TARGET_IS_DEPRECATED, level = DeprecationLevel.WARNING) -external public fun setFunction(arena: Arena, obj: Object, propertyName: Pointer, propertyLength: Int , function: Int) +@Deprecated(WASM_TARGET_IS_DEPRECATED, level = DeprecationLevel.ERROR) +public fun setFunction(arena: Arena, obj: Object, propertyName: Pointer, propertyLength: Int , function: Int) { error(WASM_TARGET_IS_DEPRECATED) } -@RetainForTarget("wasm32") -@GCUnsafeCall("Konan_js_setString") -@Deprecated(WASM_TARGET_IS_DEPRECATED, level = DeprecationLevel.WARNING) -external public fun setString(arena: Arena, obj: Object, propertyName: Pointer, propertyLength: Int, stringPtr: Pointer, stringLength: Int ) +@Deprecated(WASM_TARGET_IS_DEPRECATED, level = DeprecationLevel.ERROR) +public fun setString(arena: Arena, obj: Object, propertyName: Pointer, propertyLength: Int, stringPtr: Pointer, stringLength: Int ) { error(WASM_TARGET_IS_DEPRECATED) } -@Deprecated(WASM_TARGET_IS_DEPRECATED, level = DeprecationLevel.WARNING) +@Deprecated(WASM_TARGET_IS_DEPRECATED, level = DeprecationLevel.ERROR) fun setter(obj: JsValue, property: String, string: String) { setString(obj.arena, obj.index, stringPointer(property), stringLengthBytes(property), stringPointer(string), stringLengthBytes(string)) } -@Deprecated(WASM_TARGET_IS_DEPRECATED, level = DeprecationLevel.WARNING) +@Deprecated(WASM_TARGET_IS_DEPRECATED, level = DeprecationLevel.ERROR) fun setter(obj: JsValue, property: String, lambda: KtFunction) { val pointer = wrapFunction(lambda); setFunction(obj.arena, obj.index, stringPointer(property), stringLengthBytes(property), pointer) } -@Deprecated(WASM_TARGET_IS_DEPRECATED, level = DeprecationLevel.WARNING) +@Deprecated(WASM_TARGET_IS_DEPRECATED, level = DeprecationLevel.ERROR) fun JsValue.setter(property: String, lambda: KtFunction) { setter(this, property, lambda) } -@Deprecated(WASM_TARGET_IS_DEPRECATED, level = DeprecationLevel.WARNING) +@Deprecated(WASM_TARGET_IS_DEPRECATED, level = DeprecationLevel.ERROR) fun JsValue.setter(property: String, string: String) { setter(this, property, string) } -@Deprecated(WASM_TARGET_IS_DEPRECATED, level = DeprecationLevel.WARNING) +@Deprecated(WASM_TARGET_IS_DEPRECATED, level = DeprecationLevel.ERROR) object ArenaManager { val globalArena = allocateArena() diff --git a/kotlin-native/Interop/StubGenerator/src/main/kotlin/org/jetbrains/kotlin/native/interop/gen/jvm/CommandLine.kt b/kotlin-native/Interop/StubGenerator/src/main/kotlin/org/jetbrains/kotlin/native/interop/gen/jvm/CommandLine.kt index e327384d630..ff66a3f8778 100644 --- a/kotlin-native/Interop/StubGenerator/src/main/kotlin/org/jetbrains/kotlin/native/interop/gen/jvm/CommandLine.kt +++ b/kotlin-native/Interop/StubGenerator/src/main/kotlin/org/jetbrains/kotlin/native/interop/gen/jvm/CommandLine.kt @@ -141,17 +141,6 @@ open class CInteropArguments(argParser: ArgParser = description = "Don't add @ExperimentalForeignApi to generated Kotlin declarations") } -class JSInteropArguments(argParser: ArgParser = ArgParser("jsinterop", - prefixStyle = ArgParser.OptionPrefixStyle.JVM)): CommonInteropArguments(argParser) { - enum class TargetType { - WASM32; - - override fun toString() = name.lowercase() - } - val target by argParser.option(ArgType.Choice(), - description = "wasm target to compile to").default(TargetType.WASM32) -} - internal fun warn(msg: String) { println("warning: $msg") } diff --git a/kotlin-native/Interop/StubGenerator/src/main/kotlin/org/jetbrains/kotlin/native/interop/gen/jvm/main.kt b/kotlin-native/Interop/StubGenerator/src/main/kotlin/org/jetbrains/kotlin/native/interop/gen/jvm/main.kt index ff7843c0633..99cfa758883 100644 --- a/kotlin-native/Interop/StubGenerator/src/main/kotlin/org/jetbrains/kotlin/native/interop/gen/jvm/main.kt +++ b/kotlin-native/Interop/StubGenerator/src/main/kotlin/org/jetbrains/kotlin/native/interop/gen/jvm/main.kt @@ -39,7 +39,6 @@ import org.jetbrains.kotlin.library.metadata.resolver.impl.libraryResolver import org.jetbrains.kotlin.library.packageFqName import org.jetbrains.kotlin.library.toUnresolvedLibraries import org.jetbrains.kotlin.native.interop.gen.* -import org.jetbrains.kotlin.native.interop.gen.wasm.processIdlLib import org.jetbrains.kotlin.native.interop.indexer.* import org.jetbrains.kotlin.native.interop.tool.* import org.jetbrains.kotlin.util.removeSuffixIfPresent @@ -100,7 +99,7 @@ class Interop { val platform = KotlinPlatform.values().single { it.name.equals(flavor, ignoreCase = true) } processCLibSafe(platform, cinteropArguments, additionalArgs, runFromDaemon) } - "wasm" -> processIdlLib(args, additionalArgs) + "wasm" -> error("wasm target in Kotlin/Native is removed. See https://kotl.in/native-targets-tiers") else -> error("Unexpected flavor") } } diff --git a/kotlin-native/Interop/StubGenerator/src/main/kotlin/org/jetbrains/kotlin/native/interop/gen/wasm/StubGenerator.kt b/kotlin-native/Interop/StubGenerator/src/main/kotlin/org/jetbrains/kotlin/native/interop/gen/wasm/StubGenerator.kt deleted file mode 100644 index 908f445c100..00000000000 --- a/kotlin-native/Interop/StubGenerator/src/main/kotlin/org/jetbrains/kotlin/native/interop/gen/wasm/StubGenerator.kt +++ /dev/null @@ -1,410 +0,0 @@ -package org.jetbrains.kotlin.native.interop.gen.wasm - -import org.jetbrains.kotlin.konan.file.File -import org.jetbrains.kotlin.native.interop.gen.argsToCompiler -import org.jetbrains.kotlin.native.interop.gen.wasm.idl.* -import org.jetbrains.kotlin.native.interop.gen.jvm.InternalInteropOptions -import org.jetbrains.kotlin.native.interop.tool.JSInteropArguments - -fun kotlinHeader(packageName: String): String { - return "package $packageName\n" + - "import kotlinx.wasm.jsinterop.*\n" -} - -fun Type.toKotlinType(argName: String? = null): String = when (this) { - is idlVoid -> "Unit" - is idlInt -> "Int" - is idlFloat -> "Float" - is idlDouble -> "Double" - is idlString -> "String" - is idlObject -> "JsValue" - is idlFunction -> "KtFunction" - is idlInterfaceRef -> name - else -> error("Unexpected type") -} - -fun Arg.wasmMapping(): String = when (type) { - is idlVoid -> error("An arg can not be idlVoid") - is idlInt -> name - is idlFloat -> name - is idlDouble -> "doubleUpper($name), doubleLower($name)" - is idlString -> "stringPointer($name), stringLengthBytes($name)" - is idlObject -> TODO("implement me") - is idlFunction -> "wrapFunction($name), ArenaManager.currentArena" - is idlInterfaceRef -> TODO("Implement me") - else -> error("Unexpected type") -} - -fun Type.wasmReturnArg(): String = - when (this) { - is idlVoid -> "ArenaManager.currentArena" // TODO: optimize. - is idlInt -> "ArenaManager.currentArena" - is idlFloat -> "ArenaManager.currentArena" - is idlDouble -> "ArenaManager.currentArena" - is idlString -> "ArenaManager.currentArena" - is idlObject -> "ArenaManager.currentArena" - is idlFunction -> "ArenaManager.currentArena" - is idlInterfaceRef -> "ArenaManager.currentArena" - else -> error("Unexpected type") - } -val Operation.wasmReturnArg: String get() = returnType.wasmReturnArg() -val Attribute.wasmReturnArg: String get() = type.wasmReturnArg() - -fun Arg.wasmArgNames(): List = when (type) { - is idlVoid -> error("An arg can not be idlVoid") - is idlInt -> listOf(name) - is idlFloat -> listOf(name) - is idlDouble -> listOf("${name}Upper", "${name}Lower") - is idlString -> listOf("${name}Ptr", "${name}Len") - is idlObject -> TODO("implement me (idlObject)") - is idlFunction -> listOf("${name}Index", "${name}ResultArena") - is idlInterfaceRef -> TODO("Implement me (idlInterfaceRef)") - else -> error("Unexpected type") -} - -fun Type.wasmReturnMapping(value: String): String = when (this) { - is idlVoid -> "" - is idlInt -> value - is idlFloat -> value - is idlDouble -> value - is idlString -> "TODO(\"Implement me\")" - is idlObject -> "JsValue(ArenaManager.currentArena, $value)" - is idlFunction -> "TODO(\"Implement me\")" - is idlInterfaceRef -> "$name(ArenaManager.currentArena, $value)" - else -> error("Unexpected type") -} - -fun wasmFunctionName(functionName: String, interfaceName: String) - = "knjs__${interfaceName}_$functionName" - -fun wasmSetterName(propertyName: String, interfaceName: String) - = "knjs_set__${interfaceName}_$propertyName" - -fun wasmGetterName(propertyName: String, interfaceName: String) - = "knjs_get__${interfaceName}_$propertyName" - -val Operation.kotlinTypeParameters: String get() { - val lambdaRetTypes = args.filter { it.type is idlFunction } - .map { "R${it.name}" }. joinToString(", ") - return if (lambdaRetTypes == "") "" else "<$lambdaRetTypes>" -} - -val Interface.wasmReceiverArgs get() = - if (isGlobal) emptyList() - else listOf("this.arena", "this.index") - -fun Member.wasmReceiverArgs(parent: Interface) = - if (isStatic) emptyList() - else parent.wasmReceiverArgs - -fun Type.generateKotlinCall(name: String, wasmArgList: String) = - "$name($wasmArgList)" - -fun Type.generateKotlinCallWithReturn(name: String, wasmArgList: String) = - when(this) { - is idlVoid -> " ${generateKotlinCall(name, wasmArgList)}\n" - is idlDouble -> " ${generateKotlinCall(name, wasmArgList)}\n" + - " val wasmRetVal = ReturnSlot_getDouble()\n" - - else -> " val wasmRetVal = ${generateKotlinCall(name, wasmArgList)}\n" - } - -fun Operation.generateKotlinCallWithReturn(parent_name: String, wasmArgList: String) = - returnType.generateKotlinCallWithReturn( - wasmFunctionName(name, parent_name), - wasmArgList) - -fun Attribute.generateKotlinGetterCallWithReturn(parent_name: String, wasmArgList: String) = - type.generateKotlinCallWithReturn( - wasmGetterName(name, parent_name), - wasmArgList) - -fun Operation.generateKotlin(parent: Interface): String { - val argList = args.map { - "${it.name}: ${it.type.toKotlinType(it.name)}" - }.joinToString(", ") - - val wasmArgList = (wasmReceiverArgs(parent) + args.map(Arg::wasmMapping) + wasmReturnArg).joinToString(", ") - - // TODO: there can be multiple Rs. - return " fun $kotlinTypeParameters $name(" + - argList + - "): ${returnType.toKotlinType()} {\n" + - generateKotlinCallWithReturn(parent.name, wasmArgList) + - " return ${returnType.wasmReturnMapping("wasmRetVal")}\n"+ - " }\n\n" -} - -fun Attribute.generateKotlinSetter(parent: Interface): String { - val kotlinType = type.toKotlinType(name) - return " set(value: $kotlinType) {\n" + - " ${wasmSetterName(name, parent.name)}(" + - (wasmReceiverArgs(parent) + Arg("value", type).wasmMapping()).joinToString(", ") + - ")\n" + - " }\n\n" -} - -fun Attribute.generateKotlinGetter(parent: Interface): String { - val wasmArgList = (wasmReceiverArgs(parent) + wasmReturnArg).joinToString(", ") - return " get() {\n" + - generateKotlinGetterCallWithReturn(parent.name, wasmArgList) + - " return ${type.wasmReturnMapping("wasmRetVal")}\n"+ - " }\n\n" -} - -fun Attribute.generateKotlin(parent: Interface): String { - val kotlinType = type.toKotlinType(name) - val varOrVal = if (readOnly) "val" else "var" - return " $varOrVal $name: $kotlinType\n" + - generateKotlinGetter(parent) + - if (!readOnly) generateKotlinSetter(parent) else "" -} - -val Interface.wasmTypedReceiverArgs get() = - if (isGlobal) emptyList() - else listOf("arena: Int", "index: Int") - -fun Member.wasmTypedReceiverArgs(parent: Interface) = - if (isStatic) emptyList() else parent.wasmTypedReceiverArgs - -fun Operation.generateWasmStub(parent: Interface): String { - val wasmName = wasmFunctionName(this.name, parent.name) - val allArgs = (wasmTypedReceiverArgs(parent) + args.toList().wasmTypedMapping() + wasmTypedReturnMapping).joinToString(", ") - return "@SymbolName(\"$wasmName\")\n" + - "external public fun $wasmName($allArgs): ${returnType.wasmReturnTypeMapping()}\n\n" -} -fun Attribute.generateWasmSetterStub(parent: Interface): String { - val wasmSetter = wasmSetterName(this.name, parent.name) - val allArgs = (wasmTypedReceiverArgs(parent) + Arg("value", this.type).wasmTypedMapping()).joinToString(", ") - return "@SymbolName(\"$wasmSetter\")\n" + - "external public fun $wasmSetter($allArgs): Unit\n\n" -} -fun Attribute.generateWasmGetterStub(parent: Interface): String { - val wasmGetter = wasmGetterName(this.name, parent.name) - val allArgs = (wasmTypedReceiverArgs(parent) + wasmTypedReturnMapping).joinToString(", ") - return "@SymbolName(\"$wasmGetter\")\n" + - "external public fun $wasmGetter($allArgs): Int\n\n" -} -fun Attribute.generateWasmStubs(parent: Interface) = - generateWasmGetterStub(parent) + - if (!readOnly) generateWasmSetterStub(parent) else "" - -// TODO: consider using virtual methods -fun Member.generateKotlin(parent: Interface): String = when (this) { - is Operation -> this.generateKotlin(parent) - is Attribute -> this.generateKotlin(parent) - else -> error("Unexpected member") -} - -// TODO: consider using virtual methods -fun Member.generateWasmStub(parent: Interface) = - when (this) { - is Operation -> this.generateWasmStub(parent) - is Attribute -> this.generateWasmStubs(parent) - else -> error("Unexpected member") - - } - -fun Arg.wasmTypedMapping() - = this.wasmArgNames().map { "$it: Int" } .joinToString(", ") - -// TODO: Optimize for simple types. -fun Type.wasmTypedReturnMapping(): String = "resultArena: Int" - -val Operation.wasmTypedReturnMapping get() = returnType.wasmTypedReturnMapping() - -val Attribute.wasmTypedReturnMapping get() = type.wasmTypedReturnMapping() - -fun List.wasmTypedMapping():List - = this.map(Arg::wasmTypedMapping) - -// TODO: more complex return types, such as returning a pair of Ints -// will require a more complex approach. -fun Type.wasmReturnTypeMapping() - = if (this == idlVoid) "Unit" else "Int" - -fun Interface.generateMemberWasmStubs() = - members.map { - it.generateWasmStub(this) - }.joinToString("") - -fun Interface.generateKotlinMembers() = - members.filterNot { it.isStatic } .map { - it.generateKotlin(this) - }.joinToString("") - -fun Interface.generateKotlinCompanion() = - " companion object {\n" + - members.filter { it.isStatic } .map { - it.generateKotlin(this) - }.joinToString("") + - " }\n" - -fun Interface.generateKotlinClassHeader() = - "open class $name(arena: Int, index: Int): JsValue(arena, index) {\n" + - " constructor(jsValue: JsValue): this(jsValue.arena, jsValue.index)\n" - -fun Interface.generateKotlinClassFooter() = - "}\n" - -fun Interface.generateKotlinClassConverter() = - "val JsValue.as$name: $name\n" + - " get() {\n" + - " return $name(this.arena, this.index)\n"+ - " }\n" - -fun Interface.generateKotlin(): String { - fun unlessGlobal(value: () -> String): String { - return if (this.isGlobal) "" else value() - } - - return generateMemberWasmStubs() + - unlessGlobal { generateKotlinClassHeader() } + - generateKotlinMembers() + - unlessGlobal { - generateKotlinCompanion() + - generateKotlinClassFooter() + - generateKotlinClassConverter() - } -} - -fun generateKotlin(pkg: String, interfaces: List) = - kotlinHeader(pkg) + - interfaces.map { - it.generateKotlin() - }.joinToString("\n") + - if (pkg == "kotlinx.interop.wasm.dom") // TODO: make it a general solution. - "fun setInterval(interval: Int, lambda: KtFunction) = setInterval(lambda, interval)\n" - else "" - -///////////////////////////////////////////////////////// - -fun Arg.composeWasmArgs(): String = when (type) { - is idlVoid -> error("An arg can not be idlVoid") - is idlInt -> "" - is idlFloat -> "" - is idlDouble -> - " var $name = twoIntsToDouble(${name}Upper, ${name}Lower);\n" - is idlString -> - " var $name = toUTF16String(${name}Ptr, ${name}Len);\n" - is idlObject -> TODO("implement me") - is idlFunction -> - " var $name = konan_dependencies.env.Konan_js_wrapLambda(lambdaResultArena, ${name}Index);\n" - - is idlInterfaceRef -> TODO("Implement me") - else -> error("Unexpected type") -} - -val Interface.receiver get() = - if (isGlobal) "" else "kotlinObject(arena, obj)." - -fun Member.receiver(parent: Interface) = - if (isStatic) "${parent.name}." else parent.receiver - -val Interface.wasmReceiverArgName get() = - if (isGlobal) emptyList() else listOf("arena", "obj") - -fun Member.wasmReceiverArgName(parent: Interface) = - if (isStatic) emptyList() else parent.wasmReceiverArgName - -val Operation.wasmReturnArgName get() = - returnType.wasmReturnArgName - -val Attribute.wasmReturnArgName get() = - type.wasmReturnArgName - -val Type.wasmReturnArgName get() = - when (this) { - is idlVoid -> emptyList() - is idlInt -> emptyList() - is idlFloat -> emptyList() - is idlDouble -> emptyList() - is idlString -> listOf("resultArena") - is idlObject -> listOf("resultArena") - is idlInterfaceRef -> listOf("resultArena") - else -> error("Unexpected type: $this") - } - -val Type.wasmReturnExpression get() = - when(this) { - is idlVoid -> "" - is idlInt -> "result" - is idlFloat -> "result" // TODO: can we really pass floats as is? - is idlDouble -> "doubleToReturnSlot(result)" - is idlString -> "toArena(resultArena, result)" - is idlObject -> "toArena(resultArena, result)" - is idlInterfaceRef -> "toArena(resultArena, result)" - else -> error("Unexpected type: $this") - } - -fun Operation.generateJs(parent: Interface): String { - val allArgs = wasmReceiverArgName(parent) + args.map { it.wasmArgNames() }.flatten() + wasmReturnArgName - val wasmMapping = allArgs.joinToString(", ") - val argList = args.map { it.name }. joinToString(", ") - val composedArgsList = args.map { it.composeWasmArgs() }. joinToString("") - - return "\n ${wasmFunctionName(this.name, parent.name)}: function($wasmMapping) {\n" + - composedArgsList + - " var result = ${receiver(parent)}$name($argList);\n" + - " return ${returnType.wasmReturnExpression};\n" + - " }" -} - -fun Attribute.generateJsSetter(parent: Interface): String { - val valueArg = Arg("value", type) - val allArgs = wasmReceiverArgName(parent) + valueArg.wasmArgNames() - val wasmMapping = allArgs.joinToString(", ") - return "\n ${wasmSetterName(name, parent.name)}: function($wasmMapping) {\n" + - valueArg.composeWasmArgs() + - " ${receiver(parent)}$name = value;\n" + - " }" -} - -fun Attribute.generateJsGetter(parent: Interface): String { - val allArgs = wasmReceiverArgName(parent) + wasmReturnArgName - val wasmMapping = allArgs.joinToString(", ") - return "\n ${wasmGetterName(name, parent.name)}: function($wasmMapping) {\n" + - " var result = ${receiver(parent)}$name;\n" + - " return ${type.wasmReturnExpression};\n" + - " }" -} - -fun Attribute.generateJs(parent: Interface) = - generateJsGetter(parent) + - if (!readOnly) ",\n${generateJsSetter(parent)}" else "" - -fun Member.generateJs(parent: Interface): String = when (this) { - is Operation -> this.generateJs(parent) - is Attribute -> this.generateJs(parent) - else -> error("Unexpected member") -} - -fun generateJs(interfaces: List): String = - "konan.libraries.push ({\n" + - interfaces.map { interf -> - interf.members.map { member -> - member.generateJs(interf) - } - }.flatten() .joinToString(",\n") + - "\n})\n" - -const val idlMathPackage = "kotlinx.interop.wasm.math" -const val idlDomPackage = "kotlinx.interop.wasm.dom" - -fun processIdlLib(args: Array, additionalArgs: InternalInteropOptions): Array { - val jsInteropArguments = JSInteropArguments() - jsInteropArguments.argParser.parse(args) - // TODO: Refactor me. - val ktGenRoot = File(additionalArgs.generated).mkdirs() - val nativeLibsDir = File(additionalArgs.natives).mkdirs() - - val idl = when (jsInteropArguments.pkg) { - idlMathPackage -> idlMath - idlDomPackage -> idlDom - else -> throw IllegalArgumentException("Please choose either $idlMathPackage or $idlDomPackage for -pkg argument") - } - File(ktGenRoot, "kotlin_stubs.kt").writeText(generateKotlin(jsInteropArguments.pkg!!, idl)) - File(nativeLibsDir, "js_stubs.js").writeText(generateJs(idl)) - File((additionalArgs.manifest)!!).writeText("") // The manifest is currently unused for wasm. - return argsToCompiler(jsInteropArguments.staticLibrary.toTypedArray(), jsInteropArguments.libraryPath.toTypedArray()) -} diff --git a/kotlin-native/Interop/StubGenerator/src/main/kotlin/org/jetbrains/kotlin/native/interop/gen/wasm/idl/dom.kt b/kotlin-native/Interop/StubGenerator/src/main/kotlin/org/jetbrains/kotlin/native/interop/gen/wasm/idl/dom.kt deleted file mode 100644 index 0d799ce7671..00000000000 --- a/kotlin-native/Interop/StubGenerator/src/main/kotlin/org/jetbrains/kotlin/native/interop/gen/wasm/idl/dom.kt +++ /dev/null @@ -1,50 +0,0 @@ -package org.jetbrains.kotlin.native.interop.gen.wasm.idl - -// This shall be an output of Web IDL parser. -val idlDom = listOf( - Interface("Context", - Attribute("lineWidth", idlInt), - Attribute("fillStyle", idlString), - Attribute("strokeStyle", idlString), - - Operation("lineTo", idlVoid, Arg("x", idlInt), Arg("y", idlInt)), - Operation("moveTo", idlVoid, Arg("x", idlInt), Arg("y", idlInt)), - Operation("beginPath", idlVoid), - Operation("stroke", idlVoid), - Operation("fillRect", idlVoid, Arg("x", idlInt), Arg("y", idlInt), Arg("width", idlInt), Arg("height", idlInt)), - Operation("fillText", idlVoid, Arg("test", idlString), Arg("x", idlInt), Arg("y", idlInt), Arg("maxWidth", idlInt)), - Operation("fill", idlVoid), - Operation("closePath", idlVoid) - ), - Interface("DOMRect", - Attribute("left", idlInt), - Attribute("right", idlInt), - Attribute("top", idlInt), - Attribute("bottom", idlInt) - ), - Interface("Canvas", - Operation("getContext", idlInterfaceRef("Context"), Arg("context", idlString)), - Operation("getBoundingClientRect", idlInterfaceRef("DOMRect")) - ), - Interface("Document", - Operation("getElementById", idlObject, Arg("id", idlString)) - ), - Interface("MouseEvent", - Attribute("clientX", idlInt, readOnly = true), - Attribute("clientY", idlInt, readOnly = true) - ), - Interface("Response", - Operation("json", idlObject) - ), - Interface("Promise", - Operation("then", idlInterfaceRef("Promise"), Arg("lambda", idlFunction)) - ), - Interface("__Global", - Attribute("document", idlInterfaceRef("Document"), readOnly = true), - - Operation("fetch", idlInterfaceRef("Promise"), Arg("url", idlString)), - Operation("setInterval", idlVoid, Arg("lambda", idlFunction), Arg("interval", idlInt)) - ) -) - - diff --git a/kotlin-native/Interop/StubGenerator/src/main/kotlin/org/jetbrains/kotlin/native/interop/gen/wasm/idl/idl.kt b/kotlin-native/Interop/StubGenerator/src/main/kotlin/org/jetbrains/kotlin/native/interop/gen/wasm/idl/idl.kt deleted file mode 100644 index 0ccbd8e8fca..00000000000 --- a/kotlin-native/Interop/StubGenerator/src/main/kotlin/org/jetbrains/kotlin/native/interop/gen/wasm/idl/idl.kt +++ /dev/null @@ -1,37 +0,0 @@ -package org.jetbrains.kotlin.native.interop.gen.wasm.idl - -// This is (as of now) a poor man's IDL representation. - -interface Type -interface Member { - val isStatic: Boolean get() = false -} - -object idlVoid: Type -object idlInt: Type -object idlFloat: Type -object idlDouble: Type -object idlString: Type -object idlObject: Type -object idlFunction: Type - -data class Attribute(val name: String, val type: Type, - val readOnly: Boolean = false, - override val isStatic: Boolean = false): Member - -data class Arg(val name: String, val type: Type) - -class Operation(val name: String, val returnType: Type, - override val isStatic: Boolean = false, - vararg val args: Arg): Member { - - constructor(name: String, returnType: Type, vararg args: Arg) : - this(name, returnType, false, *args) -} - -data class idlInterfaceRef(val name: String): Type -class Interface(val name: String, vararg val members: Member) { - val isGlobal = (name == "__Global") -} - - diff --git a/kotlin-native/Interop/StubGenerator/src/main/kotlin/org/jetbrains/kotlin/native/interop/gen/wasm/idl/idlMath.kt b/kotlin-native/Interop/StubGenerator/src/main/kotlin/org/jetbrains/kotlin/native/interop/gen/wasm/idl/idlMath.kt deleted file mode 100644 index 4b6bc871eb0..00000000000 --- a/kotlin-native/Interop/StubGenerator/src/main/kotlin/org/jetbrains/kotlin/native/interop/gen/wasm/idl/idlMath.kt +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright 2010-2018 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.jetbrains.kotlin.native.interop.gen.wasm.idl - -// There are no WebIDL descriptions of Math, -// so in any case this one will be a part of the project. -// Although, may be in the form of our own WebIDL source. - -val idlMath = listOf( - Interface("Math", - Attribute("E", idlDouble, readOnly = true, isStatic = true), - Attribute("LN2", idlDouble, readOnly = true, isStatic = true), - Attribute("LN10", idlDouble, readOnly = true, isStatic = true), - Attribute("LOG2E", idlDouble, readOnly = true, isStatic = true), - Attribute("LOG10E", idlDouble, readOnly = true, isStatic = true), - Attribute("PI", idlDouble, readOnly = true, isStatic = true), - Attribute("SQRT1_2", idlDouble, readOnly = true, isStatic = true), - Attribute("SQRT2", idlDouble, readOnly = true, isStatic = true), - - Operation("abs", idlDouble, true, Arg("x", idlDouble)), - Operation("acos", idlDouble, true, Arg("x", idlDouble)), - Operation("acosh", idlDouble, true, Arg("x", idlDouble)), - Operation("asin", idlDouble, true, Arg("x", idlDouble)), - Operation("asinh", idlDouble, true, Arg("x", idlDouble)), - Operation("atan", idlDouble, true, Arg("x", idlDouble)), - Operation("atanh", idlDouble, true, Arg("x", idlDouble)), - Operation("atan2", idlDouble, true, Arg("y", idlDouble), Arg("x", idlDouble)), - Operation("cbrt", idlDouble, true, Arg("x", idlDouble)), - Operation("ceil", idlDouble, true, Arg("x", idlDouble)), - Operation("clz32", idlDouble, true, Arg("x", idlDouble)), - Operation("cos", idlDouble, true, Arg("x", idlDouble)), - Operation("cosh", idlDouble, true, Arg("x", idlDouble)), - Operation("exp", idlDouble, true, Arg("x", idlDouble)), - Operation("expm1", idlDouble, true, Arg("x", idlDouble)), - Operation("floor", idlDouble, true, Arg("x", idlDouble)), - Operation("fround", idlDouble, true, Arg("x", idlDouble)), - //Operation("imul(x, y), - Operation("log", idlDouble, true, Arg("x", idlDouble)), - Operation("log1p", idlDouble, true, Arg("x", idlDouble)), - Operation("log10", idlDouble, true, Arg("x", idlDouble)), - Operation("log2", idlDouble, true, Arg("x", idlDouble)), - Operation("pow", idlDouble, true, Arg("x", idlDouble), Arg("y", idlDouble)), - Operation("random", idlDouble, true), - Operation("round", idlDouble, true, Arg("x", idlDouble)), - Operation("sign", idlDouble, true, Arg("x", idlDouble)), - Operation("sin", idlDouble, true, Arg("x", idlDouble)), - Operation("sinh", idlDouble, true, Arg("x", idlDouble)), - Operation("sqrt", idlDouble, true, Arg("x", idlDouble)), - Operation("tan", idlDouble, true, Arg("x", idlDouble)), - Operation("tanh", idlDouble, true, Arg("x", idlDouble)), - Operation("trunc", idlDouble, true, Arg("x", idlDouble)), - - // Actually these functions have vararg parameter. - // But their kotlin analogs have only 2 parameters so we don't need to support varargs here. - Operation("hypot", idlDouble, true, Arg("x", idlDouble), Arg("y", idlDouble)), - Operation("max", idlDouble, true, Arg("x", idlDouble), Arg("y", idlDouble)), - Operation("min", idlDouble, true, Arg("x", idlDouble), Arg("y", idlDouble)) - ) -) diff --git a/kotlin-native/build.gradle b/kotlin-native/build.gradle index c500fdb22bb..0462c470c97 100644 --- a/kotlin-native/build.gradle +++ b/kotlin-native/build.gradle @@ -433,14 +433,6 @@ targetList.each { target -> dependsOn "${target}CrossDistBitcodeCopy" destinationDir project.file("$distDir/$stdlibDefaultComponent") - - if (target == 'wasm32') { - into("targets/wasm32/included") { - from(project(':kotlin-native:runtime').file('src/main/js')) - from(project(':kotlin-native:runtime').file('src/launcher/js')) - from(project(':kotlin-native:Interop:JsRuntime').file('src/main/js')) - } - } } tasks.register("${target}PlatformLibs") { diff --git a/kotlin-native/runtime/build.gradle.kts b/kotlin-native/runtime/build.gradle.kts index dcd3a01f286..ae2090d47dc 100644 --- a/kotlin-native/runtime/build.gradle.kts +++ b/kotlin-native/runtime/build.gradle.kts @@ -466,33 +466,6 @@ tasks.named("clean") { } } -val generateJsMath by tasks.registering { - dependsOn(":distCompiler") - doLast { - val distDir: File by project - val jsinteropScript = if (PlatformInfo.isWindows()) "jsinterop.bat" else "jsinterop" - val jsinterop = "$distDir/bin/$jsinteropScript" - val targetDir = "$buildDir/generated" - - project.exec { - commandLine( - jsinterop, - "-pkg", "kotlinx.interop.wasm.math", - "-o", "$targetDir/math", - "-target", "wasm32" - ) - } - - val generated = file("$targetDir/math-build/natives/js_stubs.js") - val mathJs = file("src/main/js/math.js") - mathJs.writeText( - "// NOTE: THIS FILE IS AUTO-GENERATED!\n" + - "// Run ':runtime:generateJsMath' to re-generate it.\n\n" - ) - mathJs.appendText(generated.readText()) - } -} - // region: Stdlib val commonStdlibSrcDirs = project(":kotlin-stdlib-common") diff --git a/kotlin-native/runtime/src/launcher/js/index.html b/kotlin-native/runtime/src/launcher/js/index.html deleted file mode 100644 index 6586b142e5a..00000000000 --- a/kotlin-native/runtime/src/launcher/js/index.html +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - - - - - - - diff --git a/kotlin-native/runtime/src/launcher/js/launcher.js b/kotlin-native/runtime/src/launcher/js/launcher.js deleted file mode 100644 index e63d18bdf25..00000000000 --- a/kotlin-native/runtime/src/launcher/js/launcher.js +++ /dev/null @@ -1,247 +0,0 @@ -/* - * Copyright 2010-2018 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -let instance; -let heap; -let global_arguments; - -function isBrowser() { - return typeof self !== 'undefined'; -} - -let runtime; -if (isBrowser()) { - runtime = { - print: console.log, - stdout: '', - write: function (message) { - this.stdout += message; - const lastNewlineIndex = this.stdout.lastIndexOf('\n'); - if (lastNewlineIndex == -1) return; - this.print(this.stdout.substring(0, lastNewlineIndex)); - this.stdout = this.stdout.substring(lastNewlineIndex + 1) - }, - flush: function () { - this.print(this.stdout); - }, - exit: function (status) { - throw Error("Kotlin process called exit (" + status + ")"); - } - }; -} else { - runtime = { - write: write, - print: print, - flush: function () { - }, - exit: quit - }; -} - -function print_usage() { - // TODO: any reliable way to obtain the current script name? - runtime.print('Usage: d8 --expose-wasm launcher.js -- ...') - quit(1); // TODO: this is d8 specific -} - -function utf8encode(s) { - return unescape(encodeURIComponent(s)); -} - -function utf8decode(s) { - return decodeURIComponent(escape(s)); -} - -function fromString(string, pointer) { - for (let i = 0; i < string.length; i++) { - heap[pointer + i] = string.charCodeAt(i); - } - heap[pointer + string.length] = 0; -} - -function toString(pointer) { - let string = ''; - for (let i = pointer; heap[i] != 0; i++) { - string += String.fromCharCode(heap[i]); - } - return string; -} - -function toUTF16String(pointer, size) { - let string = ''; - for (let i = pointer; i < pointer + size; i += 2) { - string += String.fromCharCode(heap[i] + heap[i + 1] * 256); - } - return string; -} - -function twoIntsToDouble(upper, lower) { - const buffer = new ArrayBuffer(8); - const ints = new Int32Array(buffer); - const doubles = new Float64Array(buffer); - ints[1] = upper; - ints[0] = lower; - return doubles[0]; -} - -function doubleToTwoInts(value) { - const buffer = new ArrayBuffer(8); - const ints = new Int32Array(buffer); - const doubles = new Float64Array(buffer); - doubles[0] = value; - return {upper: ints[1], lower: ints[0]} -} - -function int32ToHeap(value, pointer) { - heap[pointer] = value & 0xff; - heap[pointer + 1] = (value & 0xff00) >>> 8; - heap[pointer + 2] = (value & 0xff0000) >>> 16; - heap[pointer + 3] = (value & 0xff000000) >>> 24; -} - -function doubleToReturnSlot(value) { - const twoInts = doubleToTwoInts(value); - instance.exports.ReturnSlot_setDouble(twoInts.upper, twoInts.lower); -} - -let konan_dependencies = { - env: { - abort: function () { - throw new Error("abort()"); - }, - // TODO: Account for file and size. - fgets: function (str, size, file) { - // TODO: readline can't read lines without a newline. - // Browsers cant read from console at all. - fromString(utf8encode(readline() + '\n'), str); - return str; - }, - read: function (file, str, size) { - let string = utf8encode(readline() + '\n'); - fromString(string.substring(0, size), str); - return string.length; - }, - Konan_notify_memory_grow: function() { - heap = new Uint8Array(instance.exports.memory.buffer); - }, - Konan_abort: function (pointer) { - throw new Error("Konan_abort(" + utf8decode(toString(pointer)) + ")"); - }, - Konan_exit: function (status) { - runtime.exit(status); - }, - Konan_js_arg_size: function (index) { - if (index >= global_arguments.length) return -1; - return global_arguments[index].length + 1; // + 1 for trailing zero. - }, - Konan_js_fetch_arg: function (index, ptr) { - let arg = utf8encode(global_arguments[index]); - fromString(arg, ptr); - }, - Konan_date_now: function (pointer) { - let now = Date.now(); - let high = Math.floor(now / 0xffffffff); - let low = Math.floor(now % 0xffffffff); - int32ToHeap(low, pointer); - int32ToHeap(high, pointer + 4); - }, - // TODO: Account for fd and size. - write: function (fd, str, size) { - if (fd != 1 && fd != 2) throw ("write(" + fd + ", ...)"); - // TODO: There is no writeErr() in d8. - // Approximate it with write() to stdout for now. - runtime.write(utf8decode(toString(str))); - }, - fflush: function(file) { - runtime.flush(); - } - } -}; - -function linkJavaScriptLibraries() { - konan.libraries.forEach(function (library) { - for (const property in library) { - konan_dependencies.env[property] = library[property]; - } - }); -} - -function invokeModule(inst, args) { - if (args.length < 1) print_usage(); - global_arguments = args; - - instance = inst; - - heap = new Uint8Array(instance.exports.memory.buffer); - - let exit_status = 0; - - try { - exit_status = instance.exports.Konan_js_main(args.length, isBrowser() ? 0 : 1); - } catch (e) { - runtime.print("Exception executing entry point: " + e); - runtime.print(e.stack); - exit_status = 1; - } - runtime.flush(); - - return exit_status; -} - -// Instantiate module in Browser. -function instantiateAndRun(arraybuffer, args) { - linkJavaScriptLibraries(); - WebAssembly.instantiate(arraybuffer, konan_dependencies) - .then(resultObject => invokeModule(resultObject.instance, args)); -} - -// Instantiate module in d8 synchronously. -function instantiateAndRunSync(arraybuffer, args) { - const module = new WebAssembly.Module(arraybuffer); - linkJavaScriptLibraries(); - const instance = new WebAssembly.Instance(module, konan_dependencies); - return invokeModule(instance, args) -} - - -// Instantiate module in Browser using streaming instantiation. -function instantiateAndRunStreaming(filename) { - linkJavaScriptLibraries(); - WebAssembly.instantiateStreaming(fetch(filename), konan_dependencies) - .then(resultObject => invokeModule(resultObject.instance, [filename])); -} - -konan.moduleEntry = function (args) { - if (isBrowser()) { - if (!document.currentScript.hasAttribute("wasm")) { - throw new Error('Could not find the wasm attribute pointing to the WebAssembly binary.'); - } - const filename = document.currentScript.getAttribute("wasm"); - if (typeof WebAssembly.instantiateStreaming === 'function') { - instantiateAndRunStreaming(filename); - } else { - fetch(filename) - .then(response => response.arrayBuffer()) - .then(arraybuffer => instantiateAndRun(arraybuffer, [filename])); - } - } else { - // Invoke from d8. - const arrayBuffer = readbuffer(args[0]); - const exitStatus = instantiateAndRunSync(arrayBuffer, args); - quit(exitStatus); - } -}; - diff --git a/kotlin-native/runtime/src/main/js/math.js b/kotlin-native/runtime/src/main/js/math.js deleted file mode 100644 index 019aace7d1f..00000000000 --- a/kotlin-native/runtime/src/main/js/math.js +++ /dev/null @@ -1,254 +0,0 @@ -// NOTE: THIS FILE IS AUTO-GENERATED! -// Run ':runtime:generateJsMath' to re-generate it. - -konan.libraries.push ({ - - knjs_get__Math_E: function() { - var result = Math.E; - return doubleToReturnSlot(result); - }, - - knjs_get__Math_LN2: function() { - var result = Math.LN2; - return doubleToReturnSlot(result); - }, - - knjs_get__Math_LN10: function() { - var result = Math.LN10; - return doubleToReturnSlot(result); - }, - - knjs_get__Math_LOG2E: function() { - var result = Math.LOG2E; - return doubleToReturnSlot(result); - }, - - knjs_get__Math_LOG10E: function() { - var result = Math.LOG10E; - return doubleToReturnSlot(result); - }, - - knjs_get__Math_PI: function() { - var result = Math.PI; - return doubleToReturnSlot(result); - }, - - knjs_get__Math_SQRT1_2: function() { - var result = Math.SQRT1_2; - return doubleToReturnSlot(result); - }, - - knjs_get__Math_SQRT2: function() { - var result = Math.SQRT2; - return doubleToReturnSlot(result); - }, - - knjs__Math_abs: function(xUpper, xLower) { - var x = twoIntsToDouble(xUpper, xLower); - var result = Math.abs(x); - return doubleToReturnSlot(result); - }, - - knjs__Math_acos: function(xUpper, xLower) { - var x = twoIntsToDouble(xUpper, xLower); - var result = Math.acos(x); - return doubleToReturnSlot(result); - }, - - knjs__Math_acosh: function(xUpper, xLower) { - var x = twoIntsToDouble(xUpper, xLower); - var result = Math.acosh(x); - return doubleToReturnSlot(result); - }, - - knjs__Math_asin: function(xUpper, xLower) { - var x = twoIntsToDouble(xUpper, xLower); - var result = Math.asin(x); - return doubleToReturnSlot(result); - }, - - knjs__Math_asinh: function(xUpper, xLower) { - var x = twoIntsToDouble(xUpper, xLower); - var result = Math.asinh(x); - return doubleToReturnSlot(result); - }, - - knjs__Math_atan: function(xUpper, xLower) { - var x = twoIntsToDouble(xUpper, xLower); - var result = Math.atan(x); - return doubleToReturnSlot(result); - }, - - knjs__Math_atanh: function(xUpper, xLower) { - var x = twoIntsToDouble(xUpper, xLower); - var result = Math.atanh(x); - return doubleToReturnSlot(result); - }, - - knjs__Math_atan2: function(yUpper, yLower, xUpper, xLower) { - var y = twoIntsToDouble(yUpper, yLower); - var x = twoIntsToDouble(xUpper, xLower); - var result = Math.atan2(y, x); - return doubleToReturnSlot(result); - }, - - knjs__Math_cbrt: function(xUpper, xLower) { - var x = twoIntsToDouble(xUpper, xLower); - var result = Math.cbrt(x); - return doubleToReturnSlot(result); - }, - - knjs__Math_ceil: function(xUpper, xLower) { - var x = twoIntsToDouble(xUpper, xLower); - var result = Math.ceil(x); - return doubleToReturnSlot(result); - }, - - knjs__Math_clz32: function(xUpper, xLower) { - var x = twoIntsToDouble(xUpper, xLower); - var result = Math.clz32(x); - return doubleToReturnSlot(result); - }, - - knjs__Math_cos: function(xUpper, xLower) { - var x = twoIntsToDouble(xUpper, xLower); - var result = Math.cos(x); - return doubleToReturnSlot(result); - }, - - knjs__Math_cosh: function(xUpper, xLower) { - var x = twoIntsToDouble(xUpper, xLower); - var result = Math.cosh(x); - return doubleToReturnSlot(result); - }, - - knjs__Math_exp: function(xUpper, xLower) { - var x = twoIntsToDouble(xUpper, xLower); - var result = Math.exp(x); - return doubleToReturnSlot(result); - }, - - knjs__Math_expm1: function(xUpper, xLower) { - var x = twoIntsToDouble(xUpper, xLower); - var result = Math.expm1(x); - return doubleToReturnSlot(result); - }, - - knjs__Math_floor: function(xUpper, xLower) { - var x = twoIntsToDouble(xUpper, xLower); - var result = Math.floor(x); - return doubleToReturnSlot(result); - }, - - knjs__Math_fround: function(xUpper, xLower) { - var x = twoIntsToDouble(xUpper, xLower); - var result = Math.fround(x); - return doubleToReturnSlot(result); - }, - - knjs__Math_log: function(xUpper, xLower) { - var x = twoIntsToDouble(xUpper, xLower); - var result = Math.log(x); - return doubleToReturnSlot(result); - }, - - knjs__Math_log1p: function(xUpper, xLower) { - var x = twoIntsToDouble(xUpper, xLower); - var result = Math.log1p(x); - return doubleToReturnSlot(result); - }, - - knjs__Math_log10: function(xUpper, xLower) { - var x = twoIntsToDouble(xUpper, xLower); - var result = Math.log10(x); - return doubleToReturnSlot(result); - }, - - knjs__Math_log2: function(xUpper, xLower) { - var x = twoIntsToDouble(xUpper, xLower); - var result = Math.log2(x); - return doubleToReturnSlot(result); - }, - - knjs__Math_pow: function(xUpper, xLower, yUpper, yLower) { - var x = twoIntsToDouble(xUpper, xLower); - var y = twoIntsToDouble(yUpper, yLower); - var result = Math.pow(x, y); - return doubleToReturnSlot(result); - }, - - knjs__Math_random: function() { - var result = Math.random(); - return doubleToReturnSlot(result); - }, - - knjs__Math_round: function(xUpper, xLower) { - var x = twoIntsToDouble(xUpper, xLower); - var result = Math.round(x); - return doubleToReturnSlot(result); - }, - - knjs__Math_sign: function(xUpper, xLower) { - var x = twoIntsToDouble(xUpper, xLower); - var result = Math.sign(x); - return doubleToReturnSlot(result); - }, - - knjs__Math_sin: function(xUpper, xLower) { - var x = twoIntsToDouble(xUpper, xLower); - var result = Math.sin(x); - return doubleToReturnSlot(result); - }, - - knjs__Math_sinh: function(xUpper, xLower) { - var x = twoIntsToDouble(xUpper, xLower); - var result = Math.sinh(x); - return doubleToReturnSlot(result); - }, - - knjs__Math_sqrt: function(xUpper, xLower) { - var x = twoIntsToDouble(xUpper, xLower); - var result = Math.sqrt(x); - return doubleToReturnSlot(result); - }, - - knjs__Math_tan: function(xUpper, xLower) { - var x = twoIntsToDouble(xUpper, xLower); - var result = Math.tan(x); - return doubleToReturnSlot(result); - }, - - knjs__Math_tanh: function(xUpper, xLower) { - var x = twoIntsToDouble(xUpper, xLower); - var result = Math.tanh(x); - return doubleToReturnSlot(result); - }, - - knjs__Math_trunc: function(xUpper, xLower) { - var x = twoIntsToDouble(xUpper, xLower); - var result = Math.trunc(x); - return doubleToReturnSlot(result); - }, - - knjs__Math_hypot: function(xUpper, xLower, yUpper, yLower) { - var x = twoIntsToDouble(xUpper, xLower); - var y = twoIntsToDouble(yUpper, yLower); - var result = Math.hypot(x, y); - return doubleToReturnSlot(result); - }, - - knjs__Math_max: function(xUpper, xLower, yUpper, yLower) { - var x = twoIntsToDouble(xUpper, xLower); - var y = twoIntsToDouble(yUpper, yLower); - var result = Math.max(x, y); - return doubleToReturnSlot(result); - }, - - knjs__Math_min: function(xUpper, xLower, yUpper, yLower) { - var x = twoIntsToDouble(xUpper, xLower); - var y = twoIntsToDouble(yUpper, yLower); - var result = Math.min(x, y); - return doubleToReturnSlot(result); - } -}) - diff --git a/kotlin-native/utilities/cli-runner/src/main/kotlin/org/jetbrains/kotlin/cli/utilities/InteropCompiler.kt b/kotlin-native/utilities/cli-runner/src/main/kotlin/org/jetbrains/kotlin/cli/utilities/InteropCompiler.kt index 6d554883e50..a05b8f6382e 100644 --- a/kotlin-native/utilities/cli-runner/src/main/kotlin/org/jetbrains/kotlin/cli/utilities/InteropCompiler.kt +++ b/kotlin-native/utilities/cli-runner/src/main/kotlin/org/jetbrains/kotlin/cli/utilities/InteropCompiler.kt @@ -20,7 +20,10 @@ import org.jetbrains.kotlin.native.interop.tool.* * Otherwise returns array of compiler args. */ fun invokeInterop(flavor: String, args: Array, runFromDaemon: Boolean): Array? { - val arguments = if (flavor == "native") CInteropArguments() else JSInteropArguments() + check(flavor == "native") { + "wasm target in Kotlin/Native is removed. See https://kotl.in/native-targets-tiers" + } + val arguments = CInteropArguments() arguments.argParser.parse(args) val outputFileName = arguments.output val noDefaultLibs = arguments.nodefaultlibs || arguments.nodefaultlibsDeprecated @@ -38,24 +41,20 @@ fun invokeInterop(flavor: String, args: Array, runFromDaemon: Boolean): val cstubsName ="cstubs" val libraries = arguments.library val repos = arguments.repo - val targetRequest = if (arguments is CInteropArguments) arguments.target - else (arguments as JSInteropArguments).target.toString() + val targetRequest = arguments.target val target = PlatformManager( KonanHomeProvider.determineKonanHome(), konanDataDir = arguments.konanDataDir).targetManager(targetRequest).target - val cinteropArgsToCompiler = Interop().interop(flavor, args, + val cinteropArgsToCompiler = Interop().interop("native", args, InternalInteropOptions(generatedDir.absolutePath, nativesDir.absolutePath,manifest.path, - cstubsName.takeIf { flavor == "native" } + cstubsName ), runFromDaemon ) ?: return null // There is no need in compiler invocation if we're generating only metadata. val nativeStubs = - if (flavor == "wasm") - arrayOf("-include-binary", File(nativesDir, "js_stubs.js").path) - else arrayOf("-native-library", File(nativesDir, "$cstubsName.bc").path) return arrayOf( diff --git a/kotlin-native/utilities/cli-runner/src/main/kotlin/org/jetbrains/kotlin/cli/utilities/main.kt b/kotlin-native/utilities/cli-runner/src/main/kotlin/org/jetbrains/kotlin/cli/utilities/main.kt index 960dcf05c05..99aa3218712 100644 --- a/kotlin-native/utilities/cli-runner/src/main/kotlin/org/jetbrains/kotlin/cli/utilities/main.kt +++ b/kotlin-native/utilities/cli-runner/src/main/kotlin/org/jetbrains/kotlin/cli/utilities/main.kt @@ -24,8 +24,7 @@ private fun mainImpl(args: Array, runFromDaemon: Boolean, konancMain: (A konancArgs?.let { konancMain(it) } } "jsinterop" -> { - val konancArgs = invokeInterop("wasm", utilityArgs, runFromDaemon) - konancArgs?.let { konancMain(it) } + error("wasm target in Kotlin/Native is removed. See https://kotl.in/native-targets-tiers") } "klib" -> klibMain(utilityArgs) @@ -57,4 +56,4 @@ private fun inProcessMain(args: Array, konancMain: (Array) -> Un setupClangEnv() // For in-process invocation have to setup proper environment manually. mainImpl(args, true, konancMain) } -} \ No newline at end of file +}