Alloc arrays, fix RTTI for Any (#49)

This commit is contained in:
Nikolay Igotti
2016-11-11 15:03:49 +03:00
committed by GitHub
parent af85121b2c
commit 720947facb
15 changed files with 492 additions and 164 deletions
@@ -42,8 +42,25 @@ private val intrinsicTypes = setOf(
"kotlin.Float", "kotlin.Double"
)
private val arrayTypes = setOf(
"kotlin.Array",
"kotlin.ByteArray",
"kotlin.CharArray",
"kotlin.ShortArray",
"kotlin.IntArray",
"kotlin.LongArray",
"kotlin.FloatArray",
"kotlin.DoubleArray",
"kotlin.BooleanArray"
)
internal val ClassDescriptor.isIntrinsic: Boolean
get() = this.fqNameSafe.asString() in intrinsicTypes
internal val ClassDescriptor.isArray: Boolean
get() = this.fqNameSafe.asString() in arrayTypes
internal val ClassDescriptor.isInterface: Boolean
get() = (this.kind == ClassKind.INTERFACE)
@@ -25,6 +25,7 @@ internal class Context(val irModule: IrModuleFragment, val runtime: Runtime, val
private fun importRtFunction(name: String) = importFunction(name, runtime.llvmModule)
val allocInstanceFunction = importRtFunction("AllocInstance")
val allocArrayFunction = importRtFunction("AllocArrayInstance")
fun dispose() {
LLVMDisposeBuilder(llvmBuilder)
@@ -2,6 +2,7 @@ package org.jetbrains.kotlin.backend.konan.llvm
import kotlin_native.interop.*
import llvm.*
import org.jetbrains.kotlin.backend.konan.isArray
import org.jetbrains.kotlin.backend.konan.isInterface
import org.jetbrains.kotlin.backend.konan.isIntrinsic
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
@@ -19,7 +20,6 @@ import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid
import org.jetbrains.kotlin.ir.visitors.acceptVoid
import org.jetbrains.kotlin.name.Name
fun emitLLVM(module: IrModuleFragment, runtimeFile: String, outFile: String) {
val llvmModule = LLVMModuleCreateWithName("out")!! // TODO: dispose
val runtime = Runtime(runtimeFile) // TODO: dispose
@@ -407,9 +407,20 @@ internal class CodeGeneratorVisitor(val context: Context) : IrElementVisitorVoid
private fun evaluateConstructorCall(variableName: String, callee: IrCall, args: MutableList<LLVMOpaqueValue?>): LLVMOpaqueValue? {
logger.log("evaluateConstructorCall : $variableName = ${ir2string(callee)}")
memScoped {
val params = allocNativeArrayOf(LLVMOpaqueValue, generator.typeInfoValue((callee.descriptor as ClassConstructorDescriptor).containingDeclaration), Int32(1).getLlvmValue())
val thisValue = LLVMBuildCall(context.llvmBuilder, context.allocInstanceFunction, params[0], 2, variableName)
val containingClass = (callee.descriptor as ClassConstructorDescriptor).containingDeclaration
val typeInfo = generator.typeInfoValue(containingClass)
val allocHint = Int32(1).getLlvmValue()
val thisValue = if (containingClass.isArray) {
assert(args.size == 1 && LLVMTypeOf(args[0]) == LLVMInt32Type())
val size = args[0]
val params = allocNativeArrayOf(LLVMOpaqueValue, typeInfo, allocHint, size)
LLVMBuildCall(
context.llvmBuilder, context.allocArrayFunction, params[0], 3, variableName)
} else {
val params = allocNativeArrayOf(LLVMOpaqueValue, typeInfo, allocHint)
LLVMBuildCall(
context.llvmBuilder, context.allocInstanceFunction, params[0], 2, variableName)
}
val constructorParams: MutableList<LLVMOpaqueValue?> = mutableListOf()
constructorParams += thisValue
constructorParams += args
@@ -13,6 +13,7 @@ import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.resolve.OverridingUtil
import org.jetbrains.kotlin.resolve.constants.StringValue
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
import org.jetbrains.kotlin.resolve.descriptorUtil.getSuperClassNotAny
import org.jetbrains.kotlin.resolve.descriptorUtil.getSuperClassOrAny
@@ -137,11 +138,16 @@ internal class RTTIGenerator(override val context: Context) : ContextUtils {
}
private val arrayClasses = mapOf(
"kotlin.Array" to -pointerSize,
"kotlin.ByteArray" to -1,
"kotlin.CharArray" to -2,
"kotlin.IntArray" to -4,
"kotlin.String" to -1
"kotlin.Array" to -pointerSize,
"kotlin.ByteArray" to -1,
"kotlin.CharArray" to -2,
"kotlin.ShortArray" to -2,
"kotlin.IntArray" to -4,
"kotlin.LongArray" to -8,
"kotlin.FloatArray" to -4,
"kotlin.DoubleArray" to -8,
"kotlin.BooleanArray" to -1,
"kotlin.String" to -1
)
private fun getInstanceSize(classType: LLVMOpaqueType?, className: FqName) : Int {
@@ -160,7 +166,9 @@ internal class RTTIGenerator(override val context: Context) : ContextUtils {
val size = getInstanceSize(classType, className)
val superType = classDesc.getSuperClassOrAny().llvmTypeInfoPtr
val superTypeOrNull = classDesc.getSuperClassNotAny()
val superType = if (superTypeOrNull != null) superTypeOrNull.llvmTypeInfoPtr
else NullPointer(runtime.typeInfoType)
val interfaces = classDesc.implementedInterfaces.map { it.llvmTypeInfoPtr }
val interfacesPtr = staticData.placeGlobalConstArray("kintf:$className",
+5 -1
View File
@@ -186,12 +186,16 @@ task hello3(type: RunKonanTest) {
source = "runtime/basic/hello3.kt"
} */
task tostring0(type: RunKonanTest) {
goldValue = "127\n255\n239\nA\n1122334455\n112233445566778899\n1E+27\n1E-300\ntrue\nfalse\n"
source = "runtime/basic/tostring0.kt"
}
task array0(type: RunKonanTest) {
goldValue = "5\n6\n7\n8\n9\n10\n11\n12\n13\n"
source = "runtime/basic/array0.kt"
}
task if_else(type: UnitKonanTest) {
source = "codegen/branching/if_else.kt"
}
@@ -0,0 +1,29 @@
fun main(args : Array<String>) {
// Create instances of all array types.
val byteArray = ByteArray(5)
println(byteArray.size.toString())
val charArray = CharArray(6)
println(charArray.size.toString())
val shortArray = ShortArray(7)
println(shortArray.size.toString())
val intArray = IntArray(8)
println(intArray.size.toString())
val longArray = LongArray(9)
println(longArray.size.toString())
val floatArray = FloatArray(10)
println(floatArray.size.toString())
val doubleArray = FloatArray(11)
println(doubleArray.size.toString())
val booleanArray = BooleanArray(12)
println(booleanArray.size.toString())
val stringArray = Array<String>(13)
println(stringArray.size.toString())
}