[JS IR BE] Arrays, varargs

This commit is contained in:
Anton Bannykh
2018-09-12 14:31:22 +03:00
parent e24f68c357
commit 2e709a81fa
470 changed files with 761 additions and 585 deletions
+95
View File
@@ -0,0 +1,95 @@
/*
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
* that can be found in the license/LICENSE.txt file.
*/
package kotlin.js
import withType
external fun <T> Array(size: Int): Array<T>
internal fun <T> fillArrayVal(array: Array<T>, initValue: T): Array<T> {
for (i in 0..array.size - 1) {
array[i] = initValue
}
return array
}
internal inline fun <T> arrayWithFun(size: Int, init: (Int) -> T) = fillArrayFun(Array<T>(size), init)
internal inline fun <T> fillArrayFun(array: dynamic, init: (Int) -> T): Array<T> {
val result = array.unsafeCast<Array<T>>()
var i = 0
while (i != result.size) {
result[i] = init(i)
++i
}
return result
}
internal fun booleanArray(size: Int): BooleanArray = withType("BooleanArray", fillArrayVal(Array<Boolean>(size), false)).unsafeCast<BooleanArray>()
internal fun booleanArrayOf(arr: Array<Boolean>): BooleanArray = withType("BooleanArray", arr.asDynamic().slice()).unsafeCast<BooleanArray>()
internal fun charArray(size: Int): CharArray = withType("CharArray", fillArrayVal(Array<Char>(size), '\u0000')).unsafeCast<CharArray>()
internal fun charArrayOf(arr: Array<Char>): CharArray = withType("CharArray", arr.asDynamic().slice()).unsafeCast<CharArray>()
internal fun longArray(size: Int): LongArray = withType("LongArray", fillArrayVal(Array<Long>(size), 0L)).unsafeCast<LongArray>()
internal fun longArrayOf(arr: Array<Long>): LongArray = withType("LongArray", arr.asDynamic().slice()).unsafeCast<LongArray>()
internal fun <T> arrayIterator(array: Array<T>) = object : Iterator<T> {
var index = 0
override fun hasNext() = index != array.size
override fun next() = if (index != array.size) array[index++] else throw NoSuchElementException("$index")
}
internal fun booleanArrayIterator(array: BooleanArray) = object : BooleanIterator() {
var index = 0
override fun hasNext() = index != array.size
override fun nextBoolean() = if (index != array.size) array[index++] else throw NoSuchElementException("$index")
}
internal fun byteArrayIterator(array: ByteArray) = object : ByteIterator() {
var index = 0
override fun hasNext() = index != array.size
override fun nextByte() = if (index != array.size) array[index++] else throw NoSuchElementException("$index")
}
internal fun shortArrayIterator(array: ShortArray) = object : ShortIterator() {
var index = 0
override fun hasNext() = index != array.size
override fun nextShort() = if (index != array.size) array[index++] else throw NoSuchElementException("$index")
}
internal fun charArrayIterator(array: CharArray) = object : CharIterator() {
var index = 0
override fun hasNext() = index != array.size
override fun nextChar() = if (index != array.size) array[index++] else throw NoSuchElementException("$index")
}
internal fun intArrayIterator(array: IntArray) = object : IntIterator() {
var index = 0
override fun hasNext() = index != array.size
override fun nextInt() = if (index != array.size) array[index++] else throw NoSuchElementException("$index")
}
internal fun floatArrayIterator(array: FloatArray) = object : FloatIterator() {
var index = 0
override fun hasNext() = index != array.size
override fun nextFloat() = if (index != array.size) array[index++] else throw NoSuchElementException("$index")
}
internal fun doubleArrayIterator(array: DoubleArray) = object : DoubleIterator() {
var index = 0
override fun hasNext() = index != array.size
override fun nextDouble() = if (index != array.size) array[index++] else throw NoSuchElementException("$index")
}
internal fun longArrayIterator(array: LongArray) = object : LongIterator() {
var index = 0
override fun hasNext() = index != array.size
override fun nextLong() = if (index != array.size) array[index++] else throw NoSuchElementException("$index")
}
+21 -1
View File
@@ -5,6 +5,8 @@
package kotlin
import kotlin.js.*
// TODO: Ignore FunctionN interfaces
public interface Function0<out R> : Function<R> {
@@ -23,4 +25,22 @@ public interface Function3<in P1, in P2, in P3, out R> : Function<R> {
public operator fun invoke(p1: P1, p2: P2, p3: P3): R
}
public inline fun <reified T> arrayOfNulls(size: Int): Array<T?> = js("[]") // FIXME: Implement
public inline fun <reified T> arrayOfNulls(size: Int): Array<T?> = Array<T?>(size)
public inline fun <T> arrayOf(vararg a: T): Array<T> = a.unsafeCast<Array<T>>()
public inline fun booleanArrayOf(vararg a: Boolean) = a
public inline fun byteArrayOf(vararg a: Byte) = a
public inline fun shortArrayOf(vararg a: Short) = a
public inline fun charArrayOf(vararg a: Char) = a
public inline fun intArrayOf(vararg a: Int) = a
public inline fun floatArrayOf(vararg a: Float) = a
public inline fun doubleArrayOf(vararg a: Double) = a
public inline fun longArrayOf(vararg a: Long) = a
+12 -38
View File
@@ -17,33 +17,6 @@ package kotlin
*/
public inline fun <T> emptyArray(): Array<T> = js("[]")
@library
public fun <T> arrayOf(vararg elements: T): Array<T> = definedExternally
@library
public fun doubleArrayOf(vararg elements: Double): DoubleArray = definedExternally
@library
public fun floatArrayOf(vararg elements: Float): FloatArray = definedExternally
@library
public fun longArrayOf(vararg elements: Long): LongArray = definedExternally
@library
public fun intArrayOf(vararg elements: Int): IntArray = definedExternally
@library
public fun charArrayOf(vararg elements: Char): CharArray = definedExternally
@library
public fun shortArrayOf(vararg elements: Short): ShortArray = definedExternally
@library
public fun byteArrayOf(vararg elements: Byte): ByteArray = definedExternally
@library
public fun booleanArrayOf(vararg elements: Boolean): BooleanArray = definedExternally
/**
* Creates a new instance of the [Lazy] that uses the specified initialization function [initializer].
*/
@@ -67,35 +40,36 @@ internal fun fillFrom(src: dynamic, dst: dynamic): dynamic {
val srcLen: Int = src.length
val dstLen: Int = dst.length
var index: Int = 0
while (index < srcLen && index < dstLen) dst[index] = src[index++]
val arr = dst.unsafeCast<Array<Any?>>()
while (index < srcLen && index < dstLen) arr[index] = src[index++]
return dst
}
internal fun arrayCopyResize(source: dynamic, newSize: Int, defaultValue: Any?): dynamic {
val result = source.slice(0, newSize)
val result = source.slice(0, newSize).unsafeCast<Array<Any?>>()
copyArrayType(source, result)
var index: Int = source.length
if (newSize > index) {
result.length = newSize
result.asDynamic().length = newSize
while (index < newSize) result[index++] = defaultValue
}
return result
}
internal fun <T> arrayPlusCollection(array: dynamic, collection: Collection<T>): dynamic {
return TODO()
// val result = array.slice()
// result.length += collection.size
// copyArrayType(array, result)
// var index: Int = array.length
// for (element in collection) result[index++] = element
// return result
val result = array.slice().unsafeCast<Array<T>>()
result.asDynamic().length = result.size + collection.size
copyArrayType(array, result)
var index: Int = array.length
for (element in collection) result[index++] = element
return result
}
internal fun <T> fillFromCollection(dst: dynamic, startIndex: Int, collection: Collection<T>): dynamic {
var index = startIndex
for (element in collection) dst[index++] = element
val arr = dst.unsafeCast<Array<T>>()
for (element in collection) arr[index++] = element
return dst
}
@@ -0,0 +1,54 @@
/*
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
* that can be found in the license/LICENSE.txt file.
*/
import kotlin.js.*
/** Concat regular Array's and TypedArray's into an Array.
*/
@PublishedApi
internal fun <T> arrayConcat(vararg args: T): T {
val len = args.size
val typed = js("Array(len)").unsafeCast<Array<T>>()
for (i in 0 until len) {
val arr = args[i]
if (arr !is Array<*>) {
typed[i] = js("[]").slice.call(arr)
} else {
typed[i] = arr
}
}
return js("[]").concat.apply(js("[]"), typed);
}
/** Concat primitive arrays. Main use: prepare vararg arguments.
*/
@PublishedApi
internal fun <T> primitiveArrayConcat(vararg args: T): T {
var size = 0
for (i in 0 until args.size) {
size += args[i].unsafeCast<Array<Any?>>().size
}
val a = args[0]
val result = js("new a.constructor(size)").unsafeCast<Array<Any?>>()
if (a.asDynamic().`$type$` != null) {
withType(a.asDynamic().`$type$`, result)
}
size = 0
for (i in 0 until args.size) {
val arr = args[i].unsafeCast<Array<Any?>>()
for (j in 0 until arr.size) {
result[size++] = arr[j]
}
}
return result.unsafeCast<T>()
}
@PublishedApi
internal inline fun withType(type: String, array: dynamic): dynamic {
array.`$type$` = type
return array
}
@@ -72,7 +72,9 @@ public fun isInterface(ctor: dynamic, IType: dynamic): Boolean {
}
*/
fun typeOf(obj: dynamic) = js("typeof obj").unsafeCast<String>()
fun typeOf(obj: dynamic): String = js("typeof obj").unsafeCast<String>()
fun jsTypeOf(a: Any?): String = js("typeof a").unsafeCast<String>()
fun instanceOf(obj: dynamic, jsClass: dynamic) = js("obj instanceof jsClass").unsafeCast<Boolean>()
@@ -101,14 +103,14 @@ public fun isChar(c: Any): Boolean {
}
// TODO: Distinguish Boolean/Byte and Short/Char
public fun isBooleanArray(a: dynamic) = js("a instanceof Int8Array")
public fun isByteArray(a: dynamic) = js("a instanceof Int8Array")
public fun isShortArray(a: dynamic) = js("a instanceof Int16Array")
public fun isCharArray(a: dynamic) = js("a instanceof Uint16Array")
public fun isIntArray(a: dynamic) = js("a instanceof Int32Array")
public fun isFloatArray(a: dynamic) = js("a instanceof Float32Array")
public fun isDoubleArray(a: dynamic) = js("a instanceof Float64Array")
public fun isLongArray(a: dynamic) = isArray(a) // TODO: Implement
public fun isBooleanArray(a: dynamic): Boolean = isArray(a) && a.asDynamic().`$type$` == "BooleanArray"
public fun isByteArray(a: dynamic): Boolean = js("a instanceof Int8Array").unsafeCast<Boolean>()
public fun isShortArray(a: dynamic): Boolean = js("a instanceof Int16Array").unsafeCast<Boolean>()
public fun isCharArray(a: dynamic): Boolean = isArray(a) && a.asDynamic().`$type$` == "CharArray"
public fun isIntArray(a: dynamic): Boolean = js("a instanceof Int32Array").unsafeCast<Boolean>()
public fun isFloatArray(a: dynamic): Boolean = js("a instanceof Float32Array").unsafeCast<Boolean>()
public fun isDoubleArray(a: dynamic): Boolean = js("a instanceof Float64Array").unsafeCast<Boolean>()
public fun isLongArray(a: dynamic): Boolean = isArray(a) && a.asDynamic().`$type$` == "LongArray"
internal fun jsIn(x: String, y: dynamic): Boolean = js("x in y")
@@ -21,8 +21,9 @@ internal interface InternalMap<K, V> : MutableIterable<MutableMap.MutableEntry<K
fun createJsMap(): dynamic {
val result = js("Object.create(null)")
// force to switch object representation to dictionary mode
result["foo"] = 1;
deleteProperty(result, "foo")
// Using js-function due to JS_IR limitations
js("result[\"foo\"] = 1")
js("delete result[\"foo\"]")
return result
}
}