WebAssembly effort (#721)

This commit is contained in:
Nikolay Igotti
2017-07-14 16:44:46 +03:00
committed by GitHub
parent 64e106157f
commit 06e31939dd
23 changed files with 340 additions and 35 deletions
@@ -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)
+3 -1
View File
@@ -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,
@@ -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}")
}
@@ -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)!!
}
+19
View File
@@ -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
View File
@@ -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 {
+193
View File
@@ -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() {
+7 -2
View File
@@ -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()) {
+2 -1
View File
@@ -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
}
}
+5
View File
@@ -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
+1 -1
View File
@@ -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());
}
+10 -3
View File
@@ -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
}
+11 -2
View File
@@ -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) {
+3 -3
View File
@@ -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());
+11 -1
View File
@@ -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;
+7
View File
@@ -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>
+9 -1
View File
@@ -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);
+2
View File
@@ -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
+1 -1
View File
@@ -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);
+1 -1
View File
@@ -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);
-1
View File
@@ -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")