| /* |
| * Copyright 2010-2017 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. |
| */ |
| |
| #include <stdio.h> |
| #include <string.h> |
| |
| #include "KAssert.h" |
| #include "Exceptions.h" |
| #include "Memory.h" |
| #include "Natives.h" |
| #include "Types.h" |
| |
| extern "C" void checkRangeIndexes(KInt from, KInt to, KInt size); |
| |
| namespace { |
| |
| PERFORMANCE_INLINE inline void boundsCheck(const ArrayHeader* array, KInt index) { |
| // We couldn't have created an array bigger than max KInt value. |
| // So if index is < 0, conversion to an unsigned value would make it bigger |
| // than the array size. |
| if (static_cast<uint32_t>(index) >= array->count_) { |
| ThrowArrayIndexOutOfBoundsException(); |
| } |
| } |
| |
| template<typename T> |
| inline void fillImpl(KRef thiz, KInt fromIndex, KInt toIndex, T value) { |
| ArrayHeader* array = thiz->array(); |
| checkRangeIndexes(fromIndex, toIndex, array->count_); |
| T* address = PrimitiveArrayAddressOfElementAt<T>(array, fromIndex); |
| for (KInt index = fromIndex; index < toIndex; ++index) { |
| *address++ = value; |
| } |
| } |
| |
| template<typename T> |
| inline void copyImpl(KConstRef thiz, KInt fromIndex, |
| KRef destination, KInt toIndex, KInt count) { |
| const ArrayHeader* array = thiz->array(); |
| ArrayHeader* destinationArray = destination->array(); |
| if (count < 0 || |
| fromIndex < 0 || static_cast<uint32_t>(count) + fromIndex > array->count_ || |
| toIndex < 0 || static_cast<uint32_t>(count) + toIndex > destinationArray->count_) { |
| ThrowArrayIndexOutOfBoundsException(); |
| } |
| memmove(PrimitiveArrayAddressOfElementAt<T>(destinationArray, toIndex), |
| PrimitiveArrayAddressOfElementAt<T>(array, fromIndex), |
| count * sizeof(T)); |
| } |
| |
| |
| template <class T, bool BoundsCheck = true> |
| inline void PrimitiveArraySet(KRef thiz, KInt index, T value) { |
| ArrayHeader* array = thiz->array(); |
| if (BoundsCheck) |
| boundsCheck(array, index); |
| *PrimitiveArrayAddressOfElementAt<T>(array, index) = value; |
| } |
| |
| template <class T, bool BoundsCheck = true> |
| inline T PrimitiveArrayGet(KConstRef thiz, KInt index) { |
| const ArrayHeader* array = thiz->array(); |
| if (BoundsCheck) |
| boundsCheck(array, index); |
| return *PrimitiveArrayAddressOfElementAt<T>(array, index); |
| } |
| |
| template<bool BoundsCheck = true> |
| PERFORMANCE_INLINE const KRef* Kotlin_Array_get_value(KConstRef thiz, KInt index) { |
| const ArrayHeader* array = thiz->array(); |
| if (BoundsCheck) |
| boundsCheck(array, index); |
| return ArrayAddressOfElementAt(array, index); |
| } |
| |
| template<bool BoundsCheck = true> |
| PERFORMANCE_INLINE void Kotlin_Array_set_value(KRef thiz, KInt index, KConstRef value) { |
| ArrayHeader* array = thiz->array(); |
| if (BoundsCheck) |
| boundsCheck(array, index); |
| UpdateHeapRef(ArrayAddressOfElementAt(array, index), value); |
| } |
| |
| template<bool BoundsCheck = true> |
| PERFORMANCE_INLINE KByte Kotlin_ByteArray_get_value(KConstRef thiz, KInt index) { |
| const ArrayHeader* array = thiz->array(); |
| if (BoundsCheck) |
| boundsCheck(array, index); |
| return *ByteArrayAddressOfElementAt(array, index); |
| } |
| |
| template<bool BoundsCheck = true> |
| PERFORMANCE_INLINE void Kotlin_ByteArray_set_value(KRef thiz, KInt index, KByte value) { |
| ArrayHeader* array = thiz->array(); |
| if (BoundsCheck) |
| boundsCheck(array, index); |
| *ByteArrayAddressOfElementAt(array, index) = value; |
| } |
| |
| } // namespace |
| |
| extern "C" { |
| |
| // Generated as part of Kotlin standard library. |
| extern const ObjHeader theEmptyArray; |
| |
| // TODO: those must be compiler intrinsics afterwards. |
| |
| // Array.kt |
| OBJ_GETTER(Kotlin_Array_get, KConstRef thiz, KInt index) { |
| RETURN_OBJ(*Kotlin_Array_get_value(thiz, index)); |
| } |
| |
| OBJ_GETTER(Kotlin_Array_get_without_BoundCheck, KConstRef thiz, KInt index){ |
| RETURN_OBJ(*Kotlin_Array_get_value<false>(thiz, index)); |
| } |
| |
| void Kotlin_Array_set(KRef thiz, KInt index, KConstRef value) { |
| Kotlin_Array_set_value(thiz, index, value); |
| } |
| |
| void Kotlin_Array_set_without_BoundCheck(KRef thiz, KInt index, KConstRef value) { |
| Kotlin_Array_set_value<false>(thiz, index, value); |
| } |
| |
| KInt Kotlin_Array_getArrayLength(KConstRef thiz) { |
| const ArrayHeader* array = thiz->array(); |
| return array->count_; |
| } |
| |
| void Kotlin_Array_fillImpl(KRef thiz, KInt fromIndex, KInt toIndex, KRef value) { |
| ArrayHeader* array = thiz->array(); |
| checkRangeIndexes(fromIndex, toIndex, array->count_); |
| for (KInt index = fromIndex; index < toIndex; ++index) { |
| UpdateHeapRef(ArrayAddressOfElementAt(array, index), value); |
| } |
| } |
| |
| void Kotlin_Array_copyImpl(KConstRef thiz, KInt fromIndex, |
| KRef destination, KInt toIndex, KInt count) { |
| const ArrayHeader* array = thiz->array(); |
| ArrayHeader* destinationArray = destination->array(); |
| if (count < 0 || |
| fromIndex < 0 || static_cast<uint32_t>(count) + fromIndex > array->count_ || |
| toIndex < 0 || static_cast<uint32_t>(count) + toIndex > destinationArray->count_) { |
| ThrowArrayIndexOutOfBoundsException(); |
| } |
| if (fromIndex >= toIndex) { |
| for (int index = 0; index < count; index++) { |
| UpdateHeapRef(ArrayAddressOfElementAt(destinationArray, toIndex + index), |
| *ArrayAddressOfElementAt(array, fromIndex + index)); |
| } |
| } else { |
| for (int index = count - 1; index >= 0; index--) { |
| UpdateHeapRef(ArrayAddressOfElementAt(destinationArray, toIndex + index), |
| *ArrayAddressOfElementAt(array, fromIndex + index)); |
| } |
| } |
| } |
| |
| // Arrays.kt |
| OBJ_GETTER0(Kotlin_emptyArray) { |
| RETURN_OBJ(const_cast<ObjHeader*>(&theEmptyArray)); |
| } |
| |
| KByte Kotlin_ByteArray_get(KConstRef thiz, KInt index) { |
| return Kotlin_ByteArray_get_value(thiz, index); |
| } |
| |
| KByte Kotlin_ByteArray_get_without_BoundCheck(KConstRef thiz, KInt index) { |
| return Kotlin_ByteArray_get_value<false>(thiz, index); |
| } |
| |
| void Kotlin_ByteArray_set(KRef thiz, KInt index, KByte value) { |
| Kotlin_ByteArray_set_value(thiz, index, value); |
| } |
| |
| void Kotlin_ByteArray_set_without_BoundCheck(KRef thiz, KInt index, KByte value) { |
| Kotlin_ByteArray_set_value<false>(thiz, index, value); |
| } |
| |
| KInt Kotlin_ByteArray_getArrayLength(KConstRef thiz) { |
| const ArrayHeader* array = thiz->array(); |
| return array->count_; |
| } |
| |
| KChar Kotlin_ByteArray_getCharAt(KConstRef thiz, KInt index) { |
| const ArrayHeader* array = thiz->array(); |
| if (index < 0 || static_cast<uint32_t>(index) + 1 >= array->count_) { |
| ThrowArrayIndexOutOfBoundsException(); |
| } |
| #if KONAN_NO_UNALIGNED_ACCESS |
| const uint8_t* address = reinterpret_cast<const uint8_t*>(ByteArrayAddressOfElementAt(array, index)); |
| return (static_cast<KChar>(address[0]) << 0) | (static_cast<KChar>(address[1]) << 8); |
| #else |
| auto result = *reinterpret_cast<const KChar*>(ByteArrayAddressOfElementAt(array, index)); |
| #if __BIG_ENDIAN__ |
| return __builtin_bswap16(result); |
| #else |
| return result; |
| #endif // __BIG_ENDIAN__ |
| #endif // KONAN_NO_UNALIGNED_ACCESS |
| } |
| |
| KShort Kotlin_ByteArray_getShortAt(KConstRef thiz, KInt index) { |
| const ArrayHeader* array = thiz->array(); |
| if (index < 0 || static_cast<uint32_t>(index) + 1 >= array->count_) { |
| ThrowArrayIndexOutOfBoundsException(); |
| } |
| #if KONAN_NO_UNALIGNED_ACCESS |
| const uint8_t* address = reinterpret_cast<const uint8_t*>(ByteArrayAddressOfElementAt(array, index)); |
| return (static_cast<KShort>(address[0]) << 0) | (static_cast<KShort>(address[1]) << 8); |
| #else |
| auto result = *reinterpret_cast<const KShort*>(ByteArrayAddressOfElementAt(array, index)); |
| #if __BIG_ENDIAN__ |
| return __builtin_bswap16(result); |
| #else |
| return result; |
| #endif // __BIG_ENDIAN__ |
| #endif // KONAN_NO_UNALIGNED_ACCESS |
| } |
| |
| KInt Kotlin_ByteArray_getIntAt(KConstRef thiz, KInt index) { |
| const ArrayHeader* array = thiz->array(); |
| if (index < 0 || static_cast<uint32_t>(index) + 3 >= array->count_) { |
| ThrowArrayIndexOutOfBoundsException(); |
| } |
| #if KONAN_NO_UNALIGNED_ACCESS |
| const uint8_t* address = reinterpret_cast<const uint8_t*>(ByteArrayAddressOfElementAt(array, index)); |
| return (static_cast<KInt>(address[0]) << 0) | (static_cast<KInt>(address[1]) << 8) | |
| (static_cast<KInt>(address[2]) << 16) | (static_cast<KInt>(address[3]) << 24); |
| #else |
| auto result = *reinterpret_cast<const KInt*>(ByteArrayAddressOfElementAt(array, index)); |
| #if __BIG_ENDIAN__ |
| return __builtin_bswap32(result); |
| #else |
| return result; |
| #endif // __BIG_ENDIAN__ |
| #endif // KONAN_NO_UNALIGNED_ACCESS |
| } |
| |
| KLong Kotlin_ByteArray_getLongAt(KConstRef thiz, KInt index) { |
| const ArrayHeader* array = thiz->array(); |
| if (index < 0 || static_cast<uint32_t>(index) + 7 >= array->count_) { |
| ThrowArrayIndexOutOfBoundsException(); |
| } |
| #if KONAN_NO_UNALIGNED_ACCESS |
| const uint8_t* address = reinterpret_cast<const uint8_t*>(ByteArrayAddressOfElementAt(array, index)); |
| return (static_cast<KLong>(address[0]) << 0) | (static_cast<KLong>(address[1]) << 8) | |
| (static_cast<KLong>(address[2]) << 16) | (static_cast<KLong>(address[3]) << 24) | |
| (static_cast<KLong>(address[4]) << 32) | (static_cast<KLong>(address[5]) << 40) | |
| (static_cast<KLong>(address[6]) << 48) | (static_cast<KLong>(address[7]) << 56); |
| #else |
| auto result = *reinterpret_cast<const KLong*>(ByteArrayAddressOfElementAt(array, index)); |
| #if __BIG_ENDIAN__ |
| return __builtin_bswap64(result); |
| #else |
| return result; |
| #endif // __BIG_ENDIAN__ |
| #endif // KONAN_NO_UNALIGNED_ACCESS |
| } |
| |
| KFloat Kotlin_ByteArray_getFloatAt(KConstRef thiz, KInt index) { |
| const ArrayHeader* array = thiz->array(); |
| if (index < 0 || static_cast<uint32_t>(index) + 3 >= array->count_) { |
| ThrowArrayIndexOutOfBoundsException(); |
| } |
| #if KONAN_NO_UNALIGNED_ACCESS |
| const uint8_t* address = reinterpret_cast<const uint8_t*>(ByteArrayAddressOfElementAt(array, index)); |
| union { |
| KFloat f; |
| uint8_t b[4]; |
| } u; |
| #if __BIG_ENDIAN__ |
| u.b[0] = address[3]; |
| u.b[1] = address[2]; |
| u.b[2] = address[1]; |
| u.b[3] = address[0]; |
| #else |
| u.b[0] = address[0]; |
| u.b[1] = address[1]; |
| u.b[2] = address[2]; |
| u.b[3] = address[3]; |
| #endif // __BIG_ENDIAN__ |
| return u.f; |
| #else |
| auto result = *reinterpret_cast<const KFloat*>(ByteArrayAddressOfElementAt(array, index)); |
| return result; |
| #endif // KONAN_NO_UNALIGNED_ACCESS |
| } |
| |
| KDouble Kotlin_ByteArray_getDoubleAt(KConstRef thiz, KInt index) { |
| const ArrayHeader* array = thiz->array(); |
| if (index < 0 || static_cast<uint32_t>(index) + 7 >= array->count_) { |
| ThrowArrayIndexOutOfBoundsException(); |
| } |
| #if KONAN_NO_UNALIGNED_ACCESS |
| const uint8_t* address = reinterpret_cast<const uint8_t*>(ByteArrayAddressOfElementAt(array, index)); |
| union { |
| KDouble d; |
| uint8_t b[8]; |
| } u; |
| #if __BIG_ENDIAN__ |
| u.b[0] = address[7]; |
| u.b[1] = address[6]; |
| u.b[2] = address[5]; |
| u.b[3] = address[4]; |
| u.b[4] = address[3]; |
| u.b[5] = address[2]; |
| u.b[6] = address[1]; |
| u.b[7] = address[0]; |
| #else |
| u.b[0] = address[0]; |
| u.b[1] = address[1]; |
| u.b[2] = address[2]; |
| u.b[3] = address[3]; |
| u.b[4] = address[4]; |
| u.b[5] = address[5]; |
| u.b[6] = address[6]; |
| u.b[7] = address[7]; |
| #endif // __BIG_ENDIAN__ |
| return u.d; |
| #else |
| return *reinterpret_cast<const KDouble*>(ByteArrayAddressOfElementAt(array, index)); |
| #endif // KONAN_NO_UNALIGNED_ACCESS |
| } |
| |
| void Kotlin_ByteArray_setCharAt(KRef thiz, KInt index, KChar value) { |
| ArrayHeader* array = thiz->array(); |
| if (index < 0 || static_cast<uint32_t>(index) + 1 >= array->count_) { |
| ThrowArrayIndexOutOfBoundsException(); |
| } |
| #if KONAN_NO_UNALIGNED_ACCESS |
| uint8_t* address = reinterpret_cast<uint8_t*>(ByteArrayAddressOfElementAt(array, index)); |
| address[0] = (value >> 0) & 0xff; |
| address[1] = (value >> 8) & 0xff; |
| #else |
| #if __BIG_ENDIAN__ |
| value = __builtin_bswap16(value); |
| #endif // __BIG_ENDIAN__ |
| *reinterpret_cast<KChar*>(ByteArrayAddressOfElementAt(array, index)) = value; |
| #endif // KONAN_NO_UNALIGNED_ACCESS |
| } |
| |
| void Kotlin_ByteArray_setShortAt(KRef thiz, KInt index, KShort value) { |
| ArrayHeader* array = thiz->array(); |
| if (index < 0 || static_cast<uint32_t>(index) + 1 >= array->count_) { |
| ThrowArrayIndexOutOfBoundsException(); |
| } |
| #if KONAN_NO_UNALIGNED_ACCESS |
| uint8_t* address = reinterpret_cast<uint8_t*>(ByteArrayAddressOfElementAt(array, index)); |
| address[0] = (value >> 0) & 0xff; |
| address[1] = (value >> 8) & 0xff; |
| #else |
| #if __BIG_ENDIAN__ |
| value = __builtin_bswap16(value); |
| #endif |
| *reinterpret_cast<KShort*>(ByteArrayAddressOfElementAt(array, index)) = value; |
| #endif // KONAN_NO_UNALIGNED_ACCESS |
| } |
| |
| void Kotlin_ByteArray_setIntAt(KRef thiz, KInt index, KInt value) { |
| ArrayHeader* array = thiz->array(); |
| if (index < 0 || static_cast<uint32_t>(index) + 3 >= array->count_) { |
| ThrowArrayIndexOutOfBoundsException(); |
| } |
| #if KONAN_NO_UNALIGNED_ACCESS |
| uint8_t* address = reinterpret_cast<uint8_t*>(ByteArrayAddressOfElementAt(array, index)); |
| address[0] = (value >> 0) & 0xff; |
| address[1] = (value >> 8) & 0xff; |
| address[2] = (value >> 16) & 0xff; |
| address[3] = (value >> 24) & 0xff; |
| #else |
| #if __BIG_ENDIAN__ |
| value = __builtin_bswap32(value); |
| #endif // __BIG_ENDIAN__ |
| *reinterpret_cast<KInt*>(ByteArrayAddressOfElementAt(array, index)) = value; |
| #endif // KONAN_NO_UNALIGNED_ACCESS |
| } |
| |
| void Kotlin_ByteArray_setLongAt(KRef thiz, KInt index, KLong value) { |
| ArrayHeader* array = thiz->array(); |
| if (index < 0 || static_cast<uint32_t>(index) + 7 >= array->count_) { |
| ThrowArrayIndexOutOfBoundsException(); |
| } |
| #if KONAN_NO_UNALIGNED_ACCESS |
| uint8_t* address = reinterpret_cast<uint8_t*>(ByteArrayAddressOfElementAt(array, index)); |
| address[0] = (value >> 0) & 0xff; |
| address[1] = (value >> 8) & 0xff; |
| address[2] = (value >> 16) & 0xff; |
| address[3] = (value >> 24) & 0xff; |
| address[4] = (value >> 32) & 0xff; |
| address[5] = (value >> 40) & 0xff; |
| address[6] = (value >> 48) & 0xff; |
| address[7] = (value >> 56) & 0xff; |
| #else |
| #if __BIG_ENDIAN__ |
| value = __builtin_bswap64(value); |
| #endif // __BIG_ENDIAN__ |
| *reinterpret_cast<KLong*>(ByteArrayAddressOfElementAt(array, index)) = value; |
| #endif // KONAN_NO_UNALIGNED_ACCESS |
| } |
| |
| void Kotlin_ByteArray_setFloatAt(KRef thiz, KInt index, KFloat value) { |
| ArrayHeader* array = thiz->array(); |
| if (index < 0 || static_cast<uint32_t>(index) + 3 >= array->count_) { |
| ThrowArrayIndexOutOfBoundsException(); |
| } |
| #if KONAN_NO_UNALIGNED_ACCESS |
| uint8_t* address = reinterpret_cast<uint8_t*>(ByteArrayAddressOfElementAt(array, index)); |
| union { |
| KFloat f; |
| uint8_t b[4]; |
| } u; |
| u.f = value; |
| address[0] = u.b[0]; |
| address[1] = u.b[1]; |
| address[2] = u.b[2]; |
| address[3] = u.b[3]; |
| #else |
| *reinterpret_cast<KFloat*>(ByteArrayAddressOfElementAt(array, index)) = value; |
| #endif // KONAN_NO_UNALIGNED_ACCESS |
| } |
| |
| void Kotlin_ByteArray_setDoubleAt(KRef thiz, KInt index, KDouble value) { |
| ArrayHeader* array = thiz->array(); |
| if (index < 0 || static_cast<uint32_t>(index) + 7 >= array->count_) { |
| ThrowArrayIndexOutOfBoundsException(); |
| } |
| #if KONAN_NO_UNALIGNED_ACCESS |
| uint8_t* address = reinterpret_cast<uint8_t*>(ByteArrayAddressOfElementAt(array, index)); |
| union { |
| KDouble d; |
| uint8_t b[8]; |
| } u; |
| u.d = value; |
| address[0] = u.b[0]; |
| address[1] = u.b[1]; |
| address[2] = u.b[2]; |
| address[3] = u.b[3]; |
| address[4] = u.b[4]; |
| address[5] = u.b[5]; |
| address[6] = u.b[6]; |
| address[7] = u.b[7]; |
| #else |
| *reinterpret_cast<KDouble*>(ByteArrayAddressOfElementAt(array, index)) = value; |
| #endif // KONAN_NO_UNALIGNED_ACCESS |
| } |
| |
| KChar Kotlin_CharArray_get(KConstRef thiz, KInt index) { |
| return PrimitiveArrayGet<KChar>(thiz, index); |
| } |
| |
| KChar Kotlin_CharArray_get_without_BoundCheck(KConstRef thiz, KInt index) { |
| return PrimitiveArrayGet<KChar, false>(thiz, index); |
| } |
| |
| void Kotlin_CharArray_set(KRef thiz, KInt index, KChar value) { |
| PrimitiveArraySet(thiz, index, value); |
| } |
| |
| void Kotlin_CharArray_set_without_BoundCheck(KRef thiz, KInt index, KChar value) { |
| PrimitiveArraySet<KChar, false>(thiz, index, value); |
| } |
| |
| OBJ_GETTER(Kotlin_CharArray_copyOf, KConstRef thiz, KInt newSize) { |
| const ArrayHeader* array = thiz->array(); |
| if (newSize < 0) { |
| ThrowIllegalArgumentException(); |
| } |
| ArrayHeader* result = AllocArrayInstance(array->type_info(), newSize, OBJ_RESULT)->array(); |
| KInt toCopy = array->count_ < static_cast<uint32_t>(newSize) ? array->count_ : newSize; |
| memcpy( |
| PrimitiveArrayAddressOfElementAt<KChar>(result, 0), |
| PrimitiveArrayAddressOfElementAt<KChar>(array, 0), |
| toCopy * sizeof(KChar)); |
| RETURN_OBJ(result->obj()); |
| } |
| |
| KInt Kotlin_CharArray_getArrayLength(KConstRef thiz) { |
| const ArrayHeader* array = thiz->array(); |
| return array->count_; |
| } |
| |
| KShort Kotlin_ShortArray_get(KConstRef thiz, KInt index) { |
| return PrimitiveArrayGet<KShort>(thiz, index); |
| } |
| |
| KShort Kotlin_ShortArray_get_without_BoundCheck(KConstRef thiz, KInt index) { |
| return PrimitiveArrayGet<KShort, false>(thiz, index); |
| } |
| |
| void Kotlin_ShortArray_set(KRef thiz, KInt index, KShort value) { |
| PrimitiveArraySet(thiz, index, value); |
| } |
| |
| void Kotlin_ShortArray_set_without_BoundCheck(KRef thiz, KInt index, KShort value) { |
| PrimitiveArraySet<KShort, false>(thiz, index, value); |
| } |
| |
| KInt Kotlin_ShortArray_getArrayLength(KConstRef thiz) { |
| const ArrayHeader* array = thiz->array(); |
| return array->count_; |
| } |
| |
| KInt Kotlin_IntArray_get(KConstRef thiz, KInt index) { |
| return PrimitiveArrayGet<KInt>(thiz, index); |
| } |
| |
| KInt Kotlin_IntArray_get_without_BoundCheck(KConstRef thiz, KInt index) { |
| return PrimitiveArrayGet<KInt, false>(thiz, index); |
| } |
| |
| void Kotlin_IntArray_set(KRef thiz, KInt index, KInt value) { |
| PrimitiveArraySet(thiz, index, value); |
| } |
| |
| void Kotlin_IntArray_set_without_BoundCheck(KRef thiz, KInt index, KInt value) { |
| PrimitiveArraySet<KInt, false>(thiz, index, value); |
| } |
| |
| KInt Kotlin_IntArray_getArrayLength(KConstRef thiz) { |
| const ArrayHeader* array = thiz->array(); |
| return array->count_; |
| } |
| |
| void Kotlin_ByteArray_fillImpl(KRef thiz, KInt fromIndex, KInt toIndex, KByte value) { |
| fillImpl<KByte>(thiz, fromIndex, toIndex, value); |
| } |
| |
| void Kotlin_ShortArray_fillImpl(KRef thiz, KInt fromIndex, KInt toIndex, KShort value) { |
| fillImpl<KShort>(thiz, fromIndex, toIndex, value); |
| } |
| |
| void Kotlin_CharArray_fillImpl(KRef thiz, KInt fromIndex, KInt toIndex, KChar value) { |
| fillImpl<KChar>(thiz, fromIndex, toIndex, value); |
| } |
| |
| void Kotlin_IntArray_fillImpl(KRef thiz, KInt fromIndex, KInt toIndex, KInt value) { |
| fillImpl<KInt>(thiz, fromIndex, toIndex, value); |
| } |
| |
| void Kotlin_LongArray_fillImpl(KRef thiz, KInt fromIndex, KInt toIndex, KLong value) { |
| fillImpl<KLong>(thiz, fromIndex, toIndex, value); |
| } |
| |
| void Kotlin_FloatArray_fillImpl(KRef thiz, KInt fromIndex, KInt toIndex, KFloat value) { |
| fillImpl<KFloat>(thiz, fromIndex, toIndex, value); |
| } |
| |
| void Kotlin_DoubleArray_fillImpl(KRef thiz, KInt fromIndex, KInt toIndex, KDouble value) { |
| fillImpl<KDouble>(thiz, fromIndex, toIndex, value); |
| } |
| |
| void Kotlin_BooleanArray_fillImpl(KRef thiz, KInt fromIndex, KInt toIndex, KBoolean value) { |
| fillImpl<KBoolean>(thiz, fromIndex, toIndex, value); |
| } |
| |
| void Kotlin_ByteArray_copyImpl(KConstRef thiz, KInt fromIndex, |
| KRef destination, KInt toIndex, KInt count) { |
| copyImpl<KByte>(thiz, fromIndex, destination, toIndex, count); |
| } |
| |
| void Kotlin_ShortArray_copyImpl(KConstRef thiz, KInt fromIndex, |
| KRef destination, KInt toIndex, KInt count) { |
| copyImpl<KShort>(thiz, fromIndex, destination, toIndex, count); |
| } |
| |
| void Kotlin_CharArray_copyImpl(KConstRef thiz, KInt fromIndex, |
| KRef destination, KInt toIndex, KInt count) { |
| copyImpl<KChar>(thiz, fromIndex, destination, toIndex, count); |
| } |
| |
| void Kotlin_IntArray_copyImpl(KConstRef thiz, KInt fromIndex, |
| KRef destination, KInt toIndex, KInt count) { |
| copyImpl<KInt>(thiz, fromIndex, destination, toIndex, count); |
| } |
| |
| void Kotlin_LongArray_copyImpl(KConstRef thiz, KInt fromIndex, |
| KRef destination, KInt toIndex, KInt count) { |
| copyImpl<KLong>(thiz, fromIndex, destination, toIndex, count); |
| } |
| |
| void Kotlin_FloatArray_copyImpl(KConstRef thiz, KInt fromIndex, |
| KRef destination, KInt toIndex, KInt count) { |
| copyImpl<KFloat>(thiz, fromIndex, destination, toIndex, count); |
| } |
| |
| void Kotlin_DoubleArray_copyImpl(KConstRef thiz, KInt fromIndex, |
| KRef destination, KInt toIndex, KInt count) { |
| copyImpl<KDouble>(thiz, fromIndex, destination, toIndex, count); |
| } |
| |
| void Kotlin_BooleanArray_copyImpl(KConstRef thiz, KInt fromIndex, |
| KRef destination, KInt toIndex, KInt count) { |
| copyImpl<KBoolean>(thiz, fromIndex, destination, toIndex, count); |
| } |
| |
| KLong Kotlin_LongArray_get(KConstRef thiz, KInt index) { |
| return PrimitiveArrayGet<KLong>(thiz, index); |
| } |
| |
| KLong Kotlin_LongArray_get_without_BoundCheck(KConstRef thiz, KInt index) { |
| return PrimitiveArrayGet<KLong, false>(thiz, index); |
| } |
| |
| void Kotlin_LongArray_set(KRef thiz, KInt index, KLong value) { |
| PrimitiveArraySet(thiz, index, value); |
| } |
| |
| void Kotlin_LongArray_set_without_BoundCheck(KRef thiz, KInt index, KLong value) { |
| PrimitiveArraySet<KLong, false>(thiz, index, value); |
| } |
| |
| KInt Kotlin_LongArray_getArrayLength(KConstRef thiz) { |
| const ArrayHeader* array = thiz->array(); |
| return array->count_; |
| } |
| |
| KFloat Kotlin_FloatArray_get(KConstRef thiz, KInt index) { |
| return PrimitiveArrayGet<KFloat>(thiz, index); |
| } |
| |
| KFloat Kotlin_FloatArray_get_without_BoundCheck(KConstRef thiz, KInt index) { |
| return PrimitiveArrayGet<KFloat, false>(thiz, index); |
| } |
| |
| void Kotlin_FloatArray_set(KRef thiz, KInt index, KFloat value) { |
| PrimitiveArraySet(thiz, index, value); |
| } |
| |
| void Kotlin_FloatArray_set_without_BoundCheck(KRef thiz, KInt index, KFloat value) { |
| PrimitiveArraySet<KFloat, false>(thiz, index, value); |
| } |
| |
| KInt Kotlin_FloatArray_getArrayLength(KConstRef thiz) { |
| const ArrayHeader* array = thiz->array(); |
| return array->count_; |
| } |
| |
| KDouble Kotlin_DoubleArray_get(KConstRef thiz, KInt index) { |
| return PrimitiveArrayGet<KDouble>(thiz, index); |
| } |
| |
| KDouble Kotlin_DoubleArray_get_without_BoundCheck(KConstRef thiz, KInt index) { |
| return PrimitiveArrayGet<KDouble, false>(thiz, index); |
| } |
| |
| void Kotlin_DoubleArray_set(KRef thiz, KInt index, KDouble value) { |
| PrimitiveArraySet(thiz, index, value); |
| } |
| |
| void Kotlin_DoubleArray_set_without_BoundCheck(KRef thiz, KInt index, KDouble value) { |
| PrimitiveArraySet<KDouble, false>(thiz, index, value); |
| } |
| |
| KInt Kotlin_DoubleArray_getArrayLength(KConstRef thiz) { |
| const ArrayHeader* array = thiz->array(); |
| return array->count_; |
| } |
| |
| KBoolean Kotlin_BooleanArray_get(KConstRef thiz, KInt index) { |
| return PrimitiveArrayGet<KBoolean>(thiz, index); |
| } |
| |
| KBoolean Kotlin_BooleanArray_get_without_BoundCheck(KConstRef thiz, KInt index) { |
| return PrimitiveArrayGet<KBoolean, false>(thiz, index); |
| } |
| |
| void Kotlin_BooleanArray_set(KRef thiz, KInt index, KBoolean value) { |
| PrimitiveArraySet(thiz, index, value); |
| } |
| |
| void Kotlin_BooleanArray_set_without_BoundCheck(KRef thiz, KInt index, KBoolean value) { |
| PrimitiveArraySet<KBoolean, false>(thiz, index, value); |
| } |
| |
| KInt Kotlin_BooleanArray_getArrayLength(KConstRef thiz) { |
| const ArrayHeader* array = thiz->array(); |
| return array->count_; |
| } |
| |
| KNativePtr Kotlin_NativePtrArray_get(KConstRef thiz, KInt index) { |
| return PrimitiveArrayGet<KNativePtr>(thiz, index); |
| } |
| |
| KNativePtr Kotlin_NativePtrArray_get_without_BoundCheck(KConstRef thiz, KInt index) { |
| return PrimitiveArrayGet<KNativePtr, false>(thiz, index); |
| } |
| |
| void Kotlin_NativePtrArray_set(KRef thiz, KInt index, KNativePtr value) { |
| PrimitiveArraySet(thiz, index, value); |
| } |
| |
| void Kotlin_NativePtrArray_set_without_BoundCheck(KRef thiz, KInt index, KNativePtr value) { |
| PrimitiveArraySet<KNativePtr, false>(thiz, index, value); |
| } |
| |
| KInt Kotlin_NativePtrArray_getArrayLength(KConstRef thiz) { |
| const ArrayHeader* array = thiz->array(); |
| return array->count_; |
| } |
| |
| OBJ_GETTER(Kotlin_ImmutableBlob_toByteArray, KConstRef thiz, KInt startIndex, KInt endIndex) { |
| const ArrayHeader* array = thiz->array(); |
| if (startIndex < 0 || static_cast<uint32_t>(endIndex) > array->count_ || startIndex > endIndex) { |
| ThrowArrayIndexOutOfBoundsException(); |
| } |
| KInt count = endIndex - startIndex; |
| ArrayHeader* result = AllocArrayInstance(theByteArrayTypeInfo, count, OBJ_RESULT)->array(); |
| memcpy(PrimitiveArrayAddressOfElementAt<KByte>(result, 0), |
| PrimitiveArrayAddressOfElementAt<KByte>(array, startIndex), |
| count); |
| RETURN_OBJ(result->obj()); |
| } |
| |
| KNativePtr Kotlin_ImmutableBlob_asCPointerImpl(KRef thiz, KInt offset) { |
| ArrayHeader* array = thiz->array(); |
| // We couldn't have created an array bigger than max KInt value. |
| // So if index is < 0, conversion to an unsigned value would make it bigger |
| // than the array size. |
| if (static_cast<uint32_t>(offset) > array->count_) { |
| ThrowArrayIndexOutOfBoundsException(); |
| } |
| return PrimitiveArrayAddressOfElementAt<KByte>(array, offset); |
| } |
| |
| KNativePtr Kotlin_Arrays_getByteArrayAddressOfElement(KRef thiz, KInt index) { |
| ArrayHeader* array = thiz->array(); |
| boundsCheck(array, index); |
| |
| return AddressOfElementAt<KByte>(array, index); |
| } |
| |
| KNativePtr Kotlin_Arrays_getCharArrayAddressOfElement (KRef thiz, KInt index) { |
| ArrayHeader* array = thiz->array(); |
| boundsCheck(array, index); |
| |
| return CharArrayAddressOfElementAt(array, index); |
| } |
| |
| KNativePtr Kotlin_Arrays_getShortArrayAddressOfElement(KRef thiz, KInt index) { |
| ArrayHeader* array = thiz->array(); |
| boundsCheck(array, index); |
| |
| return AddressOfElementAt<KShort>(array, index); |
| } |
| |
| KNativePtr Kotlin_Arrays_getIntArrayAddressOfElement(KRef thiz, KInt index) { |
| ArrayHeader* array = thiz->array(); |
| boundsCheck(array, index); |
| |
| return AddressOfElementAt<KInt>(array, index); |
| } |
| |
| KNativePtr Kotlin_Arrays_getLongArrayAddressOfElement(KRef thiz, KInt index) { |
| ArrayHeader* array = thiz->array(); |
| boundsCheck(array, index); |
| |
| return AddressOfElementAt<KLong>(array, index); |
| } |
| |
| KNativePtr Kotlin_Arrays_getFloatArrayAddressOfElement(KRef thiz, KInt index) { |
| ArrayHeader* array = thiz->array(); |
| boundsCheck(array, index); |
| |
| return AddressOfElementAt<KFloat>(array, index); |
| } |
| |
| KNativePtr Kotlin_Arrays_getDoubleArrayAddressOfElement(KRef thiz, KInt index) { |
| ArrayHeader* array = thiz->array(); |
| boundsCheck(array, index); |
| |
| return AddressOfElementAt<KDouble>(array, index); |
| } |
| |
| } // extern "C" |