More stdlib implementation. (#17)

This commit is contained in:
Nikolay Igotti
2016-10-26 18:37:02 +03:00
committed by GitHub
parent 622ae34e61
commit 8ce0bddc17
6 changed files with 103 additions and 32 deletions
+31 -10
View File
@@ -32,10 +32,37 @@ typedef enum {
// Could be made 64-bit for large memory configs. // Could be made 64-bit for large memory configs.
typedef uint32_t container_offset_t; typedef uint32_t container_offset_t;
// Header of all container objects. Contains reference counter.
struct ContainerHeader {
// Reference counter of container. Uses two lower bits of counter for
// container type (for polymorphism in ::Release()).
volatile uint32_t ref_count_;
};
// Header of every object. // Header of every object.
struct ObjHeader { struct ObjHeader {
const TypeInfo* type_info_; const TypeInfo* type_info_;
container_offset_t container_offset_negative_; container_offset_t container_offset_negative_;
const TypeInfo* type_info() const {
// TODO: for moving collectors use meta-objects approach:
// - store tag in lower bit TypeInfo, which marks if meta-object is in place
// - when reading type_info_ check if it is unaligned
// - if it is, pointer points to the MetaObject
// - otherwise this is direct pointer to TypeInfo
// Meta-object allows storing additional data associated with some objects,
// such as stable hash code.
return type_info_;
}
void set_type_info(const TypeInfo* type_info) {
type_info_ = type_info;
}
ContainerHeader* container() const {
return reinterpret_cast<ContainerHeader*>(
reinterpret_cast<uintptr_t>(this) - container_offset_negative_);
}
}; };
// Header of value type array objects. // Header of value type array objects.
@@ -44,13 +71,6 @@ struct ArrayHeader : public ObjHeader {
uint32_t count_; uint32_t count_;
}; };
// Header of all container objects. Contains reference counter.
struct ContainerHeader {
// Reference counter of container. Uses two lower bits of counter for
// container type (for polymorphism in ::Release()).
volatile uint32_t ref_count_;
};
struct ArenaContainerHeader : public ContainerHeader { struct ArenaContainerHeader : public ContainerHeader {
// Current allocation limit. // Current allocation limit.
uint8_t* current_; uint8_t* current_;
@@ -61,12 +81,13 @@ struct ArenaContainerHeader : public ContainerHeader {
inline void* AddressOfElementAt(ArrayHeader* obj, int32_t index) { inline void* AddressOfElementAt(ArrayHeader* obj, int32_t index) {
// Instance size is negative. // Instance size is negative.
return reinterpret_cast<uint8_t*>(obj + 1) - obj->type_info_->instanceSize_ * index; return reinterpret_cast<uint8_t*>(obj + 1) -
obj->type_info()->instanceSize_ * index;
} }
inline uint32_t ArraySizeBytes(const ArrayHeader* obj) { inline uint32_t ArraySizeBytes(const ArrayHeader* obj) {
// Instance size is negative. // Instance size is negative.
return -obj->type_info_->instanceSize_ * obj->count_; return -obj->type_info()->instanceSize_ * obj->count_;
} }
@@ -135,7 +156,7 @@ class Container {
void SetMeta(ObjHeader* obj, const TypeInfo* type_info) { void SetMeta(ObjHeader* obj, const TypeInfo* type_info) {
obj->container_offset_negative_ = obj->container_offset_negative_ =
reinterpret_cast<uintptr_t>(obj) - reinterpret_cast<uintptr_t>(header_); reinterpret_cast<uintptr_t>(obj) - reinterpret_cast<uintptr_t>(header_);
obj->type_info_ = type_info; obj->set_type_info(type_info);
} }
public: public:
+30 -4
View File
@@ -9,6 +9,22 @@
extern "C" { extern "C" {
// Any.kt
KBool Kotlin_Any_equals(const ObjHeader* thiz, const ObjHeader* other) {
return thiz == other;
}
KInt Kotlin_Any_hashCode(const ObjHeader* thiz) {
// Here we will use different mechanism for stable hashcode, using meta-objects
// if moving collector will be used.
return reinterpret_cast<uintptr_t>(thiz);
}
ArrayHeader* Kotlin_Any_toString(const ObjHeader* thiz) {
return nullptr;
}
// Arrays.kt // Arrays.kt
// TODO: those must be compiler intrinsics afterwards. // TODO: those must be compiler intrinsics afterwards.
KByte Kotlin_ByteArray_get(const ArrayHeader* obj, KInt index) { KByte Kotlin_ByteArray_get(const ArrayHeader* obj, KInt index) {
@@ -97,7 +113,7 @@ KInt Kotlin_IntArray_getArrayLength(const ArrayHeader* array) {
// io/Console.kt // io/Console.kt
void Kotlin_io_Console_print(const ArrayHeader* array) { void Kotlin_io_Console_print(const ArrayHeader* array) {
RuntimeAssert(array->type_info_ == theStringTypeInfo, "Must use a string"); RuntimeAssert(array->type_info() == theStringTypeInfo, "Must use a string");
// TODO: system stdout must be aware about UTF-8. // TODO: system stdout must be aware about UTF-8.
write(STDOUT_FILENO, ByteArrayAddressOfElementAt(array, 0), array->count_); write(STDOUT_FILENO, ByteArrayAddressOfElementAt(array, 0), array->count_);
} }
@@ -122,7 +138,7 @@ KInt Kotlin_String_getStringLength(const ArrayHeader* array) {
} }
ArrayHeader* Kotlin_String_fromUtf8Array(const ArrayHeader* array) { ArrayHeader* Kotlin_String_fromUtf8Array(const ArrayHeader* array) {
RuntimeAssert(array->type_info_ == theByteArrayTypeInfo, "Must use a byte array"); RuntimeAssert(array->type_info() == theByteArrayTypeInfo, "Must use a byte array");
uint32_t length = ArraySizeBytes(array); uint32_t length = ArraySizeBytes(array);
// TODO: support full UTF-8. // TODO: support full UTF-8.
ArrayHeader* result = ArrayContainer(theStringTypeInfo, length).GetPlace(); ArrayHeader* result = ArrayContainer(theStringTypeInfo, length).GetPlace();
@@ -136,8 +152,8 @@ ArrayHeader* Kotlin_String_fromUtf8Array(const ArrayHeader* array) {
ArrayHeader* Kotlin_String_plusImpl( ArrayHeader* Kotlin_String_plusImpl(
const ArrayHeader* obj, const ArrayHeader* other) { const ArrayHeader* obj, const ArrayHeader* other) {
// TODO: support UTF-8 // TODO: support UTF-8
RuntimeAssert(obj->type_info_ == theStringTypeInfo, "Must be a string"); RuntimeAssert(obj->type_info() == theStringTypeInfo, "Must be a string");
RuntimeAssert(other->type_info_ == theStringTypeInfo, "Must be a string"); RuntimeAssert(other->type_info() == theStringTypeInfo, "Must be a string");
uint32_t result_length = obj->count_ + other->count_; uint32_t result_length = obj->count_ + other->count_;
ArrayHeader* result = ArrayContainer( ArrayHeader* result = ArrayContainer(
theStringTypeInfo, result_length).GetPlace(); theStringTypeInfo, result_length).GetPlace();
@@ -152,4 +168,14 @@ ArrayHeader* Kotlin_String_plusImpl(
return result; return result;
} }
KBool Kotlin_String_equals(
const ArrayHeader* thiz, const ObjHeader* other) {
if (other == nullptr || other->type_info() != theStringTypeInfo) return 0;
const ArrayHeader* otherString = reinterpret_cast<const ArrayHeader*>(other);
return thiz->count_ == otherString->count_ &&
memcmp(ByteArrayAddressOfElementAt(thiz, 0),
ByteArrayAddressOfElementAt(otherString, 0),
thiz->count_) == 0;
}
} }
+25 -18
View File
@@ -4,6 +4,7 @@
#include "Memory.h" #include "Memory.h"
#include "Types.h" #include "Types.h"
typedef uint8_t KBool;
typedef uint8_t KByte; typedef uint8_t KByte;
typedef uint16_t KChar; typedef uint16_t KChar;
// Note that it is signed. // Note that it is signed.
@@ -40,32 +41,38 @@ inline const KInt* IntArrayAddressOfElementAt(const ArrayHeader* obj, KInt index
extern "C" { extern "C" {
#endif #endif
// Any.kt
KBool Kotlin_Any_equals(const ObjHeader* thiz, const ObjHeader* other);
KInt Kotlin_Any_hashCode(const ObjHeader* thiz);
ArrayHeader* Kotlin_Any_toString(const ObjHeader* thiz);
// Arrays.kt
// TODO: those must be compiler intrinsics afterwards. // TODO: those must be compiler intrinsics afterwards.
// Arrays.kt ArrayHeader* Kotlin_ByteArray_clone(const ArrayHeader* thiz);
ArrayHeader* Kotlin_ByteArray_clone(const ArrayHeader* obj); KByte Kotlin_ByteArray_get(const ArrayHeader* thiz, KInt index);
KByte Kotlin_ByteArray_get(const ArrayHeader* obj, KInt index); void Kotlin_ByteArray_set(ArrayHeader* thiz, KInt index, KByte value);
void Kotlin_ByteArray_set(ArrayHeader* obj, KInt index, KByte value); KInt Kotlin_ByteArray_getArrayLength(const ArrayHeader* thiz);
KInt Kotlin_ByteArray_getArrayLength(const ArrayHeader* obj);
ArrayHeader* Kotlin_CharArray_clone(const ArrayHeader* obj); ArrayHeader* Kotlin_CharArray_clone(const ArrayHeader* thiz);
KChar Kotlin_CharArray_get(const ArrayHeader* obj, KInt index); KChar Kotlin_CharArray_get(const ArrayHeader* thiz, KInt index);
void Kotlin_CharArray_set(ArrayHeader* obj, KInt index, KChar value); void Kotlin_CharArray_set(ArrayHeader* thiz, KInt index, KChar value);
KInt Kotlin_CharArray_getArrayLength(const ArrayHeader* obj); KInt Kotlin_CharArray_getArrayLength(const ArrayHeader* thiz);
ArrayHeader* Kotlin_IntArray_clone(const ArrayHeader* obj); ArrayHeader* Kotlin_IntArray_clone(const ArrayHeader* thiz);
KInt Kotlin_IntArray_get(const ArrayHeader* obj, KInt index); KInt Kotlin_IntArray_get(const ArrayHeader* thiz, KInt index);
void Kotlin_IntArray_set(ArrayHeader* obj, KInt index, KInt value); void Kotlin_IntArray_set(ArrayHeader* thiz, KInt index, KInt value);
KInt Kotlin_IntArray_getArrayLength(const ArrayHeader* obj); KInt Kotlin_IntArray_getArrayLength(const ArrayHeader* thiz);
// io/Console.kt // io/Console.kt
void Kotlin_io_Console_print(const ArrayHeader* obj); void Kotlin_io_Console_print(const ArrayHeader* thiz);
// String.kt // String.kt
KInt Kotlin_String_compareTo(const ArrayHeader* obj, const ArrayHeader* other); KInt Kotlin_String_compareTo(const ArrayHeader* thiz, const ArrayHeader* other);
KChar Kotlin_String_get(const ArrayHeader* obj, KInt index); KChar Kotlin_String_get(const ArrayHeader* thiz, KInt index);
ArrayHeader* Kotlin_String_fromUtf8Array(const ArrayHeader* array); ArrayHeader* Kotlin_String_fromUtf8Array(const ArrayHeader* array);
ArrayHeader* Kotlin_String_plusImpl(const ArrayHeader* obj, const ArrayHeader* other); ArrayHeader* Kotlin_String_plusImpl(const ArrayHeader* thiz, const ArrayHeader* other);
KInt Kotlin_String_getStringLength(const ArrayHeader* obj); KInt Kotlin_String_getStringLength(const ArrayHeader* thiz);
KBool Kotlin_String_equals(const ArrayHeader* thiz, const ObjHeader* other);
#ifdef __cplusplus #ifdef __cplusplus
} }
+1
View File
@@ -27,6 +27,7 @@ struct TypeInfo {
int32_t instanceSize_; int32_t instanceSize_;
// Must be pointer to Any for array classes, and null for Any. // Must be pointer to Any for array classes, and null for Any.
const TypeInfo* superType_; const TypeInfo* superType_;
// All object references inside this object.
const int* objOffsets_; const int* objOffsets_;
int objOffsetsCount_; int objOffsetsCount_;
const TypeInfo* const* implementedInterfaces_; const TypeInfo* const* implementedInterfaces_;
@@ -0,0 +1,13 @@
package kotlin_native
public open class Any0 {
// @SymbolName("Kotlin_Any_equals")
// external public open operator fun equals0(other: Any0?): Boolean
// TODO: do we need that in Any?
@SymbolName("Kotlin_Any_hashCode")
external public open fun hashCode0(): Int
@SymbolName("Kotlin_Any_toString")
external public open fun toString0(): String
}
@@ -24,4 +24,7 @@ class String {
@SymbolName("Kotlin_String_plusImpl") @SymbolName("Kotlin_String_plusImpl")
external private fun plusImpl(other:Any): String external private fun plusImpl(other:Any): String
@SymbolName("Kotlin_String_equals")
external public override operator fun equals(other: Any?): Boolean
} }