diff --git a/runtime/src/main/cpp/Natives.cpp b/runtime/src/main/cpp/Natives.cpp index e187dc6ec75..f6b4a6a586d 100644 --- a/runtime/src/main/cpp/Natives.cpp +++ b/runtime/src/main/cpp/Natives.cpp @@ -1,7 +1,9 @@ +#include #include #include #include "Assert.h" +#include "City.h" #include "Exceptions.h" #include "Memory.h" #include "Natives.h" @@ -21,7 +23,6 @@ KInt Kotlin_Any_hashCode(const ObjHeader* thiz) { } ArrayHeader* Kotlin_Any_toString(const ObjHeader* thiz) { - return nullptr; } @@ -118,23 +119,36 @@ void Kotlin_io_Console_print(const ArrayHeader* array) { write(STDOUT_FILENO, ByteArrayAddressOfElementAt(array, 0), array->count_); } -// String.kt -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_); +ArrayHeader* Kotlin_io_Console_readLine() { + char data[2048]; + if (!fgets(data, sizeof(data) - 1, stdin)) { + return nullptr; + } + int32_t length = strlen(data); + ArrayHeader* result = ArrayContainer(theStringTypeInfo, length).GetPlace(); + memcpy( + ByteArrayAddressOfElementAt(result, 0), + data, length); + return result; } -KChar Kotlin_String_get(const ArrayHeader* obj, KInt index) { +// String.kt +KInt Kotlin_String_compareTo(const ArrayHeader* thiz, const ArrayHeader* other) { + return memcmp(ByteArrayAddressOfElementAt(thiz, 0), + ByteArrayAddressOfElementAt(other, 0), + thiz->count_ < other->count_ ? thiz->count_ : other->count_); +} + +KChar Kotlin_String_get(const ArrayHeader* thiz, KInt index) { // TODO: support full UTF-8. - if (static_cast(index) >= obj->count_) { + if (static_cast(index) >= thiz->count_) { ThrowArrayIndexOutOfBoundsException(); } - return *ByteArrayAddressOfElementAt(obj, index); + return *ByteArrayAddressOfElementAt(thiz, index); } -KInt Kotlin_String_getStringLength(const ArrayHeader* array) { - return array->count_; +KInt Kotlin_String_getStringLength(const ArrayHeader* thiz) { + return thiz->count_; } ArrayHeader* Kotlin_String_fromUtf8Array(const ArrayHeader* array) { @@ -150,19 +164,19 @@ ArrayHeader* Kotlin_String_fromUtf8Array(const ArrayHeader* array) { } ArrayHeader* Kotlin_String_plusImpl( - const ArrayHeader* obj, const ArrayHeader* other) { + const ArrayHeader* thiz, const ArrayHeader* other) { // TODO: support UTF-8 - RuntimeAssert(obj->type_info() == theStringTypeInfo, "Must be a string"); + RuntimeAssert(thiz->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 = thiz->count_ + other->count_; ArrayHeader* result = ArrayContainer( theStringTypeInfo, result_length).GetPlace(); memcpy( ByteArrayAddressOfElementAt(result, 0), - ByteArrayAddressOfElementAt(obj, 0), - obj->count_); + ByteArrayAddressOfElementAt(thiz, 0), + thiz->count_); memcpy( - ByteArrayAddressOfElementAt(result, obj->count_), + ByteArrayAddressOfElementAt(result, thiz->count_), ByteArrayAddressOfElementAt(other, 0), other->count_); return result; @@ -178,4 +192,10 @@ KBool Kotlin_String_equals( thiz->count_) == 0; } +KInt Kotlin_String_hashCode(const ArrayHeader* thiz) { + // TODO: consider caching strings hashes. + // TODO: maybe use some simpler hashing algorithm? + return CityHash64(ByteArrayAddressOfElementAt(thiz, 0), thiz->count_); +} + } diff --git a/runtime/src/main/cpp/Natives.h b/runtime/src/main/cpp/Natives.h index 061ead4bf77..38ff27e78d7 100644 --- a/runtime/src/main/cpp/Natives.h +++ b/runtime/src/main/cpp/Natives.h @@ -65,14 +65,17 @@ KInt Kotlin_IntArray_getArrayLength(const ArrayHeader* thiz); // io/Console.kt void Kotlin_io_Console_print(const ArrayHeader* thiz); +ArrayHeader* Kotlin_io_Console_readLine(); // String.kt +KInt Kotlin_String_hashCode(const ArrayHeader* thiz); +KBool Kotlin_String_equals(const ArrayHeader* thiz, const ObjHeader* other); KInt Kotlin_String_compareTo(const ArrayHeader* thiz, const ArrayHeader* other); KChar Kotlin_String_get(const ArrayHeader* thiz, KInt index); ArrayHeader* Kotlin_String_fromUtf8Array(const ArrayHeader* array); -ArrayHeader* Kotlin_String_plusImpl(const ArrayHeader* thiz, const ArrayHeader* other); +ArrayHeader* Kotlin_String_plusImpl( + const ArrayHeader* thiz, const ArrayHeader* other); KInt Kotlin_String_getStringLength(const ArrayHeader* thiz); -KBool Kotlin_String_equals(const ArrayHeader* thiz, const ObjHeader* other); #ifdef __cplusplus } diff --git a/runtime/src/main/kotlin/kotlin_native/String.kt b/runtime/src/main/kotlin/kotlin_native/String.kt index 8220f7922eb..1387b1d0d0a 100644 --- a/runtime/src/main/kotlin/kotlin_native/String.kt +++ b/runtime/src/main/kotlin/kotlin_native/String.kt @@ -4,6 +4,9 @@ package kotlin_native external fun fromUtf8Array(array: ByteArray) : String class String { + @SymbolName("Kotlin_String_hashCode") + external public override fun hashCode(): Int + public operator fun plus(other: Any?): String { return plusImpl(other.toString()) } diff --git a/runtime/src/main/kotlin/kotlin_native/io/Console.kt b/runtime/src/main/kotlin/kotlin_native/io/Console.kt index 229573077bc..cd41ce9f612 100644 --- a/runtime/src/main/kotlin/kotlin_native/io/Console.kt +++ b/runtime/src/main/kotlin/kotlin_native/io/Console.kt @@ -1,4 +1,7 @@ package kotlin_native.io @kotlin_native.SymbolName("Kotlin_io_Console_print") -external public fun print(message: kotlin_native.String) \ No newline at end of file +external public fun print(message: kotlin_native.String) + +@kotlin_native.SymbolName("Kotlin_io_Console_readLine") +external public fun readLine(): kotlin_native.String?