From 9ae32c5aed361fbaf0a84ca11021bc25fa5a606e Mon Sep 17 00:00:00 2001 From: KotlinCrypto Date: Wed, 25 Feb 2026 19:32:26 -0500 Subject: [PATCH] Mitigate unnecessary array copying for Kotlin/Js --- .../random/internal/js/_JsCrypto.kt | 17 ++++++ .../random/internal/js/_JsInt8Array.kt | 28 ++++++++++ .../random/internal/js/_JsUint8Array.kt | 7 ++- .../random/internal/JsWasmJsPlatform.kt | 54 ++----------------- .../random/internal/js/JsArrayLike.kt | 27 ++++++++++ .../random/internal/js/JsCrypto.kt | 4 ++ .../random/internal/js/JsInt8Array.kt | 45 ++++++++++++++++ .../random/internal/js/JsUint8Array.kt | 24 +++++++-- .../js/CryptoRandFillJsWasmJsUnitTest.kt | 51 ++++++++++++++++++ .../random/internal/js/_JsCrypto.kt | 32 +++++++++++ .../random/internal/js/_JsInt8Array.kt | 24 +++++++++ .../random/internal/js/_JsUint8Array.kt | 9 +++- .../random/internal/WasmWasiPlatform.kt | 2 +- 13 files changed, 264 insertions(+), 60 deletions(-) create mode 100644 library/crypto-rand/src/jsMain/kotlin/org/kotlincrypto/random/internal/js/_JsInt8Array.kt create mode 100644 library/crypto-rand/src/jsWasmJsMain/kotlin/org/kotlincrypto/random/internal/js/JsArrayLike.kt create mode 100644 library/crypto-rand/src/jsWasmJsMain/kotlin/org/kotlincrypto/random/internal/js/JsInt8Array.kt create mode 100644 library/crypto-rand/src/jsWasmJsTest/kotlin/org/kotlincrypto/random/internal/js/CryptoRandFillJsWasmJsUnitTest.kt create mode 100644 library/crypto-rand/src/wasmJsMain/kotlin/org/kotlincrypto/random/internal/js/_JsInt8Array.kt diff --git a/library/crypto-rand/src/jsMain/kotlin/org/kotlincrypto/random/internal/js/_JsCrypto.kt b/library/crypto-rand/src/jsMain/kotlin/org/kotlincrypto/random/internal/js/_JsCrypto.kt index 199691e..9904888 100644 --- a/library/crypto-rand/src/jsMain/kotlin/org/kotlincrypto/random/internal/js/_JsCrypto.kt +++ b/library/crypto-rand/src/jsMain/kotlin/org/kotlincrypto/random/internal/js/_JsCrypto.kt @@ -15,9 +15,26 @@ **/ package org.kotlincrypto.random.internal.js +import kotlin.math.min + internal actual val IS_NODE_JS: Boolean by lazy { isNodeJs() } internal actual fun jsCryptoBrowser(): JsCrypto = js(CODE_JS_CRYPTO_BROWSER) internal actual fun jsCryptoNode(): JsCrypto = js(CODE_JS_CRYPTO_NODE) private fun isNodeJs(): Boolean = js(CODE_IS_NODE_JS) + +internal actual fun ByteArray.cryptoRandFill(procure: (JsUint8Array) -> Unit) { + val a = asJsInt8Array().asJsUint8Array() + if (a.length < JS_CRYPTO_MAX_FILL) return procure(a) + + var remainder = size + var offset = 0 + while (remainder > 0) { + val len = min(JS_CRYPTO_MAX_FILL, remainder) + val s = a.subarray(start = offset, end = offset + len) + procure(s) + offset += len + remainder -= len + } +} diff --git a/library/crypto-rand/src/jsMain/kotlin/org/kotlincrypto/random/internal/js/_JsInt8Array.kt b/library/crypto-rand/src/jsMain/kotlin/org/kotlincrypto/random/internal/js/_JsInt8Array.kt new file mode 100644 index 0000000..9a22c0a --- /dev/null +++ b/library/crypto-rand/src/jsMain/kotlin/org/kotlincrypto/random/internal/js/_JsInt8Array.kt @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2025 KotlinCrypto + * + * 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 + * + * https://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. + **/ +@file:Suppress("NOTHING_TO_INLINE") + +package org.kotlincrypto.random.internal.js + +import kotlin.js.unsafeCast + +internal actual fun jsInt8Array(length: Int): JsInt8Array = js(CODE_JS_NEW_INT8_LENGTH) +internal actual fun jsInt8Array(buffer: JsArrayBufferLike): JsInt8Array = js(CODE_JS_NEW_INT8_BUFFER) + +internal actual fun jsInt8ArrayGet(array: JsInt8Array, index: Int): Byte = js(CODE_JS_ARRAY_GET) +internal actual fun jsInt8ArraySet(array: JsInt8Array, index: Int, value: Byte) { js(CODE_JS_ARRAY_SET) } + +internal inline fun ByteArray.asJsInt8Array(): JsInt8Array = unsafeCast() diff --git a/library/crypto-rand/src/jsMain/kotlin/org/kotlincrypto/random/internal/js/_JsUint8Array.kt b/library/crypto-rand/src/jsMain/kotlin/org/kotlincrypto/random/internal/js/_JsUint8Array.kt index 30494b0..d38ed4d 100644 --- a/library/crypto-rand/src/jsMain/kotlin/org/kotlincrypto/random/internal/js/_JsUint8Array.kt +++ b/library/crypto-rand/src/jsMain/kotlin/org/kotlincrypto/random/internal/js/_JsUint8Array.kt @@ -15,5 +15,8 @@ **/ package org.kotlincrypto.random.internal.js -internal actual fun jsUint8ArrayGet(array: JsUint8Array, index: Int): Byte = js("array[index]") -internal actual fun jsUint8ArraySet(array: JsUint8Array, index: Int, value: Byte) { js("array[index] = value") } +internal actual fun jsUint8Array(length: Int): JsUint8Array = js(CODE_JS_NEW_UINT8_LENGTH) +internal actual fun jsUint8Array(buffer: JsArrayBufferLike): JsUint8Array = js(CODE_JS_NEW_UINT8_BUFFER) + +internal actual fun jsUint8ArrayGet(array: JsUint8Array, index: Int): Short = js(CODE_JS_ARRAY_GET) +internal actual fun jsUint8ArraySet(array: JsUint8Array, index: Int, value: Byte) { js(CODE_JS_ARRAY_SET) } diff --git a/library/crypto-rand/src/jsWasmJsMain/kotlin/org/kotlincrypto/random/internal/JsWasmJsPlatform.kt b/library/crypto-rand/src/jsWasmJsMain/kotlin/org/kotlincrypto/random/internal/JsWasmJsPlatform.kt index e389fce..4878b58 100644 --- a/library/crypto-rand/src/jsWasmJsMain/kotlin/org/kotlincrypto/random/internal/JsWasmJsPlatform.kt +++ b/library/crypto-rand/src/jsWasmJsMain/kotlin/org/kotlincrypto/random/internal/JsWasmJsPlatform.kt @@ -18,13 +18,9 @@ package org.kotlincrypto.random.internal import org.kotlincrypto.random.RandomnessProcurementException import org.kotlincrypto.random.internal.js.IS_NODE_JS import org.kotlincrypto.random.internal.js.JsCrypto -import org.kotlincrypto.random.internal.js.JsUint8Array -import org.kotlincrypto.random.internal.js.get import org.kotlincrypto.random.internal.js.jsCryptoBrowser +import org.kotlincrypto.random.internal.js.cryptoRandFill import org.kotlincrypto.random.internal.js.jsCryptoNode -import org.kotlincrypto.random.internal.js.set - -private const val BUFFER_SIZE = 1024 * 8 private val JS_CRYPTO: JsCrypto by lazy { if (IS_NODE_JS) jsCryptoNode() else jsCryptoBrowser() } @@ -32,51 +28,9 @@ private val JS_CRYPTO: JsCrypto by lazy { if (IS_NODE_JS) jsCryptoNode() else js internal actual fun ByteArray.cryptoRandFill() { try { val jsCryptoFill = if (IS_NODE_JS) JS_CRYPTO::randomFillSync else JS_CRYPTO::getRandomValues - - // Cannot simply use the ByteArray when calling the supplied Crypto function. - // Must utilize Uint8Array and then copy over results (See Issue #8). Also, - // by chunking in a size less than 65536, it avoids hitting the ceiling imposed - // on JS Browser (See issue #9). - if (size <= BUFFER_SIZE) { - // 1 shot it - val buf = JsUint8Array(size) - jsCryptoFill(buf) - for (i in indices) { - this[i] = buf[i] - buf[i] = 0 // Always ensure buffer is zeroed out - } - return - } - - val buf = JsUint8Array(BUFFER_SIZE) - - var needed = size - var pos = 0 - - // chunk - while (needed > BUFFER_SIZE) { - jsCryptoFill(buf) - for (i in 0 until BUFFER_SIZE) { - this[pos++] = buf[i] - } - needed -= BUFFER_SIZE - } - - // remainder - if (needed > 0) { - jsCryptoFill(buf.subarray(0, needed)) - - for (i in 0 until needed) { - this[pos++] = buf[i] - buf[i] = 0 // Always ensure buffer is zeroed out - } - } - - for (i in needed until BUFFER_SIZE) { - buf[i] = 0 // Always ensure buffer is zeroed out - } + cryptoRandFill(procure = jsCryptoFill) } catch (t: Throwable) { - val fn = if (IS_NODE_JS) "randomFillSync" else "getRandomValues" - throw RandomnessProcurementException("Failed to obtain bytes from [crypto.$fn]", t) + val name = if (IS_NODE_JS) "randomFillSync" else "getRandomValues" + throw RandomnessProcurementException("Failed to obtain bytes from [crypto.$name]", t) } } diff --git a/library/crypto-rand/src/jsWasmJsMain/kotlin/org/kotlincrypto/random/internal/js/JsArrayLike.kt b/library/crypto-rand/src/jsWasmJsMain/kotlin/org/kotlincrypto/random/internal/js/JsArrayLike.kt new file mode 100644 index 0000000..3687001 --- /dev/null +++ b/library/crypto-rand/src/jsWasmJsMain/kotlin/org/kotlincrypto/random/internal/js/JsArrayLike.kt @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2026 KotlinCrypto + * + * 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 + * + * https://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.kotlincrypto.random.internal.js + +internal sealed external interface JsArrayBufferLike + +internal sealed external interface JsTypedArrayLike { + val buffer: JsArrayBufferLike + val length: Int + fun subarray(start: Int, end: Int): JsTypedArrayLike +} + +internal const val CODE_JS_ARRAY_GET: String = "array[index]" +internal const val CODE_JS_ARRAY_SET: String = "array[index] = value" diff --git a/library/crypto-rand/src/jsWasmJsMain/kotlin/org/kotlincrypto/random/internal/js/JsCrypto.kt b/library/crypto-rand/src/jsWasmJsMain/kotlin/org/kotlincrypto/random/internal/js/JsCrypto.kt index 85b404c..cff7c7b 100644 --- a/library/crypto-rand/src/jsWasmJsMain/kotlin/org/kotlincrypto/random/internal/js/JsCrypto.kt +++ b/library/crypto-rand/src/jsWasmJsMain/kotlin/org/kotlincrypto/random/internal/js/JsCrypto.kt @@ -22,6 +22,8 @@ internal external interface JsCrypto { fun randomFillSync(buf: JsUint8Array) } +internal const val JS_CRYPTO_MAX_FILL: Int = 65536 + internal const val CODE_IS_NODE_JS: String = """ (typeof process !== 'undefined' @@ -43,3 +45,5 @@ internal expect val IS_NODE_JS: Boolean internal expect fun jsCryptoBrowser(): JsCrypto internal expect fun jsCryptoNode(): JsCrypto + +internal expect fun ByteArray.cryptoRandFill(procure: (JsUint8Array) -> Unit) diff --git a/library/crypto-rand/src/jsWasmJsMain/kotlin/org/kotlincrypto/random/internal/js/JsInt8Array.kt b/library/crypto-rand/src/jsWasmJsMain/kotlin/org/kotlincrypto/random/internal/js/JsInt8Array.kt new file mode 100644 index 0000000..78a3bc0 --- /dev/null +++ b/library/crypto-rand/src/jsWasmJsMain/kotlin/org/kotlincrypto/random/internal/js/JsInt8Array.kt @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2025 KotlinCrypto + * + * 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 + * + * https://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. + **/ +@file:Suppress("NOTHING_TO_INLINE", "UNUSED") + +package org.kotlincrypto.random.internal.js + +import kotlin.js.JsName + +@JsName("Int8Array") +internal open external class JsInt8Array: JsTypedArrayLike { + override val buffer: JsArrayBufferLike + override val length: Int + override fun subarray(start: Int, end: Int): JsInt8Array + internal companion object +} + +internal inline fun JsInt8Array.Companion.new(length: Int): JsInt8Array = jsInt8Array(length) +internal inline fun JsInt8Array.Companion.new(buffer: JsArrayBufferLike): JsInt8Array = jsInt8Array(buffer) + +internal inline operator fun JsInt8Array.get(index: Int): Byte = jsInt8ArrayGet(this, index) +internal inline operator fun JsInt8Array.set(index: Int, value: Byte) { jsInt8ArraySet(this, index, value) } + +internal inline fun JsInt8Array.asJsUint8Array(): JsUint8Array = JsUint8Array.new(buffer) + +internal const val CODE_JS_NEW_INT8_LENGTH = "new Int8Array(length)" +internal const val CODE_JS_NEW_INT8_BUFFER = "new Int8Array(buffer)" + +internal expect fun jsInt8Array(length: Int): JsInt8Array +internal expect fun jsInt8Array(buffer: JsArrayBufferLike): JsInt8Array + +internal expect fun jsInt8ArrayGet(array: JsInt8Array, index: Int): Byte +internal expect fun jsInt8ArraySet(array: JsInt8Array, index: Int, value: Byte) diff --git a/library/crypto-rand/src/jsWasmJsMain/kotlin/org/kotlincrypto/random/internal/js/JsUint8Array.kt b/library/crypto-rand/src/jsWasmJsMain/kotlin/org/kotlincrypto/random/internal/js/JsUint8Array.kt index 382557e..558069e 100644 --- a/library/crypto-rand/src/jsWasmJsMain/kotlin/org/kotlincrypto/random/internal/js/JsUint8Array.kt +++ b/library/crypto-rand/src/jsWasmJsMain/kotlin/org/kotlincrypto/random/internal/js/JsUint8Array.kt @@ -20,12 +20,26 @@ package org.kotlincrypto.random.internal.js import kotlin.js.JsName @JsName("Uint8Array") -internal open external class JsUint8Array(length: Int) { - fun subarray(start: Int, end: Int): JsUint8Array +internal open external class JsUint8Array: JsTypedArrayLike { + override val buffer: JsArrayBufferLike + override val length: Int + override fun subarray(start: Int, end: Int): JsUint8Array + internal companion object } -internal inline operator fun JsUint8Array.get(index: Int): Byte = jsUint8ArrayGet(this, index) -internal inline operator fun JsUint8Array.set(index: Int, value: Byte) { jsUint8ArraySet(this, index, value) } +internal inline fun JsUint8Array.Companion.new(length: Int): JsUint8Array = jsUint8Array(length) +internal inline fun JsUint8Array.Companion.new(buffer: JsArrayBufferLike): JsUint8Array = jsUint8Array(buffer) -internal expect fun jsUint8ArrayGet(array: JsUint8Array, index: Int): Byte +internal inline operator fun JsUint8Array.get(index: Int): Byte = jsUint8ArrayGet(this, index).toByte() +internal inline operator fun JsUint8Array.set(index: Int, value: UByte) { jsUint8ArraySet(this, index, value.toByte()) } + +internal inline fun JsUint8Array.asJsInt8Array(): JsInt8Array = JsInt8Array.new(buffer) + +internal const val CODE_JS_NEW_UINT8_LENGTH = "new Uint8Array(length)" +internal const val CODE_JS_NEW_UINT8_BUFFER = "new Uint8Array(buffer)" + +internal expect fun jsUint8Array(length: Int): JsUint8Array +internal expect fun jsUint8Array(buffer: JsArrayBufferLike): JsUint8Array + +internal expect fun jsUint8ArrayGet(array: JsUint8Array, index: Int): Short internal expect fun jsUint8ArraySet(array: JsUint8Array, index: Int, value: Byte) diff --git a/library/crypto-rand/src/jsWasmJsTest/kotlin/org/kotlincrypto/random/internal/js/CryptoRandFillJsWasmJsUnitTest.kt b/library/crypto-rand/src/jsWasmJsTest/kotlin/org/kotlincrypto/random/internal/js/CryptoRandFillJsWasmJsUnitTest.kt new file mode 100644 index 0000000..fbcd551 --- /dev/null +++ b/library/crypto-rand/src/jsWasmJsTest/kotlin/org/kotlincrypto/random/internal/js/CryptoRandFillJsWasmJsUnitTest.kt @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2026 KotlinCrypto + * + * 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 + * + * https://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.kotlincrypto.random.internal.js + +import kotlin.test.Test +import kotlin.test.assertEquals +import kotlin.test.assertTrue + +class CryptoRandFillJsWasmJsUnitTest { + + @Test + fun givenArray_whenLessThanMax_thenFillIsInvokedOnce() { + val ba = ByteArray(20) + var invocations = 0 + ba.cryptoRandFill { jsArray -> + for (i in 0 until jsArray.length) { jsArray[i] = 1.toUByte() } + invocations++ + } + assertEquals(1, invocations) + ba.forEachIndexed { i, b -> + assertEquals(1.toByte(), b, "index[$i]") + } + } + + @Test + fun givenArray_whenGreaterThanLimit_thenFillIsMultipleTimes() { + val ba = ByteArray((JS_CRYPTO_MAX_FILL * 3) + 25) + var invocations = 0 + ba.cryptoRandFill { jsArray -> + for (i in 0 until jsArray.length) { jsArray[i] = 1.toUByte() } + invocations++ + } + assertTrue(invocations > 3, "invocations[$invocations]") + ba.forEachIndexed { i, b -> + assertEquals(1.toByte(), b, "index[$i]") + } + } +} diff --git a/library/crypto-rand/src/wasmJsMain/kotlin/org/kotlincrypto/random/internal/js/_JsCrypto.kt b/library/crypto-rand/src/wasmJsMain/kotlin/org/kotlincrypto/random/internal/js/_JsCrypto.kt index 199691e..bfd29da 100644 --- a/library/crypto-rand/src/wasmJsMain/kotlin/org/kotlincrypto/random/internal/js/_JsCrypto.kt +++ b/library/crypto-rand/src/wasmJsMain/kotlin/org/kotlincrypto/random/internal/js/_JsCrypto.kt @@ -13,11 +13,43 @@ * See the License for the specific language governing permissions and * limitations under the License. **/ +@file:Suppress("OPT_IN_USAGE") + package org.kotlincrypto.random.internal.js +import kotlin.math.min + internal actual val IS_NODE_JS: Boolean by lazy { isNodeJs() } internal actual fun jsCryptoBrowser(): JsCrypto = js(CODE_JS_CRYPTO_BROWSER) internal actual fun jsCryptoNode(): JsCrypto = js(CODE_JS_CRYPTO_NODE) private fun isNodeJs(): Boolean = js(CODE_IS_NODE_JS) + +private const val BUFFER_SIZE = 1024 * 8 + +internal actual fun ByteArray.cryptoRandFill(procure: (JsUint8Array) -> Unit) { + // Kotlin/WasmJs does not provide access to ByteArray.storage + // (i.e. the WasmByteArray), so we must always use a buffer and + // copy back and forth. + val buf = JsUint8Array.new(length = min(size, BUFFER_SIZE)) + + try { + var remainder = size + var offset = 0 + while (remainder > 0) { + val len = if (remainder >= buf.length) { + procure(buf) + buf.length + } else { + procure(buf.subarray(0, remainder)) + remainder + } + repeat(len) { i -> this[offset++] = buf[i] } + remainder -= len + } + } finally { + // Always ensure the buffer gets zeroed out when done. + repeat(buf.length) { i -> buf[i] = 0u } + } +} diff --git a/library/crypto-rand/src/wasmJsMain/kotlin/org/kotlincrypto/random/internal/js/_JsInt8Array.kt b/library/crypto-rand/src/wasmJsMain/kotlin/org/kotlincrypto/random/internal/js/_JsInt8Array.kt new file mode 100644 index 0000000..faa6351 --- /dev/null +++ b/library/crypto-rand/src/wasmJsMain/kotlin/org/kotlincrypto/random/internal/js/_JsInt8Array.kt @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2025 KotlinCrypto + * + * 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 + * + * https://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. + **/ +@file:Suppress("OPT_IN_USAGE") + +package org.kotlincrypto.random.internal.js + +internal actual fun jsInt8Array(length: Int): JsInt8Array = js(CODE_JS_NEW_INT8_LENGTH) +internal actual fun jsInt8Array(buffer: JsArrayBufferLike): JsInt8Array = js(CODE_JS_NEW_INT8_BUFFER) + +internal actual fun jsInt8ArrayGet(array: JsInt8Array, index: Int): Byte = js(CODE_JS_ARRAY_GET) +internal actual fun jsInt8ArraySet(array: JsInt8Array, index: Int, value: Byte) { js(CODE_JS_ARRAY_SET) } diff --git a/library/crypto-rand/src/wasmJsMain/kotlin/org/kotlincrypto/random/internal/js/_JsUint8Array.kt b/library/crypto-rand/src/wasmJsMain/kotlin/org/kotlincrypto/random/internal/js/_JsUint8Array.kt index 30494b0..ce5e245 100644 --- a/library/crypto-rand/src/wasmJsMain/kotlin/org/kotlincrypto/random/internal/js/_JsUint8Array.kt +++ b/library/crypto-rand/src/wasmJsMain/kotlin/org/kotlincrypto/random/internal/js/_JsUint8Array.kt @@ -13,7 +13,12 @@ * See the License for the specific language governing permissions and * limitations under the License. **/ +@file:Suppress("OPT_IN_USAGE") + package org.kotlincrypto.random.internal.js -internal actual fun jsUint8ArrayGet(array: JsUint8Array, index: Int): Byte = js("array[index]") -internal actual fun jsUint8ArraySet(array: JsUint8Array, index: Int, value: Byte) { js("array[index] = value") } +internal actual fun jsUint8Array(length: Int): JsUint8Array = js(CODE_JS_NEW_UINT8_LENGTH) +internal actual fun jsUint8Array(buffer: JsArrayBufferLike): JsUint8Array = js(CODE_JS_NEW_UINT8_BUFFER) + +internal actual fun jsUint8ArrayGet(array: JsUint8Array, index: Int): Short = js(CODE_JS_ARRAY_GET) +internal actual fun jsUint8ArraySet(array: JsUint8Array, index: Int, value: Byte) { js(CODE_JS_ARRAY_SET) } diff --git a/library/crypto-rand/src/wasmWasiMain/kotlin/org/kotlincrypto/random/internal/WasmWasiPlatform.kt b/library/crypto-rand/src/wasmWasiMain/kotlin/org/kotlincrypto/random/internal/WasmWasiPlatform.kt index 1b3161c..0803127 100644 --- a/library/crypto-rand/src/wasmWasiMain/kotlin/org/kotlincrypto/random/internal/WasmWasiPlatform.kt +++ b/library/crypto-rand/src/wasmWasiMain/kotlin/org/kotlincrypto/random/internal/WasmWasiPlatform.kt @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. **/ -@file:Suppress("ACTUAL_ANNOTATIONS_NOT_MATCH_EXPECT") +@file:Suppress("ACTUAL_ANNOTATIONS_NOT_MATCH_EXPECT", "OPT_IN_USAGE") package org.kotlincrypto.random.internal