Porting layer (#741)
This commit is contained in:
@@ -23,12 +23,14 @@
|
||||
#include <new>
|
||||
#include <utility>
|
||||
|
||||
#include "Porting.h"
|
||||
|
||||
inline void* konanAllocMemory(size_t size) {
|
||||
return calloc(1, size);
|
||||
return konan::calloc(1, size);
|
||||
}
|
||||
|
||||
inline void konanFreeMemory(void* memory) {
|
||||
free(memory);
|
||||
konan::free(memory);
|
||||
}
|
||||
|
||||
template <typename T, typename ...A>
|
||||
|
||||
@@ -14,11 +14,12 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "Porting.h"
|
||||
|
||||
void RuntimeAssertFailed(const char* location, const char* message) {
|
||||
// TODO: produce stacktrace and such.
|
||||
fprintf(stderr, "%s: runtime assert: %s\n", location, message);
|
||||
abort();
|
||||
char buf[1024];
|
||||
konan::snprintf(buf, sizeof(buf), "%s: runtime assert: %s\n", location, message);
|
||||
konan::consoleErrorUtf8(buf, konan::strnlen(buf, sizeof(buf)));
|
||||
konan::abort();
|
||||
}
|
||||
|
||||
@@ -13,27 +13,15 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "Assert.h"
|
||||
#include "Memory.h"
|
||||
#include "Natives.h"
|
||||
#include "KString.h"
|
||||
#include "Porting.h"
|
||||
#include "Types.h"
|
||||
|
||||
#include "utf8.h"
|
||||
|
||||
#ifdef KONAN_ANDROID
|
||||
#include <android/log.h>
|
||||
#endif
|
||||
|
||||
extern "C" {
|
||||
|
||||
// io/Console.kt
|
||||
@@ -43,11 +31,7 @@ void Kotlin_io_Console_print(KString message) {
|
||||
const KChar* utf16 = CharArrayAddressOfElementAt(message, 0);
|
||||
KStdString utf8;
|
||||
utf8::utf16to8(utf16, utf16 + message->count_, back_inserter(utf8));
|
||||
#ifdef KONAN_ANDROID
|
||||
__android_log_print(ANDROID_LOG_INFO, "Konan_main", "%s", utf8.c_str());
|
||||
#else
|
||||
write(STDOUT_FILENO, utf8.c_str(), utf8.size());
|
||||
#endif
|
||||
konan::consoleWriteUtf8(utf8.c_str(), utf8.size());
|
||||
}
|
||||
|
||||
void Kotlin_io_Console_println(KString message) {
|
||||
@@ -56,17 +40,13 @@ void Kotlin_io_Console_println(KString message) {
|
||||
}
|
||||
|
||||
void Kotlin_io_Console_println0() {
|
||||
#ifdef KONAN_ANDROID
|
||||
__android_log_print(ANDROID_LOG_INFO, "Konan_main", "\n");
|
||||
#else
|
||||
write(STDOUT_FILENO, "\n", 1);
|
||||
#endif
|
||||
konan::consoleWriteUtf8("\n", 1);
|
||||
}
|
||||
|
||||
OBJ_GETTER0(Kotlin_io_Console_readLine) {
|
||||
char data[4096];
|
||||
if (!fgets(data, sizeof(data) - 1, stdin)) {
|
||||
return nullptr;
|
||||
if (konan::consoleReadUtf8(data, sizeof(data)) == 0) {
|
||||
RETURN_OBJ(nullptr);
|
||||
}
|
||||
RETURN_RESULT_OF(CreateStringFromCString, data);
|
||||
}
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
#include "Memory.h"
|
||||
#include "Natives.h"
|
||||
#include "KString.h"
|
||||
#include "Porting.h"
|
||||
#include "Types.h"
|
||||
|
||||
#include "utf8.h"
|
||||
@@ -1015,16 +1016,6 @@ KInt Kotlin_String_lastIndexOfChar(KString thiz, KChar ch, KInt fromIndex) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
static void* memmem(const void* big, size_t big_len, const void* little, size_t little_len) {
|
||||
for (size_t i = 0; i + little_len <= big_len; ++i) {
|
||||
void* pos = ((char*)big) + i;
|
||||
if (memcmp(little, pos, little_len) == 0) return pos;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
#endif
|
||||
|
||||
// TODO: or code up Knuth-Moris-Pratt.
|
||||
KInt Kotlin_String_indexOfString(KString thiz, KString other, KInt fromIndex) {
|
||||
if (fromIndex < 0 || fromIndex > thiz->count_ ||
|
||||
@@ -1038,8 +1029,8 @@ KInt Kotlin_String_indexOfString(KString thiz, KString other, KInt fromIndex) {
|
||||
KInt count = thiz->count_;
|
||||
const KChar* thizRaw = CharArrayAddressOfElementAt(thiz, fromIndex);
|
||||
const KChar* otherRaw = CharArrayAddressOfElementAt(other, 0);
|
||||
void* result = memmem(thizRaw, (thiz->count_ - fromIndex) * sizeof(KChar),
|
||||
otherRaw, other->count_ * sizeof(KChar));
|
||||
void* result = konan::memmem(thizRaw, (thiz->count_ - fromIndex) * sizeof(KChar),
|
||||
otherRaw, other->count_ * sizeof(KChar));
|
||||
if (result == nullptr) return -1;
|
||||
|
||||
return (reinterpret_cast<intptr_t>(result) - reinterpret_cast<intptr_t>(
|
||||
|
||||
@@ -0,0 +1,127 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifdef KONAN_ANDROID
|
||||
#include <android/log.h>
|
||||
#endif
|
||||
#include <stdarg.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#if KONAN_WINDOWS
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
#include <chrono>
|
||||
|
||||
#include "Porting.h"
|
||||
|
||||
namespace konan {
|
||||
|
||||
// Console operations.
|
||||
void consoleInit() {
|
||||
#if KONAN_WINDOWS
|
||||
// Note that this code enforces UTF-8 console output, so we may want to rethink
|
||||
// how we perform console IO, if it turns out, that UTF-16 is better output format.
|
||||
::SetConsoleCP(CP_UTF8);
|
||||
::SetConsoleOutputCP(CP_UTF8);
|
||||
#endif
|
||||
}
|
||||
|
||||
void consoleWriteUtf8(const void* utf8, uint32_t sizeBytes) {
|
||||
#ifdef KONAN_ANDROID
|
||||
// TODO: use sizeBytes!
|
||||
__android_log_print(ANDROID_LOG_INFO, "Konan_main", "%s", utf8);
|
||||
#else
|
||||
::write(STDOUT_FILENO, utf8, sizeBytes);
|
||||
#endif
|
||||
}
|
||||
|
||||
void consoleErrorUtf8(const void* utf8, uint32_t sizeBytes) {
|
||||
#ifdef KONAN_ANDROID
|
||||
// TODO: use sizeBytes!
|
||||
__android_log_print(ANDROID_LOG_ERROR, "Konan_main", "%s", utf8);
|
||||
#else
|
||||
::write(STDERR_FILENO, utf8, sizeBytes);
|
||||
#endif
|
||||
}
|
||||
|
||||
uint32_t consoleReadUtf8(void* utf8, uint32_t maxSizeBytes) {
|
||||
char* result = ::fgets(reinterpret_cast<char*>(utf8), maxSizeBytes - 1, stdin);
|
||||
if (result == nullptr) return 0;
|
||||
return ::strlen(result);
|
||||
}
|
||||
|
||||
// Process execution.
|
||||
void abort() {
|
||||
::abort();
|
||||
}
|
||||
|
||||
// String/byte operations.
|
||||
// memcpy/memmove are not here intentionally, as frequently implemented/optimized
|
||||
// by C compiler.
|
||||
void* memmem(const void *big, size_t bigLen, const void *little, size_t littleLen) {
|
||||
#if KONAN_WINDOWS
|
||||
for (size_t i = 0; i + littleLen <= bigLen; ++i) {
|
||||
void* pos = ((char*)big) + i;
|
||||
if (::memcmp(little, pos, littleLen) == 0) return pos;
|
||||
}
|
||||
return nullptr;
|
||||
#else
|
||||
return ::memmem(big, bigLen, little, littleLen);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
int snprintf(char* buffer, size_t size, const char* format, ...) {
|
||||
va_list args;
|
||||
va_start(args, format);
|
||||
int rv = ::vsnprintf(buffer, size, format, args);
|
||||
va_end(args);
|
||||
return rv;
|
||||
}
|
||||
|
||||
size_t strnlen(const char* buffer, size_t maxSize) {
|
||||
return ::strnlen(buffer, maxSize);
|
||||
}
|
||||
|
||||
// Memory operations.
|
||||
void* calloc(size_t count, size_t size) {
|
||||
return ::calloc(count, size);
|
||||
}
|
||||
|
||||
void free(void* pointer) {
|
||||
return ::free(pointer);
|
||||
}
|
||||
|
||||
// Time operations.
|
||||
using namespace std::chrono;
|
||||
|
||||
uint64_t getTimeMillis() {
|
||||
return duration_cast<milliseconds>(high_resolution_clock::now().time_since_epoch()).count();
|
||||
}
|
||||
|
||||
uint64_t getTimeNanos() {
|
||||
return duration_cast<nanoseconds>(high_resolution_clock::now().time_since_epoch()).count();
|
||||
}
|
||||
|
||||
uint64_t getTimeMicros() {
|
||||
return duration_cast<microseconds>(high_resolution_clock::now().time_since_epoch()).count();
|
||||
}
|
||||
|
||||
} // namespace konan
|
||||
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef RUNTIME_PORTING_H
|
||||
#define RUNTIME_PORTING_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
|
||||
namespace konan {
|
||||
|
||||
// Console operations.
|
||||
void consoleInit();
|
||||
void consoleWriteUtf8(const void* utf8, uint32_t sizeBytes);
|
||||
void consoleErrorUtf8(const void* utf8, uint32_t sizeBytes);
|
||||
uint32_t consoleReadUtf8(void* utf8, uint32_t maxSizeBytes);
|
||||
|
||||
// Process control.
|
||||
void abort();
|
||||
|
||||
// String/byte operations.
|
||||
// memcpy/memmove/memcmp are not here intentionally, as frequently implemented/optimized
|
||||
// by C compiler.
|
||||
void* memmem(const void *big, size_t bigLen, const void *little, size_t littleLen);
|
||||
int snprintf(char* buffer, size_t size, const char* format, ...);
|
||||
size_t strnlen(const char* buffer, size_t maxSize);
|
||||
|
||||
// Memory operations.
|
||||
void* calloc(size_t count, size_t size);
|
||||
void free(void* ptr);
|
||||
|
||||
// Time operations.
|
||||
uint64_t getTimeMillis();
|
||||
uint64_t getTimeMicros();
|
||||
uint64_t getTimeNanos();
|
||||
|
||||
} // namespace konan
|
||||
|
||||
#endif // RUNTIME_PORTING_H
|
||||
@@ -15,12 +15,10 @@
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#if KONAN_WINDOWS
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
#include "Alloc.h"
|
||||
#include "Memory.h"
|
||||
#include "Porting.h"
|
||||
#include "Runtime.h"
|
||||
|
||||
struct RuntimeState {
|
||||
@@ -48,9 +46,7 @@ void InitOrDeinitGlobalVariables(int initialize) {
|
||||
|
||||
} // namespace
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void AppendToInitializersTail(InitNode *next) {
|
||||
// TODO: use RuntimeState.
|
||||
@@ -68,12 +64,7 @@ RuntimeState* InitRuntime() {
|
||||
result->memoryState = InitMemory();
|
||||
// Keep global variables in state as well.
|
||||
InitOrDeinitGlobalVariables(true);
|
||||
#if KONAN_WINDOWS
|
||||
// Note that this code enforces UTF-8 console output, so we may want to rethink
|
||||
// how we perform console IO, if it turns out, that UTF-16 is better output format.
|
||||
SetConsoleCP(CP_UTF8);
|
||||
SetConsoleOutputCP(CP_UTF8);
|
||||
#endif
|
||||
konan::consoleInit();
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -85,6 +76,4 @@ void DeinitRuntime(RuntimeState* state) {
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
} // extern "C"
|
||||
|
||||
@@ -1,21 +1,35 @@
|
||||
#include <chrono>
|
||||
#include "Types.h"
|
||||
#include "Natives.h"
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
using namespace std::chrono;
|
||||
#include "Natives.h"
|
||||
#include "Porting.h"
|
||||
#include "Types.h"
|
||||
|
||||
extern "C" {
|
||||
|
||||
KLong Kotlin_system_getTimeMillis() {
|
||||
return duration_cast<milliseconds>(high_resolution_clock::now().time_since_epoch()).count();
|
||||
return konan::getTimeMillis();
|
||||
}
|
||||
|
||||
KLong Kotlin_system_getTimeNanos() {
|
||||
return duration_cast<nanoseconds>(high_resolution_clock::now().time_since_epoch()).count();
|
||||
return konan::getTimeNanos();
|
||||
}
|
||||
|
||||
KLong Kotlin_system_getTimeMicros() {
|
||||
return duration_cast<microseconds>(high_resolution_clock::now().time_since_epoch()).count();
|
||||
return konan::getTimeMicros();
|
||||
}
|
||||
|
||||
} // extern "C"
|
||||
} // extern "C"
|
||||
|
||||
@@ -17,9 +17,7 @@
|
||||
#include "Types.h"
|
||||
#include "Exceptions.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
KBoolean IsInstance(const ObjHeader* obj, const TypeInfo* type_info) {
|
||||
// We assume null check is handled by caller.
|
||||
@@ -52,6 +50,4 @@ void CheckInstance(const ObjHeader* obj, const TypeInfo* type_info) {
|
||||
ThrowClassCastException();
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
} // extern "C"
|
||||
|
||||
Reference in New Issue
Block a user