WebAssembly effort (#721)
This commit is contained in:
+9
-2
@@ -88,7 +88,8 @@ private val knownTargets = mapOf(
|
||||
"raspberrypi" to "raspberrypi",
|
||||
"android_arm32" to "android_arm32",
|
||||
"android_arm64" to "android_arm64",
|
||||
"mingw" to "mingw"
|
||||
"mingw" to "mingw",
|
||||
"wasm32" to "wasm32"
|
||||
)
|
||||
|
||||
|
||||
@@ -198,6 +199,12 @@ private fun maybeExecuteHelper(dependenciesRoot: String, properties: Properties,
|
||||
}
|
||||
}
|
||||
|
||||
private fun Properties.getClangFlags(target: String, targetSysRoot: String) : List<String> {
|
||||
val flags = getTargetSpecific("clangFlags", target)
|
||||
if (flags == null) return emptyList()
|
||||
return flags.replace("<sysrootDir>", targetSysRoot).split(' ')
|
||||
}
|
||||
|
||||
private fun Properties.defaultCompilerOpts(target: String, dependencies: String): List<String> {
|
||||
val targetToolchainDir = getHostTargetSpecific("targetToolchain", target)!!
|
||||
val targetToolchain = "$dependencies/$targetToolchainDir"
|
||||
@@ -224,7 +231,7 @@ private fun Properties.defaultCompilerOpts(target: String, dependencies: String)
|
||||
val arch = getTargetSpecific("arch", target)
|
||||
val archSelector = if (quadruple != null)
|
||||
listOf("-target", quadruple) else listOf("-arch", arch!!)
|
||||
val commonArgs = listOf("-isystem", isystem, "--sysroot=$targetSysRoot")
|
||||
val commonArgs = listOf("-isystem", isystem, "--sysroot=$targetSysRoot") + getClangFlags(target, targetSysRoot)
|
||||
when (host) {
|
||||
"osx" -> {
|
||||
val osVersionMinFlag = getTargetSpecific("osVersionMinFlagClang", target)
|
||||
|
||||
@@ -161,7 +161,9 @@ targetList.each { target ->
|
||||
"-Djava.library.path=${project.buildDir}/nativelibs",
|
||||
"-Dfile.encoding=UTF-8"]
|
||||
|
||||
def konanArgs = ['-nopack', '-nostdlib','-ea', '-g',
|
||||
def defaultArgs = ['-nopack', '-nostdlib','-ea' ]
|
||||
if (target != "wasm32") defaultArgs += '-g'
|
||||
def konanArgs = [*defaultArgs,
|
||||
'-target', target,
|
||||
'-runtime', project(':runtime').file("build/${target}/runtime.bc"),
|
||||
'-properties', rootProject.konanPropertiesFile.canonicalPath,
|
||||
|
||||
+17
@@ -169,6 +169,21 @@ internal open class MingwPlatform(distribution: Distribution)
|
||||
override fun linkCommandSuffix() = linkerKonanFlags
|
||||
}
|
||||
|
||||
internal open class WasmPlatform(distribution: Distribution)
|
||||
: PlatformFlags(distribution.targetProperties) {
|
||||
|
||||
private val clang = "clang"
|
||||
|
||||
override val useCompilerDriverAsLinker: Boolean get() = false
|
||||
|
||||
override fun linkCommand(objectFiles: List<ObjectFile>, executable: ExecutableFile, optimize: Boolean, debug: Boolean): List<String> {
|
||||
|
||||
return mutableListOf(clang).apply{
|
||||
throw Error("Implement me!")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal class LinkStage(val context: Context) {
|
||||
|
||||
val config = context.config.configuration
|
||||
@@ -184,6 +199,8 @@ internal class LinkStage(val context: Context) {
|
||||
AndroidPlatform(distribution)
|
||||
KonanTarget.MINGW ->
|
||||
MingwPlatform(distribution)
|
||||
KonanTarget.WASM32 ->
|
||||
WasmPlatform(distribution)
|
||||
else ->
|
||||
error("Unexpected target platform: ${context.config.targetManager.target}")
|
||||
}
|
||||
|
||||
+7
-4
@@ -43,11 +43,14 @@ class Runtime(bitcodeFile: String) {
|
||||
val target = LLVMGetTarget(llvmModule)!!.toKString()
|
||||
|
||||
// TODO: deduce TLS model from explicit config parameter.
|
||||
val tlsMode = if (target.indexOf("android") != -1)
|
||||
LLVMThreadLocalMode.LLVMGeneralDynamicTLSModel else LLVMThreadLocalMode.LLVMLocalExecTLSModel
|
||||
|
||||
val tlsMode by lazy {
|
||||
when {
|
||||
target.indexOf("android") != -1 -> LLVMThreadLocalMode.LLVMGeneralDynamicTLSModel
|
||||
target.indexOf("wasm") != -1 -> LLVMThreadLocalMode.LLVMNotThreadLocal
|
||||
else -> LLVMThreadLocalMode.LLVMLocalExecTLSModel
|
||||
}
|
||||
}
|
||||
val dataLayout = LLVMGetDataLayout(llvmModule)!!.toKString()
|
||||
|
||||
val targetData = LLVMCreateTargetData(dataLayout)!!
|
||||
|
||||
}
|
||||
|
||||
@@ -209,3 +209,22 @@ entrySelector.mingw = -Wl,--defsym,main=Konan_main
|
||||
dependencies.mingw = \
|
||||
msys2-mingw-w64-x86_64-gcc-6.3.0-clang-llvm-3.9.1-windows-x86-64 \
|
||||
libffi-3.2.1-mingw-w64-x86-64
|
||||
|
||||
# WebAssembly 32-bit.
|
||||
targetToolchain.osx-wasm32 = target-toolchain-1-osx-wasm
|
||||
dependencies.osx-wasm32 = \
|
||||
clang-llvm-3.9.0-darwin-macos \
|
||||
target-sysroot-1-wasm \
|
||||
target-toolchain-1-osx-wasm
|
||||
|
||||
quadruple.wasm32 = wasm32
|
||||
entrySelector.wasm32 = -Wl,--defsym -Wl,main=Konan_main
|
||||
llvmLtoFlags.wasm32 = -exported-symbol=Konan_main
|
||||
targetSysRoot.wasm32 = target-sysroot-1-wasm
|
||||
clangFlags.wasm32 = -O1 -fno-rtti -fno-exceptions \
|
||||
-D_LIBCPP_ABI_VERSION=2 -DKONAN_NO_FFI=1 -DKONAN_NO_THREADS=1 -DKONAN_NO_EXCEPTIONS=1 \
|
||||
-nostdinc -Xclang -nobuiltininc -Xclang -nostdsysteminc \
|
||||
-Xclang -isystem<sysrootDir>/include/libcxx -Xclang -isystem<sysrootDir>/lib/libcxxabi/include \
|
||||
-Xclang -isystem<sysrootDir>/include/compat -Xclang -isystem<sysrootDir>/include/libc
|
||||
linkerKonanFlags.wasm32 = -lc
|
||||
linkerDebugFlags.wasm32 = -Wl,-S
|
||||
+4
-4
@@ -102,7 +102,7 @@ void loadLocalProperties() {
|
||||
if (new File("$project.rootDir/local.properties").exists()) {
|
||||
Properties props = new Properties()
|
||||
props.load(new FileInputStream("$project.rootDir/local.properties"))
|
||||
props.each {prop -> project.ext.set(prop.key, prop.value)}
|
||||
props.each { prop -> project.ext.set(prop.key, prop.value) }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -111,11 +111,11 @@ void loadCommandLineProperties() {
|
||||
throw new Error("Specify either -Ptest_flags or -Pbuild_flags.")
|
||||
}
|
||||
ext.globalBuildArgs = project.hasProperty("build_flags")
|
||||
? ext.build_flags.split(' ') : []
|
||||
? ext.build_flags.split(' '): []
|
||||
ext.globalTestArgs = project.hasProperty("test_flags")
|
||||
? ext.test_flags.split(' ') : []
|
||||
? ext.test_flags.split(' '): []
|
||||
ext.testTarget = project.hasProperty("test_target")
|
||||
? ext.test_target : null
|
||||
? ext.test_target: null
|
||||
}
|
||||
|
||||
class PlatformInfo {
|
||||
|
||||
@@ -0,0 +1,193 @@
|
||||
diff --git a/src/s2wasm.h b/src/s2wasm.h
|
||||
index 0fc0201c..c56a3a8c 100644
|
||||
--- a/src/s2wasm.h
|
||||
+++ b/src/s2wasm.h
|
||||
@@ -153,9 +153,16 @@ class S2WasmBuilder {
|
||||
|
||||
Name getStr() {
|
||||
std::string str; // TODO: optimize this and the other get* methods
|
||||
- while (*s && !isspace(*s)) {
|
||||
- str += *s;
|
||||
- s++;
|
||||
+ if (*s == '\"') {
|
||||
+ str += *s++;
|
||||
+ while (*s && *s != '\"') {
|
||||
+ str += *s++;
|
||||
+ }
|
||||
+ if (*s == '\"') str += *s++;
|
||||
+ } else {
|
||||
+ while (*s && !isspace(*s)) {
|
||||
+ str += *s++;
|
||||
+ }
|
||||
}
|
||||
return cashew::IString(str.c_str(), false);
|
||||
}
|
||||
@@ -168,6 +175,11 @@ class S2WasmBuilder {
|
||||
|
||||
Name getStrToSep() {
|
||||
std::string str;
|
||||
+ if (*s == '\"') {
|
||||
+ str += *s++;
|
||||
+ while (*s && *s != '\"') str += *s++;
|
||||
+ if (*s == '\"') str += *s++;
|
||||
+ }
|
||||
while (*s && !isspace(*s) && *s != ',' && *s != '(' && *s != ')' && *s != ':' && *s != '+' && *s != '-' && *s != '=') {
|
||||
str += *s;
|
||||
s++;
|
||||
@@ -177,10 +189,15 @@ class S2WasmBuilder {
|
||||
|
||||
Name getStrToColon() {
|
||||
std::string str;
|
||||
- while (*s && !isspace(*s) && *s != ':') {
|
||||
- str += *s;
|
||||
- s++;
|
||||
+ if (*s == '\"') {
|
||||
+ str += *s++;
|
||||
+ while (*s && *s != '\"') {
|
||||
+ str += *s++;
|
||||
+ }
|
||||
+ if (*s == '\"') str += *s++;
|
||||
}
|
||||
+ while (*s && !isspace(*s) && *s != ':')
|
||||
+ str += *s++;
|
||||
return cashew::IString(str.c_str(), false);
|
||||
}
|
||||
|
||||
@@ -330,9 +347,18 @@ class S2WasmBuilder {
|
||||
Name getSeparated(char separator) {
|
||||
skipWhitespace();
|
||||
std::string str;
|
||||
- while (*s && *s != separator && *s != '\n') {
|
||||
- str += *s;
|
||||
- s++;
|
||||
+ bool inQuoted = false;
|
||||
+ int inBrackets = 0;
|
||||
+ while (*s && (*s != separator || inQuoted || inBrackets > 0) && *s != '\n') {
|
||||
+ if (*s == '\"') {
|
||||
+ inQuoted = !inQuoted;
|
||||
+ } else if (*s == '(') {
|
||||
+ inBrackets++;
|
||||
+ } else if (*s == ')') {
|
||||
+ inBrackets--;
|
||||
+ }
|
||||
+
|
||||
+ str += *s++;
|
||||
}
|
||||
skipWhitespace();
|
||||
return cashew::IString(str.c_str(), false);
|
||||
@@ -421,14 +447,32 @@ class S2WasmBuilder {
|
||||
bool isFunctionName(Name name) {
|
||||
return !!strstr(name.str, "@FUNCTION");
|
||||
}
|
||||
- // Drop the @ and after it.
|
||||
- Name cleanFunction(Name name) {
|
||||
- if (!strchr(name.str, '@')) return name;
|
||||
+
|
||||
+ Name cleanName(Name name, char terminator = 0) {
|
||||
char *temp = strdup(name.str);
|
||||
- *strchr(temp, '@') = 0;
|
||||
+ static const char* bads = "\";<>() ";
|
||||
+ static const char* goods = "\'$__$$$";
|
||||
+ int index = 0;
|
||||
+ while (bads[index] != 0) {
|
||||
+ char *pos = temp;
|
||||
+ while ((pos = strchr(pos, bads[index])) != nullptr) {
|
||||
+ *pos = goods[index];
|
||||
+ pos++;
|
||||
+ }
|
||||
+ index++;
|
||||
+ }
|
||||
+ if (terminator != 0) {
|
||||
+ char* pos = strrchr(temp, terminator);
|
||||
+ if (pos != nullptr) *pos = '\0';
|
||||
+ }
|
||||
Name ret = cashew::IString(temp, false);
|
||||
free(temp);
|
||||
return ret;
|
||||
+ }
|
||||
+
|
||||
+ // Drop the @ and after it.
|
||||
+ Name cleanFunction(Name name) {
|
||||
+ return cleanName(name, '@');
|
||||
}
|
||||
|
||||
// processors
|
||||
@@ -446,7 +490,7 @@ class S2WasmBuilder {
|
||||
if (match(".hidden")) mustMatch(name.str);
|
||||
mustMatch(name.str);
|
||||
if (match(":")) {
|
||||
- info->implementedFunctions.insert(name);
|
||||
+ info->implementedFunctions.insert(cleanName(name));
|
||||
} else if (match("=")) {
|
||||
Name alias = getAtSeparated();
|
||||
mustMatch("@FUNCTION");
|
||||
@@ -461,7 +505,7 @@ class S2WasmBuilder {
|
||||
s = strchr(s, '\n');
|
||||
} else {
|
||||
// add data aliases
|
||||
- Name lhs = getStrToSep();
|
||||
+ Name lhs = cleanName(getStrToSep());
|
||||
// When the current line contains only one word, e.g.".text"
|
||||
if (match("\n"))
|
||||
continue;
|
||||
@@ -473,7 +517,7 @@ class S2WasmBuilder {
|
||||
}
|
||||
|
||||
// get the original name
|
||||
- Name rhs = getStrToSep();
|
||||
+ Name rhs = cleanName(getStrToSep());
|
||||
assert(!isFunctionName(rhs));
|
||||
Offset offset = 0;
|
||||
if (*s == '+') {
|
||||
@@ -620,7 +664,7 @@ class S2WasmBuilder {
|
||||
}
|
||||
|
||||
void parseGlobl() {
|
||||
- linkerObj->addGlobal(getStr());
|
||||
+ linkerObj->addGlobal(cleanName(getStr()));
|
||||
skipWhitespace();
|
||||
}
|
||||
|
||||
@@ -753,7 +797,7 @@ class S2WasmBuilder {
|
||||
skipWhitespace();
|
||||
} else break;
|
||||
}
|
||||
- Function* func = builder.makeFunction(name, std::move(params), resultType, std::move(vars));
|
||||
+ Function* func = builder.makeFunction(cleanName(name), std::move(params), resultType, std::move(vars));
|
||||
|
||||
// parse body
|
||||
func->body = allocator->alloc<Block>();
|
||||
@@ -1343,6 +1387,11 @@ class S2WasmBuilder {
|
||||
mustMatch(name.str);
|
||||
skipWhitespace();
|
||||
}
|
||||
+ if (match(".weak")) {
|
||||
+ // Do nothing special on weak symbols so far.
|
||||
+ mustMatch(name.str);
|
||||
+ skipWhitespace();
|
||||
+ }
|
||||
if (match(".align") || match(".p2align")) {
|
||||
align = getInt();
|
||||
skipWhitespace();
|
||||
@@ -1436,9 +1485,10 @@ class S2WasmBuilder {
|
||||
r->data = (uint32_t*)&raw[i];
|
||||
}
|
||||
// assign the address, add to memory
|
||||
- linkerObj->addStatic(size, align, name);
|
||||
+ Name wasmName = cleanName(name);
|
||||
+ linkerObj->addStatic(size, align, wasmName);
|
||||
if (!zero) {
|
||||
- linkerObj->addSegment(name, raw);
|
||||
+ linkerObj->addSegment(wasmName, raw);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1451,7 +1501,7 @@ class S2WasmBuilder {
|
||||
skipComma();
|
||||
localAlign = 1 << getInt();
|
||||
}
|
||||
- linkerObj->addStatic(size, std::max(align, localAlign), name);
|
||||
+ linkerObj->addStatic(size, std::max(align, localAlign), cleanName(name));
|
||||
}
|
||||
|
||||
void skipImports() {
|
||||
Vendored
+7
-2
@@ -227,13 +227,18 @@ if (isLinux()) {
|
||||
}
|
||||
|
||||
dependencyTask(MINGW, LIBFFI)
|
||||
} else {
|
||||
} else if (isMac()) {
|
||||
dependencyTask(MACBOOK, SYSROOT)
|
||||
dependencyTask(MACBOOK, LIBFFI)
|
||||
dependencyTask(IPHONE, SYSROOT)
|
||||
dependencyTask(IPHONE, LIBFFI)
|
||||
dependencyTask(WASM32, SYSROOT)
|
||||
// No FFI for webassembly.
|
||||
|
||||
// TODO: re-enable when we known how to bring the simulator sysroot to dependencies.
|
||||
// dependencyTask(IPHONE_SIM, SYSROOT)
|
||||
// dependencyTask("iphoneSim", SYSROOT)
|
||||
} else {
|
||||
throw new Error("Unsupported host")
|
||||
}
|
||||
|
||||
if (isLinux() || isMac()) {
|
||||
|
||||
@@ -27,7 +27,8 @@ targetList.each { targetName ->
|
||||
target targetName
|
||||
compilerArgs '-g'
|
||||
compilerArgs '-I' + project.file('../common/src/hash/headers')
|
||||
compilerArgs '-I' + project.file(rootProject.ext.get("${targetName}LibffiDir") + "/include")
|
||||
if (rootProject.hasProperty("${targetName}LibffiDir"))
|
||||
compilerArgs '-I' + project.file(rootProject.ext.get("${targetName}LibffiDir") + "/include")
|
||||
linkerArgs project.file("../common/build/$targetName/hash.bc").path
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,5 +20,10 @@
|
||||
#define RUNTIME_NOTHROW __attribute__((nothrow))
|
||||
#define RUNTIME_CONST __attribute__((const))
|
||||
#define RUNTIME_PURE __attribute__((pure))
|
||||
#if KONAN_NO_THREADS
|
||||
#define THREAD_LOCAL_VARIABLE
|
||||
#else
|
||||
#define THREAD_LOCAL_VARIABLE __thread
|
||||
#endif
|
||||
|
||||
#endif // RUNTIME_COMMON_H
|
||||
|
||||
@@ -30,7 +30,7 @@ void Kotlin_io_Console_print(KString message) {
|
||||
// TODO: system stdout must be aware about UTF-8.
|
||||
const KChar* utf16 = CharArrayAddressOfElementAt(message, 0);
|
||||
KStdString utf8;
|
||||
utf8::utf16to8(utf16, utf16 + message->count_, back_inserter(utf8));
|
||||
utf8::unchecked::utf16to8(utf16, utf16 + message->count_, back_inserter(utf8));
|
||||
konan::consoleWriteUtf8(utf8.c_str(), utf8.size());
|
||||
}
|
||||
|
||||
|
||||
@@ -17,6 +17,10 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#if KONAN_NO_EXCEPTIONS
|
||||
#define OMIT_BACKTRACE 1
|
||||
#endif
|
||||
#ifndef OMIT_BACKTRACE
|
||||
#if USE_GCC_UNWIND
|
||||
// GCC unwinder for backtrace.
|
||||
@@ -54,7 +58,7 @@ class AutoFree {
|
||||
struct Backtrace {
|
||||
Backtrace(int count, int skip) : index(0), skipCount(skip) {
|
||||
auto result = AllocArrayInstance(
|
||||
theArrayTypeInfo, count - skipCount, arrayHolder.slot());
|
||||
theArrayTypeInfo, count - skipCount, arrayHolder.slot());
|
||||
// TODO: throw cached OOME?
|
||||
RuntimeAssert(result != nullptr, "Cannot create backtrace array");
|
||||
}
|
||||
@@ -156,8 +160,10 @@ OBJ_GETTER0(GetCurrentStackTrace) {
|
||||
|
||||
void ThrowException(KRef exception) {
|
||||
RuntimeAssert(exception != nullptr && IsInstance(exception, theThrowableTypeInfo),
|
||||
"Throwing something non-throwable");
|
||||
|
||||
"Throwing something non-throwable");
|
||||
#if KONAN_NO_EXCEPTIONS
|
||||
RuntimeAssert(false, "Exceptions unsupported");
|
||||
#else
|
||||
#if (__MINGW32__ || __MINGW64__)
|
||||
// Workaround for https://bugs.llvm.org/show_bug.cgi?id=33220
|
||||
// This code forces the function to have at least one landingpad:
|
||||
@@ -165,6 +171,7 @@ void ThrowException(KRef exception) {
|
||||
#endif
|
||||
|
||||
throw ObjHolder(exception);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -17,14 +17,20 @@
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#ifndef KONAN_NO_FFI
|
||||
#include <ffi.h>
|
||||
#endif
|
||||
|
||||
#include "Memory.h"
|
||||
#include "Types.h"
|
||||
|
||||
|
||||
namespace {
|
||||
|
||||
typedef int FfiTypeKind;
|
||||
|
||||
#ifndef KONAN_NO_FFI
|
||||
// Also declared in Varargs.kt
|
||||
const FfiTypeKind FFI_TYPE_KIND_VOID = 0;
|
||||
const FfiTypeKind FFI_TYPE_KIND_SINT8 = 1;
|
||||
@@ -49,6 +55,7 @@ ffi_type* convertFfiTypeKindToType(FfiTypeKind typeKind) {
|
||||
default: assert(false); return nullptr;
|
||||
}
|
||||
}
|
||||
#endif // KONAN_NO_FFI
|
||||
|
||||
} // namespace
|
||||
|
||||
@@ -57,8 +64,9 @@ extern "C" {
|
||||
void Kotlin_Interop_callWithVarargs(void* codePtr, void* returnValuePtr, FfiTypeKind returnTypeKind,
|
||||
void** arguments, intptr_t* argumentTypeKinds,
|
||||
int fixedArgumentsNumber, int totalArgumentsNumber) {
|
||||
|
||||
|
||||
#ifdef KONAN_NO_FFI
|
||||
RuntimeAssert(false, "Vararg calls are not supported on this platform");
|
||||
#else
|
||||
ffi_type** argumentTypes = (ffi_type**)argumentTypeKinds;
|
||||
// In-place convertion:
|
||||
for (int i = 0; i < totalArgumentsNumber; ++i) {
|
||||
@@ -71,6 +79,7 @@ void Kotlin_Interop_callWithVarargs(void* codePtr, void* returnValuePtr, FfiType
|
||||
convertFfiTypeKindToType(returnTypeKind), argumentTypes);
|
||||
|
||||
ffi_call(&cif, (void (*)())codePtr, returnValuePtr, arguments);
|
||||
#endif
|
||||
}
|
||||
|
||||
KNativePtr Kotlin_Interop_createStablePointer(KRef any) {
|
||||
|
||||
@@ -38,12 +38,12 @@
|
||||
namespace {
|
||||
|
||||
OBJ_GETTER(utf8ToUtf16, const char* rawString, size_t rawStringLength) {
|
||||
uint32_t charCount = utf8::distance(rawString, rawString + rawStringLength);
|
||||
uint32_t charCount = utf8::unchecked::distance(rawString, rawString + rawStringLength);
|
||||
ArrayHeader* result = AllocArrayInstance(
|
||||
theStringTypeInfo, charCount, OBJ_RESULT)->array();
|
||||
KChar* rawResult = CharArrayAddressOfElementAt(result, 0);
|
||||
auto convertResult =
|
||||
utf8::utf8to16(rawString, rawString + rawStringLength, rawResult);
|
||||
utf8::unchecked::utf8to16(rawString, rawString + rawStringLength, rawResult);
|
||||
RETURN_OBJ(result->obj());
|
||||
}
|
||||
|
||||
@@ -738,7 +738,7 @@ OBJ_GETTER(Kotlin_String_toUtf8Array, KString thiz, KInt start, KInt size) {
|
||||
}
|
||||
const KChar* utf16 = CharArrayAddressOfElementAt(thiz, start);
|
||||
KStdString utf8;
|
||||
utf8::utf16to8(utf16, utf16 + size, back_inserter(utf8));
|
||||
utf8::unchecked::utf16to8(utf16, utf16 + size, back_inserter(utf8));
|
||||
ArrayHeader* result = AllocArrayInstance(
|
||||
theByteArrayTypeInfo, utf8.size() + 1, OBJ_RESULT)->array();
|
||||
::memcpy(ByteArrayAddressOfElementAt(result, 0), utf8.c_str(), utf8.size());
|
||||
|
||||
@@ -94,7 +94,7 @@ struct MemoryState {
|
||||
namespace {
|
||||
|
||||
// TODO: can we pass this variable as an explicit argument?
|
||||
__thread MemoryState* memoryState = nullptr;
|
||||
THREAD_LOCAL_VARIABLE MemoryState* memoryState = nullptr;
|
||||
|
||||
inline bool isFreeable(const ContainerHeader* header) {
|
||||
return (header->refCount_ & CONTAINER_TAG_MASK) < CONTAINER_TAG_PERMANENT;
|
||||
@@ -649,6 +649,13 @@ OBJ_GETTER(InitInstance,
|
||||
|
||||
ObjHeader* object = AllocInstance(type_info, OBJ_RESULT);
|
||||
UpdateRef(location, object);
|
||||
#if KONAN_NO_EXCEPTIONS
|
||||
ctor(object);
|
||||
#if TRACE_MEMORY
|
||||
memoryState->globalObjects->push_back(location);
|
||||
#endif
|
||||
return object;
|
||||
#else
|
||||
try {
|
||||
ctor(object);
|
||||
#if TRACE_MEMORY
|
||||
@@ -660,6 +667,7 @@ OBJ_GETTER(InitInstance,
|
||||
UpdateRef(location, nullptr);
|
||||
throw;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void SetRef(ObjHeader** location, const ObjHeader* object) {
|
||||
@@ -882,7 +890,9 @@ OBJ_GETTER(DerefStablePointer, KNativePtr pointer) {
|
||||
}
|
||||
|
||||
OBJ_GETTER(AdoptStablePointer, KNativePtr pointer) {
|
||||
#ifndef KONAN_NO_THREADS
|
||||
__sync_synchronize();
|
||||
#endif
|
||||
KRef ref = reinterpret_cast<KRef>(pointer);
|
||||
// Somewhat hacky.
|
||||
*OBJ_RESULT = ref;
|
||||
|
||||
@@ -17,6 +17,13 @@
|
||||
#ifndef RUNTIME_TYPES_H
|
||||
#define RUNTIME_TYPES_H
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#if KONAN_WASM
|
||||
// assert() is needed by WASM STL.
|
||||
#define assert(cond) if (!(cond)) abort()
|
||||
#endif
|
||||
|
||||
#include <deque>
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
|
||||
@@ -13,7 +13,10 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#define WITH_WORKERS 1
|
||||
|
||||
#ifndef KONAN_NO_THREADS
|
||||
# define WITH_WORKERS 1
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
@@ -462,6 +465,11 @@ KInt stateOfFuture(KInt id) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
KInt schedule(KInt id, KInt transferMode, KRef producer, KNativePtr jobFunction) {
|
||||
ThrowWorkerUnsupported();
|
||||
return 0;
|
||||
}
|
||||
|
||||
OBJ_GETTER(consumeFuture, KInt id) {
|
||||
ThrowWorkerUnsupported();
|
||||
RETURN_OBJ(nullptr);
|
||||
|
||||
@@ -525,7 +525,9 @@ MAX_RELEASE_CHECK_RATE default: 4095 unless not HAVE_MMAP
|
||||
|
||||
/**** Start of Konan-specific dlmalloc configuration. ****/
|
||||
#define USE_DL_PREFIX 1
|
||||
#if !KONAN_WASM
|
||||
#define USE_LOCKS 1
|
||||
#endif
|
||||
#define DLMALLOC_EXPORT extern "C"
|
||||
#define HAVE_MORECORE 1
|
||||
#define MORECORE konan::moreCore
|
||||
|
||||
@@ -642,7 +642,7 @@ KDouble Konan_FloatingPointParser_parseDoubleImpl (KString s, KInt e)
|
||||
{
|
||||
const KChar* utf16 = CharArrayAddressOfElementAt(s, 0);
|
||||
KStdString utf8;
|
||||
utf8::utf16to8(utf16, utf16 + s->count_, back_inserter(utf8));
|
||||
utf8::unchecked::utf16to8(utf16, utf16 + s->count_, back_inserter(utf8));
|
||||
const char *str = utf8.c_str();
|
||||
auto dbl = createDouble (str, e);
|
||||
|
||||
|
||||
@@ -549,7 +549,7 @@ Konan_FloatingPointParser_parseFloatImpl (KString s, KInt e)
|
||||
{
|
||||
const KChar* utf16 = CharArrayAddressOfElementAt(s, 0);
|
||||
KStdString utf8;
|
||||
utf8::utf16to8(utf16, utf16 + s->count_, back_inserter(utf8));
|
||||
utf8::unchecked::utf16to8(utf16, utf16 + s->count_, back_inserter(utf8));
|
||||
const char *str = utf8.c_str();
|
||||
auto flt = createFloat (str, e);
|
||||
|
||||
|
||||
@@ -28,7 +28,6 @@ DEALINGS IN THE SOFTWARE.
|
||||
#ifndef UTF8_FOR_CPP_2675DCD0_9480_4c0c_B92A_CC14C027B731
|
||||
#define UTF8_FOR_CPP_2675DCD0_9480_4c0c_B92A_CC14C027B731
|
||||
|
||||
#include "utf8/checked.h"
|
||||
#include "utf8/unchecked.h"
|
||||
|
||||
#endif // header guard
|
||||
|
||||
@@ -19,16 +19,15 @@ package org.jetbrains.kotlin.konan.target
|
||||
import org.jetbrains.kotlin.konan.properties.KonanProperties
|
||||
import org.jetbrains.kotlin.konan.file.File
|
||||
|
||||
class ClangTarget(val target: KonanTarget, val konanProperties: KonanProperties) {
|
||||
class ClangTarget(val target: KonanTarget, konanProperties: KonanProperties) {
|
||||
|
||||
val sysRoot = konanProperties.absoluteTargetSysRoot!!
|
||||
val sysRoot = konanProperties.absoluteTargetSysRoot
|
||||
val targetArg = konanProperties.targetArg
|
||||
|
||||
val specificClangArgs: List<String> get() {
|
||||
return when (target) {
|
||||
|
||||
val result = when (target) {
|
||||
KonanTarget.LINUX ->
|
||||
listOf("--sysroot=$sysRoot",
|
||||
listOf("--sysroot=$sysRoot",
|
||||
"-DUSE_GCC_UNWIND=1", "-DUSE_ELF_SYMBOLS=1", "-DELFSIZE=64")
|
||||
KonanTarget.RASPBERRYPI ->
|
||||
listOf("-target", targetArg!!,
|
||||
@@ -67,7 +66,16 @@ class ClangTarget(val target: KonanTarget, val konanProperties: KonanProperties)
|
||||
// HACKS!
|
||||
"-I$sysRoot/usr/include/c++/4.9.x",
|
||||
"-I$sysRoot/usr/include/c++/4.9.x/aarch64-linux-android")
|
||||
|
||||
KonanTarget.WASM32 ->
|
||||
listOf("-target", targetArg!!, "-O1", "-fno-rtti", "-fno-exceptions", "-DKONAN_WASM=1",
|
||||
"-D_LIBCPP_ABI_VERSION=2", "-DKONAN_NO_FFI=1", "-DKONAN_NO_THREADS=1", "-DKONAN_NO_EXCEPTIONS=1",
|
||||
"-DKONAN_INTERNAL_DLMALLOC=1",
|
||||
"-nostdinc", "-Xclang", "-nobuiltininc", "-Xclang", "-nostdsysteminc",
|
||||
"-Xclang", "-isystem$sysRoot/include/libcxx", "-Xclang", "-isystem$sysRoot/lib/libcxxabi/include",
|
||||
"-Xclang", "-isystem$sysRoot/include/compat", "-Xclang", "-isystem$sysRoot/include/libc")
|
||||
}
|
||||
return result + (if (target != KonanTarget.WASM32) listOf("-g") else emptyList())
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -24,7 +24,9 @@ enum class KonanTarget(val targetSuffix: String, val programSuffix: String, var
|
||||
LINUX("linux", "kexe"),
|
||||
MINGW("mingw", "exe"),
|
||||
MACBOOK("osx", "kexe"),
|
||||
RASPBERRYPI("raspberrypi", "kexe");
|
||||
RASPBERRYPI("raspberrypi", "kexe"),
|
||||
WASM32("wasm32", "kexe");
|
||||
|
||||
val userName get() = name.toLowerCase()
|
||||
}
|
||||
|
||||
@@ -115,7 +117,7 @@ class TargetManager(val userRequest: String? = null) {
|
||||
else -> throw TargetSupportException("Unknown host: $host.")
|
||||
}
|
||||
|
||||
fun host_arch(): String {
|
||||
fun host_arch(): String {
|
||||
val javaArch = System.getProperty("os.arch")
|
||||
return when (javaArch) {
|
||||
"x86_64" -> "x86_64"
|
||||
@@ -153,6 +155,7 @@ class TargetManager(val userRequest: String? = null) {
|
||||
//KonanTarget.IPHONE_SIM.enabled = true
|
||||
KonanTarget.ANDROID_ARM32.enabled = true
|
||||
KonanTarget.ANDROID_ARM64.enabled = true
|
||||
KonanTarget.WASM32.enabled = true
|
||||
}
|
||||
else ->
|
||||
throw TargetSupportException("Unknown host platform: $host")
|
||||
|
||||
Reference in New Issue
Block a user