Typed arrays API (#1398)

This commit is contained in:
Nikolay Igotti
2018-03-15 10:02:35 +03:00
committed by GitHub
parent dba7041965
commit 204fde4bf1
5 changed files with 252 additions and 0 deletions
+14
View File
@@ -1257,6 +1257,20 @@ task array3(type: RunKonanTest) {
source = "runtime/collections/array3.kt"
}
task typed_array0(type: RunKonanTest) {
// MIPS target is big-endian.
disabled = (project.testTarget == 'linux_mips32')
goldValue = "OK\n"
source = "runtime/collections/typed_array0.kt"
}
task typed_array1(type: RunKonanTest) {
disabled = (project.testTarget == 'wasm32') // No exceptions on WASM.
goldValue = "OK\n"
source = "runtime/collections/typed_array1.kt"
}
task sort0(type: RunKonanTest) {
goldValue = "[a, b, x]\n[-1, 0, 42, 239, 100500]\n"
source = "runtime/collections/sort0.kt"
@@ -0,0 +1,14 @@
package runtime.collections.typed_array0
import kotlin.test.*
@Test fun runTest() {
// Those tests assume little endian bit ordering.
val array = ByteArray(42)
array.setLongAt(5, 0x1234_5678_9abc_def0)
expect(0xdef0.toInt()) { array.charAt(5).toInt() }
expect(0x9abc.toShort()) { array.shortAt(7) }
expect(0x1234_5678) { array.intAt(9) }
println("OK")
}
@@ -0,0 +1,74 @@
package runtime.collections.typed_array1
import kotlin.test.*
@Test fun runTest() {
val array = ByteArray(17)
val results = mutableSetOf<Any>()
var counter = 0
try {
results += array.shortAt(16)
} catch (e: ArrayIndexOutOfBoundsException) {
counter++
}
try {
results += array.charAt(22)
} catch (e: ArrayIndexOutOfBoundsException) {
counter++
}
try {
results += array.intAt(15)
} catch (e: ArrayIndexOutOfBoundsException) {
counter++
}
try {
results += array.longAt(14)
} catch (e: ArrayIndexOutOfBoundsException) {
counter++
}
try {
results += array.floatAt(14)
} catch (e: ArrayIndexOutOfBoundsException) {
counter++
}
try {
results += array.doubleAt(13)
} catch (e: ArrayIndexOutOfBoundsException) {
counter++
}
try {
array.setShortAt(16, 2.toShort())
} catch (e: ArrayIndexOutOfBoundsException) {
counter++
}
try {
array.setCharAt(22, 'a')
} catch (e: ArrayIndexOutOfBoundsException) {
counter++
}
try {
array.setIntAt(15, 1234)
} catch (e: ArrayIndexOutOfBoundsException) {
counter++
}
try {
array.setLongAt(14, 1.toLong())
} catch (e: ArrayIndexOutOfBoundsException) {
counter++
}
try {
array.setFloatAt(14, 1.0f)
} catch (e: ArrayIndexOutOfBoundsException) {
counter++
}
try {
array.setDoubleAt(13, 3.0)
} catch (e: ArrayIndexOutOfBoundsException) {
counter++
}
expect(12) { counter }
expect(0) { results.size }
println("OK")
}
+96
View File
@@ -131,6 +131,102 @@ KInt Kotlin_ByteArray_getArrayLength(KConstRef thiz) {
return array->count_;
}
KChar Kotlin_ByteArray_getCharAt(KConstRef thiz, KInt index) {
const ArrayHeader* array = thiz->array();
if (static_cast<uint32_t>(index + 1) >= array->count_) {
ThrowArrayIndexOutOfBoundsException();
}
return *reinterpret_cast<const KChar*>(ByteArrayAddressOfElementAt(array, index));
}
KShort Kotlin_ByteArray_getShortAt(KConstRef thiz, KInt index) {
const ArrayHeader* array = thiz->array();
if (static_cast<uint32_t>(index + 1) >= array->count_) {
ThrowArrayIndexOutOfBoundsException();
}
return *reinterpret_cast<const KShort*>(ByteArrayAddressOfElementAt(array, index));
}
KInt Kotlin_ByteArray_getIntAt(KConstRef thiz, KInt index) {
const ArrayHeader* array = thiz->array();
if (static_cast<uint32_t>(index + 3) >= array->count_) {
ThrowArrayIndexOutOfBoundsException();
}
return *reinterpret_cast<const KInt*>(ByteArrayAddressOfElementAt(array, index));
}
KLong Kotlin_ByteArray_getLongAt(KConstRef thiz, KInt index) {
const ArrayHeader* array = thiz->array();
if (static_cast<uint32_t>(index + 7) >= array->count_) {
ThrowArrayIndexOutOfBoundsException();
}
return *reinterpret_cast<const KLong*>(ByteArrayAddressOfElementAt(array, index));
}
KFloat Kotlin_ByteArray_getFloatAt(KConstRef thiz, KInt index) {
const ArrayHeader* array = thiz->array();
if (static_cast<uint32_t>(index + 3) >= array->count_) {
ThrowArrayIndexOutOfBoundsException();
}
return *reinterpret_cast<const KFloat*>(ByteArrayAddressOfElementAt(array, index));
}
KDouble Kotlin_ByteArray_getDoubleAt(KConstRef thiz, KInt index) {
const ArrayHeader* array = thiz->array();
if (static_cast<uint32_t>(index + 7) >= array->count_) {
ThrowArrayIndexOutOfBoundsException();
}
return *reinterpret_cast<const KDouble*>(ByteArrayAddressOfElementAt(array, index));
}
void Kotlin_ByteArray_setCharAt(KRef thiz, KInt index, KChar value) {
ArrayHeader* array = thiz->array();
if (static_cast<uint32_t>(index + 1) >= array->count_) {
ThrowArrayIndexOutOfBoundsException();
}
*reinterpret_cast<KChar*>(ByteArrayAddressOfElementAt(array, index)) = value;
}
void Kotlin_ByteArray_setShortAt(KRef thiz, KInt index, KShort value) {
ArrayHeader* array = thiz->array();
if (static_cast<uint32_t>(index + 1) >= array->count_) {
ThrowArrayIndexOutOfBoundsException();
}
*reinterpret_cast<KShort*>(ByteArrayAddressOfElementAt(array, index)) = value;
}
void Kotlin_ByteArray_setIntAt(KRef thiz, KInt index, KInt value) {
ArrayHeader* array = thiz->array();
if (static_cast<uint32_t>(index + 3) >= array->count_) {
ThrowArrayIndexOutOfBoundsException();
}
*reinterpret_cast<KInt*>(ByteArrayAddressOfElementAt(array, index)) = value;
}
void Kotlin_ByteArray_setLongAt(KRef thiz, KInt index, KLong value) {
ArrayHeader* array = thiz->array();
if (static_cast<uint32_t>(index + 7) >= array->count_) {
ThrowArrayIndexOutOfBoundsException();
}
*reinterpret_cast<KLong*>(ByteArrayAddressOfElementAt(array, index)) = value;
}
void Kotlin_ByteArray_setFloatAt(KRef thiz, KInt index, KFloat value) {
ArrayHeader* array = thiz->array();
if (static_cast<uint32_t>(index + 3) >= array->count_) {
ThrowArrayIndexOutOfBoundsException();
}
*reinterpret_cast<KFloat*>(ByteArrayAddressOfElementAt(array, index)) = value;
}
void Kotlin_ByteArray_setDoubleAt(KRef thiz, KInt index, KDouble value) {
ArrayHeader* array = thiz->array();
if (static_cast<uint32_t>(index + 7) >= array->count_) {
ThrowArrayIndexOutOfBoundsException();
}
*reinterpret_cast<KDouble*>(ByteArrayAddressOfElementAt(array, index)) = value;
}
KChar Kotlin_CharArray_get(KConstRef thiz, KInt index) {
const ArrayHeader* array = thiz->array();
if (static_cast<uint32_t>(index) >= array->count_) {
@@ -0,0 +1,54 @@
/*
* Copyright 2010-2018 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package konan
import konan.SymbolName
@SymbolName("Kotlin_ByteArray_getCharAt")
external fun ByteArray.charAt(index: Int): Char
@SymbolName("Kotlin_ByteArray_getShortAt")
external fun ByteArray.shortAt(index: Int): Short
@SymbolName("Kotlin_ByteArray_getIntAt")
external fun ByteArray.intAt(index: Int): Int
@SymbolName("Kotlin_ByteArray_getLongAt")
external fun ByteArray.longAt(index: Int): Long
@SymbolName("Kotlin_ByteArray_getFloatAt")
external fun ByteArray.floatAt(index: Int): Float
@SymbolName("Kotlin_ByteArray_getDoubleAt")
external fun ByteArray.doubleAt(index: Int): Double
@SymbolName("Kotlin_ByteArray_setCharAt")
external fun ByteArray.setCharAt(index: Int, value: Char)
@SymbolName("Kotlin_ByteArray_setShortAt")
external fun ByteArray.setShortAt(index: Int, value: Short)
@SymbolName("Kotlin_ByteArray_setIntAt")
external fun ByteArray.setIntAt(index: Int, value: Int)
@SymbolName("Kotlin_ByteArray_setLongAt")
external fun ByteArray.setLongAt(index: Int, value: Long)
@SymbolName("Kotlin_ByteArray_setFloatAt")
external fun ByteArray.setFloatAt(index: Int, value: Float)
@SymbolName("Kotlin_ByteArray_setDoubleAt")
external fun ByteArray.setDoubleAt(index: Int, value: Double)