From 1473b4bb411255a7efc41a3124c4d8a47f900b0a Mon Sep 17 00:00:00 2001 From: Artem Kobzar Date: Wed, 13 Dec 2023 18:44:57 +0000 Subject: [PATCH] [K/Wasm] Introduce JsBigInt type --- .../codegen/boxWasmJsInterop/jsTypes.kt | 23 +++++++++++++++++++ .../wasm/js/internal/ExternalWrapper.kt | 20 ++++++++-------- .../stdlib/wasm/js/src/kotlin/js/JsBigInt.kt | 19 +++++++++++++++ 3 files changed, 52 insertions(+), 10 deletions(-) create mode 100644 libraries/stdlib/wasm/js/src/kotlin/js/JsBigInt.kt diff --git a/compiler/testData/codegen/boxWasmJsInterop/jsTypes.kt b/compiler/testData/codegen/boxWasmJsInterop/jsTypes.kt index dda6a07d6b6..13843e9d273 100644 --- a/compiler/testData/codegen/boxWasmJsInterop/jsTypes.kt +++ b/compiler/testData/codegen/boxWasmJsInterop/jsTypes.kt @@ -22,6 +22,7 @@ fun box(): String { assertTrue(jsNumAsAny is JsNumber) assertTrue(jsNumAsAny !is JsString) assertTrue(jsNumAsAny !is JsBoolean) + assertTrue(jsNumAsAny !is JsBigInt) assertTrue((jsNumAsAny as JsNumber).toInt() == 10) assertTrue(jsRepresentation(jsNum10) == "number:10") @@ -32,6 +33,7 @@ fun box(): String { assertTrue(jsStr1.toString() == "str1") assertTrue((jsStr1 as Any) is JsString) assertTrue((jsStr1 as Any) !is JsNumber) + assertTrue((jsStr1 as Any) !is JsBigInt) assertTrue(jsRepresentation(jsStr1) == "string:str1") // JsString @@ -57,5 +59,26 @@ fun box(): String { assertTrue(c.toJsReference().get() === c.toJsReference().get()) assertTrue(c.toJsReference() === c.toJsReference()) + // JsBigInt + val jsBigInt10: JsBigInt = 10L.toJsBigInt() + val anotherJsBigInt10: JsBigInt = 10L.toJsBigInt() + assertTrue(jsBigInt10 == anotherJsBigInt10) + assertTrue(jsBigInt10.toLong() == 10L) + assertTrue(anotherJsBigInt10.toLong() == 10L) + val jsBigIntAsJsAny: JsAny = jsBigInt10 + assertTrue(jsBigIntAsJsAny == anotherJsBigInt10) + assertTrue(jsBigIntAsJsAny is JsBigInt) + assertTrue(jsBigIntAsJsAny !is JsNumber) + assertTrue(jsBigIntAsJsAny !is JsString) + assertTrue(jsBigIntAsJsAny !is JsBoolean) + assertTrue((jsBigIntAsJsAny as JsBigInt).toLong() == 10L) + val jsBigIntAsAny: Any = jsBigInt10 + assertTrue(jsBigIntAsAny == anotherJsBigInt10) + assertTrue(jsBigIntAsAny is JsBigInt) + assertTrue(jsBigIntAsAny !is JsNumber) + assertTrue(jsBigIntAsAny !is JsString) + assertTrue(jsBigIntAsAny !is JsBoolean) + assertTrue((jsBigIntAsAny as JsBigInt).toLong() == 10L) + return "OK" } \ No newline at end of file diff --git a/libraries/stdlib/wasm/js/internal/ExternalWrapper.kt b/libraries/stdlib/wasm/js/internal/ExternalWrapper.kt index 85002f18f30..012f7db11b0 100644 --- a/libraries/stdlib/wasm/js/internal/ExternalWrapper.kt +++ b/libraries/stdlib/wasm/js/internal/ExternalWrapper.kt @@ -121,13 +121,13 @@ private fun externrefToDouble(ref: ExternalInterfaceType): Double = private fun intToExternref(x: Int): JsNumber = js("x") -private fun longToExternref(x: Long): ExternalInterfaceType = +private fun longToExternref(x: Long): JsBigInt = js("x") -private fun booleanToExternref(x: Boolean): ExternalInterfaceType = +private fun booleanToExternref(x: Boolean): JsBoolean = js("x") -private fun floatToExternref(x: Float): ExternalInterfaceType = +private fun floatToExternref(x: Float): JsNumber = js("x") private fun doubleToExternref(x: Double): JsNumber = @@ -368,7 +368,7 @@ private fun kotlinUShortToJsNumberUnsafe(x: Int): JsNumber = private fun kotlinUIntToJsNumberUnsafe(x: Int): JsNumber = js("x >>> 0") -private fun kotlinULongToJsBigIntUnsafe(x: Long): ExternalInterfaceType = +private fun kotlinULongToJsBigIntUnsafe(x: Long): JsBigInt = js("x & 0xFFFFFFFFFFFFFFFFn") internal fun kotlinUByteToJsNumber(x: UByte): JsNumber = @@ -380,25 +380,25 @@ internal fun kotlinUShortToJsNumber(x: UShort): JsNumber = internal fun kotlinUIntToJsNumber(x: UInt): JsNumber = kotlinUIntToJsNumberUnsafe(x.toInt()) -internal fun kotlinULongToJsBigInt(x: ULong): ExternalInterfaceType = +internal fun kotlinULongToJsBigInt(x: ULong): JsBigInt = kotlinULongToJsBigIntUnsafe(x.toLong()) -internal fun kotlinLongToExternRefAdapter(x: Long): ExternalInterfaceType = +internal fun kotlinLongToExternRefAdapter(x: Long): JsBigInt = longToExternref(x) -internal fun kotlinFloatToExternRefAdapter(x: Float): ExternalInterfaceType = +internal fun kotlinFloatToExternRefAdapter(x: Float): JsNumber = floatToExternref(x) internal fun kotlinDoubleToExternRefAdapter(x: Double): JsNumber = doubleToExternref(x) -internal fun kotlinByteToExternRefAdapter(x: Byte): ExternalInterfaceType = +internal fun kotlinByteToExternRefAdapter(x: Byte): JsNumber = intToExternref(x.toInt()) -internal fun kotlinShortToExternRefAdapter(x: Short): ExternalInterfaceType = +internal fun kotlinShortToExternRefAdapter(x: Short): JsNumber = intToExternref(x.toInt()) -internal fun kotlinCharToExternRefAdapter(x: Char): ExternalInterfaceType = +internal fun kotlinCharToExternRefAdapter(x: Char): JsNumber = intToExternref(x.code) internal fun newJsArray(): ExternalInterfaceType = diff --git a/libraries/stdlib/wasm/js/src/kotlin/js/JsBigInt.kt b/libraries/stdlib/wasm/js/src/kotlin/js/JsBigInt.kt new file mode 100644 index 00000000000..ca56a1bf82b --- /dev/null +++ b/libraries/stdlib/wasm/js/src/kotlin/js/JsBigInt.kt @@ -0,0 +1,19 @@ +/* + * Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package kotlin.js + +import kotlin.wasm.internal.* +import kotlin.wasm.internal.JsPrimitive + +/** JavaScript primitive bigint */ +@JsPrimitive("bigint") +public external class JsBigInt internal constructor() : JsAny + +public fun JsBigInt.toLong(): Long = + externRefToKotlinLongAdapter(this) + +public fun Long.toJsBigInt(): JsBigInt = + kotlinLongToExternRefAdapter(this) \ No newline at end of file