DFG: Use types from IR for receivers for virtual calls
This commit is contained in:
+28
-12
@@ -31,7 +31,7 @@ import org.jetbrains.kotlin.backend.konan.ir.IrSuspendableExpression
|
|||||||
import org.jetbrains.kotlin.backend.konan.ir.IrSuspensionPoint
|
import org.jetbrains.kotlin.backend.konan.ir.IrSuspensionPoint
|
||||||
import org.jetbrains.kotlin.backend.konan.ir.KonanIr
|
import org.jetbrains.kotlin.backend.konan.ir.KonanIr
|
||||||
import org.jetbrains.kotlin.backend.konan.irasdescriptors.*
|
import org.jetbrains.kotlin.backend.konan.irasdescriptors.*
|
||||||
import org.jetbrains.kotlin.backend.konan.ir.KonanSymbols
|
import org.jetbrains.kotlin.backend.konan.isValueType
|
||||||
import org.jetbrains.kotlin.backend.konan.llvm.functionName
|
import org.jetbrains.kotlin.backend.konan.llvm.functionName
|
||||||
import org.jetbrains.kotlin.backend.konan.llvm.localHash
|
import org.jetbrains.kotlin.backend.konan.llvm.localHash
|
||||||
import org.jetbrains.kotlin.descriptors.ClassKind
|
import org.jetbrains.kotlin.descriptors.ClassKind
|
||||||
@@ -42,17 +42,15 @@ import org.jetbrains.kotlin.ir.backend.js.utils.constructedClass
|
|||||||
import org.jetbrains.kotlin.ir.declarations.*
|
import org.jetbrains.kotlin.ir.declarations.*
|
||||||
import org.jetbrains.kotlin.ir.expressions.*
|
import org.jetbrains.kotlin.ir.expressions.*
|
||||||
import org.jetbrains.kotlin.ir.expressions.impl.*
|
import org.jetbrains.kotlin.ir.expressions.impl.*
|
||||||
import org.jetbrains.kotlin.ir.symbols.IrConstructorSymbol
|
|
||||||
import org.jetbrains.kotlin.ir.util.getArguments
|
import org.jetbrains.kotlin.ir.util.getArguments
|
||||||
import org.jetbrains.kotlin.ir.util.simpleFunctions
|
import org.jetbrains.kotlin.ir.util.simpleFunctions
|
||||||
import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid
|
import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid
|
||||||
import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid
|
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.resolve.DescriptorUtils
|
||||||
import org.jetbrains.kotlin.types.KotlinType
|
import org.jetbrains.kotlin.types.KotlinType
|
||||||
import org.jetbrains.kotlin.types.typeUtil.isNothing
|
import org.jetbrains.kotlin.types.typeUtil.*
|
||||||
import org.jetbrains.kotlin.types.typeUtil.isUnit
|
|
||||||
import org.jetbrains.kotlin.util.OperatorNameConventions
|
import org.jetbrains.kotlin.util.OperatorNameConventions
|
||||||
import org.jetbrains.kotlin.types.typeUtil.makeNotNullable
|
|
||||||
|
|
||||||
private fun getClassWithBoxingIncluded(type: KotlinType, ir: KonanIr): ClassDescriptor? {
|
private fun getClassWithBoxingIncluded(type: KotlinType, ir: KonanIr): ClassDescriptor? {
|
||||||
/*
|
/*
|
||||||
@@ -605,7 +603,6 @@ internal class ModuleDFGBuilder(val context: Context, val irModule: IrModuleFrag
|
|||||||
DataFlowIR.Node.StaticCall(
|
DataFlowIR.Node.StaticCall(
|
||||||
symbolTable.mapFunction(callee),
|
symbolTable.mapFunction(callee),
|
||||||
arguments,
|
arguments,
|
||||||
symbolTable.mapClass(context.ir.symbols.unit.owner),
|
|
||||||
symbolTable.mapClass(callee.constructedClass),
|
symbolTable.mapClass(callee.constructedClass),
|
||||||
null
|
null
|
||||||
)
|
)
|
||||||
@@ -629,23 +626,42 @@ internal class ModuleDFGBuilder(val context: Context, val irModule: IrModuleFrag
|
|||||||
value
|
value
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
|
callee as IrSimpleFunction
|
||||||
if (callee.isOverridable && value.superQualifier == null) {
|
if (callee.isOverridable && value.superQualifier == null) {
|
||||||
val owner = callee.containingDeclaration as ClassDescriptor
|
val owner = callee.containingDeclaration as ClassDescriptor
|
||||||
val vTableBuilder = context.getVtableBuilder(owner)
|
val actualReceiverType = value.dispatchReceiver!!.type
|
||||||
|
val receiverType =
|
||||||
|
if (actualReceiverType.constructor.declarationDescriptor is TypeParameterDescriptor
|
||||||
|
|| !callee.isReal /* Could be a bridge. */)
|
||||||
|
symbolTable.mapClass(owner)
|
||||||
|
else {
|
||||||
|
val actualClassAtCallsite = actualReceiverType.constructor.declarationDescriptor as org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||||
|
assert (DescriptorUtils.isSubclass(actualClassAtCallsite, owner.descriptor)) {
|
||||||
|
"Expected an inheritor of ${owner.descriptor}, but was $actualClassAtCallsite"
|
||||||
|
}
|
||||||
|
symbolTable.mapType(
|
||||||
|
actualReceiverType.let {
|
||||||
|
if (it.isValueType()) // A virtual call on a value type - it must be boxed.
|
||||||
|
context.ir.symbols.getTypeConversion(it, it.makeNullable())!!.descriptor.returnType!!
|
||||||
|
else it
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
if (owner.isInterface) {
|
if (owner.isInterface) {
|
||||||
|
val calleeHash = callee.functionName.localHash.value
|
||||||
DataFlowIR.Node.ItableCall(
|
DataFlowIR.Node.ItableCall(
|
||||||
symbolTable.mapFunction(callee.target),
|
symbolTable.mapFunction(callee.target),
|
||||||
symbolTable.mapClass(owner),
|
receiverType,
|
||||||
callee.functionName.localHash.value,
|
calleeHash,
|
||||||
arguments,
|
arguments,
|
||||||
value
|
value
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
val vtableIndex = vTableBuilder.vtableIndex(callee as IrSimpleFunction)
|
val vTableBuilder = context.getVtableBuilder(owner)
|
||||||
assert(vtableIndex >= 0, { "Unable to find function $callee in vtable of $owner" })
|
val vtableIndex = vTableBuilder.vtableIndex(callee)
|
||||||
DataFlowIR.Node.VtableCall(
|
DataFlowIR.Node.VtableCall(
|
||||||
symbolTable.mapFunction(callee.target),
|
symbolTable.mapFunction(callee.target),
|
||||||
symbolTable.mapClass(owner),
|
receiverType,
|
||||||
vtableIndex,
|
vtableIndex,
|
||||||
arguments,
|
arguments,
|
||||||
value
|
value
|
||||||
|
|||||||
Reference in New Issue
Block a user