Porting layer (#741)

This commit is contained in:
Nikolay Igotti
2017-07-14 14:23:52 +03:00
committed by GitHub
parent 747922ce00
commit 1565371cda
9 changed files with 222 additions and 70 deletions
+4 -2
View File
@@ -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>
+5 -4
View File
@@ -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();
}
+5 -25
View File
@@ -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);
}
+3 -12
View File
@@ -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>(
+127
View File
@@ -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
+52
View File
@@ -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
+3 -14
View File
@@ -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"
+22 -8
View File
@@ -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"
+1 -5
View File
@@ -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"