[K/N] Remove jsinterop because K/N wasm32 target is removed ^KT-59008

See https://kotl.in/native-targets-tiers for details
This commit is contained in:
Alexander Shabalin
2023-08-14 11:16:52 +02:00
committed by Space Team
parent 857bfeb92c
commit 3ec4f2e0ee
15 changed files with 46 additions and 1299 deletions
@@ -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);
}
@@ -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 <R> = ((ArrayList<JsValue>)->R)
@Deprecated(WASM_TARGET_IS_DEPRECATED, level = DeprecationLevel.WARNING)
@Deprecated(WASM_TARGET_IS_DEPRECATED, level = DeprecationLevel.ERROR)
fun <R> wrapFunction(func: KtFunction<R>): 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<JsValue>()
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<Unit>) {
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<Unit>) {
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()
@@ -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<TargetType>(),
description = "wasm target to compile to").default(TargetType.WASM32)
}
internal fun warn(msg: String) {
println("warning: $msg")
}
@@ -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")
}
}
@@ -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<R${argName!!}>"
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<R$name>($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<String> = 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<Arg>.wasmTypedMapping():List<String>
= 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<Interface>) =
kotlinHeader(pkg) +
interfaces.map {
it.generateKotlin()
}.joinToString("\n") +
if (pkg == "kotlinx.interop.wasm.dom") // TODO: make it a general solution.
"fun <R> setInterval(interval: Int, lambda: KtFunction<R>) = 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<Interface>): 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<String>, additionalArgs: InternalInteropOptions): Array<String> {
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())
}
@@ -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))
)
)
@@ -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")
}
@@ -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))
)
)
-8
View File
@@ -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") {
-27
View File
@@ -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")
@@ -1,14 +0,0 @@
<html>
<head>
<meta charset="utf-8">
</head>
<body>
<script src="/dist/konan/nativelib/launcher.js"> </script>
<script>
loadAndInvoke("/program.wasm");
</script>
</body>
</html>
@@ -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 -- <program.wasm> <program arg1> <program arg2> ...')
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);
}
};
-254
View File
@@ -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);
}
})
@@ -20,7 +20,10 @@ import org.jetbrains.kotlin.native.interop.tool.*
* Otherwise returns array of compiler args.
*/
fun invokeInterop(flavor: String, args: Array<String>, runFromDaemon: Boolean): Array<String>? {
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<String>, 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(
@@ -24,8 +24,7 @@ private fun mainImpl(args: Array<String>, 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<String>, konancMain: (Array<String>) -> Un
setupClangEnv() // For in-process invocation have to setup proper environment manually.
mainImpl(args, true, konancMain)
}
}
}