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.<init>(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.<init>(Int;Int)"(i8* %tmp_6, i32 %tmp_2, i32 42)
ret i8* %tmp_0
}
define i8* @"kfun:D.<init>(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.<init>(Int;Int)"(i8* %tmp_4, i32 %tmp_2, i32 %tmp_3)
ret i8* %tmp_0
}
define i8* @"kfun:D.<init>(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.<init>(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<--------
This commit is contained in:
committed by
vvlevchenko
parent
81742556a6
commit
bd715df0d6
+28
-1
@@ -20,6 +20,7 @@ import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid
|
|||||||
import org.jetbrains.kotlin.ir.visitors.acceptVoid
|
import org.jetbrains.kotlin.ir.visitors.acceptVoid
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||||
|
import org.jetbrains.kotlin.resolve.descriptorUtil.getAllSuperclassesWithoutAny
|
||||||
import org.jetbrains.kotlin.types.KotlinType
|
import org.jetbrains.kotlin.types.KotlinType
|
||||||
import org.jetbrains.kotlin.types.TypeUtils
|
import org.jetbrains.kotlin.types.TypeUtils
|
||||||
import org.jetbrains.kotlin.types.typeUtil.isNullableNothing
|
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())
|
val value = codegen.load(variable!!, codegen.newVar())
|
||||||
codegen.store(value, fieldPtr!!)
|
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)
|
codegen.ret(thisPtr)
|
||||||
logger.log("visitConstructor : ${ir2string(declaration)}")
|
logger.log("visitConstructor : ${ir2string(declaration)}")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//-------------------------------------------------------------------------//
|
//-------------------------------------------------------------------------//
|
||||||
|
|
||||||
override fun visitBlockBody(body: IrBlockBody) {
|
override fun visitBlockBody(body: IrBlockBody) {
|
||||||
@@ -866,4 +878,19 @@ internal class CodeGeneratorVisitor(val context: Context) : IrElementVisitorVoid
|
|||||||
return callDirect(descriptor, rargs!!, result)
|
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
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user