[K/N] Remove code for deprecated targets from runtime ^KT-59008

This commit is contained in:
Alexander Shabalin
2023-08-10 18:09:18 +02:00
committed by Space Team
parent e4a51dfa1b
commit 958d613911
59 changed files with 89 additions and 10406 deletions
@@ -7,6 +7,7 @@
#include <atomic>
#include <cstdint>
#include <cstdlib>
#include <cstring>
#include <limits>
@@ -77,7 +78,7 @@ bool SweepExtraObject(mm::ExtraObjectData* extraObject, gc::GCHandle::GCSweepExt
void* SafeAlloc(uint64_t size) noexcept {
if (size > std::numeric_limits<size_t>::max()) {
konan::consoleErrorf("Out of memory trying to allocate %" PRIu64 "bytes. Aborting.\n", size);
konan::abort();
std::abort();
}
void* memory;
bool error;
@@ -97,7 +98,7 @@ void* SafeAlloc(uint64_t size) noexcept {
}
if (error) {
konan::consoleErrorf("Out of memory trying to allocate %" PRIu64 "bytes: %s. Aborting.\n", size, strerror(errno));
konan::abort();
std::abort();
}
auto previousSize = allocatedBytesCounter.fetch_add(static_cast<size_t>(size), std::memory_order_relaxed);
OnMemoryAllocation(previousSize + static_cast<size_t>(size));
@@ -7,6 +7,7 @@
#include <algorithm>
#include <cinttypes>
#include <cstdlib>
#include <memory>
#include <mutex>
#include <type_traits>
@@ -105,7 +106,7 @@ public:
// TODO: This should throw OutOfMemoryError in the future if we add hard memory limits instead
// of limiting at virtual address space boundary.
konan::consoleErrorf("Out of memory trying to allocate %" PRIu64 " bytes. Aborting.\n", totalSize);
konan::abort();
std::abort();
}
RuntimeAssert(IsAligned(ptr, DataAlignment), "Allocator returned unaligned to %zu pointer %p", DataAlignment, ptr);
return unique_ptr<Node>(new (ptr) Node());
@@ -5,34 +5,17 @@
#include "ObjectAlloc.hpp"
#ifndef KONAN_NO_THREADS
#include <atomic>
#endif
#include "Memory.h"
#if KONAN_INTERNAL_DLMALLOC
extern "C" void* dlcalloc(size_t, size_t);
extern "C" void dlfree(void*);
#define callocImpl dlcalloc
#define freeImpl dlfree
#else
#include <cstdlib>
#define callocImpl ::calloc
#define freeImpl ::free
#endif
using namespace kotlin;
namespace {
#ifndef KONAN_NO_THREADS
std::atomic<size_t> allocatedBytesCounter = 0;
#else
size_t allocatedBytesCounter = 0;
#endif
} // namespace
@@ -40,25 +23,16 @@ void alloc::initObjectPool() noexcept {}
void* alloc::allocateInObjectPool(size_t size) noexcept {
// TODO: Check that alignment to kObjectAlignment is satisfied.
void* result = callocImpl(1, size);
#ifndef KONAN_NO_THREADS
void* result = ::calloc(1, size);
auto newSize = allocatedBytesCounter.fetch_add(size, std::memory_order_relaxed);
newSize += size;
#else
allocatedBytesCounter += size;
auto newSize = allocatedBytesCounter;
#endif
OnMemoryAllocation(newSize);
return result;
}
void alloc::freeInObjectPool(void* ptr, size_t size) noexcept {
#ifndef KONAN_NO_THREADS
allocatedBytesCounter.fetch_sub(size, std::memory_order_relaxed);
#else
allocatedBytesCounter -= size;
#endif
freeImpl(ptr);
::free(ptr);
}
void alloc::compactObjectPoolInCurrentThread() noexcept {}
@@ -66,9 +40,5 @@ void alloc::compactObjectPoolInCurrentThread() noexcept {}
void alloc::compactObjectPoolInMainThread() noexcept {}
size_t alloc::allocatedBytes() noexcept {
#ifndef KONAN_NO_THREADS
return allocatedBytesCounter.load();
#else
return allocatedBytesCounter;
#endif
}
@@ -2,8 +2,6 @@
#include "Porting.h"
#include <typeinfo>
#ifndef KONAN_NO_EXCEPTIONS
std::type_info const* ExceptionObjHolderRTTI;
// Just some DCE-surviving code referencing RTTI of ExceptionObjHolder.
@@ -11,5 +9,3 @@ std::type_info const* ExceptionObjHolderRTTI;
void referenceExceptionObjHolderRTTI() {
ExceptionObjHolderRTTI = &typeid(ExceptionObjHolder);
}
#endif
@@ -4,15 +4,16 @@
*/
#include "GCStatistics.hpp"
#include "Mutex.hpp"
#include "Porting.h"
#include "Types.h"
#include "Logging.hpp"
#include "ThreadData.hpp"
#include "std_support/Optional.hpp"
#include <cinttypes>
#include <limits>
#include <optional>
#include "Logging.hpp"
#include "Mutex.hpp"
#include "Porting.h"
#include "ThreadData.hpp"
#include "Types.h"
using namespace kotlin;
@@ -6,13 +6,12 @@
#pragma once
#include <cstdint>
#include <pthread.h>
#include <optional>
#include "Common.h"
#include "Logging.hpp"
#include "Porting.h"
#include "Utils.hpp"
#include "std_support/Optional.hpp"
#define GCLogInfo(epoch, format, ...) RuntimeLogInfo({kTagGC}, "Epoch #%" PRIu64 ": " format, epoch, ##__VA_ARGS__)
#define GCLogDebug(epoch, format, ...) RuntimeLogDebug({kTagGC}, "Epoch #%" PRIu64 ": " format, epoch, ##__VA_ARGS__)
@@ -48,11 +48,6 @@ extern "C" KInt Konan_run_start(int argc, const char** argv) {
}
extern "C" RUNTIME_USED int Init_and_run_start(int argc, const char** argv, int memoryDeInit) {
#ifdef KONAN_NO_CTORS_SECTION
extern void _Konan_constructors(void);
_Konan_constructors();
#endif
Kotlin_initRuntimeIfNeeded();
Kotlin_mm_switchThreadStateRunnable();
@@ -72,20 +67,3 @@ extern "C" RUNTIME_USED int Konan_main_standalone(int argc, const char** argv) {
#endif
return Init_and_run_start(argc, argv, 1);
}
#ifdef KONAN_WASM
// Before we pass control to Konan_main, we need to obtain argv elements
// from the javascript world.
extern "C" int Konan_js_arg_size(int index);
extern "C" int Konan_js_fetch_arg(int index, char* ptr);
extern "C" RUNTIME_USED int Konan_js_main(int argc, int memoryDeInit) {
char** argv = (char**)std_support::calloc(1, argc);
for (int i = 0; i< argc; ++i) {
argv[i] = (char*)std_support::calloc(1, Konan_js_arg_size(i));
Konan_js_fetch_arg(i, argv[i]);
}
return Init_and_run_start(argc, (const char**)argv, memoryDeInit);
}
#endif
+2 -26
View File
@@ -5,16 +5,12 @@
template <typename T>
ALWAYS_INLINE inline T atomicAdd(volatile T* where, T what) {
#ifndef KONAN_NO_THREADS
return __sync_add_and_fetch(where, what);
#else
return *where += what;
#endif
}
#pragma clang diagnostic push
#if (KONAN_ANDROID || KONAN_IOS || KONAN_WATCHOS || KONAN_LINUX) && (KONAN_ARM32 || KONAN_X86 || KONAN_MIPS32 || KONAN_MIPSEL32)
#if (KONAN_ANDROID || KONAN_IOS || KONAN_WATCHOS || KONAN_LINUX) && (KONAN_ARM32 || KONAN_X86)
// On 32-bit Android clang generates library calls for "large" atomic operations
// and warns about "significant performance penalty". See more details here:
// https://github.com/llvm/llvm-project/blob/ce56e1a1cc5714f4af5675dd963cfebed766d9e1/clang/lib/CodeGen/CGAtomic.cpp#L775
@@ -25,20 +21,10 @@ ALWAYS_INLINE inline T atomicAdd(volatile T* where, T what) {
// as if (std::atomic<T> where).compare_exchange_strong(expectedValue, newValue)
template <typename T>
ALWAYS_INLINE inline bool compareExchange(volatile T& where, T &expectedValue, T newValue) {
#ifndef KONAN_NO_THREADS
#ifdef KONAN_NO_64BIT_ATOMIC
static_assert(sizeof(T) <= 4);
#endif
return __atomic_compare_exchange_n(&where, &expectedValue, newValue, false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST);
#else
T oldValue = where;
if (oldValue == expectedValue) {
where = newValue;
return true;
}
expectedValue = oldValue;
return false;
#endif
}
template <typename T>
@@ -55,14 +41,10 @@ ALWAYS_INLINE inline bool compareAndSet(volatile T* where, T expectedValue, T ne
template <int model = __ATOMIC_SEQ_CST, typename T>
ALWAYS_INLINE inline void atomicSet(volatile T* where, T what) {
#ifndef KONAN_NO_THREADS
#ifdef KONAN_NO_64BIT_ATOMIC
static_assert(sizeof(T) <= 4);
#endif
__atomic_store(where, &what, model);
#else
*where = what;
#endif
}
template <typename T>
@@ -73,16 +55,12 @@ ALWAYS_INLINE inline void atomicSetRelease(volatile T* where, T what) {
template <int model = __ATOMIC_SEQ_CST, typename T>
ALWAYS_INLINE inline T atomicGet(volatile const T* where) {
#ifndef KONAN_NO_THREADS
#ifdef KONAN_NO_64BIT_ATOMIC
static_assert(sizeof(T) <= 4);
#endif
T what;
__atomic_load(where, &what, model);
return what;
#else
return *where;
#endif
}
template <typename T>
@@ -98,9 +76,7 @@ ALWAYS_INLINE inline T atomicGetRelaxed(volatile const T* where) {
#pragma clang diagnostic pop
static ALWAYS_INLINE inline void synchronize() {
#ifndef KONAN_NO_THREADS
__sync_synchronize();
#endif
}
#endif // RUNTIME_ATOMIC_H
#endif // RUNTIME_ATOMIC_H
@@ -51,9 +51,6 @@ void disposeCleaner(CleanerImpl* thiz) {
} // namespace
RUNTIME_NOTHROW void DisposeCleaner(KRef thiz) {
#if KONAN_NO_EXCEPTIONS
disposeCleaner(reinterpret_cast<CleanerImpl*>(thiz));
#else
try {
disposeCleaner(reinterpret_cast<CleanerImpl*>(thiz));
} catch (...) {
@@ -61,7 +58,6 @@ RUNTIME_NOTHROW void DisposeCleaner(KRef thiz) {
// and write to iOS crash log.
std::terminate();
}
#endif
}
void ShutdownCleaners(bool executeScheduledCleaners) {
@@ -40,11 +40,7 @@
#define OPTNONE __attribute__((optnone))
#if KONAN_NO_THREADS
#define THREAD_LOCAL_VARIABLE
#else
#define THREAD_LOCAL_VARIABLE __thread
#endif
#define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0]))
@@ -7,18 +7,7 @@
#define RUNTIME_COMPILER_CONSTANTS_H
#include <cstdint>
#if __has_include(<string_view>)
#include <string_view>
#elif __has_include(<experimental/string_view>)
// TODO: Remove when wasm32 is gone.
#include <xlocale.h>
#include <experimental/string_view>
namespace std {
using string_view = std::experimental::string_view;
}
#else
#error "No <string_view>"
#endif
#include "Common.h"
@@ -13,8 +13,8 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <cstdlib>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
@@ -38,29 +38,19 @@ extern "C" void ReportUnhandledException(KRef exception);
void ThrowException(KRef exception) {
RuntimeAssert(exception != nullptr && IsInstanceInternal(exception, theThrowableTypeInfo),
"Throwing something non-throwable");
#if KONAN_NO_EXCEPTIONS
PrintThrowable(exception);
RuntimeCheck(false, "Exceptions unsupported");
#else
ExceptionObjHolder::Throw(exception);
#endif
}
void HandleCurrentExceptionWhenLeavingKotlinCode() {
#if KONAN_NO_EXCEPTIONS
RuntimeCheck(false, "Exceptions unsupported");
#else
try {
std::rethrow_exception(std::current_exception());
} catch (ExceptionObjHolder& e) {
std::terminate(); // Terminate when it's a kotlin exception.
}
#endif
}
namespace {
#if !KONAN_NO_EXCEPTIONS
class {
/**
* Timeout 5 sec for concurrent (second) terminate attempt to give a chance the first one to finish.
@@ -73,7 +63,7 @@ class {
if (compareAndSet(&terminatingFlag, 0, 1)) {
block();
// block() is supposed to be NORETURN, otherwise go to normal abort()
konan::abort();
std::abort();
} else {
kotlin::NativeOrUnregisteredThreadGuard guard(/* reentrant = */ true);
sleep(timeoutSec);
@@ -82,48 +72,33 @@ class {
_Exit(EXIT_FAILURE); // force exit
}
} concurrentTerminateWrapper;
#endif
void RUNTIME_NORETURN terminateWithUnhandledException(KRef exception) {
kotlin::AssertThreadState(kotlin::ThreadState::kRunnable);
#if KONAN_NO_EXCEPTIONS
RuntimeCheck(false, "Exceptions unsupported");
#else
concurrentTerminateWrapper([exception]() {
ReportUnhandledException(exception);
#if KONAN_REPORT_BACKTRACE_TO_IOS_CRASH_LOG
ReportBacktraceToIosCrashLog(exception);
#endif
konan::abort();
std::abort();
});
#endif
}
void processUnhandledException(KRef exception) noexcept {
kotlin::AssertThreadState(kotlin::ThreadState::kRunnable);
#if KONAN_NO_EXCEPTIONS
terminateWithUnhandledException(exception);
#else
try {
Kotlin_runUnhandledExceptionHook(exception);
} catch (ExceptionObjHolder& e) {
terminateWithUnhandledException(e.GetExceptionObject());
}
#endif
}
} // namespace
ALWAYS_INLINE RUNTIME_NOTHROW OBJ_GETTER(Kotlin_getExceptionObject, void* holder) {
#if !KONAN_NO_EXCEPTIONS
RETURN_OBJ(static_cast<ExceptionObjHolder*>(holder)->GetExceptionObject());
#else
RETURN_OBJ(nullptr);
#endif
}
#if !KONAN_NO_EXCEPTIONS
namespace {
// Copy, move and assign would be safe, but not much useful, so let's delete all (rule of 5)
class TerminateHandler : private kotlin::Pinned {
@@ -191,14 +166,6 @@ void SetKonanTerminateHandler() {
TerminateHandler::install();
}
#else // !KONAN_NO_EXCEPTIONS
void SetKonanTerminateHandler() {
// Nothing to do.
}
#endif // !KONAN_NO_EXCEPTIONS
extern "C" void RUNTIME_NORETURN Kotlin_terminateWithUnhandledException(KRef exception) {
kotlin::AssertThreadState(kotlin::ThreadState::kRunnable);
terminateWithUnhandledException(exception);
@@ -14,8 +14,10 @@
* limitations under the License.
*/
#include "ExecFormat.h"
#include <cstdio>
#include "Porting.h"
#include "std_support/CStdlib.hpp"
#include "std_support/New.hpp"
@@ -357,7 +359,7 @@ extern "C" bool AddressToSymbol(const void* address, char* resultBuffer, size_t
} else if (info.dli_fname) {
result = info.dli_fname;
resultOffset = reinterpret_cast<ptrdiff_t>(address) - reinterpret_cast<ptrdiff_t>(info.dli_fbase);
} else if (0 < konan::snprintf(symbuf, sizeof(symbuf), "%p", info.dli_saddr)) {
} else if (0 < std::snprintf(symbuf, sizeof(symbuf), "%p", info.dli_saddr)) {
result = symbuf;
resultOffset = reinterpret_cast<ptrdiff_t>(address) - reinterpret_cast<ptrdiff_t>(info.dli_saddr);
} else {
@@ -5,6 +5,8 @@
#include "Format.h"
#include <cstdio>
#include "Porting.h"
using namespace kotlin;
@@ -23,7 +25,7 @@ std_support::span<char> kotlin::VFormatToSpan(std_support::span<char> buffer, co
buffer.front() = '\0';
return buffer;
}
int written = konan::vsnprintf(buffer.data(), buffer.size(), format, args);
int written = std::vsnprintf(buffer.data(), buffer.size(), format, args);
// Consider this a failure, nothing has been written. TODO: Should this be an exception/RuntimeAssert?
if (written < 0) return buffer;
// If `written` is larger than the buffer size, just pretend we filled the entire buffer (ignoring the trailing \0).
@@ -8,10 +8,10 @@
#include <cstddef>
#include <iterator>
#include <limits>
#include <optional>
#include "KAssert.h"
#include "Utils.hpp"
#include "std_support/Optional.hpp"
namespace kotlin {
@@ -1,81 +0,0 @@
/*
* Copyright 2010-2018 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.
*/
#include "Porting.h"
#include "Types.h"
typedef KInt Arena;
typedef KInt Object;
typedef KInt Pointer;
#ifndef KONAN_WASM
extern "C" {
// These functions are implemented in JS file for WASM and are not available on other platforms.
RUNTIME_NORETURN Arena Konan_js_allocateArena() {
RuntimeAssert(false, "JavaScript interop is disabled");
konan::abort();
}
RUNTIME_NORETURN void Konan_js_freeArena(Arena arena) {
RuntimeAssert(false, "JavaScript interop is disabled");
konan::abort();
}
RUNTIME_NORETURN void Konan_js_pushIntToArena(Arena arena, KInt value) {
RuntimeAssert(false, "JavaScript interop is disabled");
konan::abort();
}
RUNTIME_NORETURN KInt Konan_js_getInt(Arena arena,
Object obj,
Pointer propertyPtr,
KInt propertyLen) {
RuntimeAssert(false, "JavaScript interop is disabled");
konan::abort();
}
RUNTIME_NORETURN KInt Konan_js_getProperty(Arena arena,
Object obj,
Pointer propertyPtr,
KInt propertyLen) {
RuntimeAssert(false, "JavaScript interop is disabled");
konan::abort();
}
RUNTIME_NORETURN void Konan_js_setFunction(Arena arena,
Object obj,
Pointer propertyName,
KInt propertyLength,
KInt function) {
RuntimeAssert(false, "JavaScript interop is disabled");
konan::abort();
}
RUNTIME_NORETURN void Konan_js_setString(Arena arena,
Object obj,
Pointer propertyName,
KInt propertyLength,
Pointer stringPtr,
KInt stringLength) {
RuntimeAssert(false, "JavaScript interop is disabled");
konan::abort();
}
}; // extern "C"
#endif // #ifndef KONAN_WASM
@@ -7,6 +7,7 @@
#include <array>
#include <cstdarg>
#include <cstdlib>
#include "std_support/Span.hpp"
#include "CallsChecker.hpp"
@@ -72,5 +73,5 @@ RUNTIME_NORETURN void internal::RuntimeAssertFailedPanic(bool allowStacktrace, c
va_start(args, format);
PrintAssert(allowStacktrace, location, format, args);
va_end(args);
konan::abort();
std::abort();
}
+13 -8
View File
@@ -14,6 +14,7 @@
* limitations under the License.
*/
#include <cstdio>
#include <limits>
#include <string.h>
@@ -40,10 +41,12 @@ typedef KChar* utf8to16(const char*, const char*, KChar*);
typedef KStdStringInserter utf16to8(const KChar*,const KChar*, KStdStringInserter);
KStdStringInserter utf16toUtf8OrThrow(const KChar* start, const KChar* end, KStdStringInserter result) {
TRY_CATCH(result = utf8::utf16to8(start, end, result),
result = utf8::unchecked::utf16to8(start, end, result),
ThrowCharacterCodingException());
return result;
try {
result = utf8::utf16to8(start, end, result);
return result;
} catch (...) {
ThrowCharacterCodingException();
}
}
template<utf8to16 conversion>
@@ -70,9 +73,11 @@ OBJ_GETTER(unsafeUtf16ToUtf8Impl, KString thiz, KInt start, KInt size) {
OBJ_GETTER(utf8ToUtf16OrThrow, const char* rawString, size_t rawStringLength) {
const char* end = rawString + rawStringLength;
uint32_t charCount;
TRY_CATCH(charCount = utf8::utf16_length(rawString, end),
charCount = utf8::unchecked::utf16_length(rawString, end),
ThrowCharacterCodingException());
try {
charCount = utf8::utf16_length(rawString, end);
} catch (...) {
ThrowCharacterCodingException();
}
RETURN_RESULT_OF(utf8ToUtf16Impl<utf8::unchecked::utf8to16>, rawString, end, charCount);
}
@@ -307,7 +312,7 @@ KInt Kotlin_StringBuilder_insertInt(KRef builder, KInt position, KInt value) {
auto toArray = builder->array();
RuntimeAssert(toArray->count_ >= static_cast<uint32_t>(11 + position), "must be true");
char cstring[12];
auto length = konan::snprintf(cstring, sizeof(cstring), "%d", value);
auto length = std::snprintf(cstring, sizeof(cstring), "%d", value);
RuntimeAssert(length >= 0, "This should never happen"); // may be overkill
RuntimeAssert(static_cast<size_t>(length) < sizeof(cstring), "Unexpectedly large value"); // Can't be, but this is what sNprintf for
auto* from = &cstring[0];
@@ -20,8 +20,6 @@
#include "DoubleConversions.h"
#include "Exceptions.h"
#include "KotlinMath.h"
#include "ReturnSlot.h"
#include "Types.h"
#if (__MINGW32__ || __MINGW64__)
@@ -96,10 +94,6 @@ namespace {
extern "C" {
#ifndef KONAN_NO_MATH // We have a platform math library. Call its math functions.
#ifndef KONAN_WASM // Use libm.
// region Double math.
KDouble Kotlin_math_sin(KDouble x) { return sin(x); }
@@ -261,332 +255,4 @@ KLong Kotlin_math_absl(KLong x) { return llabs(x); }
// endregion
#else // KONAN_WASM defined. Use JS math implementation.
#define RETURN_RESULT_OF_JS_CALL(call, doubleArg) { \
call(doubleUpper(doubleArg), doubleLower(doubleArg)); \
return ReturnSlot_getDouble(); \
}
#define RETURN_RESULT_OF_JS_CALL2(call, doubleArg1, doubleArg2) { \
call(doubleUpper(doubleArg1), \
doubleLower(doubleArg1), \
doubleUpper(doubleArg2), \
doubleLower(doubleArg2)); \
return ReturnSlot_getDouble(); \
}
KDouble Kotlin_math_sin(KDouble x) { RETURN_RESULT_OF_JS_CALL(knjs__Math_sin, x); }
KDouble Kotlin_math_cos(KDouble x) { RETURN_RESULT_OF_JS_CALL(knjs__Math_cos, x); }
KDouble Kotlin_math_tan(KDouble x) { RETURN_RESULT_OF_JS_CALL(knjs__Math_tan, x); }
KDouble Kotlin_math_asin(KDouble x) { RETURN_RESULT_OF_JS_CALL(knjs__Math_asin, x); }
KDouble Kotlin_math_acos(KDouble x) { RETURN_RESULT_OF_JS_CALL(knjs__Math_acos, x); }
KDouble Kotlin_math_atan(KDouble x) { RETURN_RESULT_OF_JS_CALL(knjs__Math_atan, x); }
KDouble Kotlin_math_sinh(KDouble x) { RETURN_RESULT_OF_JS_CALL(knjs__Math_sinh, x); }
KDouble Kotlin_math_cosh(KDouble x) { RETURN_RESULT_OF_JS_CALL(knjs__Math_cosh, x); }
KDouble Kotlin_math_tanh(KDouble x) { RETURN_RESULT_OF_JS_CALL(knjs__Math_tanh, x); }
KDouble Kotlin_math_asinh(KDouble x) { RETURN_RESULT_OF_JS_CALL(knjs__Math_asinh, x); }
KDouble Kotlin_math_acosh(KDouble x) { RETURN_RESULT_OF_JS_CALL(knjs__Math_acosh, x); }
KDouble Kotlin_math_atanh(KDouble x) { RETURN_RESULT_OF_JS_CALL(knjs__Math_atanh, x); }
KDouble Kotlin_math_sqrt(KDouble x) { RETURN_RESULT_OF_JS_CALL(knjs__Math_sqrt, x); }
KDouble Kotlin_math_exp(KDouble x) { RETURN_RESULT_OF_JS_CALL(knjs__Math_exp, x); }
KDouble Kotlin_math_expm1(KDouble x) { RETURN_RESULT_OF_JS_CALL(knjs__Math_expm1, x); }
KDouble Kotlin_math_ln(KDouble x) { RETURN_RESULT_OF_JS_CALL(knjs__Math_log, x); }
KDouble Kotlin_math_log10(KDouble x) { RETURN_RESULT_OF_JS_CALL(knjs__Math_log10, x); }
KDouble Kotlin_math_log2(KDouble x) { RETURN_RESULT_OF_JS_CALL(knjs__Math_log2, x); }
KDouble Kotlin_math_ln1p(KDouble x) { RETURN_RESULT_OF_JS_CALL(knjs__Math_log1p, x); }
KDouble Kotlin_math_ceil(KDouble x) { RETURN_RESULT_OF_JS_CALL(knjs__Math_ceil, x); }
KDouble Kotlin_math_floor(KDouble x) { RETURN_RESULT_OF_JS_CALL(knjs__Math_floor, x); }
KDouble Kotlin_math_round(KDouble x) {
if (fmod(x, 0.5) != 0.0) {
RETURN_RESULT_OF_JS_CALL(knjs__Math_round, x);
}
KDouble f = floor(x);
return (fmod(f, 2) == 0.0) ? f : ceil(x);
}
KDouble Kotlin_math_abs(KDouble x) { RETURN_RESULT_OF_JS_CALL(knjs__Math_abs, x); }
KDouble Kotlin_math_atan2(KDouble y, KDouble x) { RETURN_RESULT_OF_JS_CALL2(knjs__Math_atan2, y, x); }
KDouble Kotlin_math_hypot(KDouble x, KDouble y) { RETURN_RESULT_OF_JS_CALL2(knjs__Math_hypot, x, y); }
KDouble Kotlin_math_cbrt(KDouble x) { RETURN_RESULT_OF_JS_CALL(knjs__Math_cbrt, x); }
// extensions
KDouble Kotlin_math_Double_pow(KDouble thiz, KDouble x) { RETURN_RESULT_OF_JS_CALL2(knjs__Math_pow, thiz, x); }
KDouble Kotlin_math_Double_IEEErem(KDouble thiz, KDouble divisor) {
if (isnan(thiz) || isnan(divisor) || isinf(thiz) || divisor == 0.0) {
return NAN;
}
if (!isinf(thiz) && isinf(divisor)) {
return thiz;
}
KDouble rounded = Kotlin_math_round(thiz / divisor);
return thiz - rounded * divisor;
}
KDouble Kotlin_math_Double_nextUp(KDouble thiz) {
if (isnan(thiz) || thiz == HUGE_VAL) {
return thiz;
}
if (thiz == 0.0) {
return DBL_TRUE_MIN;
}
return bitsToDouble(doubleToBits(thiz) + (thiz > 0 ? 1 : -1));
}
KDouble Kotlin_math_Double_nextDown(KDouble thiz) {
if (isnan(thiz) || thiz == -HUGE_VAL) {
return thiz;
}
if (thiz == 0.0) {
return -DBL_TRUE_MIN;
}
return bitsToDouble(doubleToBits(thiz) - (thiz > 0 ? 1 : -1));
}
KDouble Kotlin_math_Double_nextTowards(KDouble thiz, KDouble to) {
if (isnan(thiz) || isnan(to)) {
return NAN;
}
if (to > thiz) {
return Kotlin_math_Double_nextUp(thiz);
}
if (to < thiz) {
return Kotlin_math_Double_nextDown(thiz);
}
// thiz == to
return to;
}
KBoolean Kotlin_math_Double_signBit(KDouble thiz) {
return (doubleToBits(thiz) & (KLong) 1 << 63) != 0;
}
KDouble Kotlin_math_Double_withSign(KDouble thiz, KDouble sign) {
bool oldSign = Kotlin_math_Double_signBit(thiz);
bool newSign = Kotlin_math_Double_signBit(sign);
return (oldSign == newSign) ? thiz : -thiz;
}
// endregion
// region Float math.
KFloat Kotlin_math_sinf(KFloat x) { return (KFloat)Kotlin_math_sin (x); }
KFloat Kotlin_math_cosf(KFloat x) { return (KFloat)Kotlin_math_cos (x); }
KFloat Kotlin_math_tanf(KFloat x) { return (KFloat)Kotlin_math_tan (x); }
KFloat Kotlin_math_asinf(KFloat x) { return (KFloat)Kotlin_math_asin (x); }
KFloat Kotlin_math_acosf(KFloat x) { return (KFloat)Kotlin_math_acos (x); }
KFloat Kotlin_math_atanf(KFloat x) { return (KFloat)Kotlin_math_atan (x); }
KFloat Kotlin_math_sinhf(KFloat x) { return (KFloat)Kotlin_math_sinh (x); }
KFloat Kotlin_math_coshf(KFloat x) { return (KFloat)Kotlin_math_cosh (x); }
KFloat Kotlin_math_tanhf(KFloat x) { return (KFloat)Kotlin_math_tanh (x); }
KFloat Kotlin_math_asinhf(KFloat x) { return (KFloat)Kotlin_math_asinh (x); }
KFloat Kotlin_math_acoshf(KFloat x) { return (KFloat)Kotlin_math_acosh (x); }
KFloat Kotlin_math_atanhf(KFloat x) { return (KFloat)Kotlin_math_atanh (x); }
KFloat Kotlin_math_sqrtf(KFloat x) { return (KFloat)Kotlin_math_sqrt (x); }
KFloat Kotlin_math_expf(KFloat x) { return (KFloat)Kotlin_math_exp (x); }
KFloat Kotlin_math_expm1f(KFloat x) { return (KFloat)Kotlin_math_expm1 (x); }
KFloat Kotlin_math_lnf(KFloat x) { return (KFloat)Kotlin_math_ln (x); }
KFloat Kotlin_math_log10f(KFloat x) { return (KFloat)Kotlin_math_log10 (x); }
KFloat Kotlin_math_log2f(KFloat x) { return (KFloat)Kotlin_math_log2 (x); }
KFloat Kotlin_math_ln1pf(KFloat x) { return (KFloat)Kotlin_math_ln1p (x); }
KFloat Kotlin_math_ceilf(KFloat x) { return (KFloat)Kotlin_math_ceil (x); }
KFloat Kotlin_math_floorf(KFloat x) { return (KFloat)Kotlin_math_floor (x); }
KFloat Kotlin_math_roundf(KFloat x) { return (KFloat)Kotlin_math_round (x); }
KFloat Kotlin_math_absf(KFloat x) { return (KFloat)Kotlin_math_abs (x); }
KFloat Kotlin_math_atan2f(KFloat y, KFloat x) { return (KFloat)Kotlin_math_atan2(y, x); }
KFloat Kotlin_math_hypotf(KFloat x, KFloat y) { return (KFloat)Kotlin_math_hypot(x, y); }
KFloat Kotlin_math_cbrtf(KFloat x) { return (KFloat)Kotlin_math_cbrt(x); }
// extensions
KFloat Kotlin_math_Float_pow(KFloat thiz, KFloat x) { return (KFloat)Kotlin_math_Double_pow(thiz, x); }
KFloat Kotlin_math_Float_IEEErem(KFloat thiz, KFloat divisor) {
return (KFloat)Kotlin_math_Double_IEEErem(thiz, divisor);
}
KFloat Kotlin_math_Float_withSign(KFloat thiz, KFloat sign) {
return (KFloat)Kotlin_math_Double_withSign(thiz, sign);
}
KFloat Kotlin_math_Float_nextUp(KFloat thiz) {
if (isnan(thiz) || thiz == HUGE_VALF) {
return thiz;
}
if (thiz == 0.0) {
return FLT_TRUE_MIN;
}
return bitsToFloat(floatToBits(thiz) + (thiz > 0 ? 1 : -1));
}
KFloat Kotlin_math_Float_nextDown(KFloat thiz) {
if (isnan(thiz) || thiz == -HUGE_VALF) {
return thiz;
}
if (thiz == 0.0) {
return -FLT_TRUE_MIN;
}
return bitsToFloat(floatToBits(thiz) - (thiz > 0 ? 1 : -1));
}
KFloat Kotlin_math_Float_nextTowards(KFloat thiz, KFloat to) {
if (isnan(thiz) || isnan(to)) {
return NAN;
}
if (to > thiz) {
return Kotlin_math_Float_nextUp(thiz);
}
if (to < thiz) {
return Kotlin_math_Float_nextDown(thiz);
}
// thiz == to
return to;
}
KBoolean Kotlin_math_Float_signBit(KFloat thiz) { return Kotlin_math_Double_signBit(thiz); }
// endregion
// region Integer math
KInt Kotlin_math_absi(KInt x) { return (x >= 0) ? x : -x; }
KLong Kotlin_math_absl(KLong x) { return (x >= 0) ? x : -x; }
#endif // #ifndef KONAN_WASM
#else // KONAN_NO_MATH defined - we have no patform math library. Throw NotImplementedError from math functions.
namespace {
RUNTIME_NORETURN void NotImplemented() {
ThrowNotImplementedError();
}
} // namespace
KDouble Kotlin_math_sin(KDouble x) { NotImplemented(); }
KDouble Kotlin_math_cos(KDouble x) { NotImplemented(); }
KDouble Kotlin_math_tan(KDouble x) { NotImplemented(); }
KDouble Kotlin_math_asin(KDouble x) { NotImplemented(); }
KDouble Kotlin_math_acos(KDouble x) { NotImplemented(); }
KDouble Kotlin_math_atan(KDouble x) { NotImplemented(); }
KDouble Kotlin_math_atan2(KDouble y, KDouble x) { NotImplemented(); }
KDouble Kotlin_math_sinh(KDouble x) { NotImplemented(); }
KDouble Kotlin_math_cosh(KDouble x) { NotImplemented(); }
KDouble Kotlin_math_tanh(KDouble x) { NotImplemented(); }
KDouble Kotlin_math_asinh(KDouble x) { NotImplemented(); }
KDouble Kotlin_math_acosh(KDouble x) { NotImplemented(); }
KDouble Kotlin_math_atanh(KDouble x) { NotImplemented(); }
KDouble Kotlin_math_hypot(KDouble x, KDouble y) { NotImplemented(); }
KDouble Kotlin_math_sqrt(KDouble x) { NotImplemented(); }
KDouble Kotlin_math_exp(KDouble x) { NotImplemented(); }
KDouble Kotlin_math_expm1(KDouble x) { NotImplemented(); }
KDouble Kotlin_math_ln(KDouble x) { NotImplemented(); }
KDouble Kotlin_math_log10(KDouble x) { NotImplemented(); }
KDouble Kotlin_math_log2(KDouble x) { NotImplemented(); }
KDouble Kotlin_math_ln1p(KDouble x) { NotImplemented(); }
KDouble Kotlin_math_ceil(KDouble x) { NotImplemented(); }
KDouble Kotlin_math_floor(KDouble x) { NotImplemented(); }
KDouble Kotlin_math_round(KDouble x) { NotImplemented(); }
KDouble Kotlin_math_abs(KDouble x) { NotImplemented(); }
KDouble Kotlin_math_cbrt(KDouble x) { NotImplemented(); }
// extensions
KDouble Kotlin_math_Double_pow(KDouble thiz, KDouble x) { NotImplemented(); }
KDouble Kotlin_math_Double_IEEErem(KDouble thiz, KDouble divisor) { NotImplemented(); }
KDouble Kotlin_math_Double_withSign(KDouble thiz, KDouble sign) { NotImplemented(); }
KDouble Kotlin_math_Double_nextUp(KDouble thiz) { NotImplemented(); }
KDouble Kotlin_math_Double_nextDown(KDouble thiz) { NotImplemented(); }
KDouble Kotlin_math_Double_nextTowards(KDouble thiz, KDouble to) { NotImplemented(); }
KBoolean Kotlin_math_Double_signBit(KDouble thiz) { NotImplemented(); }
// endregion
// region Float math.
KFloat Kotlin_math_sinf(KFloat x) { NotImplemented(); }
KFloat Kotlin_math_cosf(KFloat x) { NotImplemented(); }
KFloat Kotlin_math_tanf(KFloat x) { NotImplemented(); }
KFloat Kotlin_math_asinf(KFloat x) { NotImplemented(); }
KFloat Kotlin_math_acosf(KFloat x) { NotImplemented(); }
KFloat Kotlin_math_atanf(KFloat x) { NotImplemented(); }
KFloat Kotlin_math_atan2f(KFloat y, KFloat x) { NotImplemented(); }
KFloat Kotlin_math_sinhf(KFloat x) { NotImplemented(); }
KFloat Kotlin_math_coshf(KFloat x) { NotImplemented(); }
KFloat Kotlin_math_tanhf(KFloat x) { NotImplemented(); }
KFloat Kotlin_math_asinhf(KFloat x) { NotImplemented(); }
KFloat Kotlin_math_acoshf(KFloat x) { NotImplemented(); }
KFloat Kotlin_math_atanhf(KFloat x) { NotImplemented(); }
KFloat Kotlin_math_hypotf(KFloat x, KFloat y) { NotImplemented(); }
KFloat Kotlin_math_sqrtf(KFloat x) { NotImplemented(); }
KFloat Kotlin_math_expf(KFloat x) { NotImplemented(); }
KFloat Kotlin_math_expm1f(KFloat x) { NotImplemented(); }
KFloat Kotlin_math_lnf(KFloat x) { NotImplemented(); }
KFloat Kotlin_math_log10f(KFloat x) { NotImplemented(); }
KFloat Kotlin_math_log2f(KFloat x) { NotImplemented(); }
KFloat Kotlin_math_ln1pf(KFloat x) { NotImplemented(); }
KFloat Kotlin_math_ceilf(KFloat x) { NotImplemented(); }
KFloat Kotlin_math_floorf(KFloat x) { NotImplemented(); }
KFloat Kotlin_math_roundf(KFloat x) { NotImplemented(); }
KFloat Kotlin_math_absf(KFloat x) { NotImplemented(); }
KFloat Kotlin_math_cbrtf(KFloat x) { NotImplemented(); }
// extensions
KFloat Kotlin_math_Float_pow(KFloat thiz, KFloat x) { NotImplemented(); }
KFloat Kotlin_math_Float_IEEErem(KFloat thiz, KFloat divisor) { NotImplemented(); }
KFloat Kotlin_math_Float_withSign(KFloat thiz, KFloat sign) { NotImplemented(); }
KFloat Kotlin_math_Float_nextUp(KFloat thiz) { NotImplemented(); }
KFloat Kotlin_math_Float_nextDown(KFloat thiz) { NotImplemented(); }
KFloat Kotlin_math_Float_nextTowards(KFloat thiz, KFloat to) { NotImplemented(); }
KBoolean Kotlin_math_Float_signBit(KFloat thiz) { NotImplemented(); }
// endregion
// region Integer math
KInt Kotlin_math_absi(KInt x) { NotImplemented(); }
KInt Kotlin_math_mini(KInt a, KInt b) { NotImplemented(); }
KInt Kotlin_math_maxi(KInt a, KInt b) { NotImplemented(); }
KLong Kotlin_math_absl(KLong x) { NotImplemented(); }
KLong Kotlin_math_minl(KLong a, KLong b) { NotImplemented(); }
KLong Kotlin_math_maxl(KLong a, KLong b) { NotImplemented(); }
#endif // #ifndef KONAN_NO_MATH
} // extern "C"
@@ -1,69 +0,0 @@
/*
* Copyright 2010-2018 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_KOTLINMATH_H
#define RUNTIME_KOTLINMATH_H
#include "Types.h"
#ifdef KONAN_WASM
extern "C" {
// TODO: consider auto-generating this header file.
// Bridges for JS math.
void knjs__Math_abs(KInt xUpper, KInt xLower);
void knjs__Math_acos(KInt xUpper, KInt xLower);
void knjs__Math_acosh(KInt xUpper, KInt xLower);
void knjs__Math_asin(KInt xUpper, KInt xLower);
void knjs__Math_asinh(KInt xUpper, KInt xLower);
void knjs__Math_atan(KInt xUpper, KInt xLower);
void knjs__Math_atan2(KInt yUpper, KInt yLower, KInt xUpper, KInt xLower);
void knjs__Math_atanh(KInt xUpper, KInt xLower);
void knjs__Math_cbrt(KInt xUpper, KInt xLower);
void knjs__Math_ceil(KInt xUpper, KInt xLower);
void knjs__Math_clz32(KInt xUpper, KInt xLower);
void knjs__Math_cos(KInt xUpper, KInt xLower);
void knjs__Math_cosh(KInt xUpper, KInt xLower);
void knjs__Math_exp(KInt xUpper, KInt xLower);
void knjs__Math_expm1(KInt xUpper, KInt xLower);
void knjs__Math_floor(KInt xUpper, KInt xLower);
void knjs__Math_fround(KInt xUpper, KInt xLower);
void knjs__Math_log(KInt xUpper, KInt xLower);
void knjs__Math_log1p(KInt xUpper, KInt xLower);
void knjs__Math_log10(KInt xUpper, KInt xLower);
void knjs__Math_log2(KInt xUpper, KInt xLower);
void knjs__Math_round(KInt xUpper, KInt xLower);
void knjs__Math_sign(KInt xUpper, KInt xLower);
void knjs__Math_sin(KInt xUpper, KInt xLower);
void knjs__Math_sinh(KInt xUpper, KInt xLower);
void knjs__Math_sqrt(KInt xUpper, KInt xLower);
void knjs__Math_tan(KInt xUpper, KInt xLower);
void knjs__Math_tanh(KInt xUpper, KInt xLower);
void knjs__Math_trunc(KInt xUpper, KInt xLower);
void knjs__Math_hypot(KInt xUpper, KInt xLower, KInt yUpper, KInt yLower);
void knjs__Math_max(KInt xUpper, KInt xLower, KInt yUpper, KInt yLower);
void knjs__Math_min(KInt xUpper, KInt xLower, KInt yUpper, KInt yLower);
void knjs__Math_pow(KInt xUpper, KInt xLower, KInt yUpper, KInt yLower);
}
#endif // KONAN_WASM
#endif // RUNTIME_KOTLINMATH_H
@@ -7,6 +7,7 @@
#include <array>
#include <cinttypes>
#include <optional>
#include "CallsChecker.hpp"
#include "Format.h"
@@ -14,7 +15,6 @@
#include "Porting.h"
#include "std_support/Map.hpp"
#include "std_support/String.hpp"
#include "std_support/Optional.hpp"
using namespace kotlin;
@@ -8,18 +8,7 @@
#include <cstdarg>
#include <initializer_list>
#if __has_include(<string_view>)
#include <string_view>
#elif __has_include(<experimental/string_view>)
// TODO: Remove when wasm32 is gone.
#include <xlocale.h>
#include <experimental/string_view>
namespace std {
using string_view = std::experimental::string_view;
}
#else
#error "No <string_view>"
#endif
#include "Clock.hpp"
#include "CompilerConstants.hpp"
@@ -77,11 +77,7 @@ struct ObjHeader {
* Hardware guaranties on many supported platforms doesn't allow this to happen.
*/
const TypeInfo* type_info() const {
#ifdef KONAN_TARGET_HAS_ADDRESS_DEPENDENCY
return atomicGetRelaxed(&clearPointerBits(typeInfoOrMetaRelaxed(), OBJECT_TAG_MASK)->typeInfo_);
#else
return atomicGetRelaxed(&clearPointerBits(typeInfoOrMetaAcquire(), OBJECT_TAG_MASK)->typeInfo_);
#endif
}
bool has_meta_object() const {
@@ -145,7 +141,6 @@ struct ArrayHeader {
};
static_assert(alignof(ArrayHeader) <= kotlin::kObjectAlignment);
#ifndef KONAN_WASM
namespace kotlin {
struct ObjectBody;
@@ -197,7 +192,6 @@ struct type_layout::descriptor<ArrayBody> {
};
} // namespace kotlin
#endif
ALWAYS_INLINE bool isPermanentOrFrozen(const ObjHeader* obj);
ALWAYS_INLINE bool isShareable(const ObjHeader* obj);
@@ -461,11 +455,9 @@ class ObjHolder {
class ExceptionObjHolder {
public:
#if !KONAN_NO_EXCEPTIONS
static void Throw(ObjHeader* exception) RUNTIME_NORETURN;
ObjHeader* GetExceptionObject() noexcept;
#endif
// Exceptions are not on a hot path, so having virtual dispatch is fine.
virtual ~ExceptionObjHolder() = default;
@@ -104,7 +104,7 @@ void Kotlin_interop_free(void* ptr) {
}
void Kotlin_system_exitProcess(KInt status) {
konan::exit(status);
std::exit(status);
}
const void* Kotlin_Any_getTypeInfo(KConstRef obj) {
+4 -255
View File
@@ -17,14 +17,12 @@
#ifdef KONAN_ANDROID
#include <android/log.h>
#endif
#include <cstdio>
#include <stdarg.h>
#include <stdint.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#if !KONAN_NO_THREADS
#include <pthread.h>
#endif
#include <unistd.h>
#if KONAN_WINDOWS
#include <windows.h>
@@ -40,15 +38,6 @@
using namespace kotlin;
#if KONAN_WASM || KONAN_ZEPHYR
extern "C" RUNTIME_NORETURN void Konan_abort(const char*);
extern "C" RUNTIME_NORETURN void Konan_exit(int32_t status);
#endif
#ifdef KONAN_ZEPHYR
// In Zephyr's Newlib strnlen(3) is not included from string.h by default.
extern "C" size_t strnlen(const char* buffer, size_t maxSize);
#endif
namespace konan {
// Console operations.
@@ -104,9 +93,7 @@ int getLastErrorMessage(char* message, uint32_t size) {
#endif
int32_t consoleReadUtf8(void* utf8, uint32_t maxSizeBytes) {
#ifdef KONAN_ZEPHYR
return 0;
#elif KONAN_WINDOWS
#if KONAN_WINDOWS
auto length = 0;
void *stdInHandle = ::GetStdHandle(STD_INPUT_HANDLE);
if (::GetFileType(stdInHandle) == FILE_TYPE_CHAR) {
@@ -153,18 +140,11 @@ int32_t consoleReadUtf8(void* utf8, uint32_t maxSizeBytes) {
return length;
}
#if KONAN_INTERNAL_SNPRINTF
extern "C" int rpl_vsnprintf(char *, size_t, const char *, va_list);
#define vsnprintf_impl rpl_vsnprintf
#else
#define vsnprintf_impl ::vsnprintf
#endif
NO_EXTERNAL_CALLS_CHECK void consolePrintf(const char* format, ...) {
char buffer[1024];
va_list args;
va_start(args, format);
int rv = vsnprintf_impl(buffer, sizeof(buffer), format, args);
int rv = std::vsnprintf(buffer, sizeof(buffer), format, args);
if (rv < 0) return; // TODO: this may be too much exotic, but should i try to print itoa(error) and terminate?
if (static_cast<size_t>(rv) >= sizeof(buffer)) rv = sizeof(buffer) - 1; // TODO: Consider realloc or report truncating.
va_end(args);
@@ -176,7 +156,7 @@ NO_EXTERNAL_CALLS_CHECK void consoleErrorf(const char* format, ...) {
char buffer[1024];
va_list args;
va_start(args, format);
int rv = vsnprintf_impl(buffer, sizeof(buffer), format, args);
int rv = std::vsnprintf(buffer, sizeof(buffer), format, args);
if (rv < 0) return; // TODO: this may be too much exotic, but should i try to print itoa(error) and terminate?
if (static_cast<size_t>(rv) >= sizeof(buffer)) rv = sizeof(buffer) - 1; // TODO: Consider realloc or report truncating.
va_end(args);
@@ -188,9 +168,6 @@ void consoleFlush() {
::fflush(stderr);
}
// Thread execution.
#if !KONAN_NO_THREADS
pthread_key_t terminationKey;
pthread_once_t terminationKeyOnceControl = PTHREAD_ONCE_INIT;
@@ -233,16 +210,7 @@ static void onThreadExitInit() {
pthread_key_create(&terminationKey, onThreadExitCallback);
}
#endif // !KONAN_NO_THREADS
void onThreadExit(void (*destructor)(void*), void* destructorParameter) {
#if KONAN_NO_THREADS
#if KONAN_WASM || KONAN_ZEPHYR
// No way to do that.
#else
#error "How to do onThreadExit()?"
#endif
#else // !KONAN_NO_THREADS
// We cannot use pthread_cleanup_push() as it is lexical scope bound.
pthread_once(&terminationKeyOnceControl, onThreadExitInit);
DestructorRecord* destructorRecord = (DestructorRecord*)std_support::calloc(1, sizeof(DestructorRecord));
@@ -251,7 +219,6 @@ void onThreadExit(void (*destructor)(void*), void* destructorParameter) {
destructorRecord->next =
reinterpret_cast<DestructorRecord*>(pthread_getspecific(terminationKey));
pthread_setspecific(terminationKey, destructorRecord);
#endif // !KONAN_NO_THREADS
}
#if KONAN_LINUX
@@ -268,14 +235,6 @@ NO_EXTERNAL_CALLS_CHECK NO_INLINE int gettid() {
#endif
NO_EXTERNAL_CALLS_CHECK int currentThreadId() {
#if KONAN_NO_THREADS
#if KONAN_WASM || KONAN_ZEPHYR
// No way to do that.
return 0;
#else
#error "How to find currentThreadId()?"
#endif
#else // !KONAN_NO_THREADS
#if defined(KONAN_OSX) or defined(KONAN_IOS) or defined(KONAN_TVOS) or defined(KONAN_WATCHOS)
uint64_t tid;
pthread_t self = pthread_self();
@@ -291,24 +250,8 @@ NO_EXTERNAL_CALLS_CHECK int currentThreadId() {
#else
#error "How to find currentThreadId()?"
#endif
#endif // !KONAN_NO_THREADS
}
// Process execution.
void abort(void) {
::abort();
}
#if KONAN_WASM || KONAN_ZEPHYR
void exit(int32_t status) {
Konan_exit(status);
}
#else
void exit(int32_t status) {
::exit(status);
}
#endif
// String/byte operations.
// memcpy/memmove are not here intentionally, as frequently implemented/optimized
// by C compiler.
@@ -325,49 +268,6 @@ void* memmem(const void *big, size_t bigLen, const void *little, size_t littleLe
}
// The sprintf family.
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;
}
int vsnprintf(char* buffer, size_t size, const char* format, va_list args) {
return vsnprintf_impl(buffer, size, format, args);
}
size_t strnlen(const char* buffer, size_t maxSize) {
return ::strnlen(buffer, maxSize);
}
#if KONAN_INTERNAL_NOW
#ifdef KONAN_ZEPHYR
void Konan_date_now(uint64_t* arg) {
// TODO: so how will we support time for embedded?
*arg = 0LL;
}
#else
extern "C" void Konan_date_now(uint64_t*);
#endif
uint64_t getTimeMillis() {
uint64_t now;
Konan_date_now(&now);
return now;
}
uint64_t getTimeMicros() {
return getTimeMillis() * 1000ULL;
}
uint64_t getTimeNanos() {
return getTimeMillis() * 1000000ULL;
}
#else
// Time operations.
using namespace std::chrono;
@@ -385,156 +285,5 @@ uint64_t getTimeNanos() {
uint64_t getTimeMicros() {
return duration_cast<microseconds>(steady_time_clock::now().time_since_epoch()).count();
}
#endif
} // namespace konan
extern "C" {
// TODO: get rid of these.
#if (KONAN_WASM || KONAN_ZEPHYR)
void _ZNKSt3__120__vector_base_commonILb1EE20__throw_length_errorEv(void) {
Konan_abort("TODO: throw_length_error not implemented.");
}
void _ZNKSt3__220__vector_base_commonILb1EE20__throw_length_errorEv(void) {
Konan_abort("TODO: throw_length_error not implemented.");
}
void _ZNKSt3__121__basic_string_commonILb1EE20__throw_length_errorEv(void) {
Konan_abort("TODO: throw_length_error not implemented.");
}
void _ZNKSt3__221__basic_string_commonILb1EE20__throw_length_errorEv(void) {
Konan_abort("TODO: throw_length_error not implemented.");
}
int _ZNSt3__212__next_primeEj(unsigned long n) {
static unsigned long primes[] = {
11UL,
101UL,
1009UL,
10007UL,
100003UL,
1000003UL,
10000019UL,
100000007UL,
1000000007UL
};
size_t table_length = sizeof(primes)/sizeof(unsigned long);
if (n > primes[table_length - 1]) konan::abort();
unsigned long prime = primes[0];
for (unsigned long i=0; i< table_length; i++) {
prime = primes[i];
if (prime >= n) break;
}
return prime;
}
int _ZNSt3__212__next_primeEm(int n) {
return _ZNSt3__212__next_primeEj(n);
}
int _ZNSt3__112__next_primeEj(unsigned long n) {
return _ZNSt3__212__next_primeEj(n);
}
void __assert_fail(const char* assertion, const char* file, int line, const char* function) {
char buf[1024];
konan::snprintf(buf, sizeof(buf), "%s:%d in %s: runtime assert: %s\n", file, line, function, assertion);
Konan_abort(buf);
}
int* __errno_location() {
static int theErrno = 0;
return &theErrno;
}
// Some math.h functions.
double pow(double x, double y) {
return __builtin_pow(x, y);
}
#endif
#ifdef KONAN_WASM
// Some string.h functions.
void *memcpy(void *dst, const void *src, size_t n) {
for (size_t i = 0; i != n; ++i)
*((char*)dst + i) = *((char*)src + i);
return dst;
}
void *memmove(void *dst, const void *src, size_t len) {
if (src < dst) {
for (long i = len; i != 0; --i) {
*((char*)dst + i - 1) = *((char*)src + i - 1);
}
} else {
memcpy(dst, src, len);
}
return dst;
}
int memcmp(const void *s1, const void *s2, size_t n) {
for (size_t i = 0; i != n; ++i) {
if (*((char*)s1 + i) != *((char*)s2 + i)) {
return *((char*)s1 + i) - *((char*)s2 + i);
}
}
return 0;
}
void *memset(void *b, int c, size_t len) {
for (size_t i = 0; i != len; ++i) {
*((char*)b + i) = c;
}
return b;
}
size_t strlen(const char *s) {
for (long i = 0;; ++i) {
if (s[i] == 0) return i;
}
}
size_t strnlen(const char *s, size_t maxlen) {
for (size_t i = 0; i<=maxlen; ++i) {
if (s[i] == 0) return i;
}
return maxlen;
}
#endif
#ifdef KONAN_ZEPHYR
RUNTIME_USED void Konan_abort(const char*) {
while(1) {}
}
#endif // KONAN_ZEPHYR
#if defined(KONAN_MIPS32) || defined(KONAN_MIPSEL32)
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Watomic-alignment"
// By some reasons clang generates __sync functions instead of __atomic ones,
// but they are not actually available on mips. So let's implement them ourselfs using existing __atomic ones.
int64_t replace_sync_fetch_and_add_8(int64_t *ptr, int64_t value) asm("__sync_fetch_and_add_8");
RUNTIME_USED int64_t replace_sync_fetch_and_add_8(int64_t *ptr, int64_t value) {
return __atomic_fetch_add(ptr, value, __ATOMIC_SEQ_CST);
}
int64_t replace_sync_val_compare_and_swap(int64_t *ptr, int64_t oldval, int64_t newval) asm("__sync_val_compare_and_swap_8");
RUNTIME_USED int64_t replace_sync_val_compare_and_swap (int64_t *ptr, int64_t oldval, int64_t newval) {
__atomic_compare_exchange_n(ptr, &oldval, newval, false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST);
return oldval;
}
int64_t replace_sync_lock_test_and_set(int64_t *ptr, int64_t value) asm("__sync_lock_test_and_set_8");
RUNTIME_USED int64_t replace_sync_lock_test_and_set(int64_t *ptr, int64_t value) {
return __atomic_exchange_n(ptr, value, __ATOMIC_SEQ_CST);
}
#pragma clang diagnostic pop
#endif
} // extern "C"
@@ -35,10 +35,6 @@ void consoleErrorUtf8(const char* utf8, uint32_t sizeBytes);
int32_t consoleReadUtf8(void* utf8, uint32_t maxSizeBytes);
void consoleFlush();
// Process control.
RUNTIME_NORETURN void abort(void);
RUNTIME_NORETURN void exit(int32_t status);
// Thread control.
void onThreadExit(void (*destructor)(void*), void* destructorParameter);
bool isOnThreadExitNotSetOrAlreadyStarted();
@@ -48,52 +44,12 @@ int currentThreadId();
// 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, ...) __attribute__((format(printf, 3, 4)));
int vsnprintf(char* buffer, size_t size, const char* format, va_list args) __attribute__((format(printf, 3, 0)));
size_t strnlen(const char* buffer, size_t maxSize);
// These functions should be marked with RUNTIME_USED attribute for wasm target
// because clang replaces these operations with intrinsics that will be
// replaced back to library calls only on codegen step. And there is no stdlib
// for wasm target for now :(
// Otherwise `opt` will see no usages of these definitions and will remove them.
extern "C" {
#ifdef KONAN_WASM
RUNTIME_USED
double pow(double x, double y);
RUNTIME_USED
void *memcpy(void *dst, const void *src, size_t n);
RUNTIME_USED
void *memmove(void *dst, const void *src, size_t len);
RUNTIME_USED
int memcmp(const void *s1, const void *s2, size_t n);
RUNTIME_USED
void *memset(void *b, int c, size_t len);
#endif
}
// Time operations.
uint64_t getTimeMillis();
uint64_t getTimeMicros();
uint64_t getTimeNanos();
#if KONAN_NO_EXCEPTIONS
#define TRY_CATCH(tryAction, actionWithoutExceptions, catchAction) actionWithoutExceptions;
#else
#define TRY_CATCH(tryAction, actionWithoutExceptions, catchAction) \
do { \
try { tryAction; } \
catch(...) { catchAction; } \
} while(0)
#endif
} // namespace konan
#endif // RUNTIME_PORTING_H
@@ -5,8 +5,6 @@
#pragma once
#ifndef KONAN_NO_THREADS
#include <condition_variable>
#include <mutex>
#include <string_view>
@@ -80,5 +78,3 @@ private:
};
} // namespace kotlin
#endif // !KONAN_NO_THREADS
@@ -1,40 +0,0 @@
/*
* 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.
*/
#include "ReturnSlot.h"
#ifdef KONAN_WASM
namespace {
THREAD_LOCAL_VARIABLE long long storage;
} // namespace
extern "C" {
RUNTIME_USED
KDouble ReturnSlot_getDouble() {
return *reinterpret_cast<KDouble*>(&::storage);
}
RUNTIME_USED
void ReturnSlot_setDouble(KInt upper, KInt lower) {
reinterpret_cast<KInt*>(&::storage)[0] = lower;
reinterpret_cast<KInt*>(&::storage)[1] = upper;
}
} // extern "C"
#endif // KONAN_WASM
@@ -1,32 +0,0 @@
/*
* 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.
*/
#include "Types.h"
#ifdef KONAN_WASM
#ifdef __cplusplus
extern "C" {
#endif
KDouble ReturnSlot_getDouble();
void ReturnSlot_setDouble(KInt upper, KInt lower);
#ifdef __cplusplus
} // extern "C"
#endif
#endif // KONAN_WASM
+4 -26
View File
@@ -18,10 +18,8 @@
#include "KString.h"
#include "std_support/New.hpp"
#include <atomic>
#ifndef KONAN_NO_THREADS
#include <cstdlib>
#include <thread>
#endif
using namespace kotlin;
@@ -107,7 +105,7 @@ RuntimeState* initRuntime() {
firstRuntime = atomicAdd(&aliveRuntimesCount, 1) == 1;
if (!kotlin::kSupportsMultipleMutators && !firstRuntime) {
konan::consoleErrorf("This GC implementation does not support multiple mutator threads.");
konan::abort();
std::abort();
}
break;
case kotlin::compiler::DestroyRuntimeMode::kOnShutdown:
@@ -121,7 +119,7 @@ RuntimeState* initRuntime() {
firstRuntime = lastStatus == kGlobalRuntimeUninitialized;
if (!kotlin::kSupportsMultipleMutators && !firstRuntime) {
konan::consoleErrorf("This GC implementation does not support multiple mutator threads.");
konan::abort();
std::abort();
}
result->memoryState = InitMemory(firstRuntime);
// Switch thread state because worker and globals inits require the runnable state.
@@ -277,7 +275,7 @@ void Kotlin_shutdownRuntime() {
if (Kotlin_forceCheckedShutdown()) {
if (otherRuntimesCount > 0) {
konan::consoleErrorf("Cannot run checkers when there are %d alive runtimes at the shutdown", otherRuntimesCount);
konan::abort();
std::abort();
}
} else {
// Cannot destroy runtime globally if there're some other threads with Kotlin runtime on them.
@@ -315,8 +313,6 @@ KInt Konan_Platform_getOsFamily() {
return 4;
#elif KONAN_ANDROID
return 5;
#elif KONAN_WASM
return 6;
#elif KONAN_TVOS
return 7;
#elif KONAN_WATCHOS
@@ -336,12 +332,6 @@ KInt Konan_Platform_getCpuArchitecture() {
return 3;
#elif KONAN_X64
return 4;
#elif KONAN_MIPS32
return 5;
#elif KONAN_MIPSEL32
return 6;
#elif KONAN_WASM
return 7;
#else
#warning "Unknown CPU"
return 0;
@@ -369,9 +359,6 @@ KBoolean Konan_Platform_getMemoryLeakChecker() {
}
KInt Konan_Platform_getAvailableProcessors() {
#ifdef KONAN_NO_THREADS
return 1;
#else
auto res = std::thread::hardware_concurrency();
// C++ standard says that if this function can return 0 if value is not "well defined or not computable"
// In current libstdc++ implementation, seems it can happen only on unsupported targets.
@@ -384,7 +371,6 @@ KInt Konan_Platform_getAvailableProcessors() {
res = std::numeric_limits<int>::max();
}
return static_cast<KInt>(res);
#endif
}
OBJ_GETTER0(Konan_Platform_getAvailableProcessorsEnv) {
@@ -484,9 +470,6 @@ NO_INLINE void CallInitGlobalPossiblyLock(int* state, void (*init)()) {
}
if (compareAndSwap(state, FILE_NOT_INITIALIZED, FILE_BEING_INITIALIZED | (threadId << 2)) == FILE_NOT_INITIALIZED) {
// actual initialization
#if KONAN_NO_EXCEPTIONS
init();
#else
try {
CurrentFrameGuard guard;
init();
@@ -496,7 +479,6 @@ NO_INLINE void CallInitGlobalPossiblyLock(int* state, void (*init)()) {
atomicSetRelease(state, FILE_FAILED_TO_INITIALIZE);
ThrowFileFailedToInitializeException(exception);
}
#endif
atomicSetRelease(state, FILE_INITIALIZED);
} else {
CallInitGlobalAwaitInitialized(state);
@@ -507,9 +489,6 @@ void CallInitThreadLocal(int volatile* globalState, int* localState, void (*init
if (*localState == FILE_FAILED_TO_INITIALIZE || (globalState != nullptr && *globalState == FILE_FAILED_TO_INITIALIZE))
ThrowFileFailedToInitializeException(nullptr);
*localState = FILE_INITIALIZED;
#if KONAN_NO_EXCEPTIONS
init();
#else
try {
CurrentFrameGuard guard;
init();
@@ -519,7 +498,6 @@ void CallInitThreadLocal(int volatile* globalState, int* localState, void (*init
*localState = FILE_FAILED_TO_INITIALIZE;
ThrowFileFailedToInitializeException(exception);
}
#endif
}
} // extern "C"
@@ -3,8 +3,6 @@
* that can be found in the LICENSE file.
*/
#ifndef KONAN_NO_THREADS
#include "ScopedThread.hpp"
#include <cstring>
@@ -28,5 +26,3 @@ void internal::setCurrentThreadName(std::string_view name) noexcept {
}
#endif
}
#endif // !KONAN_NO_THREADS
@@ -5,8 +5,6 @@
#pragma once
#ifndef KONAN_NO_THREADS
#include <functional>
#include <optional>
#include <string_view>
@@ -97,5 +95,3 @@ private:
};
} // namespace kotlin
#endif // !KONAN_NO_THREADS
@@ -5,9 +5,7 @@
#include "StackTrace.hpp"
#if KONAN_NO_BACKTRACE
// Nothing to include
#elif USE_GCC_UNWIND
#if USE_GCC_UNWIND
// GCC unwinder for backtrace.
#include <unwind.h>
#if __MINGW64__
@@ -118,21 +116,15 @@ NO_INLINE size_t winAPIUnwind(size_t skipCount, std_support::span<void*> result)
THREAD_LOCAL_VARIABLE bool disallowSourceInfo = false;
#if !KONAN_NO_BACKTRACE
int getSourceInfo(void* symbol, SourceInfo *result, int result_len) {
return disallowSourceInfo ? 0 : compiler::getSourceInfo(symbol, result, result_len);
}
#endif
} // namespace
// TODO: this implementation is just a hack, e.g. the result is inexact;
// however it is better to have an inexact stacktrace than not to have any.
NO_INLINE std_support::vector<void*> kotlin::internal::GetCurrentStackTrace(size_t skipFrames) noexcept {
#if KONAN_NO_BACKTRACE
return {};
#else
// Skip GetCurrentStackTrace + anything asked by the caller.
const size_t kSkipFrames = 1 + skipFrames;
@@ -167,16 +159,11 @@ NO_INLINE std_support::vector<void*> kotlin::internal::GetCurrentStackTrace(size
result.erase(result.begin(), std::next(result.begin(), kSkipFrames));
return result;
#endif // !USE_GCC_UNWIND
#endif // !KONAN_NO_BACKTRACE
}
// TODO: this implementation is just a hack, e.g. the result is inexact;
// however it is better to have an inexact stacktrace than not to have any.
NO_INLINE size_t kotlin::internal::GetCurrentStackTrace(size_t skipFrames, std_support::span<void*> buffer) noexcept {
#if KONAN_NO_BACKTRACE
return {};
#else
// Skip GetCurrentStackTrace + anything asked by the caller.
const size_t kSkipFrames = 1 + skipFrames;
@@ -197,10 +184,8 @@ NO_INLINE size_t kotlin::internal::GetCurrentStackTrace(size_t skipFrames, std_s
std::copy_n(std::begin(tmpBuffer) + kSkipFrames, elementsCount, std::begin(buffer));
return elementsCount;
#endif // !USE_GCC_UNWIND
#endif // !KONAN_NO_BACKTRACE
}
#if ! KONAN_NO_BACKTRACE
#include <cstdarg>
#include <cstring>
#include "std_support/Span.hpp"
@@ -245,7 +230,6 @@ static size_t snprintf_with_addr(char* buf, size_t size, size_t frame, const voi
va_end(args);
return size - buffer.size();
}
#endif // ! KONAN_NO_BACKTRACE
/*
@@ -274,11 +258,6 @@ KNativePtr adjustAddressForSourceInfo(KNativePtr address) { return address; }
#endif
std_support::vector<std_support::string> kotlin::GetStackTraceStrings(std_support::span<void* const> stackTrace) noexcept {
#if KONAN_NO_BACKTRACE
std_support::vector<std_support::string> strings;
strings.push_back("<UNIMPLEMENTED>");
return strings;
#else
size_t size = stackTrace.size();
std_support::vector<std_support::string> strings;
strings.reserve(size);
@@ -329,7 +308,6 @@ std_support::vector<std_support::string> kotlin::GetStackTraceStrings(std_suppor
}
}
return strings;
#endif // !KONAN_NO_BACKTRACE
}
void kotlin::DisallowSourceInfo() {
@@ -24,9 +24,7 @@ enum class StackTraceCapacityKind {
template <StackTraceCapacityKind kind>
constexpr size_t GetMaxStackTraceDepth() noexcept {
#if KONAN_NO_BACKTRACE
return 0;
#elif USE_GCC_UNWIND
#if USE_GCC_UNWIND
return std::numeric_limits<size_t>::max();
#else
switch (kind) {
@@ -5,6 +5,7 @@
#include "StackTrace.hpp"
#include <cstdlib>
#include <signal.h>
#include "gmock/gmock.h"
@@ -50,7 +51,7 @@ OPTNONE StackTrace<Capacity> GetDeepStackTrace(size_t depth) {
NO_INLINE void AbortWithStackTrace(int) {
PrintStackTraceStderr();
konan::abort();
std::abort();
}
} // namespace
@@ -14,8 +14,8 @@
* limitations under the License.
*/
#include <cstdio>
#include <limits.h>
#include <stdio.h>
#include <string.h>
#include "KAssert.h"
@@ -71,7 +71,7 @@ extern "C" {
OBJ_GETTER(Kotlin_Byte_toString, KByte value) {
char cstring[8];
konan::snprintf(cstring, sizeof(cstring), "%d", value);
std::snprintf(cstring, sizeof(cstring), "%d", value);
RETURN_RESULT_OF(CreateStringFromCString, cstring);
}
@@ -83,13 +83,13 @@ OBJ_GETTER(Kotlin_Char_toString, KChar value) {
OBJ_GETTER(Kotlin_Short_toString, KShort value) {
char cstring[8];
konan::snprintf(cstring, sizeof(cstring), "%d", value);
std::snprintf(cstring, sizeof(cstring), "%d", value);
RETURN_RESULT_OF(CreateStringFromCString, cstring);
}
OBJ_GETTER(Kotlin_Int_toString, KInt value) {
char cstring[16];
konan::snprintf(cstring, sizeof(cstring), "%d", value);
std::snprintf(cstring, sizeof(cstring), "%d", value);
RETURN_RESULT_OF(CreateStringFromCString, cstring);
}
@@ -99,7 +99,7 @@ OBJ_GETTER(Kotlin_Int_toStringRadix, KInt value, KInt radix) {
OBJ_GETTER(Kotlin_Long_toString, KLong value) {
char cstring[32];
konan::snprintf(cstring, sizeof(cstring), "%lld", static_cast<long long>(value));
std::snprintf(cstring, sizeof(cstring), "%lld", static_cast<long long>(value));
RETURN_RESULT_OF(CreateStringFromCString, cstring);
}
@@ -109,7 +109,7 @@ OBJ_GETTER(Kotlin_Long_toStringRadix, KLong value, KInt radix) {
OBJ_GETTER(Kotlin_DurationValue_formatToExactDecimals, KDouble value, KInt decimals) {
char cstring[40]; // log(2^62*1_000_000) + 2 (sign, decimal point) + 12 (max decimals)
konan::snprintf(cstring, sizeof(cstring), "%.*f", decimals, value);
std::snprintf(cstring, sizeof(cstring), "%.*f", decimals, value);
RETURN_RESULT_OF(CreateStringFromCString, cstring)
}
@@ -5,8 +5,6 @@
#pragma once
#ifndef KONAN_WASM
#include <algorithm>
#include <cinttypes>
#include <cstddef>
@@ -194,5 +192,3 @@ public:
};
} // namespace kotlin::type_layout
#endif
+2 -107
View File
@@ -14,18 +14,12 @@
* limitations under the License.
*/
#ifndef KONAN_NO_THREADS
#define WITH_WORKERS 1
#endif
#include <stdlib.h>
#include <cstdlib>
#include <string.h>
#include <stdio.h>
#if WITH_WORKERS
#include <pthread.h>
#include "PthreadUtils.h"
#endif
#include "Exceptions.h"
#include "KAssert.h"
@@ -49,7 +43,6 @@ RUNTIME_NORETURN void ThrowWorkerAlreadyTerminated();
RUNTIME_NORETURN void ThrowWrongWorkerOrAlreadyTerminated();
RUNTIME_NORETURN void ThrowCannotTransferOwnership();
RUNTIME_NORETURN void ThrowFutureInvalidState();
RUNTIME_NORETURN void ThrowWorkerUnsupported();
OBJ_GETTER(WorkerLaunchpad, KRef);
} // extern "C"
@@ -73,8 +66,6 @@ WorkerExceptionHandling workerExceptionHandling() noexcept {
} // namespace
#if WITH_WORKERS
namespace {
class Future;
@@ -220,12 +211,8 @@ class Worker {
MemoryState* memoryState_ = nullptr;
};
#endif // WITH_WORKERS
namespace {
#if WITH_WORKERS
THREAD_LOCAL_VARIABLE Worker* g_worker = nullptr;
KNativePtr transfer(ObjHolder* holder, KInt mode) {
@@ -639,7 +626,7 @@ class State {
"Use `Platform.isMemoryLeakCheckerActive = false` to avoid this check.\n",
remainingNativeWorkers);
konan::consoleFlush();
konan::abort();
std::abort();
}
}
@@ -808,86 +795,13 @@ OBJ_GETTER0(activeWorkers) {
RETURN_RESULT_OF0(theState()->getActiveWorkers);
}
#else
KInt startWorker(WorkerExceptionHandling exceptionHandling, KRef customName) {
ThrowWorkerUnsupported();
}
KInt stateOfFuture(KInt id) {
ThrowWorkerUnsupported();
}
KInt execute(KInt id, KInt transferMode, KRef producer, KNativePtr jobFunction) {
ThrowWorkerUnsupported();
}
void executeAfter(KInt id, KRef job, KLong afterMicroseconds) {
ThrowWorkerUnsupported();
}
KBoolean processQueue(KInt id) {
ThrowWorkerUnsupported();
}
KBoolean park(KInt id, KLong timeoutMicroseconds, KBoolean process) {
ThrowWorkerUnsupported();
}
KInt currentWorker() {
ThrowWorkerUnsupported();
}
OBJ_GETTER(consumeFuture, KInt id) {
ThrowWorkerUnsupported();
}
OBJ_GETTER(getWorkerName, KInt id) {
ThrowWorkerUnsupported();
}
KInt requestTermination(KInt id, KBoolean processScheduledJobs) {
ThrowWorkerUnsupported();
}
KBoolean waitForAnyFuture(KInt versionToken, KInt millis) {
ThrowWorkerUnsupported();
}
KInt versionToken() {
ThrowWorkerUnsupported();
}
OBJ_GETTER(attachObjectGraphInternal, KNativePtr stable) {
ThrowWorkerUnsupported();
}
KNativePtr detachObjectGraphInternal(KInt transferMode, KRef producer) {
ThrowWorkerUnsupported();
}
KULong platformThreadId(KInt id) {
ThrowWorkerUnsupported();
}
OBJ_GETTER0(activeWorkers) {
ThrowWorkerUnsupported();
}
#endif // WITH_WORKERS
} // namespace
KInt GetWorkerId(Worker* worker) {
#if WITH_WORKERS
return worker->id();
#else
return 0;
#endif // WITH_WORKERS
}
Worker* WorkerInit(MemoryState* memoryState) {
#if WITH_WORKERS
Worker* worker;
if (::g_worker != nullptr) {
worker = ::g_worker;
@@ -898,46 +812,29 @@ Worker* WorkerInit(MemoryState* memoryState) {
worker->setThread(pthread_self());
worker->setMemoryState(memoryState);
return worker;
#else
return nullptr;
#endif // WITH_WORKERS
}
void WorkerDeinit(Worker* worker) {
#if WITH_WORKERS
::g_worker = nullptr;
theState()->destroyWorkerUnlocked(worker);
#endif // WITH_WORKERS
}
void WorkerDestroyThreadDataIfNeeded(KInt id) {
#if WITH_WORKERS
theState()->destroyWorkerThreadDataUnlocked(id);
#endif
}
void WaitNativeWorkersTermination() {
#if WITH_WORKERS
theState()->waitNativeWorkersTerminationUnlocked(true, [](KInt worker) { return true; });
#endif
}
void WaitNativeWorkerTermination(KInt id) {
#if WITH_WORKERS
theState()->waitNativeWorkersTerminationUnlocked(false, [id](KInt worker) { return worker == id; });
#endif
}
bool WorkerSchedule(KInt id, KNativePtr jobStablePtr) {
#if WITH_WORKERS
return theState()->scheduleJobInWorkerUnlocked(id, jobStablePtr);
#else
return false;
#endif // WITH_WORKERS
}
#if WITH_WORKERS
Worker::~Worker() {
RuntimeAssert(pthread_equal(thread(), pthread_self()),
"Worker destruction must be executed by the worker thread.");
@@ -1198,8 +1095,6 @@ JobKind Worker::processQueueElement(bool blocking) {
return job.kind;
}
#endif // WITH_WORKERS
extern "C" {
KInt Kotlin_Worker_startInternal(KBoolean errorReporting, KRef customName) {
File diff suppressed because it is too large Load Diff
@@ -25,8 +25,6 @@
#include "../Natives.h"
#include "../Porting.h"
#include "../utf8.h"
#include "../KotlinMath.h"
#include "../ReturnSlot.h"
#include "../DoubleConversions.h"
#include "../std_support/CStdlib.hpp"
#include "../std_support/String.hpp"
@@ -293,15 +291,6 @@ KDouble createDouble (const char *s, KInt e)
}
#ifdef KONAN_WASM
double konan_pow(double base, double exponent) {
knjs__Math_pow(doubleUpper(base), doubleLower(base), doubleUpper(exponent), doubleLower(exponent));
return ReturnSlot_getDouble();
}
#else
#define konan_pow(arg1, arg2) pow(arg1, arg2)
#endif
KDouble
createDouble1 (U_64 * f, IDATA length, KInt e)
{
@@ -324,7 +313,7 @@ createDouble1 (U_64 * f, IDATA length, KInt e)
}
else if (e >= 0 && e < APPROX_MAX_MAGNITUDE)
{
result = toDoubleHighPrecision (f, length) * konan_pow (10.0, (double) e);
result = toDoubleHighPrecision (f, length) * pow (10.0, (double) e);
}
else if (e >= APPROX_MAX_MAGNITUDE)
{
@@ -344,14 +333,14 @@ createDouble1 (U_64 * f, IDATA length, KInt e)
}
else if (e > APPROX_MIN_MAGNITUDE)
{
result = toDoubleHighPrecision (f, length) / konan_pow (10.0, (double) -e);
result = toDoubleHighPrecision (f, length) / pow (10.0, (double) -e);
}
if (e <= APPROX_MIN_MAGNITUDE)
{
result = toDoubleHighPrecision (f, length) * konan_pow (10.0, (double) (e + 52));
result = result * konan_pow (10.0, (double) -52);
result = toDoubleHighPrecision (f, length) * pow (10.0, (double) (e + 52));
result = result * pow (10.0, (double) -52);
}
@@ -660,9 +649,12 @@ KDouble Kotlin_native_FloatingPointParser_parseDoubleImpl (KString s, KInt e)
const KChar* utf16 = CharArrayAddressOfElementAt(s, 0);
std_support::string utf8;
utf8.reserve(s->count_);
TRY_CATCH(utf8::utf16to8(utf16, utf16 + s->count_, back_inserter(utf8)),
utf8::unchecked::utf16to8(utf16, utf16 + s->count_, back_inserter(utf8)),
/* Illegal UTF-16 string. */ ThrowNumberFormatException());
try {
utf8::utf16to8(utf16, utf16 + s->count_, back_inserter(utf8));
} catch (...) {
/* Illegal UTF-16 string. */
ThrowNumberFormatException();
}
const char *str = utf8.c_str();
auto dbl = createDouble (str, e);
@@ -548,9 +548,12 @@ Kotlin_native_FloatingPointParser_parseFloatImpl(KString s, KInt e)
const KChar* utf16 = CharArrayAddressOfElementAt(s, 0);
std_support::string utf8;
utf8.reserve(s->count_);
TRY_CATCH(utf8::utf16to8(utf16, utf16 + s->count_, back_inserter(utf8)),
utf8::unchecked::utf16to8(utf16, utf16 + s->count_, back_inserter(utf8)),
/* Illegal UTF-16 string. */ ThrowNumberFormatException());
try {
utf8::utf16to8(utf16, utf16 + s->count_, back_inserter(utf8));
} catch (...) {
/* Illegal UTF-16 string. */
ThrowNumberFormatException();
}
const char *str = utf8.c_str();
auto flt = createFloat(str, e);
@@ -1,128 +0,0 @@
musl as a whole is licensed under the following standard MIT license:
----------------------------------------------------------------------
Copyright © 2005-2014 Rich Felker, et al.
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
----------------------------------------------------------------------
Authors/contributors include:
Anthony G. Basile
Arvid Picciani
Bobby Bingham
Boris Brezillon
Chris Spiegel
Emil Renner Berthing
Hiltjo Posthuma
Isaac Dunham
Jens Gustedt
Jeremy Huntwork
John Spencer
Justin Cormack
Luca Barbato
Luka Perkov
Michael Forney
Nicholas J. Kain
orc
Pascal Cuoq
Pierre Carrier
Rich Felker
Richard Pennington
Solar Designer
Strake
Szabolcs Nagy
Timo Teräs
Valentin Ochs
William Haddon
Portions of this software are derived from third-party works licensed
under terms compatible with the above MIT license:
The TRE regular expression implementation (src/regex/reg* and
src/regex/tre*) is Copyright © 2001-2008 Ville Laurikari and licensed
under a 2-clause BSD license (license text in the source files). The
included version has been heavily modified by Rich Felker in 2012, in
the interests of size, simplicity, and namespace cleanliness.
Much of the math library code (src/math/* and src/complex/*) is
Copyright © 1993,2004 Sun Microsystems or
Copyright © 2003-2011 David Schultz or
Copyright © 2003-2009 Steven G. Kargl or
Copyright © 2003-2009 Bruce D. Evans or
Copyright © 2008 Stephen L. Moshier
and labelled as such in comments in the individual source files. All
have been licensed under extremely permissive terms.
The ARM memcpy code (src/string/armel/memcpy.s) is Copyright © 2008
The Android Open Source Project and is licensed under a two-clause BSD
license. It was taken from Bionic libc, used on Android.
The implementation of DES for crypt (src/misc/crypt_des.c) is
Copyright © 1994 David Burren. It is licensed under a BSD license.
The implementation of blowfish crypt (src/misc/crypt_blowfish.c) was
originally written by Solar Designer and placed into the public
domain. The code also comes with a fallback permissive license for use
in jurisdictions that may not recognize the public domain.
The smoothsort implementation (src/stdlib/qsort.c) is Copyright © 2011
Valentin Ochs and is licensed under an MIT-style license.
The BSD PRNG implementation (src/prng/random.c) and XSI search API
(src/search/*.c) functions are Copyright © 2011 Szabolcs Nagy and
licensed under following terms: "Permission to use, copy, modify,
and/or distribute this code for any purpose with or without fee is
hereby granted. There is no warranty."
The x86_64 port was written by Nicholas J. Kain. Several files (crt)
were released into the public domain; others are licensed under the
standard MIT license terms at the top of this file. See individual
files for their copyright status.
The mips and microblaze ports were originally written by Richard
Pennington for use in the ellcc project. The original code was adapted
by Rich Felker for build system and code conventions during upstream
integration. It is licensed under the standard MIT terms.
The powerpc port was also originally written by Richard Pennington,
and later supplemented and integrated by John Spencer. It is licensed
under the standard MIT terms.
All other files which have no copyright comments are original works
produced specifically for use as part of this library, written either
by Rich Felker, the main author of the library, or by one or more
contibutors listed above. Details on authorship of individual files
can be found in the git version control history of the project. The
omission of copyright and license comments in each file is in the
interest of source tree size.
All public header files (include/* and arch/*/bits/*) should be
treated as Public Domain as they intentionally contain no content
which can be covered by copyright. Some source modules may fall in
this category as well. If you believe that a file is so trivial that
it should be in the Public Domain, please contact the authors and
request an explicit statement releasing it from copyright.
The following files are trivial, believed not to be copyrightable in
the first place, and hereby explicitly released to the Public Domain:
All public headers: include/*, arch/*/bits/*
Startup files: crt/*
@@ -1,86 +0,0 @@
#ifdef KONAN_WASM
#ifndef _ENDIAN_H
#define _ENDIAN_H
#include <features.h>
#define __LITTLE_ENDIAN 1234
#define __BIG_ENDIAN 4321
#define __PDP_ENDIAN 3412
#if defined(__GNUC__) && defined(__BYTE_ORDER__)
#define __BYTE_ORDER __BYTE_ORDER__
#else
#include <bits/endian.h>
#endif
#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
#define BIG_ENDIAN __BIG_ENDIAN
#define LITTLE_ENDIAN __LITTLE_ENDIAN
#define PDP_ENDIAN __PDP_ENDIAN
#define BYTE_ORDER __BYTE_ORDER
#include <stdint.h>
static __inline uint16_t __bswap16(uint16_t __x)
{
return __x<<8 | __x>>8;
}
static __inline uint32_t __bswap32(uint32_t __x)
{
return __x>>24 | __x>>8&0xff00 | __x<<8&0xff0000 | __x<<24;
}
static __inline uint64_t __bswap64(uint64_t __x)
{
return __bswap32(__x)+0ULL<<32 | __bswap32(__x>>32);
}
#if __BYTE_ORDER == __LITTLE_ENDIAN
#define htobe16(x) __bswap16(x)
#define be16toh(x) __bswap16(x)
#define betoh16(x) __bswap16(x)
#define htobe32(x) __bswap32(x)
#define be32toh(x) __bswap32(x)
#define betoh32(x) __bswap32(x)
#define htobe64(x) __bswap64(x)
#define be64toh(x) __bswap64(x)
#define betoh64(x) __bswap64(x)
#define htole16(x) (uint16_t)(x)
#define le16toh(x) (uint16_t)(x)
#define letoh16(x) (uint16_t)(x)
#define htole32(x) (uint32_t)(x)
#define le32toh(x) (uint32_t)(x)
#define letoh32(x) (uint32_t)(x)
#define htole64(x) (uint64_t)(x)
#define le64toh(x) (uint64_t)(x)
#define letoh64(x) (uint64_t)(x)
#else
#define htobe16(x) (uint16_t)(x)
#define be16toh(x) (uint16_t)(x)
#define betoh16(x) (uint16_t)(x)
#define htobe32(x) (uint32_t)(x)
#define be32toh(x) (uint32_t)(x)
#define betoh32(x) (uint32_t)(x)
#define htobe64(x) (uint64_t)(x)
#define be64toh(x) (uint64_t)(x)
#define betoh64(x) (uint64_t)(x)
#define htole16(x) __bswap16(x)
#define le16toh(x) __bswap16(x)
#define letoh16(x) __bswap16(x)
#define htole32(x) __bswap32(x)
#define le32toh(x) __bswap32(x)
#define letoh32(x) __bswap32(x)
#define htole64(x) __bswap64(x)
#define le64toh(x) __bswap64(x)
#define letoh64(x) __bswap64(x)
#endif
#endif
#endif
#endif // KONAN_WASM
@@ -1,74 +0,0 @@
#ifdef KONAN_WASM
#include <math.h>
#include <stdint.h>
#include "Common.h"
RUNTIME_USED
double fmod(double x, double y)
{
union {double f; uint64_t i;} ux = {x}, uy = {y};
int ex = ux.i>>52 & 0x7ff;
int ey = uy.i>>52 & 0x7ff;
int sx = ux.i>>63;
uint64_t i;
/* in the followings uxi should be ux.i, but then gcc wrongly adds */
/* float load/store to inner loops ruining performance and code size */
uint64_t uxi = ux.i;
if (uy.i<<1 == 0 || isnan(y) || ex == 0x7ff)
return (x*y)/(x*y);
if (uxi<<1 <= uy.i<<1) {
if (uxi<<1 == uy.i<<1)
return 0*x;
return x;
}
/* normalize x and y */
if (!ex) {
for (i = uxi<<12; i>>63 == 0; ex--, i <<= 1);
uxi <<= -ex + 1;
} else {
uxi &= -1ULL >> 12;
uxi |= 1ULL << 52;
}
if (!ey) {
for (i = uy.i<<12; i>>63 == 0; ey--, i <<= 1);
uy.i <<= -ey + 1;
} else {
uy.i &= -1ULL >> 12;
uy.i |= 1ULL << 52;
}
/* x mod y */
for (; ex > ey; ex--) {
i = uxi - uy.i;
if (i >> 63 == 0) {
if (i == 0)
return 0*x;
uxi = i;
}
uxi <<= 1;
}
i = uxi - uy.i;
if (i >> 63 == 0) {
if (i == 0)
return 0*x;
uxi = i;
}
for (; uxi>>52 == 0; uxi <<= 1, ex--);
/* scale result */
if (ex > 0) {
uxi -= 1ULL << 52;
uxi |= (uint64_t)ex << 52;
} else {
uxi >>= -ex + 1;
}
uxi |= (uint64_t)sx << 63;
ux.i = uxi;
return ux.f;
}
#endif // KONAN_WASM
@@ -1,71 +0,0 @@
#ifdef KONAN_WASM
#include <math.h>
#include <stdint.h>
#include "Common.h"
RUNTIME_USED
float fmodf(float x, float y)
{
union {float f; uint32_t i;} ux = {x}, uy = {y};
int ex = ux.i>>23 & 0xff;
int ey = uy.i>>23 & 0xff;
uint32_t sx = ux.i & 0x80000000;
uint32_t i;
uint32_t uxi = ux.i;
if (uy.i<<1 == 0 || isnan(y) || ex == 0xff)
return (x*y)/(x*y);
if (uxi<<1 <= uy.i<<1) {
if (uxi<<1 == uy.i<<1)
return 0*x;
return x;
}
/* normalize x and y */
if (!ex) {
for (i = uxi<<9; i>>31 == 0; ex--, i <<= 1);
uxi <<= -ex + 1;
} else {
uxi &= -1U >> 9;
uxi |= 1U << 23;
}
if (!ey) {
for (i = uy.i<<9; i>>31 == 0; ey--, i <<= 1);
uy.i <<= -ey + 1;
} else {
uy.i &= -1U >> 9;
uy.i |= 1U << 23;
}
/* x mod y */
for (; ex > ey; ex--) {
i = uxi - uy.i;
if (i >> 31 == 0) {
if (i == 0)
return 0*x;
uxi = i;
}
uxi <<= 1;
}
i = uxi - uy.i;
if (i >> 31 == 0) {
if (i == 0)
return 0*x;
uxi = i;
}
for (; uxi>>23 == 0; uxi <<= 1, ex--);
/* scale result up */
if (ex > 0) {
uxi -= 1U << 23;
uxi |= (uint32_t)ex << 23;
} else {
uxi >>= -ex + 1;
}
uxi |= sx;
ux.i = uxi;
return ux.f;
}
#endif // KONAN_WASM
@@ -1,167 +0,0 @@
#ifdef KONAN_WASM
/* origin: FreeBSD /usr/src/lib/msun/src/math_private.h */
/*
* ====================================================
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
*
* Developed at SunPro, a Sun Microsystems, Inc. business.
* Permission to use, copy, modify, and distribute this
* software is freely granted, provided that this notice
* is preserved.
* ====================================================
*/
#ifndef _LIBM_H
#define _LIBM_H
#include <stdint.h>
#include <float.h>
#include <math.h>
//#include "endian.h"
#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
#elif LDBL_MANT_DIG == 64 && LDBL_MAX_EXP == 16384 && __BYTE_ORDER == __LITTLE_ENDIAN
union ldshape {
long double f;
struct {
uint64_t m;
uint16_t se;
} i;
};
#elif LDBL_MANT_DIG == 113 && LDBL_MAX_EXP == 16384 && __BYTE_ORDER == __LITTLE_ENDIAN
union ldshape {
long double f;
struct {
uint64_t lo;
uint32_t mid;
uint16_t top;
uint16_t se;
} i;
struct {
uint64_t lo;
uint64_t hi;
} i2;
};
#else
#error Unsupported long double representation
#endif
#ifdef __EMSCRIPTEN__
/*
* asm.js doesn't have user-accessible floating point exceptions, so there's
* no point in trying to force expression evaluations to produce them.
*/
#define FORCE_EVAL(x)
#else
#define FORCE_EVAL(x) do { \
if (sizeof(x) == sizeof(float)) { \
volatile float __x; \
__x = (x); \
} else if (sizeof(x) == sizeof(double)) { \
volatile double __x; \
__x = (x); \
} else { \
volatile long double __x; \
__x = (x); \
} \
} while(0)
#endif
/* Get two 32 bit ints from a double. */
#define EXTRACT_WORDS(hi,lo,d) \
do { \
union {double f; uint64_t i;} __u; \
__u.f = (d); \
(hi) = __u.i >> 32; \
(lo) = (uint32_t)__u.i; \
} while (0)
/* Get the more significant 32 bit int from a double. */
#define GET_HIGH_WORD(hi,d) \
do { \
union {double f; uint64_t i;} __u; \
__u.f = (d); \
(hi) = __u.i >> 32; \
} while (0)
/* Get the less significant 32 bit int from a double. */
#define GET_LOW_WORD(lo,d) \
do { \
union {double f; uint64_t i;} __u; \
__u.f = (d); \
(lo) = (uint32_t)__u.i; \
} while (0)
/* Set a double from two 32 bit ints. */
#define INSERT_WORDS(d,hi,lo) \
do { \
union {double f; uint64_t i;} __u; \
__u.i = ((uint64_t)(hi)<<32) | (uint32_t)(lo); \
(d) = __u.f; \
} while (0)
/* Set the more significant 32 bits of a double from an int. */
#define SET_HIGH_WORD(d,hi) \
do { \
union {double f; uint64_t i;} __u; \
__u.f = (d); \
__u.i &= 0xffffffff; \
__u.i |= (uint64_t)(hi) << 32; \
(d) = __u.f; \
} while (0)
/* Set the less significant 32 bits of a double from an int. */
#define SET_LOW_WORD(d,lo) \
do { \
union {double f; uint64_t i;} __u; \
__u.f = (d); \
__u.i &= 0xffffffff00000000ull; \
__u.i |= (uint32_t)(lo); \
(d) = __u.f; \
} while (0)
/* Get a 32 bit int from a float. */
#define GET_FLOAT_WORD(w,d) \
do { \
union {float f; uint32_t i;} __u; \
__u.f = (d); \
(w) = __u.i; \
} while (0)
/* Set a float from a 32 bit int. */
#define SET_FLOAT_WORD(d,w) \
do { \
union {float f; uint32_t i;} __u; \
__u.i = (w); \
(d) = __u.f; \
} while (0)
/* fdlibm kernel functions */
int __rem_pio2_large(double*,double*,int,int,int);
int __rem_pio2(double,double*);
double __sin(double,double,int);
double __cos(double,double);
double __tan(double,double,int);
double __expo2(double);
int __rem_pio2f(float,double*);
float __sindf(double);
float __cosdf(double);
float __tandf(double,int);
float __expo2f(float);
int __rem_pio2l(long double, long double *);
long double __sinl(long double, long double, int);
long double __cosl(long double, long double);
long double __tanl(long double, long double, int);
/* polynomial evaluation */
long double __polevll(long double, const long double *, int);
long double __p1evll(long double, const long double *, int);
#endif
#endif // KONAN_WASM
@@ -1,35 +0,0 @@
#ifdef KONAN_WASM
#include <math.h>
#include <stdint.h>
double scalbn(double x, int n)
{
union {double f; uint64_t i;} u;
double_t y = x;
if (n > 1023) {
y *= 0x1p1023;
n -= 1023;
if (n > 1023) {
y *= 0x1p1023;
n -= 1023;
if (n > 1023)
n = 1023;
}
} else if (n < -1022) {
y *= 0x1p-1022;
n += 1022;
if (n < -1022) {
y *= 0x1p-1022;
n += 1022;
if (n < -1022)
n = -1022;
}
}
u.i = (uint64_t)(0x3ff+n)<<52;
x = y * u.f;
return x;
}
#endif // KONAN_WASM
@@ -1,9 +0,0 @@
Patrick Powell <papowell@astart.com>
Brandon Long <blong@fiction.net>
Thomas Roessler <roessler@does-not-exist.org>
Michael Elkins <me@mutt.org>
Andrew Tridgell <tridge@samba.org>
Russ Allbery <rra@stanford.edu>
Hrvoje Niksic <hniksic@xemacs.org>
Damien Miller <djm@mindrot.org>
Holger Weiss <holger@jhweiss.de>
@@ -1,3 +0,0 @@
UNLESS SPECIFIED OTHERWISE IN THE INDIVIDUAL SOURCE FILES INCLUDED WITH
THIS PACKAGE, they may freely be used, modified and/or redistributed for
any purpose.
File diff suppressed because it is too large Load Diff
@@ -7,6 +7,7 @@
#include <cstdint>
#include <cstdlib>
#include <mm_malloc.h>
#include <unistd.h>
#include "Alignment.hpp"
@@ -14,123 +15,29 @@
using namespace kotlin;
#if KONAN_INTERNAL_DLMALLOC
extern "C" void* dlmalloc(size_t);
extern "C" void* dlcalloc(size_t, size_t);
extern "C" void* dlrealloc(void*, size_t);
extern "C" void* dlmemalign(size_t, size_t);
extern "C" void dlfree(void*);
#define malloc_impl dlmalloc
#define aligned_malloc_impl dlmemalign
#define calloc_impl dlcalloc
#define realloc_impl dlrealloc
#define free_impl dlfree
#define aligned_free_impl dlfree
#else
#include <mm_malloc.h>
#define malloc_impl std::malloc
#define aligned_malloc_impl(alignment, size) ::_mm_malloc(size, alignment)
#define calloc_impl std::calloc
#define realloc_impl std::realloc
#define free_impl std::free
#define aligned_free_impl ::_mm_free
#endif
void* std_support::malloc(std::size_t size) noexcept {
return malloc_impl(size);
return std::malloc(size);
}
void* std_support::aligned_malloc(std::size_t alignment, std::size_t size) noexcept {
// Enforcing alignment requirements of std::aligned_alloc.
RuntimeAssert(IsValidAlignment(alignment), "Invalid alignment %zu", alignment);
RuntimeAssert(IsAligned(size, alignment), "Size %zu must be aligned to %zu", size, alignment);
return aligned_malloc_impl(alignment, size);
return ::_mm_malloc(size, alignment);
}
void* std_support::calloc(std::size_t num, std::size_t size) noexcept {
return calloc_impl(num, size);
return std::calloc(num, size);
}
void* std_support::realloc(void* ptr, std::size_t size) noexcept {
return realloc_impl(ptr, size);
return std::realloc(ptr, size);
}
void std_support::free(void* ptr) noexcept {
return free_impl(ptr);
return std::free(ptr);
}
void std_support::aligned_free(void* ptr) noexcept {
return aligned_free_impl(ptr);
return ::_mm_free(ptr);
}
namespace konan {
#if KONAN_INTERNAL_DLMALLOC
// This function is being called when memory allocator needs more RAM.
#if KONAN_WASM
namespace {
constexpr uint32_t MFAIL = ~(uint32_t)0;
constexpr uint32_t WASM_PAGESIZE_EXPONENT = 16;
constexpr uint32_t WASM_PAGESIZE = 1u << WASM_PAGESIZE_EXPONENT;
constexpr uint32_t WASM_PAGEMASK = WASM_PAGESIZE - 1;
uint32_t pageAlign(int32_t value) {
return (value + WASM_PAGEMASK) & ~(WASM_PAGEMASK);
}
uint32_t inBytes(uint32_t pageCount) {
return pageCount << WASM_PAGESIZE_EXPONENT;
}
uint32_t inPages(uint32_t value) {
return value >> WASM_PAGESIZE_EXPONENT;
}
extern "C" void Konan_notify_memory_grow();
uint32_t memorySize() {
return __builtin_wasm_memory_size(0);
}
int32_t growMemory(uint32_t delta) {
int32_t oldLength = __builtin_wasm_memory_grow(0, delta);
Konan_notify_memory_grow();
return oldLength;
}
} // namespace
void* moreCore(int32_t delta) {
uint32_t top = inBytes(memorySize());
if (delta > 0) {
if (growMemory(inPages(pageAlign(delta))) == 0) {
return (void*)MFAIL;
}
} else if (delta < 0) {
return (void*)MFAIL;
}
return (void*)top;
}
// dlmalloc() wants to know the page size.
long getpagesize() {
return WASM_PAGESIZE;
}
#else
void* moreCore(int size) {
return sbrk(size);
}
long getpagesize() {
return sysconf(_SC_PAGESIZE);
}
#endif
#endif
} // namespace konan
@@ -57,10 +57,6 @@ T* allocator_new(const Allocator& allocator, Args&&... args) {
auto a = TAllocator(allocator);
T* ptr = TAllocatorTraits::allocate(a, 1);
#if KONAN_NO_EXCEPTIONS
TAllocatorTraits::construct(a, ptr, std::forward<Args>(args)...);
return ptr;
#else
try {
TAllocatorTraits::construct(a, ptr, std::forward<Args>(args)...);
return ptr;
@@ -68,7 +64,6 @@ T* allocator_new(const Allocator& allocator, Args&&... args) {
TAllocatorTraits::deallocate(a, ptr, 1);
throw;
}
#endif
}
template <typename T, typename Allocator>
@@ -1,20 +0,0 @@
/*
* Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
#pragma once
#if __has_include(<optional>)
#include <optional>
#elif __has_include(<experimental/optional>)
// TODO: Remove when wasm32 is gone.
#include <experimental/optional>
namespace std {
template <typename T>
using optional = std::experimental::optional<T>;
inline constexpr auto nullopt = std::experimental::nullopt;
} // namespace std
#else
#error "No <optional>"
#endif
@@ -25,4 +25,3 @@ Adjustments:
`std_support::kdelete` as a replacement for operator `delete` for objects created with custom `new`.
* `Deque.hpp`, `ForwardList.hpp`, `List.hpp`, `Map.hpp`, `Set.hpp`, `String.hpp`, `UnorderedMap.hpp`, `UnorderedSet.hpp`, `Vector.hpp` -
standard containers and `std_support::string` that default to using `std_support::allocator`.
* `Optional.hpp` - wrapper choosing correct way to include on different platforms.
@@ -31,8 +31,6 @@ DEALINGS IN THE SOFTWARE.
#include "utf8/unchecked.h"
#include "utf8/with_replacement.h"
#if !KONAN_NO_EXCEPTIONS
#include "utf8/checked.h"
#endif
#endif // header guard
@@ -5,7 +5,6 @@
#include "CallsChecker.hpp"
#ifndef KONAN_NO_EXTERNAL_CALLS_CHECKER
#include <string_view>
#include <cstring>
@@ -373,8 +372,3 @@ extern "C" RUNTIME_NOTHROW RUNTIME_NODEBUG void Kotlin_mm_checkStateAtExternalFu
CallsCheckerIgnoreGuard::CallsCheckerIgnoreGuard() noexcept { ++ignoreGuardsCount; }
CallsCheckerIgnoreGuard::~CallsCheckerIgnoreGuard() { --ignoreGuardsCount; }
#else
kotlin::CallsCheckerIgnoreGuard::CallsCheckerIgnoreGuard() noexcept {}
kotlin::CallsCheckerIgnoreGuard::~CallsCheckerIgnoreGuard() {}
#endif // KONAN_NO_EXTERNAL_CALLS_CHECKER
@@ -13,7 +13,6 @@ using namespace kotlin;
namespace {
#if !KONAN_NO_EXCEPTIONS
class ExceptionObjHolderImpl : public ExceptionObjHolder, private Pinned {
public:
explicit ExceptionObjHolderImpl(ObjHeader* obj) noexcept : stableRef_(mm::StableRef::create(obj)) {}
@@ -25,11 +24,9 @@ public:
private:
mm::StableRef stableRef_;
};
#endif
} // namespace
#if !KONAN_NO_EXCEPTIONS
// static
RUNTIME_NORETURN void ExceptionObjHolder::Throw(ObjHeader* exception) {
throw ExceptionObjHolderImpl(exception);
@@ -38,4 +35,3 @@ RUNTIME_NORETURN void ExceptionObjHolder::Throw(ObjHeader* exception) {
ObjHeader* ExceptionObjHolder::GetExceptionObject() noexcept {
return static_cast<ExceptionObjHolderImpl*>(this)->obj();
}
#endif
@@ -43,8 +43,6 @@ sealed class ClangArgs(
"WINDOWS".takeIf { target.family == Family.MINGW },
"MACOSX".takeIf { target.family == Family.OSX },
"NO_THREADS".takeUnless { target.supportsThreads() },
"NO_EXCEPTIONS".takeUnless { target.supportsExceptions() },
"NO_MEMMEM".takeUnless { target.suportsMemMem() },
"NO_64BIT_ATOMIC".takeUnless { target.supports64BitAtomics() },
"NO_UNALIGNED_ACCESS".takeUnless { target.supportsUnalignedAccess() },
@@ -55,7 +53,6 @@ sealed class ClangArgs(
"HAS_UIKIT_FRAMEWORK".takeIf { target.hasUIKitFramework() },
"REPORT_BACKTRACE_TO_IOS_CRASH_LOG".takeIf { target.supportsIosCrashLog() },
"NEED_SMALL_BINARY".takeIf { target.needSmallBinary() },
"TARGET_HAS_ADDRESS_DEPENDENCY".takeIf { target.hasAddressDependencyInMemoryModel() },
"SUPPORTS_GRAND_CENTRAL_DISPATCH".takeIf { target.supportsGrandCentralDispatch },
).map { "KONAN_$it=1" }
val otherOptions = listOfNotNull(
@@ -71,8 +68,7 @@ sealed class ClangArgs(
// so just undefine it.
"NS_FORMAT_ARGUMENT(A)=".takeIf { target.family.isAppleFamily },
)
val customOptions = target.customArgsForKonanSources()
return (konanOptions + otherOptions + customOptions).map { "-D$it" }
return (konanOptions + otherOptions).map { "-D$it" }
}
private val binDir = when (HostManager.host) {
@@ -177,26 +177,3 @@ val KonanTarget.supportsGrandCentralDispatch
Family.WATCHOS, Family.IOS, Family.TVOS, Family.OSX -> true
else -> false
}
// TODO: this is bad function. It should be replaced by capabilities functions like above
// but two affected targets are too strange, so we postpone it
fun KonanTarget.customArgsForKonanSources() = when (this) {
KonanTarget.WASM32 -> listOf(
"KONAN_NO_FFI=1",
"KONAN_INTERNAL_DLMALLOC=1",
"KONAN_INTERNAL_SNPRINTF=1",
"KONAN_INTERNAL_NOW=1",
"KONAN_NO_CTORS_SECTION=1",
"KONAN_NO_BACKTRACE=1",
"KONAN_NO_EXTERNAL_CALLS_CHECKER=1",
)
is KonanTarget.ZEPHYR -> listOf(
"KONAN_NO_FFI=1",
"KONAN_NO_MATH=1",
"KONAN_INTERNAL_SNPRINTF=1",
"KONAN_INTERNAL_NOW=1",
"KONAN_NO_CTORS_SECTION=1",
"KONAN_NO_BACKTRACE=1"
)
else -> emptyList()
}