diff --git a/backend.native/cli.bc/src/org/jetbrains/kotlin/cli/bc/K2Native.kt b/backend.native/cli.bc/src/org/jetbrains/kotlin/cli/bc/K2Native.kt index 8b228bdc2b2..7fc0b1a8df6 100644 --- a/backend.native/cli.bc/src/org/jetbrains/kotlin/cli/bc/K2Native.kt +++ b/backend.native/cli.bc/src/org/jetbrains/kotlin/cli/bc/K2Native.kt @@ -50,6 +50,8 @@ class K2Native : CLICompiler() { configuration.put(CommonConfigurationKeys.MODULE_NAME, JvmAbi.DEFAULT_MODULE_NAME) configuration.addKotlinSourceRoots(arguments.freeArgs) + // TODO: add to source set, once we know how to not compile them. + configuration.addKotlinSourceRoots(arguments.headers.asList()) val environment = KotlinCoreEnvironment.createForProduction(rootDisposable, configuration, Arrays.asList("extensions/common.xml")) diff --git a/backend.native/cli.bc/src/org/jetbrains/kotlin/cli/bc/K2NativeCompilerArguments.java b/backend.native/cli.bc/src/org/jetbrains/kotlin/cli/bc/K2NativeCompilerArguments.java index e5babda3546..f5abe1a5165 100644 --- a/backend.native/cli.bc/src/org/jetbrains/kotlin/cli/bc/K2NativeCompilerArguments.java +++ b/backend.native/cli.bc/src/org/jetbrains/kotlin/cli/bc/K2NativeCompilerArguments.java @@ -14,4 +14,8 @@ public class K2NativeCompilerArguments extends CommonCompilerArguments { @ValueDescription("") public String runtimeFile; + @Argument(value = "headers", description = "Header files used for compilation") + @ValueDescription("") + public String[] headers; + } diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/native/llvm/IrToBitcode.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/native/llvm/IrToBitcode.kt index f86ebc853bd..82db286cbb9 100644 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/native/llvm/IrToBitcode.kt +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/native/llvm/IrToBitcode.kt @@ -29,6 +29,7 @@ fun emitLLVM(module: IrModuleFragment, runtimeFile: String, outFile: String) { // TODO: use LLVMDisposeMessage() on errorRef, once possible in interop. if (LLVMVerifyModule( llvmModule, LLVMVerifierFailureAction.LLVMPrintMessageAction, errorRef) == 1) { + LLVMDumpModule(llvmModule) throw Error("Invalid module"); } } diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/native/llvm/RTTIGenerator.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/native/llvm/RTTIGenerator.kt index 91bcea62ff0..a4886ea32a6 100644 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/native/llvm/RTTIGenerator.kt +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/native/llvm/RTTIGenerator.kt @@ -127,6 +127,19 @@ internal class RTTIGenerator(override val context: Context) : ContextUtils { } } + private val arrayClasses = mapOf( + Pair("kotlin_native.ByteArray", -1), + Pair("kotlin_native.CharArray", -2), + Pair("kotlin_native.IntArray", -4), + Pair("kotlin_native.String", -1) + ); + + private fun getInstanceSize(classType: LLVMOpaqueType?, className: FqName) : Int { + val arraySize = arrayClasses.get(className.asString()); + if (arraySize != null) return arraySize; + return LLVMStoreSizeOfType(runtime.targetData, classType).toInt() + } + fun generate(classDesc: ClassDescriptor) { val className = classDesc.fqNameSafe @@ -135,7 +148,7 @@ internal class RTTIGenerator(override val context: Context) : ContextUtils { val name = className.globalHash - val size = LLVMStoreSizeOfType(runtime.targetData, classType).toInt() + val size = getInstanceSize(classType, className) val superType = classDesc.getSuperClassOrAny().llvmTypeInfoPtr diff --git a/backend.native/tests/build.gradle b/backend.native/tests/build.gradle index 9dc357008c4..9a0cfcc524b 100644 --- a/backend.native/tests/build.gradle +++ b/backend.native/tests/build.gradle @@ -30,8 +30,8 @@ public class KonanTest extends DefaultTask { classpath = project.configurations.cli_bc args "-output", "${sourceBc.absolutePath}", "-runtime", "${runtimeBc.absolutePath}", - "${sourceKt.absolutePath}", - project.project(':runtime').file('src/main/kotlin') + "-headers", project.project(':runtime').file('src/main/kotlin'), + "${sourceKt.absolutePath}" jvmArgs "-Djava.library.path=${backendNative.buildDir.canonicalPath}/nativelibs" } @@ -75,11 +75,9 @@ task sum (type:KonanTest) { source = "codegen/function/sum.kt" } -/* Investigate task objectInitialization(type: KonanTest) { source = "codegen/object/initialization.kt" } -*/ /* task objectBasic(type: KonanTest) { source = "$codegen/klass/basic.kt" @@ -101,7 +99,16 @@ task sum_3const(type: KonanTest) { source = "codegen/function/sum_3const.kt" } +/* TODO: enable, once kotlin.String -> kotlin_native.String is mapped. +task hello0(type: KonanTest) { + source = "runtime/basic/hello0.kt" +} + +task hello1(type: KonanTest) { + source = "runtime/basic/hello1.kt" + } */ + // TODO: waiting for boolean to be implemented //task bool_yes(type: KonanTest) { // source = "codegen/function/boolean.kt" -//} \ No newline at end of file +//} diff --git a/backend.native/tests/runtime/basic/hello0.kt b/backend.native/tests/runtime/basic/hello0.kt new file mode 100644 index 00000000000..7cfbd894802 --- /dev/null +++ b/backend.native/tests/runtime/basic/hello0.kt @@ -0,0 +1,4 @@ +// TODO: remove kotlin_native.io once overrides are in place. +fun main(args : Array) { + kotlin_native.io.print("Hello, world!") +} diff --git a/backend.native/tests/runtime/basic/hello1-test.c b/backend.native/tests/runtime/basic/hello1-test.c new file mode 100644 index 00000000000..69709087ec0 --- /dev/null +++ b/backend.native/tests/runtime/basic/hello1-test.c @@ -0,0 +1,11 @@ +extern void *resolve_symbol(const char*); + +int +run_test() { + void (*main)(void*) = resolve_symbol("kfun:main"); + + main((void*)0); + + return 0; +} + diff --git a/backend.native/tests/runtime/basic/hello1.kt b/backend.native/tests/runtime/basic/hello1.kt new file mode 100644 index 00000000000..2e0ff78386b --- /dev/null +++ b/backend.native/tests/runtime/basic/hello1.kt @@ -0,0 +1,4 @@ +// TODO: remove kotlin_native.io once overrides are in place. +fun main(args : Array) { + kotlin_native.io.print(kotlin_native.io.readLine()) +} diff --git a/runtime/src/main/cpp/Memory.cpp b/runtime/src/main/cpp/Memory.cpp index 140f2ef332c..3f1475a5aaf 100644 --- a/runtime/src/main/cpp/Memory.cpp +++ b/runtime/src/main/cpp/Memory.cpp @@ -20,21 +20,27 @@ ArenaContainer::ArenaContainer(uint32_t size) { void ObjectContainer::Init(const TypeInfo* type_info) { RuntimeAssert(type_info->instanceSize_ >= 0, "Must be an object"); - header_ = reinterpret_cast( - calloc(sizeof(ContainerHeader) + sizeof(ObjHeader) + - type_info->instanceSize_, 1)); - header_->ref_count_ = CONTAINER_TAG_INCREMENT; - SetMeta(GetPlace(), type_info); + uint32_t alloc_size = + sizeof(ContainerHeader) + sizeof(ObjHeader) + type_info->instanceSize_; + header_ = reinterpret_cast(calloc(alloc_size, 1)); + if (header_) { + header_->ref_count_ = CONTAINER_TAG_INCREMENT; + SetMeta(GetPlace(), type_info); + } } void ArrayContainer::Init(const TypeInfo* type_info, uint32_t elements) { RuntimeAssert(type_info->instanceSize_ < 0, "Must be an array"); - header_ = reinterpret_cast( - calloc(sizeof(ContainerHeader) + sizeof(ArrayHeader) - - type_info->instanceSize_ * elements, 1)); - header_->ref_count_ = CONTAINER_TAG_INCREMENT; - GetPlace()->count_ = elements; - SetMeta(GetPlace(), type_info); + uint32_t alloc_size = + sizeof(ContainerHeader) + sizeof(ArrayHeader) - + type_info->instanceSize_ * elements; + header_ = reinterpret_cast(calloc(alloc_size, 1)); + RuntimeAssert(header_ != nullptr, "Cannot alloc memory"); + if (header_) { + header_->ref_count_ = CONTAINER_TAG_INCREMENT; + GetPlace()->count_ = elements; + SetMeta(GetPlace(), type_info); + } } ObjHeader* ArenaContainer::PlaceObject(const TypeInfo* type_info) { diff --git a/runtime/src/main/kotlin/kotlin_native/io/Console.kt b/runtime/src/main/kotlin/kotlin_native/io/Console.kt index cd41ce9f612..cc14038fa35 100644 --- a/runtime/src/main/kotlin/kotlin_native/io/Console.kt +++ b/runtime/src/main/kotlin/kotlin_native/io/Console.kt @@ -4,4 +4,4 @@ package kotlin_native.io external public fun print(message: kotlin_native.String) @kotlin_native.SymbolName("Kotlin_io_Console_readLine") -external public fun readLine(): kotlin_native.String? +external public fun readLine(): kotlin_native.String