[stdlib] Proper expects for API used in intermediate shared source sets Write expect declarations for internal implementation functions used in native-wasm and wasmCommonMain source sets but declared lower in source sets hierarchy. KT-68240
diff --git a/kotlin-native/runtime/build.gradle.kts b/kotlin-native/runtime/build.gradle.kts index 4bed691..5671d06 100644 --- a/kotlin-native/runtime/build.gradle.kts +++ b/kotlin-native/runtime/build.gradle.kts
@@ -591,6 +591,7 @@ srcDir(project(":kotlin-stdlib").file("common/src/generated")) srcDir(project(":kotlin-stdlib").file("unsigned/src")) srcDir(project(":kotlin-stdlib").file("src")) + srcDir(project(":kotlin-stdlib").file("native-wasm/src/")) srcDir(project(":kotlin-test").files("annotations-common/src/main/kotlin")) srcDir(project(":kotlin-test").files("common/src/main/kotlin")) srcDir(project(":kotlin-native:Interop:Runtime").file("src/main/kotlin")) @@ -600,7 +601,6 @@ srcDir(project(":kotlin-native:Interop:Runtime").file("src/native/kotlin")) srcDir(project(":kotlin-native:Interop:JsRuntime").file("src/main/kotlin")) srcDir(project.file("src/main/kotlin")) - srcDir(project(":kotlin-stdlib").file("native-wasm/src/")) } dependsOn(":prepare:build.version:writeStdlibVersion")
diff --git a/kotlin-native/runtime/src/main/kotlin/generated/_ArraysNative.kt b/kotlin-native/runtime/src/main/kotlin/generated/_ArraysNative.kt index c39f2b4..720249b 100644 --- a/kotlin-native/runtime/src/main/kotlin/generated/_ArraysNative.kt +++ b/kotlin-native/runtime/src/main/kotlin/generated/_ArraysNative.kt
@@ -1777,7 +1777,7 @@ * Attempts to read _uninitialized_ values from this array work in implementation-dependent manner, * either throwing exception or returning some kind of implementation-specific default value. */ -internal fun <T> Array<T>.copyOfUninitializedElements(newSize: Int): Array<T> { +internal actual fun <T> Array<T>.copyOfUninitializedElements(newSize: Int): Array<T> { return copyOfUninitializedElements(0, newSize) }
diff --git a/kotlin-native/runtime/src/main/kotlin/kotlin/Assertions.kt b/kotlin-native/runtime/src/main/kotlin/kotlin/Assertions.kt index b18c577..a6fed28 100644 --- a/kotlin-native/runtime/src/main/kotlin/kotlin/Assertions.kt +++ b/kotlin-native/runtime/src/main/kotlin/kotlin/Assertions.kt
@@ -13,7 +13,7 @@ */ @Suppress("NOTHING_TO_INLINE") @ExperimentalNativeApi -public inline fun assert(value: Boolean) { +public actual inline fun assert(value: Boolean) { assert(value) { "Assertion failed" } } @@ -22,7 +22,7 @@ * and runtime assertions have been enabled during compilation. */ @ExperimentalNativeApi -public inline fun assert(value: Boolean, lazyMessage: () -> Any) { +public actual inline fun assert(value: Boolean, lazyMessage: () -> Any) { if (!value) { val message = lazyMessage() throw AssertionError(message)
diff --git a/kotlin-native/runtime/src/main/kotlin/kotlin/Exceptions.kt b/kotlin-native/runtime/src/main/kotlin/kotlin/Exceptions.kt index c5c8e558..f50028b 100644 --- a/kotlin-native/runtime/src/main/kotlin/kotlin/Exceptions.kt +++ b/kotlin-native/runtime/src/main/kotlin/kotlin/Exceptions.kt
@@ -158,11 +158,11 @@ actual constructor(cause: Throwable?) : super(cause) } -public open class OutOfMemoryError : Error { +public actual open class OutOfMemoryError : Error { - public constructor() : super() + public actual constructor() : super() - public constructor(message: String?) : super(message) + public actual constructor(message: String?) : super(message) } public actual open class NumberFormatException : IllegalArgumentException {
diff --git a/kotlin-native/runtime/src/main/kotlin/kotlin/collections/ArrayUtil.kt b/kotlin-native/runtime/src/main/kotlin/kotlin/collections/ArrayUtil.kt index 9548bd6..4fd0c4f 100644 --- a/kotlin-native/runtime/src/main/kotlin/kotlin/collections/ArrayUtil.kt +++ b/kotlin-native/runtime/src/main/kotlin/kotlin/collections/ArrayUtil.kt
@@ -15,7 +15,7 @@ * either throwing exception or returning some kind of implementation-specific default value. */ @PublishedApi -internal inline fun <E> arrayOfUninitializedElements(size: Int): Array<E> { +internal actual inline fun <E> arrayOfUninitializedElements(size: Int): Array<E> { // TODO: special case for size == 0? require(size >= 0) { "capacity must be non-negative." } @Suppress("TYPE_PARAMETER_AS_REIFIED") @@ -29,7 +29,7 @@ * Attempts to read _uninitialized_ value work in implementation-dependent manner, * either throwing exception or returning some kind of implementation-specific default value. */ -internal fun <E> Array<E>.resetAt(index: Int) { +internal actual fun <E> Array<E>.resetAt(index: Int) { (@Suppress("UNCHECKED_CAST")(this as Array<Any?>))[index] = null } @@ -78,7 +78,7 @@ * Attempts to read _uninitialized_ values work in implementation-dependent manner, * either throwing exception or returning some kind of implementation-specific default value. */ -internal fun <E> Array<E>.resetRange(fromIndex: Int, toIndex: Int) { +internal actual fun <E> Array<E>.resetRange(fromIndex: Int, toIndex: Int) { arrayFill(@Suppress("UNCHECKED_CAST") (this as Array<Any?>), fromIndex, toIndex, null) }
diff --git a/kotlin-native/runtime/src/main/kotlin/kotlin/collections/CollectionsNative.kt b/kotlin-native/runtime/src/main/kotlin/kotlin/collections/CollectionsNative.kt index 3af4c80..1a41c7a 100644 --- a/kotlin-native/runtime/src/main/kotlin/kotlin/collections/CollectionsNative.kt +++ b/kotlin-native/runtime/src/main/kotlin/kotlin/collections/CollectionsNative.kt
@@ -12,7 +12,7 @@ */ // Deprecate in favour of KT-57152 when it's provided. @ExperimentalNativeApi -public fun <T> MutableList<T>.replaceAll(transformation: (T) -> T) { +public actual fun <T> MutableList<T>.replaceAll(transformation: (T) -> T) { val it = listIterator() while (it.hasNext()) { val element = it.next()
diff --git a/kotlin-native/runtime/src/main/kotlin/kotlin/concurrent/Atomics.kt b/kotlin-native/runtime/src/main/kotlin/kotlin/concurrent/Atomics.kt index 7130088..ca5de3e 100644 --- a/kotlin-native/runtime/src/main/kotlin/kotlin/concurrent/Atomics.kt +++ b/kotlin-native/runtime/src/main/kotlin/kotlin/concurrent/Atomics.kt
@@ -143,7 +143,8 @@ * An object reference that is always updated atomically. */ @SinceKotlin("1.9") -public class AtomicReference<T>(public @Volatile var value: T) { +@Suppress("ACTUAL_WITHOUT_EXPECT") // actual visibility mismatch +public actual class AtomicReference<T> actual constructor(public @Volatile actual var value: T) { /** * Atomically sets the value to the given [new value][newValue] and returns the old value. @@ -158,7 +159,7 @@ * * Comparison of values is done by reference. */ - public fun compareAndSet(expected: T, newValue: T): Boolean = this::value.compareAndSetField(expected, newValue) + public actual fun compareAndSet(expected: T, newValue: T): Boolean = this::value.compareAndSetField(expected, newValue) /** * Atomically sets the value to the given [new value][newValue] if the current value equals the [expected value][expected] @@ -168,7 +169,7 @@ * * Comparison of values is done by reference. */ - public fun compareAndExchange(expected: T, newValue: T): T = this::value.compareAndExchangeField(expected, newValue) + public actual fun compareAndExchange(expected: T, newValue: T): T = this::value.compareAndExchangeField(expected, newValue) /** * Returns the string representation of the current [value].
diff --git a/kotlin-native/runtime/src/main/kotlin/kotlin/native/BitSet.kt b/kotlin-native/runtime/src/main/kotlin/kotlin/native/BitSet.kt index 3fb7ca5..2692627 100644 --- a/kotlin-native/runtime/src/main/kotlin/kotlin/native/BitSet.kt +++ b/kotlin-native/runtime/src/main/kotlin/kotlin/native/BitSet.kt
@@ -12,7 +12,10 @@ * @param size the size of one element in the array used to store bits. */ @ObsoleteNativeApi -public class BitSet(size: Int = ELEMENT_SIZE) { +@Suppress("ACTUAL_WITHOUT_EXPECT") // actual visibility mismatch +public actual class BitSet +@Suppress("ACTUAL_FUNCTION_WITH_DEFAULT_ARGUMENTS") +actual constructor(size: Int = ELEMENT_SIZE) { @kotlin.native.internal.CanBePrecreated public companion object { @@ -33,11 +36,11 @@ get() = previousSetBit(size) /** True if this BitSet contains no bits set to true. */ - public val isEmpty: Boolean + public actual val isEmpty: Boolean get() = bits.all { it == ALL_FALSE } /** Actual number of bits available in the set. All bits with indices >= size assumed to be 0 */ - public var size: Int = size + public actual var size: Int = size private set /** @@ -135,17 +138,20 @@ } /** Set the bit specified to the specified value. */ - public fun set(index: Int, value: Boolean = true) { + @Suppress("ACTUAL_FUNCTION_WITH_DEFAULT_ARGUMENTS") + public actual fun set(index: Int, value: Boolean = true) { ensureCapacity(index) val (elementIndex, offset) = index.asBitCoordinates setBitsWithMask(elementIndex, offset.asMask, value) } /** Sets the bits with indices between [from] (inclusive) and [to] (exclusive) to the specified value. */ - public fun set(from : Int, to: Int, value: Boolean = true): Unit = set(from until to, value) + @Suppress("ACTUAL_FUNCTION_WITH_DEFAULT_ARGUMENTS") + public actual fun set(from : Int, to: Int, value: Boolean = true): Unit = set(from until to, value) /** Sets the bits from the range specified to the specified value. */ - public fun set(range: IntRange, value: Boolean = true) { + @Suppress("ACTUAL_FUNCTION_WITH_DEFAULT_ARGUMENTS") + public actual fun set(range: IntRange, value: Boolean = true) { if (range.start < 0 || range.endInclusive < 0) { throw IndexOutOfBoundsException() } @@ -262,7 +268,8 @@ * Returns -1 if there is no such bits after [startIndex]. * @throws IndexOutOfBoundException if [startIndex] < 0. */ - public fun nextSetBit(startIndex: Int = 0): Int = nextBit(startIndex, true) + @Suppress("ACTUAL_FUNCTION_WITH_DEFAULT_ARGUMENTS") + public actual fun nextSetBit(startIndex: Int = 0): Int = nextBit(startIndex, true) /** * Returns an index of a next bit which value is `false` after [startIndex] (inclusive). @@ -270,7 +277,8 @@ * sequence of `false` bits after (size - 1)-th. * @throws IndexOutOfBoundException if [startIndex] < 0. */ - public fun nextClearBit(startIndex: Int = 0): Int = nextBit(startIndex, false) + @Suppress("ACTUAL_FUNCTION_WITH_DEFAULT_ARGUMENTS") + public actual fun nextClearBit(startIndex: Int = 0): Int = nextBit(startIndex, false) /** * Returns the biggest index of a bit which value is [lookFor] before [startIndex] (inclusive). @@ -335,7 +343,7 @@ public fun previousClearBit(startIndex: Int): Int = previousBit(startIndex, false) /** Returns a value of a bit with the [index] specified. */ - public operator fun get(index: Int): Boolean { + public actual operator fun get(index: Int): Boolean { if (index < 0) { throw IndexOutOfBoundsException() } @@ -360,16 +368,16 @@ } /** Performs a logical and operation over corresponding bits of this and [another] BitSets. The result is saved in this BitSet. */ - public fun and(another: BitSet): Unit = doOperation(another, Long::and) + public actual fun and(another: BitSet): Unit = doOperation(another, Long::and) /** Performs a logical or operation over corresponding bits of this and [another] BitSets. The result is saved in this BitSet. */ - public fun or(another: BitSet): Unit = doOperation(another, Long::or) + public actual fun or(another: BitSet): Unit = doOperation(another, Long::or) /** Performs a logical xor operation over corresponding bits of this and [another] BitSets. The result is saved in this BitSet. */ - public fun xor(another: BitSet): Unit = doOperation(another, Long::xor) + public actual fun xor(another: BitSet): Unit = doOperation(another, Long::xor) /** Performs a logical and + not operations over corresponding bits of this and [another] BitSets. The result is saved in this BitSet. */ - public fun andNot(another: BitSet) { + public actual fun andNot(another: BitSet) { ensureCapacity(another.lastIndex) var index = 0 while (index < another.bits.size) { @@ -383,7 +391,7 @@ } /** Returns true if the specified BitSet has any bits set to true that are also set to true in this BitSet. */ - public fun intersects(another: BitSet): Boolean = + public actual fun intersects(another: BitSet): Boolean = (0 until minOf(bits.size, another.bits.size)).any { bits[it] and another.bits[it] != 0L } override fun toString(): String {
diff --git a/kotlin-native/runtime/src/main/kotlin/kotlin/native/ObsoleteNativeApi.kt b/kotlin-native/runtime/src/main/kotlin/kotlin/native/ObsoleteNativeApi.kt index ed82714..bdbca0e 100644 --- a/kotlin-native/runtime/src/main/kotlin/kotlin/native/ObsoleteNativeApi.kt +++ b/kotlin-native/runtime/src/main/kotlin/kotlin/native/ObsoleteNativeApi.kt
@@ -33,4 +33,5 @@ ) @MustBeDocumented @SinceKotlin("1.9") -public annotation class ObsoleteNativeApi \ No newline at end of file +@Suppress("ACTUAL_WITHOUT_EXPECT") // actual visibility mismatch +public actual annotation class ObsoleteNativeApi \ No newline at end of file
diff --git a/kotlin-native/runtime/src/main/kotlin/kotlin/native/concurrent/Freezing.kt b/kotlin-native/runtime/src/main/kotlin/kotlin/native/concurrent/Freezing.kt index ee806e7..36aa593 100644 --- a/kotlin-native/runtime/src/main/kotlin/kotlin/native/concurrent/Freezing.kt +++ b/kotlin-native/runtime/src/main/kotlin/kotlin/native/concurrent/Freezing.kt
@@ -34,7 +34,7 @@ * @see ensureNeverFrozen */ @FreezingIsDeprecated -public fun <T> T.freeze(): T { +public actual fun <T> T.freeze(): T { freezeInternal(this) return this } @@ -45,7 +45,7 @@ * @return true if given object is null or frozen or permanent */ @FreezingIsDeprecated -public val Any?.isFrozen: Boolean +public actual val Any?.isFrozen: Boolean get() = isFrozenInternal(this) /**
diff --git a/kotlin-native/runtime/src/main/kotlin/kotlin/native/internal/Annotations.kt b/kotlin-native/runtime/src/main/kotlin/kotlin/native/internal/Annotations.kt index 628451e..67f5a3d 100644 --- a/kotlin-native/runtime/src/main/kotlin/kotlin/native/internal/Annotations.kt +++ b/kotlin-native/runtime/src/main/kotlin/kotlin/native/internal/Annotations.kt
@@ -137,7 +137,7 @@ @Target(AnnotationTarget.CLASS) @Retention(AnnotationRetention.SOURCE) @PublishedApi -internal annotation class CanBePrecreated +internal actual annotation class CanBePrecreated /** * Marks a class that has a finalizer.
diff --git a/kotlin-native/runtime/src/main/kotlin/kotlin/native/internal/KonanCollections.kt b/kotlin-native/runtime/src/main/kotlin/kotlin/native/internal/KonanCollections.kt index d98bdc7..a9356b9 100644 --- a/kotlin-native/runtime/src/main/kotlin/kotlin/native/internal/KonanCollections.kt +++ b/kotlin-native/runtime/src/main/kotlin/kotlin/native/internal/KonanCollections.kt
@@ -5,11 +5,11 @@ package kotlin.native.internal -internal interface KonanSet<out E> : Set<E> { +internal actual interface KonanSet<out E> : Set<E> { /** * Searches for the specified element in this set. * * @return the element from the set equal to [element], or `null` if no such element found. */ - fun getElement(element: @UnsafeVariance E): E? + actual fun getElement(element: @UnsafeVariance E): E? }
diff --git a/kotlin-native/runtime/src/main/kotlin/kotlin/text/CharNative.kt b/kotlin-native/runtime/src/main/kotlin/kotlin/text/CharNative.kt index f8645a6..ed9e76d 100644 --- a/kotlin-native/runtime/src/main/kotlin/kotlin/text/CharNative.kt +++ b/kotlin-native/runtime/src/main/kotlin/kotlin/text/CharNative.kt
@@ -39,7 +39,7 @@ */ @ExperimentalNativeApi // TODO: Consider removing from public API -public fun Char.Companion.toCodePoint(high: Char, low: Char): Int = +public actual fun Char.Companion.toCodePoint(high: Char, low: Char): Int = (((high - MIN_HIGH_SURROGATE) shl 10) or (low - MIN_LOW_SURROGATE)) + 0x10000 /** @@ -50,7 +50,7 @@ */ @ExperimentalNativeApi // TODO: Consider removing from public API -public fun Char.Companion.isSupplementaryCodePoint(codepoint: Int): Boolean = +public actual fun Char.Companion.isSupplementaryCodePoint(codepoint: Int): Boolean = codepoint in MIN_SUPPLEMENTARY_CODE_POINT..MAX_CODE_POINT /** @@ -58,7 +58,7 @@ */ @ExperimentalNativeApi // TODO: Consider removing from public API -public fun Char.Companion.isSurrogatePair(high: Char, low: Char): Boolean = high.isHighSurrogate() && low.isLowSurrogate() +public actual fun Char.Companion.isSurrogatePair(high: Char, low: Char): Boolean = high.isHighSurrogate() && low.isLowSurrogate() /** * Converts the codepoint specified to a char array. If the codepoint is not supplementary, the method will @@ -72,7 +72,7 @@ @ExperimentalNativeApi // TODO: Consider removing from public API @Suppress("DEPRECATION") -public fun Char.Companion.toChars(codePoint: Int): CharArray = +public actual fun Char.Companion.toChars(codePoint: Int): CharArray = when { codePoint in 0 until MIN_SUPPLEMENTARY_CODE_POINT -> charArrayOf(codePoint.toChar()) codePoint in MIN_SUPPLEMENTARY_CODE_POINT..MAX_CODE_POINT -> {
diff --git a/kotlin-native/runtime/src/main/kotlin/kotlin/text/StringBuilderNative.kt b/kotlin-native/runtime/src/main/kotlin/kotlin/text/StringBuilderNative.kt index 95a6c95..450487f 100644 --- a/kotlin-native/runtime/src/main/kotlin/kotlin/text/StringBuilderNative.kt +++ b/kotlin-native/runtime/src/main/kotlin/kotlin/text/StringBuilderNative.kt
@@ -79,7 +79,7 @@ public fun StringBuilder.appendln(): StringBuilder = appendLine() @GCUnsafeCall("Kotlin_StringBuilder_insertString") -internal external fun insertString(array: CharArray, distIndex: Int, value: String, sourceIndex: Int, count: Int): Int +internal actual external fun insertString(array: CharArray, destinationIndex: Int, value: String, sourceIndex: Int, count: Int): Int @GCUnsafeCall("Kotlin_StringBuilder_insertInt") -internal external fun insertInt(array: CharArray, start: Int, value: Int): Int \ No newline at end of file +internal actual external fun insertInt(array: CharArray, start: Int, value: Int): Int \ No newline at end of file
diff --git a/kotlin-native/runtime/src/main/kotlin/kotlin/text/Strings.kt b/kotlin-native/runtime/src/main/kotlin/kotlin/text/Strings.kt index 9ee696d..e0153c5 100644 --- a/kotlin-native/runtime/src/main/kotlin/kotlin/text/Strings.kt +++ b/kotlin-native/runtime/src/main/kotlin/kotlin/text/Strings.kt
@@ -355,7 +355,7 @@ } @GCUnsafeCall("Kotlin_String_unsafeStringFromCharArray") -internal external fun unsafeStringFromCharArray(array: CharArray, start: Int, size: Int) : String +internal actual external fun unsafeStringFromCharArray(array: CharArray, start: Int, size: Int) : String /** * Returns a [CharArray] containing characters of this string or its substring.
diff --git a/kotlin-native/runtime/src/main/kotlin/kotlin/text/regex/DecompositionHelpers.kt b/kotlin-native/runtime/src/main/kotlin/kotlin/text/regex/DecompositionHelpers.kt index 948acd5..87d9650 100644 --- a/kotlin-native/runtime/src/main/kotlin/kotlin/text/regex/DecompositionHelpers.kt +++ b/kotlin-native/runtime/src/main/kotlin/kotlin/text/regex/DecompositionHelpers.kt
@@ -10,27 +10,27 @@ // Access to the decomposition tables. ========================================================================= /** Gets canonical class for given codepoint from decomposition mappings table. */ @GCUnsafeCall("Kotlin_text_regex_getCanonicalClassInternal") -external internal fun getCanonicalClassInternal(ch: Int): Int +internal actual external fun getCanonicalClassInternal(ch: Int): Int /** Check if the given character is in table of single decompositions. */ @GCUnsafeCall("Kotlin_text_regex_hasSingleCodepointDecompositionInternal") -external internal fun hasSingleCodepointDecompositionInternal(ch: Int): Boolean +internal actual external fun hasSingleCodepointDecompositionInternal(ch: Int): Boolean /** Returns a decomposition for a given codepoint. */ @GCUnsafeCall("Kotlin_text_regex_getDecompositionInternal") -external internal fun getDecompositionInternal(ch: Int): IntArray? +internal external fun getDecompositionInternal(ch: Int): IntArray? /** * Decomposes the given string represented as an array of codepoints. Saves the decomposition into [outputCodepoints] array. * Returns the length of the decomposition. */ @GCUnsafeCall("Kotlin_text_regex_decomposeString") -external internal fun decomposeString(inputCodePoints: IntArray, inputLength: Int, outputCodePoints: IntArray): Int +internal actual external fun decomposeString(inputCodePoints: IntArray, inputLength: Int, outputCodePoints: IntArray): Int /** * Decomposes the given codepoint. Saves the decomposition into [outputCodepoints] array starting with [fromIndex]. * Returns the length of the decomposition. */ @GCUnsafeCall("Kotlin_text_regex_decomposeCodePoint") -external internal fun decomposeCodePoint(codePoint: Int, outputCodePoints: IntArray, fromIndex: Int): Int +internal actual external fun decomposeCodePoint(codePoint: Int, outputCodePoints: IntArray, fromIndex: Int): Int // ============================================================================================================= \ No newline at end of file
diff --git a/libraries/stdlib/common/src/kotlin/ExceptionsH.kt b/libraries/stdlib/common/src/kotlin/ExceptionsH.kt index fd858af..5329f49 100644 --- a/libraries/stdlib/common/src/kotlin/ExceptionsH.kt +++ b/libraries/stdlib/common/src/kotlin/ExceptionsH.kt
@@ -95,6 +95,7 @@ } @Deprecated("This exception type is not supposed to be thrown or caught in common code and will be removed from kotlin-stdlib-common soon.", level = DeprecationLevel.ERROR) +@Suppress("EXPECT_ACTUAL_INCOMPATIBILITY") // internal in Native and Wasm public expect open class NoWhenBranchMatchedException : RuntimeException { public constructor() public constructor(message: String?) @@ -103,6 +104,7 @@ } @Deprecated("This exception type is not supposed to be thrown or caught in common code and will be removed from kotlin-stdlib-common soon.", level = DeprecationLevel.ERROR) +@Suppress("EXPECT_ACTUAL_INCOMPATIBILITY") // internal in Native and Wasm public expect class UninitializedPropertyAccessException : RuntimeException { public constructor() public constructor(message: String?)
diff --git a/libraries/stdlib/native-wasm/src/kotlin/Assertions.kt b/libraries/stdlib/native-wasm/src/kotlin/Assertions.kt new file mode 100644 index 0000000..884191b --- /dev/null +++ b/libraries/stdlib/native-wasm/src/kotlin/Assertions.kt
@@ -0,0 +1,16 @@ +/* + * Copyright 2010-2021 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 + +/** + * Throws an [AssertionError] if the [value] is false. + */ +internal expect fun assert(value: Boolean) + +/** + * Throws an [AssertionError] calculated by [lazyMessage] if the [value] is false. + */ +internal expect fun assert(value: Boolean, lazyMessage: () -> Any)
diff --git a/libraries/stdlib/native-wasm/src/kotlin/Exceptions.kt b/libraries/stdlib/native-wasm/src/kotlin/Exceptions.kt new file mode 100644 index 0000000..c2c37fb --- /dev/null +++ b/libraries/stdlib/native-wasm/src/kotlin/Exceptions.kt
@@ -0,0 +1,11 @@ +/* + * Copyright 2010-2024 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 + +public expect open class OutOfMemoryError : Error { + public constructor() + public constructor(message: String?) +} \ No newline at end of file
diff --git a/libraries/stdlib/native-wasm/src/kotlin/atomics.kt b/libraries/stdlib/native-wasm/src/kotlin/atomics.kt new file mode 100644 index 0000000..12a740a --- /dev/null +++ b/libraries/stdlib/native-wasm/src/kotlin/atomics.kt
@@ -0,0 +1,12 @@ +/* + * Copyright 2010-2024 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.concurrent + +internal expect class AtomicReference<T>(value: T) { + public var value: T + public fun compareAndExchange(expected: T, newValue: T): T + public fun compareAndSet(expected: T, newValue: T): Boolean +}
diff --git a/libraries/stdlib/native-wasm/src/kotlin/collections/Arrays.kt b/libraries/stdlib/native-wasm/src/kotlin/collections/Arrays.kt index ac24b33..4d3acbe 100644 --- a/libraries/stdlib/native-wasm/src/kotlin/collections/Arrays.kt +++ b/libraries/stdlib/native-wasm/src/kotlin/collections/Arrays.kt
@@ -103,4 +103,10 @@ val result = @Suppress("TYPE_PARAMETER_AS_REIFIED") arrayOfNulls<E>(newSize) this.copyInto(result, 0, fromIndex, toIndex.coerceAtMost(size)) return result -} \ No newline at end of file +} + +@PublishedApi +internal expect inline fun <E> arrayOfUninitializedElements(size: Int): Array<E> +internal expect fun <T> Array<T>.copyOfUninitializedElements(newSize: Int): Array<T> +internal expect fun <E> Array<E>.resetAt(index: Int) +internal expect fun <E> Array<E>.resetRange(fromIndex: Int, toIndex: Int) \ No newline at end of file
diff --git a/libraries/stdlib/native-wasm/src/kotlin/collections/Collections.kt b/libraries/stdlib/native-wasm/src/kotlin/collections/Collections.kt index 2d0f808..897f1cd 100644 --- a/libraries/stdlib/native-wasm/src/kotlin/collections/Collections.kt +++ b/libraries/stdlib/native-wasm/src/kotlin/collections/Collections.kt
@@ -124,6 +124,11 @@ } /** + * Replaces each element in the list with a result of a transformation specified. + */ +internal expect fun <T> MutableList<T>.replaceAll(transformation: (T) -> T) + +/** * Returns a new read-only list containing only the specified object [element]. * * @sample samples.collections.Collections.Lists.singletonReadOnlyList
diff --git a/libraries/stdlib/native-wasm/src/kotlin/native/BitSet.kt b/libraries/stdlib/native-wasm/src/kotlin/native/BitSet.kt new file mode 100644 index 0000000..fa2870a --- /dev/null +++ b/libraries/stdlib/native-wasm/src/kotlin/native/BitSet.kt
@@ -0,0 +1,66 @@ +/* + * Copyright 2010-2021 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.native + +@ObsoleteNativeApi +internal const val BIT_SET_ELEMENT_SIZE: Int = 64 + +/** + * A vector of bits growing if necessary and allowing one to set/clear/read bits from it by a bit index. + * (this is the stripped copy of K/N implementation for Regex) + * + * @constructor creates an empty bit set with the specified [size] + * @param size the size of one element in the array used to store bits. + */ +@ObsoleteNativeApi +internal expect class BitSet constructor(size: Int = BIT_SET_ELEMENT_SIZE) { + /** True if this BitSet contains no bits set to true. */ + val isEmpty: Boolean + var size: Int + private set + /** Set the bit specified to the specified value. */ + fun set(index: Int, value: Boolean = true) + + /** Sets the bits with indices between [from] (inclusive) and [to] (exclusive) to the specified value. */ + fun set(from : Int, to: Int, value: Boolean = true) + + /** Sets the bits from the range specified to the specified value. */ + fun set(range: IntRange, value: Boolean = true) + + /** + * Returns an index of a next bit which value is `true` after [startIndex] (inclusive). + * Returns -1 if there is no such bits after [startIndex]. + * @throws IndexOutOfBoundException if [startIndex] < 0. + */ + fun nextSetBit(startIndex: Int = 0): Int + + /** + * Returns an index of a next bit which value is `false` after [startIndex] (inclusive). + * Returns [size] if there is no such bits between [startIndex] and [size] - 1 assuming that the set has an infinite + * sequence of `false` bits after (size - 1)-th. + * @throws IndexOutOfBoundException if [startIndex] < 0. + */ + fun nextClearBit(startIndex: Int = 0): Int + + /** Returns a value of a bit with the [index] specified. */ + operator fun get(index: Int): Boolean + + /** Performs a logical and operation over corresponding bits of this and [another] BitSets. The result is saved in this BitSet. */ + fun and(another: BitSet) + + /** Performs a logical or operation over corresponding bits of this and [another] BitSets. The result is saved in this BitSet. */ + fun or(another: BitSet) + + /** Performs a logical xor operation over corresponding bits of this and [another] BitSets. The result is saved in this BitSet. */ + fun xor(another: BitSet) + + /** Performs a logical and + not operations over corresponding bits of this and [another] BitSets. The result is saved in this BitSet. */ + fun andNot(another: BitSet) + + /** Returns true if the specified BitSet has any bits set to true that are also set to true in this BitSet. */ + fun intersects(another: BitSet): Boolean +}
diff --git a/libraries/stdlib/native-wasm/src/kotlin/native/ObsoleteNativeApi.kt b/libraries/stdlib/native-wasm/src/kotlin/native/ObsoleteNativeApi.kt new file mode 100644 index 0000000..d417ba5 --- /dev/null +++ b/libraries/stdlib/native-wasm/src/kotlin/native/ObsoleteNativeApi.kt
@@ -0,0 +1,34 @@ +/* + * 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.native + +import kotlin.annotation.AnnotationTarget.* + +/** + * This annotation marks the Kotlin/Native standard library API that is considered obsolete and is being phased out. + * + * This is an internal copy of the public K/N annotation. + * It is used to [OptIn] obsolete K/N API used in the shared native-wasm directory. + */ +@RequiresOptIn(message = "This API is obsolete and subject to removal in a future release.", level = RequiresOptIn.Level.ERROR) +@Retention(AnnotationRetention.BINARY) +@Target( + AnnotationTarget.CLASS, + AnnotationTarget.ANNOTATION_CLASS, + AnnotationTarget.PROPERTY, + AnnotationTarget.FIELD, + AnnotationTarget.LOCAL_VARIABLE, + AnnotationTarget.VALUE_PARAMETER, + AnnotationTarget.CONSTRUCTOR, + AnnotationTarget.FUNCTION, + AnnotationTarget.PROPERTY_GETTER, + AnnotationTarget.PROPERTY_SETTER, + AnnotationTarget.TYPEALIAS +) +@MustBeDocumented +@SinceKotlin("1.9") +@OptionalExpectation // though it has actuals in all dependent source sets, otherwise it is not possible to make it require opt-in +internal expect annotation class ObsoleteNativeApi() \ No newline at end of file
diff --git a/libraries/stdlib/native-wasm/src/kotlin/native/concurrent/Freezing.kt b/libraries/stdlib/native-wasm/src/kotlin/native/concurrent/Freezing.kt new file mode 100644 index 0000000..9ea7dbe --- /dev/null +++ b/libraries/stdlib/native-wasm/src/kotlin/native/concurrent/Freezing.kt
@@ -0,0 +1,10 @@ +/* + * Copyright 2010-2024 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.native.concurrent + +internal expect val Any?.isFrozen: Boolean + +internal expect fun <T> T.freeze(): T \ No newline at end of file
diff --git a/libraries/stdlib/native-wasm/src/kotlin/native/internal.kt b/libraries/stdlib/native-wasm/src/kotlin/native/internal.kt new file mode 100644 index 0000000..6fd9c01 --- /dev/null +++ b/libraries/stdlib/native-wasm/src/kotlin/native/internal.kt
@@ -0,0 +1,14 @@ +/* + * Copyright 2010-2024 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.native.internal + +internal expect interface KonanSet<out E> : Set<E> { + fun getElement(element: @UnsafeVariance E): E? +} + +@Target(AnnotationTarget.CLASS) +@Retention(AnnotationRetention.SOURCE) +internal expect annotation class CanBePrecreated() \ No newline at end of file
diff --git a/libraries/stdlib/native-wasm/src/kotlin/text/Char.kt b/libraries/stdlib/native-wasm/src/kotlin/text/Char.kt index 37f1d1d..b4a3896 100644 --- a/libraries/stdlib/native-wasm/src/kotlin/text/Char.kt +++ b/libraries/stdlib/native-wasm/src/kotlin/text/Char.kt
@@ -229,15 +229,18 @@ @PublishedApi @Suppress("DEPRECATION") internal actual fun checkRadix(radix: Int): Int { - if(radix !in Char.MIN_RADIX..Char.MAX_RADIX) { - throw IllegalArgumentException("radix $radix was not in valid range ${Char.MIN_RADIX..Char.MAX_RADIX}") + if(radix !in Char_MIN_RADIX..Char_MAX_RADIX) { + throw IllegalArgumentException("radix $radix was not in valid range ${Char_MIN_RADIX..Char_MAX_RADIX}") } return radix } // Char.Compaion methods. Konan specific. - +internal const val Char_MIN_RADIX: Int = 2 +internal const val Char_MAX_RADIX: Int = 36 // TODO: Make public when supplementary codepoints are supported. +internal const val Char_MIN_SUPPLEMENTARY_CODE_POINT: Int = 0x10000 + /** Converts a unicode code point to lower case. */ internal fun Char.Companion.toLowerCase(codePoint: Int): Int = if (codePoint <= MAX_VALUE.code) { @@ -255,3 +258,8 @@ } else { codePoint // TODO: Implement this transformation for supplementary codepoints. } + +internal expect fun Char.Companion.toCodePoint(high: Char, low: Char): Int +internal expect fun Char.Companion.toChars(codePoint: Int): CharArray +internal expect fun Char.Companion.isSupplementaryCodePoint(codepoint: Int): Boolean +internal expect fun Char.Companion.isSurrogatePair(high: Char, low: Char): Boolean
diff --git a/libraries/stdlib/native-wasm/src/kotlin/text/StringBuilder.kt b/libraries/stdlib/native-wasm/src/kotlin/text/StringBuilder.kt index d2050da..8be37fe 100644 --- a/libraries/stdlib/native-wasm/src/kotlin/text/StringBuilder.kt +++ b/libraries/stdlib/native-wasm/src/kotlin/text/StringBuilder.kt
@@ -956,3 +956,9 @@ @Deprecated("Use deleteAt(index: Int) instead", ReplaceWith("deleteAt(index)")) @kotlin.internal.InlineOnly public inline fun StringBuilder.deleteCharAt(index: Int): StringBuilder = this.deleteAt(index) + + + +internal expect fun unsafeStringFromCharArray(array: CharArray, start: Int, size: Int): String +internal expect fun insertInt(array: CharArray, start: Int, value: Int): Int +internal expect fun insertString(array: CharArray, destinationIndex: Int, value: String, sourceIndex: Int, count: Int): Int \ No newline at end of file
diff --git a/libraries/stdlib/native-wasm/src/kotlin/text/regex/AbstractCharClass.kt b/libraries/stdlib/native-wasm/src/kotlin/text/regex/AbstractCharClass.kt index f7d5426..1b005ab 100644 --- a/libraries/stdlib/native-wasm/src/kotlin/text/regex/AbstractCharClass.kt +++ b/libraries/stdlib/native-wasm/src/kotlin/text/regex/AbstractCharClass.kt
@@ -380,7 +380,7 @@ object: AbstractCharClass() { override fun contains(ch: Int): Boolean = alt xor (ch in start..end) }.apply { - if (end >= Char.MIN_SUPPLEMENTARY_CODE_POINT) { + if (end >= Char_MIN_SUPPLEMENTARY_CODE_POINT) { mayContainSupplCodepoints = true } val minSurrogate = Char.MIN_SURROGATE.toInt()
diff --git a/libraries/stdlib/native-wasm/src/kotlin/text/regex/CharClass.kt b/libraries/stdlib/native-wasm/src/kotlin/text/regex/CharClass.kt index 6354e72..6a64d7a 100644 --- a/libraries/stdlib/native-wasm/src/kotlin/text/regex/CharClass.kt +++ b/libraries/stdlib/native-wasm/src/kotlin/text/regex/CharClass.kt
@@ -239,7 +239,7 @@ lowHighSurrogates.set(surrogatesStart - minSurrogate, surrogatesEnd - minSurrogate + 1, !invertedSurrogates) - if (!mayContainSupplCodepoints && end >= Char.MIN_SUPPLEMENTARY_CODE_POINT) { + if (!mayContainSupplCodepoints && end >= Char_MIN_SUPPLEMENTARY_CODE_POINT) { mayContainSupplCodepoints = true } }
diff --git a/libraries/stdlib/native-wasm/src/kotlin/text/regex/DecompositionHelpers.kt b/libraries/stdlib/native-wasm/src/kotlin/text/regex/DecompositionHelpers.kt new file mode 100644 index 0000000..31c08d5 --- /dev/null +++ b/libraries/stdlib/native-wasm/src/kotlin/text/regex/DecompositionHelpers.kt
@@ -0,0 +1,24 @@ +/* + * Copyright 2010-2024 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.text.regex + +/** Gets canonical class for given codepoint from decomposition mappings table. */ +internal expect fun getCanonicalClassInternal(ch: Int): Int + +/** Check if the given character is in table of single decompositions. */ +internal expect fun hasSingleCodepointDecompositionInternal(ch: Int): Boolean + +/** + * Decomposes the given string represented as an array of codepoints. Saves the decomposition into [outputCodepoints] array. + * Returns the length of the decomposition. + */ +internal expect fun decomposeString(inputCodePoints: IntArray, inputLength: Int, outputCodePoints: IntArray): Int + +/** + * Decomposes the given codepoint. Saves the decomposition into [outputCodepoints] array starting with [fromIndex]. + * Returns the length of the decomposition. + */ +internal expect fun decomposeCodePoint(codePoint: Int, outputCodePoints: IntArray, fromIndex: Int): Int \ No newline at end of file
diff --git a/libraries/stdlib/wasm/js/builtins/kotlin/Throwable.kt b/libraries/stdlib/wasm/js/builtins/kotlin/Throwable.kt index 31a8597..93c2611 100644 --- a/libraries/stdlib/wasm/js/builtins/kotlin/Throwable.kt +++ b/libraries/stdlib/wasm/js/builtins/kotlin/Throwable.kt
@@ -48,5 +48,11 @@ } } +internal actual var Throwable.suppressedExceptionsList: MutableList<Throwable>? + get() = this.suppressedExceptionsList + set(value) { this.suppressedExceptionsList = value } + +internal actual val Throwable.stack: String get() = this.stack + private fun captureStackTrace(): ExternalInterfaceType = js("new Error().stack")
diff --git a/libraries/stdlib/wasm/js/src/kotlin/io.kt b/libraries/stdlib/wasm/js/src/kotlin/io.kt index 96aa45e..45a252f 100644 --- a/libraries/stdlib/wasm/js/src/kotlin/io.kt +++ b/libraries/stdlib/wasm/js/src/kotlin/io.kt
@@ -9,7 +9,7 @@ import kotlin.wasm.internal.* -internal fun printError(error: String?): Unit = +internal actual fun printError(error: String?): Unit = js("console.error(error)") private fun printlnImpl(message: String?): Unit =
diff --git a/libraries/stdlib/wasm/src/generated/_ArraysWasm.kt b/libraries/stdlib/wasm/src/generated/_ArraysWasm.kt index 526a921..135bb65 100644 --- a/libraries/stdlib/wasm/src/generated/_ArraysWasm.kt +++ b/libraries/stdlib/wasm/src/generated/_ArraysWasm.kt
@@ -1803,7 +1803,7 @@ * Attempts to read _uninitialized_ values from this array work in implementation-dependent manner, * either throwing exception or returning some kind of implementation-specific default value. */ -internal fun <T> Array<T>.copyOfUninitializedElements(newSize: Int): Array<T> { +internal actual fun <T> Array<T>.copyOfUninitializedElements(newSize: Int): Array<T> { return copyOfUninitializedElements(0, newSize) }
diff --git a/libraries/stdlib/wasm/src/kotlin/Assertions.kt b/libraries/stdlib/wasm/src/kotlin/Assertions.kt index 9053880..74d9d42 100644 --- a/libraries/stdlib/wasm/src/kotlin/Assertions.kt +++ b/libraries/stdlib/wasm/src/kotlin/Assertions.kt
@@ -10,14 +10,14 @@ /** * Throws an [AssertionError] if the [value] is false. */ -internal fun assert(value: Boolean) { +internal actual fun assert(value: Boolean) { assert(value) { "Assertion failed" } } /** * Throws an [AssertionError] calculated by [lazyMessage] if the [value] is false. */ -internal fun assert(value: Boolean, lazyMessage: () -> Any) { +internal actual fun assert(value: Boolean, lazyMessage: () -> Any) { if (!value) { val message = lazyMessage() throw AssertionError(message)
diff --git a/libraries/stdlib/wasm/src/kotlin/Exceptions.kt b/libraries/stdlib/wasm/src/kotlin/Exceptions.kt index d8b62c0..4861d1f 100644 --- a/libraries/stdlib/wasm/src/kotlin/Exceptions.kt +++ b/libraries/stdlib/wasm/src/kotlin/Exceptions.kt
@@ -111,7 +111,7 @@ public actual constructor(cause: Throwable?) : super(cause) } -public open class OutOfMemoryError : Error { - public constructor() : super() - public constructor(message: String?) : super(message) +public actual open class OutOfMemoryError : Error { + public actual constructor() : super() + public actual constructor(message: String?) : super(message) } \ No newline at end of file
diff --git a/libraries/stdlib/wasm/src/kotlin/collections/ArraysWasm.kt b/libraries/stdlib/wasm/src/kotlin/collections/ArraysWasm.kt index 236e693..50271fd 100644 --- a/libraries/stdlib/wasm/src/kotlin/collections/ArraysWasm.kt +++ b/libraries/stdlib/wasm/src/kotlin/collections/ArraysWasm.kt
@@ -20,6 +20,6 @@ internal fun <T> copyToArray(collection: Collection<T>): Array<T> = if (collection is AbstractCollection<T>) //TODO: Find more proper way to call abstract collection's toArray - @Suppress("INVISIBLE_MEMBER") collection.toArray() as Array<T> + @Suppress("INVISIBLE_MEMBER", "INVISIBLE_REFERENCE") collection.toArray() as Array<T> else collectionToArray(collection) as Array<T> \ No newline at end of file
diff --git a/libraries/stdlib/wasm/src/kotlin/collections/CollectionsWasm.kt b/libraries/stdlib/wasm/src/kotlin/collections/CollectionsWasm.kt index a371cc2..8a95939 100644 --- a/libraries/stdlib/wasm/src/kotlin/collections/CollectionsWasm.kt +++ b/libraries/stdlib/wasm/src/kotlin/collections/CollectionsWasm.kt
@@ -8,7 +8,7 @@ /** * Replaces each element in the list with a result of a transformation specified. */ -internal fun <T> MutableList<T>.replaceAll(transformation: (T) -> T) { +internal actual fun <T> MutableList<T>.replaceAll(transformation: (T) -> T) { val it = listIterator() while (it.hasNext()) { val element = it.next()
diff --git a/libraries/stdlib/wasm/src/kotlin/collections/Helpers.kt b/libraries/stdlib/wasm/src/kotlin/collections/Helpers.kt index 7568e46..7242c657 100644 --- a/libraries/stdlib/wasm/src/kotlin/collections/Helpers.kt +++ b/libraries/stdlib/wasm/src/kotlin/collections/Helpers.kt
@@ -12,18 +12,18 @@ */ @Suppress("NOTHING_TO_INLINE") @PublishedApi -internal inline fun <E> arrayOfUninitializedElements(size: Int): Array<E> { +internal actual inline fun <E> arrayOfUninitializedElements(size: Int): Array<E> { require(size >= 0) { "capacity must be non-negative." } @Suppress("TYPE_PARAMETER_AS_REIFIED") return Array<E>(size) } -internal fun <E> Array<E>.resetRange(fromIndex: Int, toIndex: Int) { +internal actual fun <E> Array<E>.resetRange(fromIndex: Int, toIndex: Int) { @Suppress("UNCHECKED_CAST") this.fill(null as E, fromIndex, toIndex) } -internal fun <E> Array<E>.resetAt(index: Int) { +internal actual fun <E> Array<E>.resetAt(index: Int) { @Suppress("UNCHECKED_CAST") (this as Array<Any?>)[index] = null } \ No newline at end of file
diff --git a/libraries/stdlib/wasm/src/kotlin/text/CharWasm.kt b/libraries/stdlib/wasm/src/kotlin/text/CharWasm.kt index a5b31b4..999af76 100644 --- a/libraries/stdlib/wasm/src/kotlin/text/CharWasm.kt +++ b/libraries/stdlib/wasm/src/kotlin/text/CharWasm.kt
@@ -28,14 +28,14 @@ public actual fun Char.isLowSurrogate(): Boolean = this in Char.MIN_LOW_SURROGATE..Char.MAX_LOW_SURROGATE /** Converts a surrogate pair to a unicode code point. Doesn't validate that the characters are a valid surrogate pair. */ -internal fun Char.Companion.toCodePoint(high: Char, low: Char): Int = +internal actual fun Char.Companion.toCodePoint(high: Char, low: Char): Int = (((high - MIN_HIGH_SURROGATE) shl 10) or (low - MIN_LOW_SURROGATE)) + 0x10000 /** Checks if the codepoint specified is a supplementary codepoint or not. */ -internal fun Char.Companion.isSupplementaryCodePoint(codepoint: Int): Boolean = +internal actual fun Char.Companion.isSupplementaryCodePoint(codepoint: Int): Boolean = codepoint in MIN_SUPPLEMENTARY_CODE_POINT..MAX_CODE_POINT -internal fun Char.Companion.isSurrogatePair(high: Char, low: Char): Boolean = high.isHighSurrogate() && low.isLowSurrogate() +internal actual fun Char.Companion.isSurrogatePair(high: Char, low: Char): Boolean = high.isHighSurrogate() && low.isLowSurrogate() /** * Converts the codepoint specified to a char array. If the codepoint is not supplementary, the method will @@ -43,7 +43,7 @@ * a low surrogate in A[1]. */ @Suppress("DEPRECATION") -internal fun Char.Companion.toChars(codePoint: Int): CharArray = +internal actual fun Char.Companion.toChars(codePoint: Int): CharArray = when { codePoint in 0 until MIN_SUPPLEMENTARY_CODE_POINT -> charArrayOf(codePoint.toChar()) codePoint in MIN_SUPPLEMENTARY_CODE_POINT..MAX_CODE_POINT -> {
diff --git a/libraries/stdlib/wasm/src/kotlin/text/StringBuilderWasm.kt b/libraries/stdlib/wasm/src/kotlin/text/StringBuilderWasm.kt index 59a6142..8308abe 100644 --- a/libraries/stdlib/wasm/src/kotlin/text/StringBuilderWasm.kt +++ b/libraries/stdlib/wasm/src/kotlin/text/StringBuilderWasm.kt
@@ -37,18 +37,18 @@ @kotlin.internal.InlineOnly public actual inline fun StringBuilder.appendLine(value: Double): StringBuilder = append(value).appendLine() -internal fun insertString(array: CharArray, destinationIndex: Int, value: String, sourceIndex: Int, count: Int): Int { +internal actual fun insertString(array: CharArray, destinationIndex: Int, value: String, sourceIndex: Int, count: Int): Int { copyWasmArray(value.chars, array.storage, sourceIndex, destinationIndex, count) return count } -internal fun unsafeStringFromCharArray(array: CharArray, start: Int, size: Int): String { +internal actual fun unsafeStringFromCharArray(array: CharArray, start: Int, size: Int): String { val copy = WasmCharArray(size) copyWasmArray(array.storage, copy, start, 0, size) return copy.createString() } -internal fun insertInt(array: CharArray, start: Int, value: Int): Int { +internal actual fun insertInt(array: CharArray, start: Int, value: Int): Int { val valueString = value.toString() val length = valueString.length insertString(array, start, valueString, 0, length)
diff --git a/libraries/stdlib/wasm/src/kotlin/text/regex/BitSet.kt b/libraries/stdlib/wasm/src/kotlin/text/regex/BitSet.kt index 58e07d5..3e11001 100644 --- a/libraries/stdlib/wasm/src/kotlin/text/regex/BitSet.kt +++ b/libraries/stdlib/wasm/src/kotlin/text/regex/BitSet.kt
@@ -13,7 +13,10 @@ * @constructor creates an empty bit set with the specified [size] * @param size the size of one element in the array used to store bits. */ -internal class BitSet constructor(size: Int = ELEMENT_SIZE) { +@Suppress("NO_ACTUAL_CLASS_MEMBER_FOR_EXPECTED_CLASS") +internal actual class BitSet +@Suppress("ACTUAL_FUNCTION_WITH_DEFAULT_ARGUMENTS") +actual constructor(size: Int = ELEMENT_SIZE) { companion object { // Default size of one element in the array used to store bits. @@ -29,11 +32,11 @@ get() = size - 1 /** True if this BitSet contains no bits set to true. */ - val isEmpty: Boolean + actual val isEmpty: Boolean get() = bits.all { it == ALL_FALSE } /** Actual number of bits available in the set. All bits with indices >= size assumed to be 0 */ - var size: Int = size + actual var size: Int = size private set // Transforms a bit index into an element index in the `bits` array. @@ -116,17 +119,20 @@ } /** Set the bit specified to the specified value. */ - fun set(index: Int, value: Boolean = true) { + @Suppress("ACTUAL_FUNCTION_WITH_DEFAULT_ARGUMENTS") + actual fun set(index: Int, value: Boolean = true) { ensureCapacity(index) val (elementIndex, offset) = index.asBitCoordinates setBitsWithMask(elementIndex, offset.asMask, value) } /** Sets the bits with indices between [from] (inclusive) and [to] (exclusive) to the specified value. */ - fun set(from : Int, to: Int, value: Boolean = true) = set(from until to, value) + @Suppress("ACTUAL_FUNCTION_WITH_DEFAULT_ARGUMENTS") + actual fun set(from : Int, to: Int, value: Boolean = true) = set(from until to, value) /** Sets the bits from the range specified to the specified value. */ - fun set(range: IntRange, value: Boolean = true) { + @Suppress("ACTUAL_FUNCTION_WITH_DEFAULT_ARGUMENTS") + actual fun set(range: IntRange, value: Boolean = true) { if (range.start < 0 || range.endInclusive < 0) { throw IndexOutOfBoundsException() } @@ -193,7 +199,8 @@ * Returns -1 if there is no such bits after [startIndex]. * @throws IndexOutOfBoundException if [startIndex] < 0. */ - fun nextSetBit(startIndex: Int = 0): Int = nextBit(startIndex, true) + @Suppress("ACTUAL_FUNCTION_WITH_DEFAULT_ARGUMENTS") + actual fun nextSetBit(startIndex: Int = 0): Int = nextBit(startIndex, true) /** * Returns an index of a next bit which value is `false` after [startIndex] (inclusive). @@ -201,10 +208,11 @@ * sequence of `false` bits after (size - 1)-th. * @throws IndexOutOfBoundException if [startIndex] < 0. */ - fun nextClearBit(startIndex: Int = 0): Int = nextBit(startIndex, false) + @Suppress("ACTUAL_FUNCTION_WITH_DEFAULT_ARGUMENTS") + actual fun nextClearBit(startIndex: Int = 0): Int = nextBit(startIndex, false) /** Returns a value of a bit with the [index] specified. */ - operator fun get(index: Int): Boolean { + actual operator fun get(index: Int): Boolean { if (index < 0) { throw IndexOutOfBoundsException() } @@ -229,16 +237,16 @@ } /** Performs a logical and operation over corresponding bits of this and [another] BitSets. The result is saved in this BitSet. */ - fun and(another: BitSet) = doOperation(another, Long::and) + actual fun and(another: BitSet) = doOperation(another, Long::and) /** Performs a logical or operation over corresponding bits of this and [another] BitSets. The result is saved in this BitSet. */ - fun or(another: BitSet) = doOperation(another, Long::or) + actual fun or(another: BitSet) = doOperation(another, Long::or) /** Performs a logical xor operation over corresponding bits of this and [another] BitSets. The result is saved in this BitSet. */ - fun xor(another: BitSet) = doOperation(another, Long::xor) + actual fun xor(another: BitSet) = doOperation(another, Long::xor) /** Performs a logical and + not operations over corresponding bits of this and [another] BitSets. The result is saved in this BitSet. */ - fun andNot(another: BitSet) { + actual fun andNot(another: BitSet) { ensureCapacity(another.lastIndex) var index = 0 while (index < another.bits.size) { @@ -252,6 +260,6 @@ } /** Returns true if the specified BitSet has any bits set to true that are also set to true in this BitSet. */ - fun intersects(another: BitSet): Boolean = + actual fun intersects(another: BitSet): Boolean = (0 until minOf(bits.size, another.bits.size)).any { bits[it] and another.bits[it] != 0L } }
diff --git a/libraries/stdlib/wasm/src/kotlin/text/regex/DecompositionHelpers.kt b/libraries/stdlib/wasm/src/kotlin/text/regex/DecompositionHelpers.kt index cc62191..3c4efc9 100644 --- a/libraries/stdlib/wasm/src/kotlin/text/regex/DecompositionHelpers.kt +++ b/libraries/stdlib/wasm/src/kotlin/text/regex/DecompositionHelpers.kt
@@ -247,12 +247,12 @@ } /** Gets canonical class for given codepoint from decomposition mappings table. */ -internal fun getCanonicalClassInternal(ch: Int): Int { +internal actual fun getCanonicalClassInternal(ch: Int): Int { return getCanonicalClass(ch) } /** Check if the given character is in table of single decompositions. */ -internal fun hasSingleCodepointDecompositionInternal(ch: Int): Boolean { +internal actual fun hasSingleCodepointDecompositionInternal(ch: Int): Boolean { val index: Int = binarySearchRange(singleDecompositions, ch) return index != -1 && singleDecompositions[index] == ch } @@ -261,7 +261,7 @@ * Decomposes the given string represented as an array of codepoints. Saves the decomposition into [outputCodepoints] array. * Returns the length of the decomposition. */ -internal fun decomposeString(inputCodePoints: IntArray, inputLength: Int, outputCodePoints: IntArray): Int { +internal actual fun decomposeString(inputCodePoints: IntArray, inputLength: Int, outputCodePoints: IntArray): Int { if (inputLength == 0) return 0 var outputLength = 0 @@ -281,7 +281,7 @@ * Decomposes the given codepoint. Saves the decomposition into [outputCodepoints] array starting with [fromIndex]. * Returns the length of the decomposition. */ -internal fun decomposeCodePoint(codePoint: Int, outputCodePoints: IntArray, fromIndex: Int): Int { +internal actual fun decomposeCodePoint(codePoint: Int, outputCodePoints: IntArray, fromIndex: Int): Int { val decomposition = getDecomposition(codePoint) if (decomposition == null) { outputCodePoints[fromIndex] = codePoint
diff --git a/libraries/stdlib/wasm/src/kotlin/text/regex/ObsoleteNativeApi.kt b/libraries/stdlib/wasm/src/kotlin/text/regex/ObsoleteNativeApi.kt index 637e767..ff75b8a 100644 --- a/libraries/stdlib/wasm/src/kotlin/text/regex/ObsoleteNativeApi.kt +++ b/libraries/stdlib/wasm/src/kotlin/text/regex/ObsoleteNativeApi.kt
@@ -30,4 +30,4 @@ ) @MustBeDocumented @SinceKotlin("1.9") -internal annotation class ObsoleteNativeApi \ No newline at end of file +internal actual annotation class ObsoleteNativeApi \ No newline at end of file
diff --git a/libraries/stdlib/wasm/src/kotlin/throwableExtensions.kt b/libraries/stdlib/wasm/src/kotlin/throwableExtensions.kt index 835a2e5..07e15e6 100644 --- a/libraries/stdlib/wasm/src/kotlin/throwableExtensions.kt +++ b/libraries/stdlib/wasm/src/kotlin/throwableExtensions.kt
@@ -49,6 +49,9 @@ return this.suppressedExceptionsList ?: emptyList() } +internal expect var Throwable.suppressedExceptionsList: MutableList<Throwable>? +internal expect val Throwable.stack: String + private class ExceptionTraceBuilder { private val target = StringBuilder() private val visited = mutableListOf<Throwable>()
diff --git a/libraries/stdlib/wasm/src/kotlin/util/io.kt b/libraries/stdlib/wasm/src/kotlin/util/io.kt new file mode 100644 index 0000000..75b9893 --- /dev/null +++ b/libraries/stdlib/wasm/src/kotlin/util/io.kt
@@ -0,0 +1,8 @@ +/* + * Copyright 2010-2024 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.io + +internal expect fun printError(error: String?) \ No newline at end of file
diff --git a/libraries/stdlib/wasm/stubs/atomics.kt b/libraries/stdlib/wasm/stubs/atomics.kt index c8789699..988f84e 100644 --- a/libraries/stdlib/wasm/stubs/atomics.kt +++ b/libraries/stdlib/wasm/stubs/atomics.kt
@@ -7,18 +7,18 @@ // Only for compatibility with shared K/N stdlib code -internal class AtomicReference<T>(public var value: T) { - public fun compareAndExchange(expected: T, new: T): T { +internal actual class AtomicReference<T> actual constructor(public actual var value: T) { + public actual fun compareAndExchange(expected: T, newValue: T): T { if (value == expected) { val old = value - value = new + value = newValue return old } return value } - public fun compareAndSet(expected: T, new: T): Boolean { + public actual fun compareAndSet(expected: T, newValue: T): Boolean { if (value == expected) { - value = new + value = newValue return true } return false
diff --git a/libraries/stdlib/wasm/stubs/native/concurrent.kt b/libraries/stdlib/wasm/stubs/native/concurrent.kt index e65fd60..184d77b 100644 --- a/libraries/stdlib/wasm/stubs/native/concurrent.kt +++ b/libraries/stdlib/wasm/stubs/native/concurrent.kt
@@ -7,8 +7,8 @@ // Only for compatibility with shared K/N stdlib code -internal val Any?.isFrozen +internal actual val Any?.isFrozen inline get() = false @Suppress("NOTHING_TO_INLINE") -internal inline fun <T> T.freeze(): T = this +internal actual inline fun <T> T.freeze(): T = this
diff --git a/libraries/stdlib/wasm/stubs/native/internal.kt b/libraries/stdlib/wasm/stubs/native/internal.kt index 72d8415..be82ab7 100644 --- a/libraries/stdlib/wasm/stubs/native/internal.kt +++ b/libraries/stdlib/wasm/stubs/native/internal.kt
@@ -7,10 +7,10 @@ // Only for compatibility with shared K/N stdlib code -internal interface KonanSet<out E> : Set<E> { - fun getElement(element: @UnsafeVariance E): E? +internal actual interface KonanSet<out E> : Set<E> { + actual fun getElement(element: @UnsafeVariance E): E? } @Target(AnnotationTarget.CLASS) @Retention(AnnotationRetention.SOURCE) -internal annotation class CanBePrecreated +internal actual annotation class CanBePrecreated
diff --git a/libraries/stdlib/wasm/wasi/builtins/kotlin/Throwable.kt b/libraries/stdlib/wasm/wasi/builtins/kotlin/Throwable.kt index baddf1a..6c6e404 100644 --- a/libraries/stdlib/wasm/wasi/builtins/kotlin/Throwable.kt +++ b/libraries/stdlib/wasm/wasi/builtins/kotlin/Throwable.kt
@@ -33,4 +33,10 @@ val s = getSimpleName(this.typeInfo) return if (message != null) s + ": " + message.toString() else s } -} \ No newline at end of file +} + +internal actual var Throwable.suppressedExceptionsList: MutableList<Throwable>? + get() = this.suppressedExceptionsList + set(value) { this.suppressedExceptionsList = value } + +internal actual val Throwable.stack: String get() = this.stack \ No newline at end of file
diff --git a/libraries/stdlib/wasm/wasi/src/kotlin/io.kt b/libraries/stdlib/wasm/wasi/src/kotlin/io.kt index 75de3be..f79cc7c 100644 --- a/libraries/stdlib/wasm/wasi/src/kotlin/io.kt +++ b/libraries/stdlib/wasm/wasi/src/kotlin/io.kt
@@ -72,7 +72,7 @@ } } -internal fun printError(error: String?) { +internal actual fun printError(error: String?) { printImpl(error, useErrorStream = true, newLine = false) }
diff --git a/libraries/tools/kotlin-stdlib-gen/src/templates/Arrays.kt b/libraries/tools/kotlin-stdlib-gen/src/templates/Arrays.kt index 4e70c79..83c4b60 100644 --- a/libraries/tools/kotlin-stdlib-gen/src/templates/Arrays.kt +++ b/libraries/tools/kotlin-stdlib-gen/src/templates/Arrays.kt
@@ -1005,6 +1005,9 @@ """ } body { "return copyOfUninitializedElements(0, newSize)" } + specialFor(InvariantArraysOfObjects) { + explicitActual() + } } val f_copyOfUninitializedElements_range = fn("copyOfUninitializedElements(fromIndex: Int, toIndex: Int)") {
diff --git a/libraries/tools/kotlin-stdlib-gen/src/templates/dsl/MemberBuilder.kt b/libraries/tools/kotlin-stdlib-gen/src/templates/dsl/MemberBuilder.kt index f67a2fb..9b8de39 100644 --- a/libraries/tools/kotlin-stdlib-gen/src/templates/dsl/MemberBuilder.kt +++ b/libraries/tools/kotlin-stdlib-gen/src/templates/dsl/MemberBuilder.kt
@@ -57,6 +57,7 @@ var inline: Inline = Inline.No; private set var infix: Boolean = false; private set var operator: Boolean = false; private set + var explicitActual: Boolean = false; private set val typeParams = mutableListOf<String>() var primaryTypeParameter: String? = null; private set var customReceiver: String? = null; private set @@ -94,6 +95,7 @@ } } fun inlineOnly() { inline = Inline.Only } + fun explicitActual(value: Boolean = true) { explicitActual = value } fun receiver(value: String) { customReceiver = value } @Deprecated("Use receiver()", ReplaceWith("receiver(value)")) @@ -184,7 +186,7 @@ val isImpl: Boolean if (!legacyMode) { headerOnly = target.platform == Platform.Common && hasPlatformSpecializations - isImpl = target.platform != Platform.Common && Platform.Common in allowedPlatforms + isImpl = explicitActual || target.platform != Platform.Common && Platform.Common in allowedPlatforms } else { // legacy mode when all is headerOnly + no_impl