diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/Context.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/Context.kt index 24bb6b29f54..851aefd423b 100644 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/Context.kt +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/Context.kt @@ -24,11 +24,11 @@ internal class Context(val irModule: IrModuleFragment, val runtime: Runtime, val val allocInstanceFunction = importRtFunction("AllocInstance") val allocArrayFunction = importRtFunction("AllocArrayInstance") + val setArrayFunction = importRtFunction("Kotlin_Array_set") val lookupFieldOffset = importRtFunction("LookupFieldOffset") val lookupOpenMethodFunction = importRtFunction("LookupOpenMethod") val isInstanceFunction = importRtFunction("IsInstance") val checkInstanceFunction = importRtFunction("CheckInstance") val throwExceptionFunction = importRtFunction("ThrowException") - val usedFunctions = mutableListOf() } diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/IrToBitcode.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/IrToBitcode.kt index bed7091280d..7b8471c68a7 100644 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/IrToBitcode.kt +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/IrToBitcode.kt @@ -596,6 +596,7 @@ internal class CodeGeneratorVisitor(val context: Context) : IrElementVisitorVoid is IrStringConcatenation -> return evaluateStringConcatenation(tmpVariableName, value) is IrBlockBody -> return evaluateBlock (tmpVariableName, value as IrStatementContainer) is IrWhileLoop -> return evaluateWhileLoop ( value) + is IrVararg -> return evaluateVararg (tmpVariableName, value) null -> return null else -> { TODO("${ir2string(value)}") @@ -678,6 +679,20 @@ internal class CodeGeneratorVisitor(val context: Context) : IrElementVisitorVoid } } + + //-------------------------------------------------------------------------// + + private fun evaluateVararg(tmpVariableName: String, value: IrVararg): LLVMValueRef? { + val arrayCreationArgs = listOf(codegen.kTheArrayTypeInfo!!, kImmInt32One!!, Int32(value.elements.size).getLlvmValue()!!) + val array = currentCodeContext.genCall(context.allocArrayFunction, arrayCreationArgs, tmpVariableName) + value.elements.forEachIndexed { i, it -> + val elementValueRaw = evaluateExpression(codegen.newVar(), it) + currentCodeContext.genCall(context.setArrayFunction, listOf(array!!, Int32(i).getLlvmValue()!!, elementValueRaw!!), "") + return@forEachIndexed + } + return array + } + //-------------------------------------------------------------------------// private fun evaluateStringConcatenation(tmpVariableName: String, value: IrStringConcatenation): LLVMValueRef? { @@ -693,7 +708,6 @@ internal class CodeGeneratorVisitor(val context: Context) : IrElementVisitorVoid return concatResult } - //-------------------------------------------------------------------------// private fun evaluateThrow(tmpVariableName: String, expression: IrThrow): LLVMValueRef? { diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/LlvmUtils.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/LlvmUtils.kt index 77a0da9ec5b..d6b1724e84b 100644 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/LlvmUtils.kt +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/LlvmUtils.kt @@ -96,6 +96,10 @@ internal val int8TypePtr = pointerType(int8Type) internal val voidType = LLVMVoidType() +internal val ContextUtils.kTheAnyTypeInfo: LLVMValueRef? + get() = KonanPlatform.builtIns.any.llvmTypeInfoPtr.getLlvmValue() +internal val ContextUtils.kTheArrayTypeInfo: LLVMValueRef? + get() = KonanPlatform.builtIns.array.llvmTypeInfoPtr.getLlvmValue() internal val ContextUtils.kTypeInfo: LLVMTypeRef get() = LLVMGetTypeByName(context.llvmModule, "struct.TypeInfo")!! internal val ContextUtils.kObjHeader: LLVMTypeRef @@ -113,6 +117,7 @@ internal val ContextUtils.kTypeInfoPtr: LLVMTypeRef internal val kInt1 = LLVMInt1Type() internal val kInt8Ptr = pointerType(LLVMInt8Type()) internal val kInt8PtrPtr = pointerType(kInt8Ptr) +internal val kImmInt32One = Int32(1).getLlvmValue() internal val ContextUtils.kNullObjHeaderPtr: LLVMValueRef get() = LLVMConstNull(this.kObjHeaderPtr)!! internal val ContextUtils.kNullArrayHeaderPtr: LLVMValueRef diff --git a/backend.native/tests/build.gradle b/backend.native/tests/build.gradle index 4932cf27343..0370de4d016 100644 --- a/backend.native/tests/build.gradle +++ b/backend.native/tests/build.gradle @@ -453,11 +453,18 @@ task array_list1(type: RunKonanTest) { source = "runtime/collections/array_list1.kt" } +task listof0(type: RunKonanTest) { + goldValue = "abc\n" + source = "runtime/collections/listof0.kt" +} + + task moderately_large_array(type: RunKonanTest) { goldValue = "0\n" source = "runtime/collections/moderately_large_array.kt" } + task string_builder0(type: RunKonanTest) { goldValue = "OK\n" source = "runtime/text/string_builder0.kt" diff --git a/backend.native/tests/runtime/collections/listof0.kt b/backend.native/tests/runtime/collections/listof0.kt new file mode 100644 index 00000000000..01aab4c4c0c --- /dev/null +++ b/backend.native/tests/runtime/collections/listof0.kt @@ -0,0 +1,5 @@ +fun main(args : Array) { + val list = arrayListOf("a", "b", "c") + for (element in list) print(element) + println() +} \ No newline at end of file diff --git a/runtime/src/main/kotlin/kotlin/collections/ArrayUtil.kt b/runtime/src/main/kotlin/kotlin/collections/ArrayUtil.kt index 3a6af3c76dd..02a5bcd265b 100644 --- a/runtime/src/main/kotlin/kotlin/collections/ArrayUtil.kt +++ b/runtime/src/main/kotlin/kotlin/collections/ArrayUtil.kt @@ -6,7 +6,7 @@ package kotlin.collections * either throwing exception or returning some kind of implementation-specific default value. */ fun arrayOfLateInitElements(size: Int): Array { - // TODO: maybe use an empoty array. + // TODO: maybe use an empty array, fix array creation. // return (if (size == 0) emptyArray else Array(size)) as Array return Array(size) as Array } diff --git a/runtime/src/main/kotlin/kotlin/collections/Collections.kt b/runtime/src/main/kotlin/kotlin/collections/Collections.kt index a873cb69ca7..7275958f484 100644 --- a/runtime/src/main/kotlin/kotlin/collections/Collections.kt +++ b/runtime/src/main/kotlin/kotlin/collections/Collections.kt @@ -22,3 +22,21 @@ public interface MutableIterable : Iterable { */ override fun iterator(): MutableIterator } + +public fun arrayListOf(vararg args: T): MutableList { + // TODO: fix me! + val result = ArrayList(args.size) as ArrayList + for (arg in args) { + result.add(arg) + } + return result +} + +/* + * FIXME: Suggested code from @olonho is following + * + * public fun listOf(element: T): List = arrayListOf(element) + * + * but in Big Kotlin this function is following: (see libraries/stdlib/src/kotlin/collections/Collections.kt) + * public fun listOf(vararg elements: T): List = if (elements.size > 0) elements.asList() else emptyList() + */