Documentation fixes to stdlib (#2026)

This commit is contained in:
Pavel Punegov
2018-09-10 18:51:21 +03:00
committed by Nikolay Igotti
parent 78aac03c10
commit db8555b561
30 changed files with 411 additions and 227 deletions
+3 -2
View File
@@ -78,12 +78,13 @@
<a name="detach"></a> <a name="detach"></a>
## Object subgraph detachment ## Object subgraph detachment
An object subgraph without external references can be disconnected using `detachObjectGraph` to An object subgraph without external references can be disconnected using `DetachedObjectGraph<T>` to
a `COpaquePointer` value, which could be stored in `void*` data, so the disconnected object subgraphs a `COpaquePointer` value, which could be stored in `void*` data, so the disconnected object subgraphs
can be stored in a C data structure, and later attached back with `attachObjectGraph<T>` in an arbitrary thread can be stored in a C data structure, and later attached back with `DetachedObjectGraph<T>.attach()` in an arbitrary thread
or a worker. Combining it with [raw memory sharing](#shared) it allows side channel object transfer between or a worker. Combining it with [raw memory sharing](#shared) it allows side channel object transfer between
concurrent threads, if the worker mechanisms are insufficient for a particular task. concurrent threads, if the worker mechanisms are insufficient for a particular task.
<a name="shared"></a> <a name="shared"></a>
## Raw shared memory ## Raw shared memory
+6 -6
View File
@@ -188,7 +188,7 @@ i.e. the value located in memory rather than simple immutable self-contained
value. Think C++ references, as similar concept. value. Think C++ references, as similar concept.
For structs (and `typedef`s to structs) this representation is the main one For structs (and `typedef`s to structs) this representation is the main one
and has the same name as the struct itself, for Kotlin enums it is named and has the same name as the struct itself, for Kotlin enums it is named
`${type}.Var`, for `CPointer<T>` it is `CPointerVar<T>`, and for most other `${type}Var`, for `CPointer<T>` it is `CPointerVar<T>`, and for most other
types it is `${type}Var`. types it is `${type}Var`.
For those types that have both representations, the "lvalue" one has mutable For those types that have both representations, the "lvalue" one has mutable
@@ -343,7 +343,7 @@ In all cases the C string is supposed to be encoded as UTF-8.
### Scope-local pointers ### ### Scope-local pointers ###
It is possible to create scope-stable pointer of C representation of `CValues<T>` It is possible to create scope-stable pointer of C representation of `CValues<T>`
instance using `CValues<T>.ptr` extension property available under memScoped { ... }. instance using `CValues<T>.ptr` extension property available under `memScoped { ... }`.
It allows to use APIs which requires C pointers with lifetime bound to certain `MemScope`. For example: It allows to use APIs which requires C pointers with lifetime bound to certain `MemScope`. For example:
``` ```
memScoped { memScoped {
@@ -400,11 +400,11 @@ provided by user when configuring the callback. It is passed to some C function
However references to Kotlin objects can't be directly passed to C. However references to Kotlin objects can't be directly passed to C.
So they require wrapping before configuring callback and then unwrapping in So they require wrapping before configuring callback and then unwrapping in
the callback itself, to safely swim from Kotlin to Kotlin through the C world. the callback itself, to safely swim from Kotlin to Kotlin through the C world.
Such wrapping is possible with `StableObjPtr` class. Such wrapping is possible with `StableRef` class.
To wrap the reference: To wrap the reference:
``` ```
val stablePtr = StableObjPtr.create(kotlinReference) val stablePtr = StableRef.create(kotlinReference)
val voidPtr = stablePtr.value val voidPtr = stablePtr.value
``` ```
where the `voidPtr` is `COpaquePointer` and can be passed to the C function. where the `voidPtr` is `COpaquePointer` and can be passed to the C function.
@@ -412,13 +412,13 @@ where the `voidPtr` is `COpaquePointer` and can be passed to the C function.
To unwrap the reference: To unwrap the reference:
``` ```
val stablePtr = StableObjPtr.fromValue(voidPtr) val stablePtr = StableRef.fromValue(voidPtr)
val kotlinReference = stablePtr.get() val kotlinReference = stablePtr.get()
``` ```
where `kotlinReference` is the original wrapped reference (however it's type is where `kotlinReference` is the original wrapped reference (however it's type is
`Any` so it may require casting). `Any` so it may require casting).
The created `StableObjPtr` should eventually be manually disposed using The created `StableRef` should eventually be manually disposed using
`.dispose()` method to prevent memory leaks: `.dispose()` method to prevent memory leaks:
``` ```
@@ -49,6 +49,11 @@ inline fun <reified T : NativePointed> interpretNullablePointed(ptr: NativePtr):
} }
} }
/**
* Creates a [CPointer] from the raw pointer of [NativePtr].
*
* @return a [CPointer] representation, or `null` if the [rawValue] represents native `nullptr`.
*/
fun <T : CPointed> interpretCPointer(rawValue: NativePtr) = fun <T : CPointed> interpretCPointer(rawValue: NativePtr) =
if (rawValue == nativeNullPtr) { if (rawValue == nativeNullPtr) {
null null
@@ -33,12 +33,15 @@ inline val nativeNullPtr: NativePtr
fun <T : CVariable> typeOf(): CVariable.Type = throw Error("typeOf() is called with erased argument") fun <T : CVariable> typeOf(): CVariable.Type = throw Error("typeOf() is called with erased argument")
/** /**
* Returns interpretation of entity with given pointer, or `null` if it is null. * Performs type cast of the native pointer to given interop type, including null values.
* *
* @param T must not be abstract * @param T must not be abstract
*/ */
@Intrinsic external fun <T : NativePointed> interpretNullablePointed(ptr: NativePtr): T? @Intrinsic external fun <T : NativePointed> interpretNullablePointed(ptr: NativePtr): T?
/**
* Performs type cast of the [CPointer] from the given raw pointer.
*/
@Intrinsic external fun <T : CPointed> interpretCPointer(rawValue: NativePtr): CPointer<T>? @Intrinsic external fun <T : CPointed> interpretCPointer(rawValue: NativePtr): CPointer<T>?
@Intrinsic external fun NativePointed.getRawPointer(): NativePtr @Intrinsic external fun NativePointed.getRawPointer(): NativePtr
@@ -47,6 +50,12 @@ fun <T : CVariable> typeOf(): CVariable.Type = throw Error("typeOf() is called w
internal fun CPointer<*>.cPointerToString() = "CPointer(raw=$rawValue)" internal fun CPointer<*>.cPointerToString() = "CPointer(raw=$rawValue)"
/**
* Returns a pointer to C function which calls given Kotlin *static* function.
*
* @param function must be *static*, i.e. an (unbound) reference to a Kotlin function or
* a closure which doesn't capture any variable
*/
@Intrinsic external fun <R> staticCFunction(@VolatileLambda function: () -> R): CPointer<CFunction<() -> R>> @Intrinsic external fun <R> staticCFunction(@VolatileLambda function: () -> R): CPointer<CFunction<() -> R>>
@Intrinsic external fun <P1, R> staticCFunction(@VolatileLambda function: (P1) -> R): CPointer<CFunction<(P1) -> R>> @Intrinsic external fun <P1, R> staticCFunction(@VolatileLambda function: (P1) -> R): CPointer<CFunction<(P1) -> R>>
+33 -1
View File
@@ -10,9 +10,19 @@ import kotlin.native.internal.ExportTypeInfo
import kotlin.native.internal.InlineConstructor import kotlin.native.internal.InlineConstructor
import kotlin.native.internal.PointsTo import kotlin.native.internal.PointsTo
/**
* Represents an array. Array instances can be created using the constructor, [arrayOf], [arrayOfNulls] and [emptyArray]
* standard library functions.
* See [Kotlin language documentation](http://kotlinlang.org/docs/reference/basic-types.html#arrays)
* for more information on arrays.
*/
@ExportTypeInfo("theArrayTypeInfo") @ExportTypeInfo("theArrayTypeInfo")
public final class Array<T> { public final class Array<T> {
/**
* Creates a new array with the specified [size], where each element is calculated by calling the specified
* [init] function. The [init] function returns an array element given its index.
*/
@InlineConstructor @InlineConstructor
@Suppress("TYPE_PARAMETER_AS_REIFIED") @Suppress("TYPE_PARAMETER_AS_REIFIED")
public constructor(size: Int, init: (Int) -> T): this(size) { public constructor(size: Int, init: (Int) -> T): this(size) {
@@ -26,17 +36,37 @@ public final class Array<T> {
@ExportForCompiler @ExportForCompiler
internal constructor(@Suppress("UNUSED_PARAMETER") size: Int) {} internal constructor(@Suppress("UNUSED_PARAMETER") size: Int) {}
/**
* Returns the number of elements in the array.
*/
public val size: Int public val size: Int
get() = getArrayLength() get() = getArrayLength()
/**
* Returns the array element at the specified [index]. This method can be called using the
* index operator:
* ```
* value = arr[index]
* ```
*/
@SymbolName("Kotlin_Array_get") @SymbolName("Kotlin_Array_get")
@PointsTo(0b0100, 0, 0b0001) // <this> points to <return>, <return> points to <this>. @PointsTo(0b0100, 0, 0b0001) // <this> points to <return>, <return> points to <this>.
external public operator fun get(index: Int): T external public operator fun get(index: Int): T
/**
* Sets the array element at the specified [index] to the specified [value]. This method can
* be called using the index operator:
* ```
* arr[index] = value
* ```
*/
@SymbolName("Kotlin_Array_set") @SymbolName("Kotlin_Array_set")
@PointsTo(0b0100, 0, 0b0001) // <this> points to <value>, <value> points to <this>. @PointsTo(0b0100, 0, 0b0001) // <this> points to <value>, <value> points to <this>.
external public operator fun set(index: Int, value: T): Unit external public operator fun set(index: Int, value: T): Unit
/**
* Creates an [Iterator] for iterating over the elements of the array.
*/
public operator fun iterator(): kotlin.collections.Iterator<T> { public operator fun iterator(): kotlin.collections.Iterator<T> {
return IteratorImpl(this) return IteratorImpl(this)
} }
@@ -58,7 +88,9 @@ private class IteratorImpl<T>(val collection: Array<T>) : Iterator<T> {
} }
} }
/**
* Returns an array containing all elements of the original array and then all elements of the given [elements] array.
*/
@kotlin.internal.InlineOnly @kotlin.internal.InlineOnly
public inline operator fun <T> Array<T>.plus(elements: Array<T>): Array<T> { public inline operator fun <T> Array<T>.plus(elements: Array<T>): Array<T> {
val result = copyOfUninitializedElements(this.size + elements.size) val result = copyOfUninitializedElements(this.size + elements.size)
+7
View File
@@ -87,6 +87,7 @@ public final class CharArray {
} }
} }
/** Returns the number of elements in the array. */
public val size: Int public val size: Int
get() = getArrayLength() get() = getArrayLength()
@@ -138,6 +139,7 @@ public final class ShortArray {
} }
} }
/** Returns the number of elements in the array. */
public val size: Int public val size: Int
get() = getArrayLength() get() = getArrayLength()
@@ -189,6 +191,7 @@ public final class IntArray {
} }
} }
/** Returns the number of elements in the array. */
public val size: Int public val size: Int
get() = getArrayLength() get() = getArrayLength()
@@ -240,6 +243,7 @@ public final class LongArray {
} }
} }
/** Returns the number of elements in the array. */
public val size: Int public val size: Int
get() = getArrayLength() get() = getArrayLength()
@@ -291,6 +295,7 @@ public final class FloatArray {
} }
} }
/** Returns the number of elements in the array. */
public val size: Int public val size: Int
get() = getArrayLength() get() = getArrayLength()
@@ -338,6 +343,7 @@ public final class DoubleArray {
} }
} }
/** Returns the number of elements in the array. */
public val size: Int public val size: Int
get() = getArrayLength() get() = getArrayLength()
@@ -385,6 +391,7 @@ public final class BooleanArray {
} }
} }
/** Returns the number of elements in the array. */
public val size: Int public val size: Int
get() = getArrayLength() get() = getArrayLength()
-8
View File
@@ -17,14 +17,6 @@ public abstract class Enum<E: Enum<E>>(public val name: String, public val ordin
public override final fun compareTo(other: E): Int { return ordinal - other.ordinal } public override final fun compareTo(other: E): Int { return ordinal - other.ordinal }
/**
* Throws an exception since enum constants cannot be cloned.
* This method prevents enum classes from inheriting from [Cloneable].
*/
protected final fun clone(): Any {
throw UnsupportedOperationException()
}
public override final fun equals(other: Any?): Boolean { public override final fun equals(other: Any?): Boolean {
return this === other return this === other
} }
+3
View File
@@ -7,6 +7,9 @@ package kotlin
import kotlin.native.internal.ExportTypeInfo import kotlin.native.internal.ExportTypeInfo
/**
* The type with only one value: the `Unit` object.
*/
@ExportTypeInfo("theUnitTypeInfo") @ExportTypeInfo("theUnitTypeInfo")
public object Unit { public object Unit {
override fun toString() = "kotlin.Unit" override fun toString() = "kotlin.Unit"
@@ -5,6 +5,11 @@
package kotlin.collections package kotlin.collections
/**
* Provides a skeletal implementation of the [MutableCollection] interface.
*
* @param E the type of elements contained in the collection. The collection is invariant on its element type.
*/
public abstract class AbstractMutableCollection<E> protected constructor(): MutableCollection<E>, AbstractCollection<E>() { public abstract class AbstractMutableCollection<E> protected constructor(): MutableCollection<E>, AbstractCollection<E>() {
// Bulk Modification Operations // Bulk Modification Operations
@@ -9,7 +9,7 @@ import kotlin.comparisons.*
import kotlin.internal.InlineOnly import kotlin.internal.InlineOnly
import kotlin.random.* import kotlin.random.*
// Copies typed varargs array to an array of objects /** Copies typed varargs array to an array of objects */
internal actual fun <T> Array<out T>.copyToArrayOfAny(isVarargs: Boolean): Array<out Any?> = internal actual fun <T> Array<out T>.copyToArrayOfAny(isVarargs: Boolean): Array<out Any?> =
if (isVarargs) if (isVarargs)
// if the array came from varargs and already is array of Any, copying isn't required. // if the array came from varargs and already is array of Any, copying isn't required.
@@ -5,5 +5,7 @@
package kotlin.collections package kotlin.collections
// A marker interface indicating the fast indexed access support /**
* Marker interface indicating that the [List] implementation supports fast indexed access.
*/
public actual interface RandomAccess public actual interface RandomAccess
+10 -73
View File
@@ -5,95 +5,32 @@
package kotlin.io package kotlin.io
/** Prints the given [message] to the standard output stream. */
@SymbolName("Kotlin_io_Console_print") @SymbolName("Kotlin_io_Console_print")
external public fun print(message: String) external public fun print(message: String)
/* TODO: use something like that. /** Prints the given [message] to the standard output stream. */
public fun<T> print(message: T) {
print(message.toString())
} */
public actual fun print(message: Any?) { public actual fun print(message: Any?) {
print(message.toString()) print(message.toString())
} }
public fun print(message: Byte) { /** Prints the given [message] and newline to the standard output stream. */
print(message.toString())
}
public fun print(message: Short) {
print(message.toString())
}
public fun print(message: Char) {
print(message.toString())
}
public fun print(message: Int) {
print(message.toString())
}
public fun print(message: Long) {
print(message.toString())
}
public fun print(message: Float) {
print(message.toString())
}
public fun print(message: Double) {
print(message.toString())
}
public fun print(message: Boolean) {
print(message.toString())
}
@SymbolName("Kotlin_io_Console_println") @SymbolName("Kotlin_io_Console_println")
external public fun println(message: String) external public fun println(message: String)
/** Prints the given [message] and newline to the standard output stream. */
public actual fun println(message: Any?) { public actual fun println(message: Any?) {
println(message.toString()) println(message.toString())
} }
public fun println(message: Byte) { /** Prints newline to the standard output stream. */
println(message.toString())
}
public fun println(message: Short) {
println(message.toString())
}
public fun println(message: Char) {
println(message.toString())
}
public fun println(message: Int) {
println(message.toString())
}
public fun println(message: Long) {
println(message.toString())
}
public fun println(message: Float) {
println(message.toString())
}
public fun println(message: Double) {
println(message.toString())
}
public fun println(message: Boolean) {
println(message.toString())
}
/* TODO: use something like that.
public fun<T> println(message: T) {
print(message.toString())
} */
@SymbolName("Kotlin_io_Console_println0") @SymbolName("Kotlin_io_Console_println0")
external public actual fun println() external public actual fun println()
/**
* Reads a line of input from the standard input stream.
*
* @return the line read or `null` if the input is empty.
*/
@SymbolName("Kotlin_io_Console_readLine") @SymbolName("Kotlin_io_Console_readLine")
external public fun readLine(): String? external public fun readLine(): String?
@@ -60,8 +60,9 @@ public annotation class SharedImmutable
/** /**
* Makes top level function available from C/C++ code with the given name. * Makes top level function available from C/C++ code with the given name.
* `externName` controls the name of top level function, `shortName` controls the short name. *
* If `externName` is empty, no top level declaration is being created. * [externName] controls the name of top level function, [shortName] controls the short name.
* If [externName] is empty, no top level declaration is being created.
*/ */
@Target(AnnotationTarget.FUNCTION) @Target(AnnotationTarget.FUNCTION)
@Retention(AnnotationRetention.BINARY) @Retention(AnnotationRetention.BINARY)
@@ -7,11 +7,14 @@ package kotlin.native
/** /**
* A vector of bits growing if necessary and allowing one to set/clear/read bits from it by a bit index. * A vector of bits growing if necessary and allowing one to set/clear/read bits from it by a bit index.
*
* @constructor creates an empty bit set with the specified [size]
* @param seze the size of one element in the array used to store bits.
*/ */
public class BitSet(size: Int = ELEMENT_SIZE) { public class BitSet(size: Int = ELEMENT_SIZE) {
companion object { companion object {
// Size of one element in the array used to store bits. // Default size of one element in the array used to store bits.
private const val ELEMENT_SIZE = 64 private const val ELEMENT_SIZE = 64
private const val MAX_BIT_OFFSET = ELEMENT_SIZE - 1 private const val MAX_BIT_OFFSET = ELEMENT_SIZE - 1
private const val ALL_TRUE = -1L // 0xFFFF_FFFF_FFFF_FFFF private const val ALL_TRUE = -1L // 0xFFFF_FFFF_FFFF_FFFF
@@ -35,8 +38,9 @@ public class BitSet(size: Int = ELEMENT_SIZE) {
var size: Int = size var size: Int = size
private set private set
// TODO: Add more constructors. /**
* Creates a bit set of given [length] filling elements using [initializer]
*/
constructor(length: Int, initializer: (Int) -> Boolean): this(length) { constructor(length: Int, initializer: (Int) -> Boolean): this(length) {
for (i in 0 until length) { for (i in 0 until length) {
set(i, initializer(i)) set(i, initializer(i))
@@ -111,7 +115,7 @@ public class BitSet(size: Int = ELEMENT_SIZE) {
/** /**
* Checks if index is valid and extends the `bits` array if the index exceeds its size. * Checks if index is valid and extends the `bits` array if the index exceeds its size.
* Throws [IndexOutOfBoundsException] if [index] < 0. * @throws [IndexOutOfBoundsException] if [index] < 0.
*/ */
private fun ensureCapacity(index: Int) { private fun ensureCapacity(index: Int) {
if (index < 0) { if (index < 0) {
@@ -220,7 +224,7 @@ public class BitSet(size: Int = ELEMENT_SIZE) {
* (if [lookFor] == false) bit after [startIndex] (inclusive). * (if [lookFor] == false) bit after [startIndex] (inclusive).
* Returns -1 (for [lookFor] == true) or [size] (for lookFor == false) * Returns -1 (for [lookFor] == true) or [size] (for lookFor == false)
* if there is no such bits between [startIndex] and [size] - 1. * if there is no such bits between [startIndex] and [size] - 1.
* Throws IndexOutOfBoundException if [startIndex] < 0. * @throws IndexOutOfBoundException if [startIndex] < 0.
*/ */
private fun nextBit(startIndex: Int, lookFor: Boolean): Int { private fun nextBit(startIndex: Int, lookFor: Boolean): Int {
if (startIndex < 0) { if (startIndex < 0) {
@@ -254,7 +258,7 @@ public class BitSet(size: Int = ELEMENT_SIZE) {
/** /**
* Returns an index of a next bit which value is `true` after [startIndex] (inclusive). * Returns an index of a next bit which value is `true` after [startIndex] (inclusive).
* Returns -1 if there is no such bits after [startIndex]. * Returns -1 if there is no such bits after [startIndex].
* Throws IndexOutOfBoundException if [startIndex] < 0. * @throws IndexOutOfBoundException if [startIndex] < 0.
*/ */
fun nextSetBit(startIndex: Int = 0): Int = nextBit(startIndex, true) fun nextSetBit(startIndex: Int = 0): Int = nextBit(startIndex, true)
@@ -262,7 +266,7 @@ public class BitSet(size: Int = ELEMENT_SIZE) {
* Returns an index of a next bit which value is `false` after [startIndex] (inclusive). * 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 * 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. * sequence of `false` bits after (size - 1)-th.
* Throws IndexOutOfBoundException if [startIndex] < 0. * @throws IndexOutOfBoundException if [startIndex] < 0.
*/ */
fun nextClearBit(startIndex: Int = 0): Int = nextBit(startIndex, false) fun nextClearBit(startIndex: Int = 0): Int = nextBit(startIndex, false)
@@ -315,7 +319,7 @@ public class BitSet(size: Int = ELEMENT_SIZE) {
* Returns the biggest index of a bit which value is `true` before [startIndex] (inclusive). * Returns the biggest index of a bit which value is `true` before [startIndex] (inclusive).
* Returns -1 if there is no such bits before [startIndex] or if [startIndex] == -1. * Returns -1 if there is no such bits before [startIndex] or if [startIndex] == -1.
* If [startIndex] >= size will search from (size - 1)-th bit. * If [startIndex] >= size will search from (size - 1)-th bit.
* Throws IndexOutOfBoundException if [startIndex] < -1. * @throws IndexOutOfBoundException if [startIndex] < -1.
*/ */
fun previousSetBit(startIndex: Int): Int = previousBit(startIndex, true) fun previousSetBit(startIndex: Int): Int = previousBit(startIndex, true)
@@ -324,7 +328,7 @@ public class BitSet(size: Int = ELEMENT_SIZE) {
* Returns -1 if there is no such bits before [startIndex] or if [startIndex] == -1. * Returns -1 if there is no such bits before [startIndex] or if [startIndex] == -1.
* If [startIndex] >= size will return [startIndex] assuming that the set has an infinite * If [startIndex] >= size will return [startIndex] assuming that the set has an infinite
* sequence of `false` bits after (size - 1)-th. * sequence of `false` bits after (size - 1)-th.
* Throws IndexOutOfBoundException if [startIndex] < -1. * @throws IndexOutOfBoundException if [startIndex] < -1.
*/ */
fun previousClearBit(startIndex: Int): Int = previousBit(startIndex, false) fun previousClearBit(startIndex: Int): Int = previousBit(startIndex, false)
@@ -42,26 +42,30 @@ private class ImmutableBlobIteratorImpl(val blob: ImmutableBlob) : ByteIterator(
} }
/** /**
* Allocates new ByteArray or UByteArray and copies the data from blob. * Allocates new [ByteArray] and copies the data from blob starting from [start]
* and with [count] amount of bytes.
*/ */
@SymbolName("Kotlin_ImmutableBlob_toByteArray") @SymbolName("Kotlin_ImmutableBlob_toByteArray")
public external fun ImmutableBlob.toByteArray(start: Int = 0, count: Int = size): ByteArray public external fun ImmutableBlob.toByteArray(start: Int = 0, count: Int = size): ByteArray
/**
* Allocates new [UByteArray] and copies the data from blob starting from [start]
* and with [count] amount of bytes.
*/
@ExperimentalUnsignedTypes @ExperimentalUnsignedTypes
@SymbolName("Kotlin_ImmutableBlob_toByteArray") @SymbolName("Kotlin_ImmutableBlob_toByteArray")
public external fun ImmutableBlob.toUByteArray(start: Int = 0, count: Int = size): UByteArray public external fun ImmutableBlob.toUByteArray(start: Int = 0, count: Int = size): UByteArray
/** /**
* Returns stable C pointer to data at certain offset, useful as a way to pass resource * Returns stable C pointer to data at certain [offset], useful as a way to pass resource
* to C APIs. * to C APIs.
* @see kotlinx.cinterop.CPointer
*/ */
public fun ImmutableBlob.asCPointer(offset: Int = 0): CPointer<ByteVar> = public fun ImmutableBlob.asCPointer(offset: Int = 0): CPointer<ByteVar> =
interpretCPointer<ByteVar>(asCPointerImpl(offset))!! interpretCPointer<ByteVar>(asCPointerImpl(offset))!!
/*
public fun ImmutableBlob.asUCPointer(offset: Int = 0): CPointer<UByteVar> = public fun ImmutableBlob.asUCPointer(offset: Int = 0): CPointer<UByteVar> =
interpretCPointer<UByteVar>(asCPointerImpl(offset))!! interpretCPointer<UByteVar>(asCPointerImpl(offset))!!
*/
@SymbolName("Kotlin_ImmutableBlob_asCPointerImpl") @SymbolName("Kotlin_ImmutableBlob_asCPointerImpl")
private external fun ImmutableBlob.asCPointerImpl(offset: Int): kotlin.native.internal.NativePtr private external fun ImmutableBlob.asCPointerImpl(offset: Int): kotlin.native.internal.NativePtr
@@ -17,6 +17,10 @@ public annotation class Volatile
@Retention(AnnotationRetention.SOURCE) @Retention(AnnotationRetention.SOURCE)
public annotation class Synchronized public annotation class Synchronized
/**
* An actual implementation of `synchronized` method. This method is not supported in Kotlin/Native
* @throws UnsupportedOperationException always
*/
@kotlin.internal.InlineOnly @kotlin.internal.InlineOnly
public actual inline fun <R> synchronized(@Suppress("UNUSED_PARAMETER") lock: Any, block: () -> R): R = public actual inline fun <R> synchronized(@Suppress("UNUSED_PARAMETER") lock: Any, block: () -> R): R =
throw UnsupportedOperationException("synchronized() is unsupported") throw UnsupportedOperationException("synchronized() is unsupported")
@@ -11,7 +11,7 @@ package kotlin.native
external public fun initRuntimeIfNeeded(): Unit external public fun initRuntimeIfNeeded(): Unit
/** /**
* Deiitializes Kotlin runtime for the current thread, if was inited. * Deinitializes Kotlin runtime for the current thread, if was inited.
*/ */
@SymbolName("Kotlin_deinitRuntimeIfNeeded") @SymbolName("Kotlin_deinitRuntimeIfNeeded")
external public fun deinitRuntimeIfNeeded(): Unit external public fun deinitRuntimeIfNeeded(): Unit
@@ -15,7 +15,8 @@ public fun ByteArray.stringFromUtf8(start: Int = 0, size: Int = this.size) : Str
private external fun ByteArray.stringFromUtf8Impl(start: Int, size: Int) : String private external fun ByteArray.stringFromUtf8Impl(start: Int, size: Int) : String
/** /**
* Converts an UTF-8 array into a [String]. Throws [IllegalCharacterConversionException] if the input is invalid. * Converts an UTF-8 array into a [String].
* @throws [IllegalCharacterConversionException] if the input is invalid.
*/ */
public fun ByteArray.stringFromUtf8OrThrow(start: Int = 0, size: Int = this.size) : String = public fun ByteArray.stringFromUtf8OrThrow(start: Int = 0, size: Int = this.size) : String =
stringFromUtf8OrThrowImpl(start, size) stringFromUtf8OrThrowImpl(start, size)
@@ -33,7 +34,8 @@ public fun String.toUtf8(start: Int = 0, size: Int = this.length) : ByteArray =
private external fun String.toUtf8Impl(start: Int, size: Int) : ByteArray private external fun String.toUtf8Impl(start: Int, size: Int) : ByteArray
/** /**
* Converts a [String] into an UTF-8 array. Throws [IllegalCharacterConversionException] if the input is invalid. * Converts a [String] into an UTF-8 array.
* @throws [IllegalCharacterConversionException] if the input is invalid.
*/ */
public fun String.toUtf8OrThrow(start: Int = 0, size: Int = this.length) : ByteArray = public fun String.toUtf8OrThrow(start: Int = 0, size: Int = this.length) : ByteArray =
toUtf8OrThrowImpl(start, size) toUtf8OrThrowImpl(start, size)
@@ -7,68 +7,152 @@ package kotlin.native
import kotlin.native.SymbolName import kotlin.native.SymbolName
/** /**
* Those operations allows to extract primitive values out of the byte buffers. * Those operations allows to extract primitive values out of the [ByteArray] byte buffers.
* Data is treated as if it was in Least-Significant-Byte first (little-endian) byte order. * Data is treated as if it was in Least-Significant-Byte first (little-endian) byte order.
* If index is outside of array boundaries - ArrayIndexOutOfBoundsException is thrown. * If index is outside of array boundaries - [ArrayIndexOutOfBoundsException] is thrown.
*/
/**
* Gets [UByte] out of the [ByteArray] byte buffer at specified index [index]
* @throws ArrayIndexOutOfBoundsException if [index] is outside of array boundaries.
*/ */
@ExperimentalUnsignedTypes @ExperimentalUnsignedTypes
public fun ByteArray.ubyteAt(index: Int): UByte = UByte(get(index)) public fun ByteArray.ubyteAt(index: Int): UByte = UByte(get(index))
/**
* Gets [Char] out of the [ByteArray] byte buffer at specified index [index]
* @throws ArrayIndexOutOfBoundsException if [index] is outside of array boundaries.
*/
@SymbolName("Kotlin_ByteArray_getCharAt") @SymbolName("Kotlin_ByteArray_getCharAt")
public external fun ByteArray.charAt(index: Int): Char public external fun ByteArray.charAt(index: Int): Char
/**
* Gets [Short] out of the [ByteArray] byte buffer at specified index [index]
* @throws ArrayIndexOutOfBoundsException if [index] is outside of array boundaries.
*/
@SymbolName("Kotlin_ByteArray_getShortAt") @SymbolName("Kotlin_ByteArray_getShortAt")
public external fun ByteArray.shortAt(index: Int): Short public external fun ByteArray.shortAt(index: Int): Short
/**
* Gets [UShort] out of the [ByteArray] byte buffer at specified index [index]
* @throws ArrayIndexOutOfBoundsException if [index] is outside of array boundaries.
*/
@SymbolName("Kotlin_ByteArray_getShortAt") @SymbolName("Kotlin_ByteArray_getShortAt")
@ExperimentalUnsignedTypes @ExperimentalUnsignedTypes
public external fun ByteArray.ushortAt(index: Int): UShort public external fun ByteArray.ushortAt(index: Int): UShort
/**
* Gets [Int] out of the [ByteArray] byte buffer at specified index [index]
* @throws ArrayIndexOutOfBoundsException if [index] is outside of array boundaries.
*/
@SymbolName("Kotlin_ByteArray_getIntAt") @SymbolName("Kotlin_ByteArray_getIntAt")
public external fun ByteArray.intAt(index: Int): Int public external fun ByteArray.intAt(index: Int): Int
/**
* Gets [UInt] out of the [ByteArray] byte buffer at specified index [index]
* @throws ArrayIndexOutOfBoundsException if [index] is outside of array boundaries.
*/
@SymbolName("Kotlin_ByteArray_getIntAt") @SymbolName("Kotlin_ByteArray_getIntAt")
@ExperimentalUnsignedTypes @ExperimentalUnsignedTypes
public external fun ByteArray.uintAt(index: Int): UInt public external fun ByteArray.uintAt(index: Int): UInt
/**
* Gets [Long] out of the [ByteArray] byte buffer at specified index [index]
* @throws ArrayIndexOutOfBoundsException if [index] is outside of array boundaries.
*/
@SymbolName("Kotlin_ByteArray_getLongAt") @SymbolName("Kotlin_ByteArray_getLongAt")
public external fun ByteArray.longAt(index: Int): Long public external fun ByteArray.longAt(index: Int): Long
/**
* Gets [ULong] out of the [ByteArray] byte buffer at specified index [index]
* @throws ArrayIndexOutOfBoundsException if [index] is outside of array boundaries.
*/
@SymbolName("Kotlin_ByteArray_getLongAt") @SymbolName("Kotlin_ByteArray_getLongAt")
@ExperimentalUnsignedTypes @ExperimentalUnsignedTypes
public external fun ByteArray.ulongAt(index: Int): ULong public external fun ByteArray.ulongAt(index: Int): ULong
/**
* Gets [Float] out of the [ByteArray] byte buffer at specified index [index]
* @throws ArrayIndexOutOfBoundsException if [index] is outside of array boundaries.
*/
@SymbolName("Kotlin_ByteArray_getFloatAt") @SymbolName("Kotlin_ByteArray_getFloatAt")
public external fun ByteArray.floatAt(index: Int): Float public external fun ByteArray.floatAt(index: Int): Float
/**
* Gets [Double] out of the [ByteArray] byte buffer at specified index [index]
* @throws ArrayIndexOutOfBoundsException if [index] is outside of array boundaries.
*/
@SymbolName("Kotlin_ByteArray_getDoubleAt") @SymbolName("Kotlin_ByteArray_getDoubleAt")
public external fun ByteArray.doubleAt(index: Int): Double public external fun ByteArray.doubleAt(index: Int): Double
/**
* Sets [UByte] out of the [ByteArray] byte buffer at specified index [index]
* @throws ArrayIndexOutOfBoundsException if [index] is outside of array boundaries.
*/
@SymbolName("Kotlin_ByteArray_set")
public external fun ByteArray.setUByteAt(index: Int, value: UByte)
/**
* Sets [Char] out of the [ByteArray] byte buffer at specified index [index]
* @throws ArrayIndexOutOfBoundsException if [index] is outside of array boundaries.
*/
@SymbolName("Kotlin_ByteArray_setCharAt") @SymbolName("Kotlin_ByteArray_setCharAt")
public external fun ByteArray.setCharAt(index: Int, value: Char) public external fun ByteArray.setCharAt(index: Int, value: Char)
/**
* Sets [Short] out of the [ByteArray] byte buffer at specified index [index]
* @throws ArrayIndexOutOfBoundsException if [index] is outside of array boundaries.
*/
@SymbolName("Kotlin_ByteArray_setShortAt") @SymbolName("Kotlin_ByteArray_setShortAt")
public external fun ByteArray.setShortAt(index: Int, value: Short) public external fun ByteArray.setShortAt(index: Int, value: Short)
/**
* Sets [UShort] out of the [ByteArray] byte buffer at specified index [index]
* @throws ArrayIndexOutOfBoundsException if [index] is outside of array boundaries.
*/
@SymbolName("Kotlin_ByteArray_setShortAt") @SymbolName("Kotlin_ByteArray_setShortAt")
@ExperimentalUnsignedTypes @ExperimentalUnsignedTypes
public external fun ByteArray.setUShortAt(index: Int, value: UShort) public external fun ByteArray.setUShortAt(index: Int, value: UShort)
/**
* Sets [Int] out of the [ByteArray] byte buffer at specified index [index]
* @throws ArrayIndexOutOfBoundsException if [index] is outside of array boundaries.
*/
@SymbolName("Kotlin_ByteArray_setIntAt") @SymbolName("Kotlin_ByteArray_setIntAt")
public external fun ByteArray.setIntAt(index: Int, value: Int) public external fun ByteArray.setIntAt(index: Int, value: Int)
/**
* Sets [UInt] out of the [ByteArray] byte buffer at specified index [index]
* @throws ArrayIndexOutOfBoundsException if [index] is outside of array boundaries.
*/
@SymbolName("Kotlin_ByteArray_setIntAt") @SymbolName("Kotlin_ByteArray_setIntAt")
public external fun ByteArray.setUIntAt(index: Int, value: UInt) public external fun ByteArray.setUIntAt(index: Int, value: UInt)
/**
* Sets [Long] out of the [ByteArray] byte buffer at specified index [index]
* @throws ArrayIndexOutOfBoundsException if [index] is outside of array boundaries.
*/
@SymbolName("Kotlin_ByteArray_setLongAt") @SymbolName("Kotlin_ByteArray_setLongAt")
public external fun ByteArray.setLongAt(index: Int, value: Long) public external fun ByteArray.setLongAt(index: Int, value: Long)
/**
* Sets [ULong] out of the [ByteArray] byte buffer at specified index [index]
* @throws ArrayIndexOutOfBoundsException if [index] is outside of array boundaries.
*/
@SymbolName("Kotlin_ByteArray_setLongAt") @SymbolName("Kotlin_ByteArray_setLongAt")
@ExperimentalUnsignedTypes @ExperimentalUnsignedTypes
public external fun ByteArray.setULongAt(index: Int, value: ULong) public external fun ByteArray.setULongAt(index: Int, value: ULong)
/**
* Sets [Float] out of the [ByteArray] byte buffer at specified index [index]
* @throws ArrayIndexOutOfBoundsException if [index] is outside of array boundaries.
*/
@SymbolName("Kotlin_ByteArray_setFloatAt") @SymbolName("Kotlin_ByteArray_setFloatAt")
public external fun ByteArray.setFloatAt(index: Int, value: Float) public external fun ByteArray.setFloatAt(index: Int, value: Float)
/**
* Sets [Double] out of the [ByteArray] byte buffer at specified index [index]
* @throws ArrayIndexOutOfBoundsException if [index] is outside of array boundaries.
*/
@SymbolName("Kotlin_ByteArray_setDoubleAt") @SymbolName("Kotlin_ByteArray_setDoubleAt")
public external fun ByteArray.setDoubleAt(index: Int, value: Double) public external fun ByteArray.setDoubleAt(index: Int, value: Double)
@@ -17,27 +17,38 @@ import kotlinx.cinterop.NativePtr
*/ */
@Frozen @Frozen
public class AtomicInt(private var value_: Int) { public class AtomicInt(private var value_: Int) {
/**
* The value being held by this class.
*/
public var value: Int public var value: Int
get() = getImpl() get() = getImpl()
set(new) = setImpl(new) set(new) = setImpl(new)
/** /**
* Increments the value by [delta] and returns the new value. * Increments the value by [delta] and returns the new value.
*
* @param delta the value to add
* @return the new value
*/ */
@SymbolName("Kotlin_AtomicInt_addAndGet") @SymbolName("Kotlin_AtomicInt_addAndGet")
external public fun addAndGet(delta: Int): Int external public fun addAndGet(delta: Int): Int
/** /**
* Compares value with [expected] and replaces it with [new] value if values matches. * Compares value with [expected] and replaces it with [new] value if values matches.
* Returns the old value. *
* @param expected the expected value
* @param new the new value
* @return the old value
*/ */
@SymbolName("Kotlin_AtomicInt_compareAndSwap") @SymbolName("Kotlin_AtomicInt_compareAndSwap")
external public fun compareAndSwap(expected: Int, new: Int): Int external public fun compareAndSwap(expected: Int, new: Int): Int
/** /**
* Compares value with [expected] and replaces it with [new] value if values matches. * Compares value with [expected] and replaces it with [new] value if values matches.
* Returns true if successful. *
* @param expected the expected value
* @param new the new value
* @return true if successful
*/ */
@SymbolName("Kotlin_AtomicInt_compareAndSet") @SymbolName("Kotlin_AtomicInt_compareAndSet")
external public fun compareAndSet(expected: Int, new: Int): Boolean external public fun compareAndSet(expected: Int, new: Int): Boolean
@@ -58,6 +69,8 @@ public class AtomicInt(private var value_: Int) {
/** /**
* Returns the string representation of this object. * Returns the string representation of this object.
*
* @return the string representation
*/ */
public override fun toString(): String = value.toString() public override fun toString(): String = value.toString()
@@ -71,32 +84,46 @@ public class AtomicInt(private var value_: Int) {
@Frozen @Frozen
public class AtomicLong(private var value_: Long = 0) { public class AtomicLong(private var value_: Long = 0) {
/**
* The value being held by this class.
*/
public var value: Long public var value: Long
get() = getImpl() get() = getImpl()
set(new) = setImpl(new) set(new) = setImpl(new)
/** /**
* Increments the value by [delta] and returns the new value. * Increments the value by [delta] and returns the new value.
*
* @param delta the value to add
* @return the new value
*/ */
@SymbolName("Kotlin_AtomicLong_addAndGet") @SymbolName("Kotlin_AtomicLong_addAndGet")
external public fun addAndGet(delta: Long): Long external public fun addAndGet(delta: Long): Long
/** /**
* Increments the value by [delta] and returns the new value. * Increments the value by [delta] and returns the new value.
*
* @param delta the value to add
* @return the new value
*/ */
public fun addAndGet(delta: Int): Long = addAndGet(delta.toLong()) public fun addAndGet(delta: Int): Long = addAndGet(delta.toLong())
/** /**
* Compares value with [expected] and replaces it with [new] value if values matches. * Compares value with [expected] and replaces it with [new] value if values matches.
* Returns the old value. *
* @param expected the expected value
* @param new the new value
* @return the old value
*/ */
@SymbolName("Kotlin_AtomicLong_compareAndSwap") @SymbolName("Kotlin_AtomicLong_compareAndSwap")
external public fun compareAndSwap(expected: Long, new: Long): Long external public fun compareAndSwap(expected: Long, new: Long): Long
/** /**
* Compares value with [expected] and replaces it with [new] value if values matches. * Compares value with [expected] and replaces it with [new] value if values matches.
* Returns true if successful. *
* @param expected the expected value
* @param new the new value
* @return true if successful, false if state is unchanged
*/ */
@SymbolName("Kotlin_AtomicLong_compareAndSet") @SymbolName("Kotlin_AtomicLong_compareAndSet")
external public fun compareAndSet(expected: Long, new: Long): Boolean external public fun compareAndSet(expected: Long, new: Long): Boolean
@@ -117,6 +144,8 @@ public class AtomicLong(private var value_: Long = 0) {
/** /**
* Returns the string representation of this object. * Returns the string representation of this object.
*
* @return the string representation of this object
*/ */
public override fun toString(): String = value.toString() public override fun toString(): String = value.toString()
@@ -130,26 +159,39 @@ public class AtomicLong(private var value_: Long = 0) {
@Frozen @Frozen
public class AtomicNativePtr(private var value_: NativePtr) { public class AtomicNativePtr(private var value_: NativePtr) {
/**
* The value being held by this class.
*/
public var value: NativePtr public var value: NativePtr
get() = getImpl() get() = getImpl()
set(new) = setImpl(new) set(new) = setImpl(new)
/** /**
* Compares value with [expected] and replaces it with [new] value if values matches. * Compares value with [expected] and replaces it with [new] value if values matches.
* Returns the old value. * If [new] value is not null, it must be frozen or permanent object.
*
* @param expected the expected value
* @param new the new value
* @throws InvalidMutabilityException if [new] is not frozen or a permanent object
* @return the old value
*/ */
@SymbolName("Kotlin_AtomicNativePtr_compareAndSwap") @SymbolName("Kotlin_AtomicNativePtr_compareAndSwap")
external public fun compareAndSwap(expected: NativePtr, new: NativePtr): NativePtr external public fun compareAndSwap(expected: NativePtr, new: NativePtr): NativePtr
/** /**
* Compares value with [expected] and replaces it with [new] value if values matches. * Compares value with [expected] and replaces it with [new] value if values matches.
*
* @param expected the expected value
* @param new the new value
* @return true if successful
*/ */
@SymbolName("Kotlin_AtomicNativePtr_compareAndSet") @SymbolName("Kotlin_AtomicNativePtr_compareAndSet")
external public fun compareAndSet(expected: NativePtr, new: NativePtr): Boolean external public fun compareAndSet(expected: NativePtr, new: NativePtr): Boolean
/** /**
* Returns the string representation of this object. * Returns the string representation of this object.
*
* @return string representation of this object
*/ */
public override fun toString(): String = value.toString() public override fun toString(): String = value.toString()
@@ -173,17 +215,19 @@ public class AtomicReference<T>(private var value_: T) {
private var lock: Int = 0 private var lock: Int = 0
/** /**
* Creates a new atomic reference pointing to given [ref]. If reference is not frozen, * Creates a new atomic reference pointing to given [ref].
* @InvalidMutabilityException is thrown. * @throws InvalidMutabilityException if reference is not frozen.
*/ */
init { init {
checkIfFrozen(value) checkIfFrozen(value)
} }
/** /**
* Sets the value to [new] value * The referenced value.
* If [new] value is not null, it must be frozen or permanent object, otherwise an * Gets the value or sets the [new] value. If [new] value is not null,
* @InvalidMutabilityException is thrown. * it must be frozen or permanent object.
*
* @throws InvalidMutabilityException if the value is not frozen or a permanent object
*/ */
public var value: T public var value: T
get() = @Suppress("UNCHECKED_CAST")(getImpl() as T) get() = @Suppress("UNCHECKED_CAST")(getImpl() as T)
@@ -191,18 +235,30 @@ public class AtomicReference<T>(private var value_: T) {
/** /**
* Compares value with [expected] and replaces it with [new] value if values matches. * Compares value with [expected] and replaces it with [new] value if values matches.
* If [new] value is not null, it must be frozen or permanent object, otherwise an * If [new] value is not null, it must be frozen or permanent object.
* @InvalidMutabilityException is thrown. *
* Returns the old value. * @param expected the expected value
* @param new the new value
* @throws InvalidMutabilityException if the value is not frozen or a permanent object
* @return the old value
*/ */
@SymbolName("Kotlin_AtomicReference_compareAndSwap") @SymbolName("Kotlin_AtomicReference_compareAndSwap")
external public fun compareAndSwap(expected: T, new: T): T external public fun compareAndSwap(expected: T, new: T): T
/**
* Compares value with [expected] and replaces it with [new] value if values matches.
*
* @param expected the expected value
* @param new the new value
* @return true if successful
*/
@SymbolName("Kotlin_AtomicReference_compareAndSet") @SymbolName("Kotlin_AtomicReference_compareAndSet")
external public fun compareAndSet(expected: T, new: T): Boolean external public fun compareAndSet(expected: T, new: T): Boolean
/** /**
* Returns the string representation of this object. * Returns the string representation of this object.
*
* @return string representation of this object
*/ */
public override fun toString(): String = "Atomic reference to $value" public override fun toString(): String = "Atomic reference to $value"
@@ -7,13 +7,17 @@ package kotlin.native.concurrent
/** /**
* Exception thrown whenever freezing is not possible. * Exception thrown whenever freezing is not possible.
* [blocker] is an object preventing freezing, usually one marked with [ensureNeverFrozen] earlier. *
* @param toFreeze an object intended to be frozen.
* @param blocker an object preventing freezing, usually one marked with [ensureNeverFrozen] earlier.
*/ */
public class FreezingException(toFreeze: Any, blocker: Any) : public class FreezingException(toFreeze: Any, blocker: Any) :
RuntimeException("freezing of $toFreeze has failed, first blocker is $blocker") RuntimeException("freezing of $toFreeze has failed, first blocker is $blocker")
/** /**
* Exception thrown whenever we attempt to mutate frozen objects. * Exception thrown whenever we attempt to mutate frozen objects.
*
* @param where a frozen object that was attempted to mutate
*/ */
public class InvalidMutabilityException(where: Any) : public class InvalidMutabilityException(where: Any) :
RuntimeException("mutation attempt of frozen $where (hash is 0x${where.hashCode().toString(16)})") RuntimeException("mutation attempt of frozen $where (hash is 0x${where.hashCode().toString(16)})")
@@ -21,6 +25,10 @@ public class InvalidMutabilityException(where: Any) :
/** /**
* Freezes object subgraph reachable from this object. Frozen objects can be freely * Freezes object subgraph reachable from this object. Frozen objects can be freely
* shared between threads/workers. * shared between threads/workers.
*
* @throws FreezingException if freezing is not possible
* @return the object itself
* @see ensureNeverFrozen
*/ */
public fun <T> T.freeze(): T { public fun <T> T.freeze(): T {
freezeInternal(this) freezeInternal(this)
@@ -29,13 +37,18 @@ public fun <T> T.freeze(): T {
/** /**
* Checks if given object is null or frozen or permanent (i.e. instantiated at compile-time). * Checks if given object is null or frozen or permanent (i.e. instantiated at compile-time).
*
* @return true if given object is null or frozen or permanent
*/ */
public val Any?.isFrozen public val Any?.isFrozen
get() = isFrozenInternal(this) get() = isFrozenInternal(this)
/** /**
* This function ensures that if we see such an object during freezing attempt - freeze fails and * This function ensures that if we see such an object during freezing attempt - freeze fails and
* [FreezingException] is thrown. Is object is already frozen - [FreezingException] is thrown immediately. * [FreezingException] is thrown.
*
* @throws FreezingException thrown immediately if this object is already frozen
* @see freeze
*/ */
@SymbolName("Kotlin_Worker_ensureNeverFrozen") @SymbolName("Kotlin_Worker_ensureNeverFrozen")
public external fun Any.ensureNeverFrozen() public external fun Any.ensureNeverFrozen()
@@ -12,11 +12,11 @@ import kotlin.native.internal.Frozen
*/ */
enum class FutureState(val value: Int) { enum class FutureState(val value: Int) {
INVALID(0), INVALID(0),
// Future is scheduled for execution. /** Future is scheduled for execution. */
SCHEDULED(1), SCHEDULED(1),
// Future result is computed. /** Future result is computed. */
COMPUTED(2), COMPUTED(2),
// Future is cancelled. /** Future is cancelled. */
CANCELLED(3) CANCELLED(3)
} }
@@ -27,6 +27,9 @@ enum class FutureState(val value: Int) {
public class Future<T> internal constructor(val id: Int) { public class Future<T> internal constructor(val id: Int) {
/** /**
* Blocks execution until the future is ready. * Blocks execution until the future is ready.
*
* @return the execution result of [code] consumed futures's computaiton
* @throws IllegalStateException if current future has [FutureState.INVALID] or [FutureState.CANCELLED] state
*/ */
public inline fun <R> consume(code: (T) -> R): R = public inline fun <R> consume(code: (T) -> R): R =
when (state) { when (state) {
@@ -41,11 +44,15 @@ public class Future<T> internal constructor(val id: Int) {
} }
/** /**
* The result of the future computation.
* Blocks execution until the future is ready. Second attempt to get will result in an error. * Blocks execution until the future is ready. Second attempt to get will result in an error.
*/ */
public val result: T public val result: T
get() = consume { it -> it } get() = consume { it -> it }
/**
* A [FutureState] of this future
*/
public val state: FutureState public val state: FutureState
get() = FutureState.values()[stateOfFuture(id)] get() = FutureState.values()[stateOfFuture(id)]
@@ -58,7 +65,9 @@ public class Future<T> internal constructor(val id: Int) {
/** /**
* Wait for availability of futures in the collection. Returns set with all futures which have * Wait for availability of futures in the collection. Returns set with all futures which have
* value available for the consumption. * value available for the consumption, i.e. [FutureState.COMPUTED]
*
* @param millis the amount of time to wait for the computed future
*/ */
public fun <T> Collection<Future<T>>.waitForMultipleFutures(millis: Int): Set<Future<T>> { public fun <T> Collection<Future<T>>.waitForMultipleFutures(millis: Int): Set<Future<T>> {
val result = mutableSetOf<Future<T>>() val result = mutableSetOf<Future<T>>()
@@ -114,7 +114,7 @@ internal class AtomicLazyImpl<out T>(initializer: () -> T) : Lazy<T> {
/** /**
* Atomic lazy initializer, could be used in frozen objects, freezes initializing lambda, * Atomic lazy initializer, could be used in frozen objects, freezes initializing lambda,
* so use very carefully. Also, as with other uses of an @AtomicReference may potentially * so use very carefully. Also, as with other uses of an [AtomicReference] may potentially
* leak memory, so it is recommended to use `atomicLazy` in cases of objects living forever, * leak memory, so it is recommended to use `atomicLazy` in cases of objects living forever,
* such as object signletons, or in cases where it's guaranteed not to have cyclical garbage. * such as object signletons, or in cases where it's guaranteed not to have cyclical garbage.
*/ */
@@ -9,13 +9,13 @@ import kotlinx.cinterop.*
import kotlin.native.internal.Frozen import kotlin.native.internal.Frozen
/** /**
* Object Transfer Basics. * ## Object Transfer Basics.
* *
* Objects can be passed between threads in one of two possible modes. * Objects can be passed between threads in one of two possible modes.
* *
* - SAFE - object subgraph is checked to be not reachable by other globals or locals, and passed * - [SAFE] - object subgraph is checked to be not reachable by other globals or locals, and passed
* if so, otherwise an exception is thrown * if so, otherwise an exception is thrown
* - UNSAFE - object is blindly passed to another worker, if there are references * - [UNSAFE] - object is blindly passed to another worker, if there are references
* left in the passing worker - it may lead to crash or program malfunction * left in the passing worker - it may lead to crash or program malfunction
* *
* Safe mode checks if object is no longer used in passing worker, using memory-management * Safe mode checks if object is no longer used in passing worker, using memory-management
@@ -28,14 +28,26 @@ import kotlin.native.internal.Frozen
* ownership without further checks. * ownership without further checks.
* *
* Note, that for some cases cycle collection need to be done to ensure that dead cycles do not affect * Note, that for some cases cycle collection need to be done to ensure that dead cycles do not affect
* reachability of passed object graph. See `[kotlin.native.internal.GC.collect]`. * reachability of passed object graph.
* *
* @see [kotlin.native.internal.GC.collect].
*/ */
public enum class TransferMode(val value: Int) { public enum class TransferMode(val value: Int) {
/**
* Reachibility check is performed.
*/
SAFE(0), SAFE(0),
UNSAFE(1) // USE UNSAFE MODE ONLY IF ABSOLUTELY SURE WHAT YOU'RE DOING!!! /**
* Skip reachibility check, can lead to mysterious crashes in an application.
* USE UNSAFE MODE ONLY IF ABSOLUTELY SURE WHAT YOU'RE DOING!!!
*/
UNSAFE(1)
} }
/**
* Detached object graph encapsulates transferrable detached subgraph which cannot be accessed
* externally, until it is attached with the [attach] extension function.
*/
@Frozen @Frozen
public class DetachedObjectGraph<T> internal constructor(pointer: NativePtr) { public class DetachedObjectGraph<T> internal constructor(pointer: NativePtr) {
@PublishedApi @PublishedApi
@@ -55,14 +67,14 @@ public class DetachedObjectGraph<T> internal constructor(pointer: NativePtr) {
public constructor(pointer: COpaquePointer?) : this(pointer?.rawValue ?: NativePtr.NULL) public constructor(pointer: COpaquePointer?) : this(pointer?.rawValue ?: NativePtr.NULL)
/** /**
* Returns raw C pointer value. * Returns raw C pointer value, usable for interoperability with C scenarious.
*/ */
public fun asCPointer(): COpaquePointer? = interpretCPointer<COpaque>(stable.value) public fun asCPointer(): COpaquePointer? = interpretCPointer<COpaque>(stable.value)
} }
/** /**
* Attaches previously detached with [detachObjectGraph] object subgraph. * Attaches previously detached object subgraph created by [DetachedObjectGraph].
* Please note, that once object graph is attached, the stable pointer does not have sense anymore, * Please note, that once object graph is attached, the [DetachedObjectGraph.stable] pointer does not have sense anymore,
* and shall be discarded. * and shall be discarded.
*/ */
public inline fun <reified T> DetachedObjectGraph<T>.attach(): T { public inline fun <reified T> DetachedObjectGraph<T>.attach(): T {
@@ -11,12 +11,12 @@ import kotlin.native.internal.VolatileLambda
import kotlinx.cinterop.* import kotlinx.cinterop.*
/** /**
* Workers: theory of operations. * ## Workers: theory of operations.
* *
* Worker represent asynchronous and concurrent computation, usually performed by other threads * [Worker] represents asynchronous and concurrent computation, usually performed by other threads
* in the same process. Object passing between workers is performed using transfer operation, so that * in the same process. Object passing between workers is performed using transfer operation, so that
* object graph belongs to one worker at the time, but can be disconnected and reconnected as needed. * object graph belongs to one worker at the time, but can be disconnected and reconnected as needed.
* See 'Object Transfer Basics' below for more details on how objects shall be transferred. * See 'Object Transfer Basics' and [TransferMode] for more details on how objects shall be transferred.
* This approach ensures that no concurrent access happens to same object, while data may flow between * This approach ensures that no concurrent access happens to same object, while data may flow between
* workers as needed. * workers as needed.
*/ */
@@ -36,25 +36,29 @@ public class Worker private constructor(val id: Int) {
} }
/** /**
* Requests termination of the worker. `processScheduledJobs` controls is we shall wait * Requests termination of the worker.
* until all scheduled jobs processed, or terminate immediately. *
* @param processScheduledJobs controls is we shall wait until all scheduled jobs processed,
* or terminate immediately.
*/ */
public fun requestTermination(processScheduledJobs: Boolean = true) = public fun requestTermination(processScheduledJobs: Boolean = true) =
Future<Unit>(requestTerminationInternal(id, processScheduledJobs)) Future<Unit>(requestTerminationInternal(id, processScheduledJobs))
/** /**
* Plan job for further execution in the worker. Execute is a two-phase operation, * Plan job for further execution in the worker. Execute is a two-phase operation:
* first `producer` function is executed, and resulting object and whatever it refers to * - first [producer] function is executed, and resulting object and whatever it refers to
* is analyzed for being an isolated object subgraph, if in checked mode. * is analyzed for being an isolated object subgraph, if in checked mode.
* Afterwards, this disconnected object graph and `job` function pointer is being added to jobs queue * - Afterwards, this disconnected object graph and [job] function pointer is being added to jobs queue
* of the selected worker. Note that `job` must not capture any state itself, so that whole state is * of the selected worker. Note that [job] must not capture any state itself, so that whole state is
* explicitly stored in object produced by `producer`. Scheduled job is being executed by the worker, * explicitly stored in object produced by [producer]. Scheduled job is being executed by the worker,
* and result of such a execution is being disconnected from worker's object graph. Whoever will consume * and result of such a execution is being disconnected from worker's object graph. Whoever will consume
* the future, can use result of worker's computations. * the future, can use result of worker's computations.
*
* @return the future with the computation result of [job]
*/ */
@Suppress("UNUSED_PARAMETER") @Suppress("UNUSED_PARAMETER")
public fun <T1, T2> execute(mode: TransferMode, producer: () -> T1, @VolatileLambda job: (T1) -> T2): Future<T2> = public fun <T1, T2> execute(mode: TransferMode, producer: () -> T1, @VolatileLambda job: (T1) -> T2): Future<T2> =
/** /*
* This function is a magical operation, handled by lowering in the compiler, and replaced with call to * This function is a magical operation, handled by lowering in the compiler, and replaced with call to
* executeImpl(worker, mode, producer, job) * executeImpl(worker, mode, producer, job)
* but first ensuring that `job` parameter doesn't capture any state. * but first ensuring that `job` parameter doesn't capture any state.
@@ -26,17 +26,10 @@ import kotlin.comparisons.*
* represents and multiplying by 10 raised to the power of the * represents and multiplying by 10 raised to the power of the
* exponent. Returns the closest double value to the real number. * exponent. Returns the closest double value to the real number.
* @param s * @param s the String that will be parsed to a floating point
* * the String that will be parsed to a floating point * @param e an int represent the 10 to part
* *
* @param e
* * an int represent the 10 to part
* *
* @return the double closest to the real number * @return the double closest to the real number
* * * @exception NumberFormatException if the String doesn't represent a positive integer value
* *
* @exception NumberFormatException
* * if the String doesn't represent a positive integer value
*/ */
@SymbolName("Kotlin_native_FloatingPointParser_parseDoubleImpl") @SymbolName("Kotlin_native_FloatingPointParser_parseDoubleImpl")
private external fun parseDoubleImpl(s: String, e: Int): Double private external fun parseDoubleImpl(s: String, e: Int): Double
@@ -48,17 +41,10 @@ private external fun parseDoubleImpl(s: String, e: Int): Double
* represents and multiplying by 10 raised to the power of the * represents and multiplying by 10 raised to the power of the
* exponent. Returns the closest float value to the real number. * exponent. Returns the closest float value to the real number.
* @param s * @param s the String that will be parsed to a floating point
* * the String that will be parsed to a floating point * @param e an int represent the 10 to part
* *
* @param e
* * an int represent the 10 to part
* *
* @return the float closest to the real number * @return the float closest to the real number
* * * @exception NumberFormatException if the String doesn't represent a positive integer value
* *
* @exception NumberFormatException
* * if the String doesn't represent a positive integer value
*/ */
@SymbolName("Kotlin_native_FloatingPointParser_parseFloatImpl") @SymbolName("Kotlin_native_FloatingPointParser_parseFloatImpl")
private external fun parseFloatImpl(s: String, e: Int): Float private external fun parseFloatImpl(s: String, e: Int): Float
@@ -89,14 +75,9 @@ object FloatingPointParser {
* taking the positive integer the String represents and multiplying by 10 * taking the positive integer the String represents and multiplying by 10
* raised to the power of the exponent. * raised to the power of the exponent.
* @param string * @param string the String that will be parsed to a floating point
* * the String that will be parsed to a floating point
* *
* @return a StringExponentPair with necessary values * @return a StringExponentPair with necessary values
* * * @exception NumberFormatException if the String doesn't pass basic tests
* *
* @exception NumberFormatException
* * if the String doesn't pass basic tests
*/ */
private fun initialParse(string: String): StringExponentPair { private fun initialParse(string: String): StringExponentPair {
var s = string var s = string
@@ -306,15 +287,10 @@ object FloatingPointParser {
/** /**
* Returns the closest double value to the real number in the string. * Returns the closest double value to the real number in the string.
*
* @param string * @param string the String that will be parsed to a floating point
* * the String that will be parsed to a floating point
* *
* @return the double closest to the real number * @return the double closest to the real number
* * * @exception NumberFormatException if the String doesn't represent a double
* *
* @exception NumberFormatException
* * if the String doesn't represent a double
*/ */
fun parseDouble(string: String): Double { fun parseDouble(string: String): Double {
var s = string var s = string
@@ -358,15 +334,10 @@ object FloatingPointParser {
/** /**
* Returns the closest float value to the real number in the string. * Returns the closest float value to the real number in the string.
*
* @param s * @param s the String that will be parsed to a floating point
* * the String that will be parsed to a floating point
* *
* @return the float closest to the real number * @return the float closest to the real number
* * * @exception NumberFormatException if the String doesn't represent a float
* *
* @exception NumberFormatException
* * if the String doesn't represent a float
*/ */
fun parseFloat(string: String): Float { fun parseFloat(string: String): Float {
var s = string var s = string
@@ -5,46 +5,60 @@
package kotlin.native.internal package kotlin.native.internal
// Cycle garbage collector interface. /**
// * ## Cycle garbage collector interface.
// Konan relies upon reference counting for object management, however it could *
// not collect cyclical garbage, so we perform periodic garbage collection. * Konan relies upon reference counting for object management, however it could
// This may slow down application, so this interface provides control over how * not collect cyclical garbage, so we perform periodic garbage collection.
// garbage collector activates and runs. * This may slow down application, so this interface provides control over how
// Garbage collector can be in one of the following states: * garbage collector activates and runs.
// * running * Garbage collector can be in one of the following states:
// * suspended (so cycle candidates are collected, but GC is not performed until resume) * - running
// * stopped (all cyclical garbage is hopelessly lost) * - suspended (so cycle candidates are collected, but GC is not performed until resume)
// Immediately after startup GC is in running state. * - stopped (all cyclical garbage is hopelessly lost)
// Depending on application needs it may select to suspend GC for certain phases of * Immediately after startup GC is in running state.
// its lifetime, and resume it later on, or just completely turn it off, if GC pauses * Depending on application needs it may select to suspend GC for certain phases of
// are less desirable than cyclical garbage leaks. * its lifetime, and resume it later on, or just completely turn it off, if GC pauses
* are less desirable than cyclical garbage leaks.
*/
object GC { object GC {
// To force garbage collection immediately, unless collector is stopped /**
// with stop() operation. Even if GC is suspended, collect() still triggers collection. * To force garbage collection immediately, unless collector is stopped
* with [stop] operation. Even if GC is suspended, [collect] still triggers collection.
*/
@SymbolName("Kotlin_native_internal_GC_collect") @SymbolName("Kotlin_native_internal_GC_collect")
external fun collect() external fun collect()
// Suspend garbage collection. Release candidates are still collected, but /**
// GC algorithm is not executed. * Suspend garbage collection. Release candidates are still collected, but
* GC algorithm is not executed.
*/
@SymbolName("Kotlin_native_internal_GC_suspend") @SymbolName("Kotlin_native_internal_GC_suspend")
external fun suspend() external fun suspend()
// Resume garbage collection. Can potentially lead to GC immediately. /**
* Resume garbage collection. Can potentially lead to GC immediately.
*/
@SymbolName("Kotlin_native_internal_GC_resume") @SymbolName("Kotlin_native_internal_GC_resume")
external fun resume() external fun resume()
// Stop garbage collection. Cyclical garbage is no longer collected. /**
* Stop garbage collection. Cyclical garbage is no longer collected.
*/
@SymbolName("Kotlin_native_internal_GC_stop") @SymbolName("Kotlin_native_internal_GC_stop")
external fun stop() external fun stop()
// Start garbage collection. Cyclical garbage produced while GC was stopped /**
// cannot be reclaimed, but all new garbage is collected. * Start garbage collection. Cyclical garbage produced while GC was stopped
* cannot be reclaimed, but all new garbage is collected.
*/
@SymbolName("Kotlin_native_internal_GC_start") @SymbolName("Kotlin_native_internal_GC_start")
external fun start() external fun start()
// GC threshold, controlling how frequenly GC is activated, and how much time GC /**
// takes. Bigger values lead to longer GC pauses, but less GCs. * GC threshold, controlling how frequenly GC is activated, and how much time GC
* takes. Bigger values lead to longer GC pauses, but less GCs.
*/
var threshold: Int var threshold: Int
get() = getThreshold() get() = getThreshold()
set(value) = setThreshold(value) set(value) = setThreshold(value)
@@ -24,6 +24,9 @@ private external fun bigIntDigitGeneratorInstImpl(results: IntArray, uArray: Int
@SymbolName("Kotlin_native_NumberConverter_ceil") @SymbolName("Kotlin_native_NumberConverter_ceil")
private external fun ceil(x: Double): Double private external fun ceil(x: Double): Double
/**
* Converts [Float] or [Double] numbers to the [String] representation
*/
class NumberConverter { class NumberConverter {
private var setCount: Int = 0 // Number of times u and k have been gotten. private var setCount: Int = 0 // Number of times u and k have been gotten.
@@ -7,10 +7,11 @@ package kotlin.system
/** /**
* Terminates the currently running process. * Terminates the currently running process.
* The argument serves as a status code; by convention, *
* @param status serves as a status code; by convention,
* a nonzero status code indicates abnormal termination. * a nonzero status code indicates abnormal termination.
* *
* This method never returns normally. * @return This method never returns normally.
*/ */
@SymbolName("Kotlin_system_exitProcess") @SymbolName("Kotlin_system_exitProcess")
public external fun exitProcess(status: Int): Nothing public external fun exitProcess(status: Int): Nothing
@@ -5,30 +5,39 @@
package kotlin.system package kotlin.system
/**
* Gets current system time in milliseconds since epoch
*/
@SymbolName("Kotlin_system_getTimeMillis") @SymbolName("Kotlin_system_getTimeMillis")
public external fun getTimeMillis() : Long public external fun getTimeMillis() : Long
/**
* Gets current system time in nanoseconds since epoch
*/
@SymbolName("Kotlin_system_getTimeNanos") @SymbolName("Kotlin_system_getTimeNanos")
public external fun getTimeNanos() : Long public external fun getTimeNanos() : Long
/**
* Gets current system time in microseconds since epoch
*/
@SymbolName("Kotlin_system_getTimeMicros") @SymbolName("Kotlin_system_getTimeMicros")
public external fun getTimeMicros() : Long public external fun getTimeMicros() : Long
/** Executes the given block and returns elapsed time in milliseconds. */ /** Executes the given [block] and returns elapsed time in milliseconds. */
public inline fun measureTimeMillis(block: () -> Unit) : Long { public inline fun measureTimeMillis(block: () -> Unit) : Long {
val start = getTimeMillis() val start = getTimeMillis()
block() block()
return getTimeMillis() - start return getTimeMillis() - start
} }
/** Executes the given block and returns elapsed time in microseconds (Kotlin/Native only). */ /** Executes the given [block] and returns elapsed time in microseconds (Kotlin/Native only). */
public inline fun measureTimeMicros(block: () -> Unit) : Long { public inline fun measureTimeMicros(block: () -> Unit) : Long {
val start = getTimeMicros() val start = getTimeMicros()
block() block()
return getTimeMicros() - start return getTimeMicros() - start
} }
/** Executes the given block and returns elapsed time in nanoseconds. */ /** Executes the given [block] and returns elapsed time in nanoseconds. */
public inline fun measureNanoTime(block: () -> Unit) : Long { public inline fun measureNanoTime(block: () -> Unit) : Long {
val start = getTimeNanos() val start = getTimeNanos()
block() block()