From bd715df0d6061638036fec7760ef44008bbb8f6f Mon Sep 17 00:00:00 2001 From: Konstantin Anisimov Date: Tue, 22 Nov 2016 12:23:43 +0300 Subject: [PATCH] CODEGEN: construction body evaluation for code: --------8<-------- > cat ../backend.native/tests/codegen/object/initialization.kt open class A(val a:Int, val b:Int) open class B(val c:Int, d:Int):A(c, d) open class C(i:Int, j:Int):B(i + j, 42) class D (i: Int, j:Int) : C(i, j){ constructor(i: Int, j:Int, k:Int) : this(i, j) { foo(i) } constructor():this(1, 2) } fun foo(i:Int) : Unit {} fun foo(i:Int, j:Int):Int { val c = D(i, j) return c.c } --------8<-------- folowing code is generated: --------8<-------- ; ModuleID = '../backend.native/tests/codegen/object/initialization.kt.bc' target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128" target triple = "x86_64-apple-macosx10.12.0" ... define i8* @"kfun:C.(Int;Int)"(i8*, i32, i32) { entry: %this = alloca i8* store i8* %0, i8** %this %i = alloca i32 store i32 %1, i32* %i %j = alloca i32 store i32 %2, i32* %j %tmp_0 = load i8*, i8** %this %tmp_3 = load i32, i32* %i %tmp_4 = load i32, i32* %j %tmp_2 = call i32 @Kotlin_Int_plus_Int(i32 %tmp_3, i32 %tmp_4) %tmp_6 = load i8*, i8** %this %tmp_1 = call i8* @"kfun:B.(Int;Int)"(i8* %tmp_6, i32 %tmp_2, i32 42) ret i8* %tmp_0 } define i8* @"kfun:D.(Int;Int)"(i8*, i32, i32) { entry: %this = alloca i8* store i8* %0, i8** %this %i = alloca i32 store i32 %1, i32* %i %j = alloca i32 store i32 %2, i32* %j %tmp_0 = load i8*, i8** %this %tmp_2 = load i32, i32* %i %tmp_3 = load i32, i32* %j %tmp_4 = load i8*, i8** %this %tmp_1 = call i8* @"kfun:C.(Int;Int)"(i8* %tmp_4, i32 %tmp_2, i32 %tmp_3) ret i8* %tmp_0 } define i8* @"kfun:D.(Int;Int;Int)"(i8*, i32, i32, i32) { entry: %this = alloca i8* store i8* %0, i8** %this %i = alloca i32 store i32 %1, i32* %i %j = alloca i32 store i32 %2, i32* %j %k = alloca i32 store i32 %3, i32* %k %tmp_0 = load i8*, i8** %this %tmp_2 = load i32, i32* %i %tmp_3 = load i32, i32* %j %tmp_4 = load i8*, i8** %this %tmp_1 = call i8* @"kfun:D.(Int;Int)"(i8* %tmp_4, i32 %tmp_2, i32 %tmp_3) %tmp_5 = load i32, i32* %i call void @"kfun:foo(Int)"(i32 %tmp_5) ret i8* %tmp_0 } --------8<-------- --- .../kotlin/backend/konan/llvm/IrToBitcode.kt | 29 ++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) 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 c5516c87bc7..7941f6169a8 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 @@ -20,6 +20,7 @@ import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid import org.jetbrains.kotlin.ir.visitors.acceptVoid import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.resolve.DescriptorUtils +import org.jetbrains.kotlin.resolve.descriptorUtil.getAllSuperclassesWithoutAny import org.jetbrains.kotlin.types.KotlinType import org.jetbrains.kotlin.types.TypeUtils import org.jetbrains.kotlin.types.typeUtil.isNullableNothing @@ -168,12 +169,23 @@ internal class CodeGeneratorVisitor(val context: Context) : IrElementVisitorVoid val value = codegen.load(variable!!, codegen.newVar()) codegen.store(value, fieldPtr!!) } + /** + * IR for kotlin.Any is: + * BLOCK_BODY + * DELEGATING_CONSTRUCTOR_CALL 'constructor Any()' + * INSTANCE_INITIALIZER_CALL classDescriptor='Any' + * + * to avoid possible recursion we manually reject body generation for Any. + */ + + if (!skipConstructorBodyGeneration(declaration)) + declaration.acceptChildrenVoid(this) - /* TODO: body */ codegen.ret(thisPtr) logger.log("visitConstructor : ${ir2string(declaration)}") } + //-------------------------------------------------------------------------// override fun visitBlockBody(body: IrBlockBody) { @@ -866,4 +878,19 @@ internal class CodeGeneratorVisitor(val context: Context) : IrElementVisitorVoid return callDirect(descriptor, rargs!!, result) } + //-------------------------------------------------------------------------// + + private fun skipConstructorBodyGeneration(declaration: IrConstructor): Boolean { + var skipBody = false + declaration.acceptChildrenVoid(object : IrElementVisitorVoid { + override fun visitElement(element: IrElement) { + element.acceptChildrenVoid(this) + } + + override fun visitDelegatingConstructorCall(expression: IrDelegatingConstructorCall) { + skipBody = expression.descriptor == declaration.descriptor + } + }) + return skipBody + } }