From 0cfb80144aa65cca104303644d600ee44e3fac49 Mon Sep 17 00:00:00 2001 From: Abduqodiri Qurbonzoda Date: Tue, 13 Jun 2023 02:57:48 +0300 Subject: [PATCH] [K/N] Throwable.printStackTrace() should print to the stderr output Aligns with the JVM behavior. As a part of efforts to stabilize Native stdlib. --- .../runtime/src/main/cpp/Console.cpp | 41 +++++++++++++++++-- kotlin-native/runtime/src/main/cpp/Natives.h | 1 + .../runtime/src/main/cpp/Porting.cpp | 2 +- .../src/main/kotlin/kotlin/Throwable.kt | 6 +-- .../src/main/kotlin/kotlin/io/Console.kt | 4 ++ 5 files changed, 46 insertions(+), 8 deletions(-) diff --git a/kotlin-native/runtime/src/main/cpp/Console.cpp b/kotlin-native/runtime/src/main/cpp/Console.cpp index 3b503718238..fea60f2b4a4 100644 --- a/kotlin-native/runtime/src/main/cpp/Console.cpp +++ b/kotlin-native/runtime/src/main/cpp/Console.cpp @@ -32,24 +32,40 @@ using namespace kotlin; -extern "C" { +namespace { -// io/Console.kt -void Kotlin_io_Console_print(KString message) { +std_support::string kStringToUtf8(KString message) { if (message->type_info() != theStringTypeInfo) { ThrowClassCastException(message->obj(), theStringTypeInfo); } - // TODO: system stdout must be aware about UTF-8. const KChar* utf16 = CharArrayAddressOfElementAt(message, 0); std_support::string utf8; utf8.reserve(message->count_); // Replace incorrect sequences with a default codepoint (see utf8::with_replacement::default_replacement) utf8::with_replacement::utf16to8(utf16, utf16 + message->count_, back_inserter(utf8)); + return utf8; +} + +} // namespace + +extern "C" { + +// io/Console.kt +void Kotlin_io_Console_print(KString message) { + // TODO: system stdout must be aware about UTF-8. + auto utf8 = kStringToUtf8(message); kotlin::ThreadStateGuard guard(kotlin::ThreadState::kNative); konan::consoleWriteUtf8(utf8.c_str(), utf8.size()); } +void Kotlin_io_Console_printToStdErr(KString message) { + // TODO: system stderr must be aware about UTF-8. + auto utf8 = kStringToUtf8(message); + kotlin::ThreadStateGuard guard(kotlin::ThreadState::kNative); + konan::consoleErrorUtf8(utf8.c_str(), utf8.size()); +} + void Kotlin_io_Console_println(KString message) { Kotlin_io_Console_print(message); #ifndef KONAN_ANDROID @@ -62,11 +78,28 @@ void Kotlin_io_Console_println(KString message) { #endif } +void Kotlin_io_Console_printlnToStdErr(KString message) { + Kotlin_io_Console_printToStdErr(message); +#ifndef KONAN_ANDROID + Kotlin_io_Console_println0ToStdErr(); +#else + // On Android single print produces logcat entry, so no need in linefeed. + if (!kotlin::compiler::printToAndroidLogcat()) { + Kotlin_io_Console_println0ToStdErr(); + } +#endif +} + void Kotlin_io_Console_println0() { kotlin::ThreadStateGuard guard(kotlin::ThreadState::kNative); konan::consoleWriteUtf8("\n", 1); } +void Kotlin_io_Console_println0ToStdErr() { + kotlin::ThreadStateGuard guard(kotlin::ThreadState::kNative); + konan::consoleErrorUtf8("\n", 1); +} + OBJ_GETTER0(Kotlin_io_Console_readLine) { char data[4096]; int32_t result; diff --git a/kotlin-native/runtime/src/main/cpp/Natives.h b/kotlin-native/runtime/src/main/cpp/Natives.h index f7405679875..862ea7be329 100644 --- a/kotlin-native/runtime/src/main/cpp/Natives.h +++ b/kotlin-native/runtime/src/main/cpp/Natives.h @@ -87,6 +87,7 @@ extern "C" { OBJ_GETTER0(TheEmptyString); void Kotlin_io_Console_println0(); +void Kotlin_io_Console_println0ToStdErr(); void Kotlin_NativePtrArray_set(KRef thiz, KInt index, KNativePtr value); KNativePtr Kotlin_NativePtrArray_get(KConstRef thiz, KInt index); diff --git a/kotlin-native/runtime/src/main/cpp/Porting.cpp b/kotlin-native/runtime/src/main/cpp/Porting.cpp index 6d4a657ecd7..0b908641908 100644 --- a/kotlin-native/runtime/src/main/cpp/Porting.cpp +++ b/kotlin-native/runtime/src/main/cpp/Porting.cpp @@ -76,7 +76,7 @@ void consoleWriteUtf8(const char* utf8, uint32_t sizeBytes) { #endif } -NO_EXTERNAL_CALLS_CHECK void consoleErrorUtf8(const char* utf8, uint32_t sizeBytes) { +void consoleErrorUtf8(const char* utf8, uint32_t sizeBytes) { #ifdef KONAN_ANDROID if (kotlin::compiler::printToAndroidLogcat()) { // TODO: use sizeBytes! diff --git a/kotlin-native/runtime/src/main/kotlin/kotlin/Throwable.kt b/kotlin-native/runtime/src/main/kotlin/kotlin/Throwable.kt index c6a6791c326..308988593e2 100644 --- a/kotlin-native/runtime/src/main/kotlin/kotlin/Throwable.kt +++ b/kotlin-native/runtime/src/main/kotlin/kotlin/Throwable.kt @@ -50,7 +50,7 @@ public open class Throwable(open val message: String?, open val cause: Throwable (0 until stackTrace.size).map { index -> stackTrace[index].toLong() } /** - * Prints the [detailed description][Throwable.stackTraceToString] of this throwable to the standard output. + * Prints the [detailed description][Throwable.stackTraceToString] of this throwable to the standard error output. * * Note that the format of the output is not stable and may change in the future. */ @@ -75,7 +75,7 @@ public open class Throwable(open val message: String?, open val cause: Throwable private fun StringBuilder.endln() { if (printOut) { - println(this) + printlnToStdErr(this.toString()) clear() } else { appendLine() @@ -169,7 +169,7 @@ private external fun getStackTraceStrings(stackTrace: NativePtrArray): Array