More array types, bind to native. (#13)

More array types, bind to native implementations.
This commit is contained in:
Nikolay Igotti
2016-10-21 17:50:16 +03:00
committed by GitHub
parent 639c4f9786
commit 5a30a0f2f9
8 changed files with 326 additions and 41 deletions
-9
View File
@@ -64,15 +64,6 @@ inline void* AddressOfElementAt(ArrayHeader* obj, int32_t index) {
return reinterpret_cast<uint8_t*>(obj + 1) - obj->type_info_->instanceSize_ * index;
}
// Optimized version not accessing type info.
inline uint8_t* ByteArrayAddressOfElementAt(ArrayHeader* obj, int32_t index) {
return reinterpret_cast<uint8_t*>(obj + 1) + index;
}
inline const uint8_t* ByteArrayAddressOfElementAt(const ArrayHeader* obj, int32_t index) {
return reinterpret_cast<const uint8_t*>(obj + 1) + index;
}
inline uint32_t ArraySizeBytes(const ArrayHeader* obj) {
// Instance size is negative.
return -obj->type_info_->instanceSize_ * obj->count_;
+103 -4
View File
@@ -9,21 +9,97 @@
extern "C" {
// TODO: those must be compiler intrinsics afterwards.
KByte Kotlin_ByteArray_get(const ArrayHeader* obj, int32_t index) {
KByte Kotlin_ByteArray_get(const ArrayHeader* obj, KInt index) {
if (static_cast<uint32_t>(index) >= obj->count_) {
ThrowArrayIndexOutOfBoundsException();
}
return *ByteArrayAddressOfElementAt(obj, index);
}
void Kotlin_ByteArray_set(ArrayHeader* obj, int32_t index, KByte value) {
void Kotlin_ByteArray_set(ArrayHeader* obj, KInt index, KByte value) {
if (static_cast<uint32_t>(index) >= obj->count_) {
ThrowArrayIndexOutOfBoundsException();
}
*ByteArrayAddressOfElementAt(obj, index) = value;
}
KChar Kotlin_String_get(const ArrayHeader* obj, int32_t index) {
ArrayHeader* Kotlin_ByteArray_clone(const ArrayHeader* array) {
uint32_t length = ArraySizeBytes(array);
ArrayHeader* result = ArrayContainer(theByteArrayTypeInfo, length).GetPlace();
memcpy(
ByteArrayAddressOfElementAt(result, 0),
ByteArrayAddressOfElementAt(array, 0),
length);
return result;
}
KInt Kotlin_ByteArray_getArrayLength(const ArrayHeader* array) {
return array->count_;
}
KChar Kotlin_CharArray_get(const ArrayHeader* obj, KInt index) {
if (static_cast<uint32_t>(index) >= obj->count_) {
ThrowArrayIndexOutOfBoundsException();
}
return *CharArrayAddressOfElementAt(obj, index);
}
void Kotlin_CharArray_set(ArrayHeader* obj, KInt index, KChar value) {
if (static_cast<uint32_t>(index) >= obj->count_) {
ThrowArrayIndexOutOfBoundsException();
}
*CharArrayAddressOfElementAt(obj, index) = value;
}
ArrayHeader* Kotlin_CharArray_clone(const ArrayHeader* array) {
uint32_t length = ArraySizeBytes(array);
ArrayHeader* result = ArrayContainer(theCharArrayTypeInfo, length).GetPlace();
memcpy(
CharArrayAddressOfElementAt(result, 0),
CharArrayAddressOfElementAt(array, 0),
length);
return result;
}
KInt Kotlin_CharArray_getArrayLength(const ArrayHeader* array) {
return array->count_;
}
KInt Kotlin_IntArray_get(const ArrayHeader* obj, KInt index) {
if (static_cast<uint32_t>(index) >= obj->count_) {
ThrowArrayIndexOutOfBoundsException();
}
return *IntArrayAddressOfElementAt(obj, index);
}
void Kotlin_IntArray_set(ArrayHeader* obj, KInt index, KInt value) {
if (static_cast<uint32_t>(index) >= obj->count_) {
ThrowArrayIndexOutOfBoundsException();
}
*IntArrayAddressOfElementAt(obj, index) = value;
}
ArrayHeader* Kotlin_IntArray_clone(const ArrayHeader* array) {
uint32_t length = ArraySizeBytes(array);
ArrayHeader* result = ArrayContainer(theIntArrayTypeInfo, length).GetPlace();
memcpy(
IntArrayAddressOfElementAt(result, 0),
IntArrayAddressOfElementAt(array, 0),
length);
return result;
}
KInt Kotlin_IntArray_getArrayLength(const ArrayHeader* array) {
return array->count_;
}
KInt Kotlin_String_compareTo(const ArrayHeader* obj, const ArrayHeader* other) {
return memcmp(ByteArrayAddressOfElementAt(obj, 0),
ByteArrayAddressOfElementAt(other, 0),
obj->count_ < other->count_ ? obj->count_ : other->count_);
}
KChar Kotlin_String_get(const ArrayHeader* obj, KInt index) {
// TODO: support full UTF-8.
if (static_cast<uint32_t>(index) >= obj->count_) {
ThrowArrayIndexOutOfBoundsException();
@@ -31,8 +107,12 @@ KChar Kotlin_String_get(const ArrayHeader* obj, int32_t index) {
return *ByteArrayAddressOfElementAt(obj, index);
}
KInt Kotlin_String_getStringLength(const ArrayHeader* array) {
return array->count_;
}
ArrayHeader* Kotlin_String_fromUtf8Array(const ArrayHeader* array) {
RuntimeAssert(array->type_info_ == theByteArrayTypeInfo, "Must get a byte array");
RuntimeAssert(array->type_info_ == theByteArrayTypeInfo, "Must use a byte array");
uint32_t length = ArraySizeBytes(array);
// TODO: support full UTF-8.
ArrayHeader* result = ArrayContainer(theStringTypeInfo, length).GetPlace();
@@ -43,4 +123,23 @@ ArrayHeader* Kotlin_String_fromUtf8Array(const ArrayHeader* array) {
return result;
}
ArrayHeader* Kotlin_String_plusImpl(
const ArrayHeader* obj, const ArrayHeader* other) {
// TODO: support UTF-8
RuntimeAssert(obj->type_info_ == theStringTypeInfo, "Must be a string");
RuntimeAssert(other->type_info_ == theStringTypeInfo, "Must be a string");
uint32_t result_length = obj->count_ + other->count_;
ArrayHeader* result = ArrayContainer(
theStringTypeInfo, result_length).GetPlace();
memcpy(
ByteArrayAddressOfElementAt(result, 0),
ByteArrayAddressOfElementAt(obj, 0),
obj->count_);
memcpy(
ByteArrayAddressOfElementAt(result, obj->count_),
ByteArrayAddressOfElementAt(other, 0),
other->count_);
return result;
}
}
+49 -4
View File
@@ -4,18 +4,63 @@
#include "Memory.h"
#include "Types.h"
typedef uint16_t KChar;
typedef uint8_t KByte;
typedef uint16_t KChar;
// Note that it is signed.
typedef int32_t KInt;
// Optimized versions not accessing type info.
inline KByte* ByteArrayAddressOfElementAt(ArrayHeader* obj, KInt index) {
return reinterpret_cast<KByte*>(obj + 1) + index;
}
inline const KByte* ByteArrayAddressOfElementAt(
const ArrayHeader* obj, KInt index) {
return reinterpret_cast<const KByte*>(obj + 1) + index;
}
inline KChar* CharArrayAddressOfElementAt(ArrayHeader* obj, KInt index) {
return reinterpret_cast<KChar*>(obj + 1) + index;
}
inline const KChar* CharArrayAddressOfElementAt(
const ArrayHeader* obj, KInt index) {
return reinterpret_cast<const KChar*>(obj + 1) + index;
}
inline KInt* IntArrayAddressOfElementAt(ArrayHeader* obj, KInt index) {
return reinterpret_cast<KInt*>(obj + 1) + index;
}
inline const KInt* IntArrayAddressOfElementAt(const ArrayHeader* obj, KInt index) {
return reinterpret_cast<const KInt*>(obj + 1) + index;
}
#ifdef __cplusplus
extern "C" {
#endif
// TODO: those must be compiler intrinsics afterwards.
KByte Kotlin_ByteArray_get(const ArrayHeader* obj, int32_t index);
void Kotlin_ByteArray_set(ArrayHeader* obj, int32_t index, KByte value);
KChar Kotlin_String_get(const ArrayHeader* obj, int32_t index);
ArrayHeader* Kotlin_ByteArray_clone(const ArrayHeader* obj);
KByte Kotlin_ByteArray_get(const ArrayHeader* obj, KInt index);
void Kotlin_ByteArray_set(ArrayHeader* obj, KInt index, KByte value);
KInt Kotlin_ByteArray_getArrayLength(const ArrayHeader* obj);
ArrayHeader* Kotlin_CharArray_clone(const ArrayHeader* obj);
KChar Kotlin_CharArray_get(const ArrayHeader* obj, KInt index);
void Kotlin_CharArray_set(ArrayHeader* obj, KInt index, KChar value);
KInt Kotlin_CharArray_getArrayLength(const ArrayHeader* obj);
ArrayHeader* Kotlin_IntArray_clone(const ArrayHeader* obj);
KInt Kotlin_IntArray_get(const ArrayHeader* obj, KInt index);
void Kotlin_IntArray_set(ArrayHeader* obj, KInt index, KInt value);
KInt Kotlin_IntArray_getArrayLength(const ArrayHeader* obj);
KInt Kotlin_String_compareTo(const ArrayHeader* obj, const ArrayHeader* other);
KChar Kotlin_String_get(const ArrayHeader* obj, KInt index);
ArrayHeader* Kotlin_String_fromUtf8Array(const ArrayHeader* array);
ArrayHeader* Kotlin_String_plusImpl(const ArrayHeader* obj, const ArrayHeader* other);
KInt Kotlin_String_getStringLength(const ArrayHeader* obj);
#ifdef __cplusplus
}
+1 -1
View File
@@ -29,7 +29,7 @@ struct TypeInfo {
const TypeInfo* superType_;
const int* objOffsets_;
int objOffsetsCount_;
TypeInfo* const* implementedInterfaces_;
const TypeInfo* const* implementedInterfaces_;
int implementedInterfacesCount_;
void* const* vtable_; // TODO: place vtable at the end of TypeInfo to eliminate the indirection
const MethodTableRecord* openMethods_;
+105 -12
View File
@@ -1,3 +1,4 @@
#include "Natives.h"
#include "Types.h"
namespace {
@@ -20,22 +21,111 @@ const TypeInfo implAnyTypeInfo = {
0 // fieldsCount_
};
const TypeInfo implCloneableTypeInfo = {
// kotlin.Cloneable
{ 0x2d, 0x4b, 0x3d, 0x2f, 0x69, 0x0d, 0x1c, 0xb5, 0x6e, 0xc6,
0x67, 0xa7, 0x24, 0x57, 0x35, 0x98, 0xa4, 0x23, 0x0b, 0xc5 },
0, // instanceSize_
nullptr, // superType_
nullptr, // objOffsets
0, // objOffsetsCount_
nullptr, // implementedInterfaces_
0, // implementedInterfacesCount_
nullptr, // vtable_
nullptr, // openMethods_
0, // openMethodsCount_
nullptr, // fields_
0 // fieldsCount_
};
void* const implByteArrayTypeInfoVTbl[] = {
reinterpret_cast<void*>(Kotlin_ByteArray_clone)
};
const MethodTableRecord implByteArrayTypeInfoMethods[] = {
// TODO: fill in hash.
{ 0, reinterpret_cast<void*>(Kotlin_ByteArray_clone) }
};
const TypeInfo* implByteArrayTypeInfoIfaces[] = {
&implCloneableTypeInfo
};
const TypeInfo implByteArrayTypeInfo = {
// kotlin.ByteArray
{ 0x9e, 0x23, 0xa6, 0xa6, 0x91, 0x9b, 0x6b, 0x0a, 0x00, 0xc5,
0x35, 0xe8, 0xd9, 0xd1, 0xa3, 0xb6, 0xc5, 0xc6, 0xd7, 0x65 },
-1, // instanceSize_, array of 1 byte elements
&implAnyTypeInfo, // superType_
nullptr, // objOffsets
0, // objOffsetsCount_
// TODO: actually, shall implement cloneable, it seems.
nullptr, // implementedInterfaces_
0, // implementedInterfacesCount_
nullptr, // vtable_
nullptr, // openMethods_
0, // openMethodsCount_
nullptr, // fields_
0 // fieldsCount_
-1, // instanceSize_, array of 1 byte elements
&implAnyTypeInfo, // superType_
nullptr, // objOffsets
0, // objOffsetsCount_
implByteArrayTypeInfoIfaces, // implementedInterfaces_
1, // implementedInterfacesCount_
implByteArrayTypeInfoVTbl, // vtable_
implByteArrayTypeInfoMethods, // openMethods_
1, // openMethodsCount_
nullptr, // fields_
0 // fieldsCount_
};
void* const implCharArrayTypeInfoVTbl[] = {
reinterpret_cast<void*>(Kotlin_CharArray_clone)
};
const MethodTableRecord implCharArrayTypeInfoMethods[] = {
// TODO: fill in hash.
{ 0, reinterpret_cast<void*>(Kotlin_CharArray_clone) }
};
const TypeInfo* implCharArrayTypeInfoIfaces[] = {
&implCloneableTypeInfo
};
const TypeInfo implCharArrayTypeInfo = {
// kotlin.CharArray
{ 0x70, 0x88, 0xd4, 0x20, 0x91, 0x6e, 0x25, 0x80, 0x33, 0x64,
0x5a, 0x8d, 0x56, 0xaf, 0x99, 0x19, 0x14, 0xde, 0x5b, 0x71 },
-2, // instanceSize_, array of 2 byte elements
&implAnyTypeInfo, // superType_
nullptr, // objOffsets
0, // objOffsetsCount_
implCharArrayTypeInfoIfaces, // implementedInterfaces_
1, // implementedInterfacesCount_
implCharArrayTypeInfoVTbl, // vtable_
implCharArrayTypeInfoMethods, // openMethods_
1, // openMethodsCount_
nullptr, // fields_
0 // fieldsCount_
};
void* const implIntArrayTypeInfoVTbl[] = {
reinterpret_cast<void*>(Kotlin_IntArray_clone)
};
const MethodTableRecord implIntArrayTypeInfoMethods[] = {
// TODO: fill in hash.
{ 0, reinterpret_cast<void*>(Kotlin_IntArray_clone) }
};
const TypeInfo* implIntArrayTypeInfoIfaces[] = {
&implCloneableTypeInfo
};
const TypeInfo implIntArrayTypeInfo = {
// kotlin.IntArray
{ 0xdd, 0x69, 0x38, 0x31, 0x3e, 0x03, 0xc6, 0xfd, 0x88, 0x8f,
0x1c, 0x83, 0x18, 0x06, 0xcc, 0xcb, 0x8d, 0x71, 0xd1, 0x4c },
-4, // instanceSize_, array of 4 byte elements
&implAnyTypeInfo, // superType_
nullptr, // objOffsets
0, // objOffsetsCount_
implIntArrayTypeInfoIfaces, // implementedInterfaces_
1, // implementedInterfacesCount_
implIntArrayTypeInfoVTbl, // vtable_
implIntArrayTypeInfoMethods, // openMethods_
1, // openMethodsCount_
nullptr, // fields_
0 // fieldsCount_
};
const TypeInfo implStringTypeInfo = {
@@ -61,7 +151,10 @@ extern "C" {
#endif
const TypeInfo* theAnyTypeInfo = &implAnyTypeInfo;
const TypeInfo* theCloneableTypeInfo = &implCloneableTypeInfo;
const TypeInfo* theByteArrayTypeInfo = &implByteArrayTypeInfo;
const TypeInfo* theCharArrayTypeInfo = &implCharArrayTypeInfo;
const TypeInfo* theIntArrayTypeInfo = &implIntArrayTypeInfo;
const TypeInfo* theStringTypeInfo = &implStringTypeInfo;
#ifdef __cplusplus
+3
View File
@@ -8,7 +8,10 @@ extern "C" {
#endif
extern const TypeInfo* theAnyTypeInfo;
extern const TypeInfo* theCloneableTypeInfo;
extern const TypeInfo* theByteArrayTypeInfo;
extern const TypeInfo* theCharArrayTypeInfo;
extern const TypeInfo* theIntArrayTypeInfo;
extern const TypeInfo* theStringTypeInfo;
#ifdef __cplusplus
+64 -10
View File
@@ -1,28 +1,82 @@
package kotlin_native
class ByteArray(size: Int) {
public val size: Int
external public operator fun get(index: Int): Byte
external public operator fun set(index: Int, value: Byte): Unit
public interface Cloneable {
public fun clone(): Any
}
class ByteArray(size: Int) : Cloneable {
public val size: Int
get() = getArrayLength()
@SymbolName("Kotlin_ByteArray_get")
external public operator fun get(index: Int): Byte
@SymbolName("Kotlin_ByteArray_set")
external public operator fun set(index: Int, value: Byte): Unit
@SymbolName("Kotlin_ByteArray_clone")
external public override fun clone(): Any
@SymbolName("Kotlin_ByteArray_getArrayLength")
external private fun getArrayLength(): Int
}
class CharArray(size: Int) : Cloneable {
public val size: Int
get() = getArrayLength()
@SymbolName("Kotlin_CharArray_get")
external public operator fun get(index: Int): Char
@SymbolName("Kotlin_CharArray_set")
external public operator fun set(index: Int, value: Char): Unit
@SymbolName("Kotlin_CharArray_clone")
external public override fun clone(): Any
@SymbolName("Kotlin_CharArray_getArrayLength")
external private fun getArrayLength(): Int
}
class IntArray(size: Int) : Cloneable {
public val size: Int
get() = getArrayLength()
@SymbolName("Kotlin_IntArray_get")
external public operator fun get(index: Int): Char
@SymbolName("Kotlin_IntArray_set")
external public operator fun set(index: Int, value: Char): Unit
@SymbolName("Kotlin_IntArray_clone")
external public override fun clone(): Any
@SymbolName("Kotlin_IntArray_getArrayLength")
external private fun getArrayLength(): Int
}
@SymbolName("Kotlin_String_fromUtf8Array")
external fun fromUtf8Array(array: ByteArray) : String
class String {
companion object {
external fun fromUtf8Array(ByteArray: array) : String
public operator fun plus(other: Any?): String {
return plusImpl(other.toString())
}
external public operator fun plus(other: Any?): String
public val length: Int
get() = getStringLength()
// Can be O(N).
@SymbolName("Kotlin_String_get")
external public fun get(index: Int): Char
// external public fun subSequence(startIndex: Int, endIndex: Int): CharSequence
@SymbolName("Kotlin_String_compareTo")
external public fun compareTo(other: String): Int
@SymbolName("Kotlin_String_getStringLength")
external private fun getStringLength(): Int
@SymbolName("Kotlin_String_plusImpl")
external private fun plusImpl(other:Any): String
}
@@ -8,4 +8,4 @@ package kotlin_native
*/
@Target(AnnotationTarget.FUNCTION)
@Retention(AnnotationRetention.BINARY)
annotation class SymbolName(val name: String)
annotation class SymbolName(val name: kotlin.String)