Use symbols in IrGet/SetValue

This commit is contained in:
Mikhael Bogdanov
2018-04-27 09:46:00 +02:00
parent 077f3a4ed2
commit 5a2e62dd4f
6 changed files with 71 additions and 56 deletions
@@ -67,12 +67,12 @@ class InitializersLowering(
if (declaration.descriptor.dispatchReceiverParameter != null) // TODO isStaticField if (declaration.descriptor.dispatchReceiverParameter != null) // TODO isStaticField
IrGetValueImpl( IrGetValueImpl(
irFieldInitializer.startOffset, irFieldInitializer.endOffset, irFieldInitializer.startOffset, irFieldInitializer.endOffset,
irClass.descriptor.thisAsReceiverParameter irClass.thisReceiver!!.symbol
) )
else null else null
val irSetField = IrSetFieldImpl( val irSetField = IrSetFieldImpl(
irFieldInitializer.startOffset, irFieldInitializer.endOffset, irFieldInitializer.startOffset, irFieldInitializer.endOffset,
declaration.descriptor, declaration.symbol,
receiver, receiver,
irFieldInitializer, irFieldInitializer,
null, null null, null
@@ -5,19 +5,20 @@
package org.jetbrains.kotlin.backend.common.lower package org.jetbrains.kotlin.backend.common.lower
import org.jetbrains.kotlin.backend.common.BackendContext import org.jetbrains.kotlin.backend.common.BodyLoweringPass import org.jetbrains.kotlin.backend.common.BackendContext
import org.jetbrains.kotlin.backend.common.BodyLoweringPass
import org.jetbrains.kotlin.backend.common.ClassLoweringPass import org.jetbrains.kotlin.backend.common.ClassLoweringPass
import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.ir.IrStatement import org.jetbrains.kotlin.ir.IrStatement
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
import org.jetbrains.kotlin.ir.declarations.IrClass import org.jetbrains.kotlin.ir.declarations.IrClass
import org.jetbrains.kotlin.ir.declarations.IrConstructor import org.jetbrains.kotlin.ir.declarations.IrConstructor
import org.jetbrains.kotlin.ir.declarations.IrDeclarationOriginImpl import org.jetbrains.kotlin.ir.declarations.IrDeclarationOriginImpl
import org.jetbrains.kotlin.ir.declarations.IrValueParameter
import org.jetbrains.kotlin.ir.declarations.impl.IrConstructorImpl import org.jetbrains.kotlin.ir.declarations.impl.IrConstructorImpl
import org.jetbrains.kotlin.ir.declarations.impl.IrFieldImpl import org.jetbrains.kotlin.ir.declarations.impl.IrFieldImpl
import org.jetbrains.kotlin.ir.declarations.impl.IrValueParameterImpl
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.util.createParameterDeclarations
import org.jetbrains.kotlin.ir.util.dump import org.jetbrains.kotlin.ir.util.dump
import org.jetbrains.kotlin.ir.util.transformFlat import org.jetbrains.kotlin.ir.util.transformFlat
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
@@ -37,7 +38,7 @@ class InnerClassesLowering(val context: BackendContext) : ClassLoweringPass {
lateinit var outerThisFieldDescriptor: PropertyDescriptor lateinit var outerThisFieldDescriptor: PropertyDescriptor
val oldConstructorParameterToNew = HashMap<ValueDescriptor, ValueDescriptor>() val oldConstructorParameterToNew = HashMap<ValueDescriptor, IrValueParameter>()
fun lowerInnerClass() { fun lowerInnerClass() {
if (!irClass.descriptor.isInner) return if (!irClass.descriptor.isInner) return
@@ -73,10 +74,17 @@ class InnerClassesLowering(val context: BackendContext) : ClassLoweringPass {
val endOffset = irConstructor.endOffset val endOffset = irConstructor.endOffset
val newSymbol = context.descriptorsFactory.getInnerClassConstructorWithOuterThisParameter(oldDescriptor) val newSymbol = context.descriptorsFactory.getInnerClassConstructorWithOuterThisParameter(oldDescriptor)
val outerThisValueParameter = newSymbol.descriptor.valueParameters[0] val loweredConstructor = IrConstructorImpl(
startOffset, endOffset,
irConstructor.origin, // TODO special origin for lowered inner class constructors?
newSymbol,
null
)
loweredConstructor.createParameterDeclarations()
val outerThisValueParameter = loweredConstructor.valueParameters[0].symbol
oldDescriptor.valueParameters.forEach { oldValueParameter -> oldDescriptor.valueParameters.forEach { oldValueParameter ->
oldConstructorParameterToNew[oldValueParameter] = newSymbol.descriptor.valueParameters[oldValueParameter.index + 1] oldConstructorParameterToNew[oldValueParameter] = loweredConstructor.valueParameters[oldValueParameter.index + 1]
} }
val blockBody = irConstructor.body as? IrBlockBody ?: throw AssertionError("Unexpected constructor body: ${irConstructor.body}") val blockBody = irConstructor.body as? IrBlockBody ?: throw AssertionError("Unexpected constructor body: ${irConstructor.body}")
@@ -85,12 +93,12 @@ class InnerClassesLowering(val context: BackendContext) : ClassLoweringPass {
if (instanceInitializerIndex >= 0) { if (instanceInitializerIndex >= 0) {
// Initializing constructor: initialize 'this.this$0' with '$outer' // Initializing constructor: initialize 'this.this$0' with '$outer'
blockBody.statements.add( blockBody.statements.add(
instanceInitializerIndex, instanceInitializerIndex,
IrSetFieldImpl( IrSetFieldImpl(
startOffset, endOffset, outerThisFieldDescriptor, startOffset, endOffset, outerThisFieldDescriptor,
IrGetValueImpl(startOffset, endOffset, classDescriptor.thisAsReceiverParameter), IrGetValueImpl(startOffset, endOffset, irClass.thisReceiver!!.symbol),
IrGetValueImpl(startOffset, endOffset, outerThisValueParameter) IrGetValueImpl(startOffset, endOffset, outerThisValueParameter)
) )
) )
} }
else { else {
@@ -103,22 +111,8 @@ class InnerClassesLowering(val context: BackendContext) : ClassLoweringPass {
) )
} }
return IrConstructorImpl( loweredConstructor.body = blockBody
startOffset, endOffset, return loweredConstructor
irConstructor.origin, // TODO special origin for lowered inner class constructors?
newSymbol,
blockBody
).apply {
newSymbol.descriptor.valueParameters.forEachIndexed { i, desc ->
val valueParameter = if (i == 0) {
IrValueParameterImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, FIELD_FOR_OUTER_THIS, desc, null)
} else {
val origParam = irConstructor.valueParameters[i - 1]
IrValueParameterImpl(origParam.startOffset, origParam.endOffset, origParam.origin, desc, origParam.defaultValue)
}
valueParameters.add(valueParameter)
}
}
} }
private fun lowerConstructorParameterUsages() { private fun lowerConstructorParameterUsages() {
@@ -145,7 +139,7 @@ class InnerClassesLowering(val context: BackendContext) : ClassLoweringPass {
val endOffset = expression.endOffset val endOffset = expression.endOffset
val origin = expression.origin val origin = expression.origin
var irThis: IrExpression = IrGetValueImpl(startOffset, endOffset, classDescriptor.thisAsReceiverParameter, origin) var irThis: IrExpression = IrGetValueImpl(startOffset, endOffset, irClass.thisReceiver!!.symbol, origin)
var innerClass = classDescriptor var innerClass = classDescriptor
while (innerClass != implicitThisClass) { while (innerClass != implicitThisClass) {
@@ -56,16 +56,16 @@ class DeclarationIrBuilder(
) )
abstract class AbstractVariableRemapper : IrElementTransformerVoid() { abstract class AbstractVariableRemapper : IrElementTransformerVoid() {
protected abstract fun remapVariable(value: ValueDescriptor): ValueDescriptor? protected abstract fun remapVariable(value: ValueDescriptor): IrValueParameter?
override fun visitGetValue(expression: IrGetValue): IrExpression = override fun visitGetValue(expression: IrGetValue): IrExpression =
remapVariable(expression.descriptor)?.let { remapVariable(expression.descriptor)?.let {
IrGetValueImpl(expression.startOffset, expression.endOffset, it, expression.origin) IrGetValueImpl(expression.startOffset, expression.endOffset, it.symbol, expression.origin)
} ?: expression } ?: expression
} }
class VariableRemapper(val mapping: Map<ValueDescriptor, ValueDescriptor>) : AbstractVariableRemapper() { class VariableRemapper(val mapping: Map<ValueDescriptor, IrValueParameter>) : AbstractVariableRemapper() {
override fun remapVariable(value: ValueDescriptor): ValueDescriptor? = override fun remapVariable(value: ValueDescriptor): IrValueParameter? =
mapping[value] mapping[value]
} }
@@ -213,7 +213,7 @@ class BridgeLowering(val context: JvmBackendContext) : ClassLoweringPass {
//TODO //TODO
//MemberCodegen.markLineNumberForDescriptor(owner.getThisDescriptor(), iv) //MemberCodegen.markLineNumberForDescriptor(owner.getThisDescriptor(), iv)
if (delegateTo.method.argumentTypes.isNotEmpty() && isSpecialBridge) { if (delegateTo.method.argumentTypes.isNotEmpty() && isSpecialBridge) {
generateTypeCheckBarrierIfNeeded(descriptor, bridgeDescriptor, delegateTo.method.argumentTypes) generateTypeCheckBarrierIfNeeded(descriptor, bridgeDescriptor, irFunction, delegateTo.method.argumentTypes)
} }
val implementation = if (isSpecialBridge) delegateTo.descriptor.copyAsDeclaration() else delegateTo.descriptor val implementation = if (isSpecialBridge) delegateTo.descriptor.copyAsDeclaration() else delegateTo.descriptor
@@ -225,21 +225,21 @@ class BridgeLowering(val context: JvmBackendContext) : ClassLoweringPass {
call.dispatchReceiver = IrGetValueImpl( call.dispatchReceiver = IrGetValueImpl(
UNDEFINED_OFFSET, UNDEFINED_OFFSET,
UNDEFINED_OFFSET, UNDEFINED_OFFSET,
containingClass.thisAsReceiverParameter, irFunction.dispatchReceiverParameter!!.symbol,
JvmLoweredStatementOrigin.BRIDGE_DELEGATION JvmLoweredStatementOrigin.BRIDGE_DELEGATION
) )
bridgeDescriptor.valueParameters.mapIndexed { i, valueParameterDescriptor -> irFunction.valueParameters.mapIndexed { i, valueParameter ->
call.putValueArgument( call.putValueArgument(
i, i,
IrGetValueImpl( IrGetValueImpl(
UNDEFINED_OFFSET, UNDEFINED_OFFSET,
UNDEFINED_OFFSET, UNDEFINED_OFFSET,
valueParameterDescriptor, valueParameter.symbol,
JvmLoweredStatementOrigin.BRIDGE_DELEGATION JvmLoweredStatementOrigin.BRIDGE_DELEGATION
) )
) )
} }
+IrReturnImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, bridgeDescriptor, call) +IrReturnImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, irFunction.symbol, call)
}.apply { }.apply {
irFunction.body = this irFunction.body = this
} }
@@ -250,21 +250,27 @@ class BridgeLowering(val context: JvmBackendContext) : ClassLoweringPass {
private fun IrBlockBodyBuilder.generateTypeCheckBarrierIfNeeded( private fun IrBlockBodyBuilder.generateTypeCheckBarrierIfNeeded(
overrideDescriptor: FunctionDescriptor, overrideDescriptor: FunctionDescriptor,
bridgeDescriptor: FunctionDescriptor, bridgeDescriptor: FunctionDescriptor,
bridgeFunction: IrFunction,
delegateParameterTypes: Array<Type>? delegateParameterTypes: Array<Type>?
) { ) {
val typeSafeBarrierDescription = val typeSafeBarrierDescription =
BuiltinMethodsWithSpecialGenericSignature.getDefaultValueForOverriddenBuiltinFunction(overrideDescriptor) ?: return BuiltinMethodsWithSpecialGenericSignature.getDefaultValueForOverriddenBuiltinFunction(overrideDescriptor) ?: return
BuiltinMethodsWithSpecialGenericSignature.getOverriddenBuiltinFunctionWithErasedValueParametersInJava(overrideDescriptor) BuiltinMethodsWithSpecialGenericSignature.getOverriddenBuiltinFunctionWithErasedValueParametersInJava(overrideDescriptor)
?: error("Overridden built-in method should not be null for " + overrideDescriptor) ?: error("Overridden built-in method should not be null for $overrideDescriptor")
val conditions = bridgeDescriptor.valueParameters.withIndex().filter { (i, parameterDescriptor) -> val conditions = bridgeDescriptor.valueParameters.withIndex().filter { (i, parameterDescriptor) ->
typeSafeBarrierDescription.checkParameter(i) || typeSafeBarrierDescription.checkParameter(i) ||
!(delegateParameterTypes == null || OBJECT_TYPE == delegateParameterTypes[i]) || !(delegateParameterTypes == null || OBJECT_TYPE == delegateParameterTypes[i]) ||
!TypeUtils.isNullableType(parameterDescriptor.type) !TypeUtils.isNullableType(parameterDescriptor.type)
}.map { (i, parameterDescriptor) -> }.map { (i, _) ->
val checkValue = val checkValue =
IrGetValueImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, parameterDescriptor, JvmLoweredStatementOrigin.BRIDGE_DELEGATION) IrGetValueImpl(
UNDEFINED_OFFSET,
UNDEFINED_OFFSET,
bridgeFunction.valueParameters[i].symbol,
JvmLoweredStatementOrigin.BRIDGE_DELEGATION
)
if (delegateParameterTypes == null || OBJECT_TYPE == delegateParameterTypes[i]) { if (delegateParameterTypes == null || OBJECT_TYPE == delegateParameterTypes[i]) {
irNotEquals(checkValue, irNull()) irNotEquals(checkValue, irNull())
} else { } else {
@@ -53,7 +53,7 @@ class InterfaceDelegationLowering(val state: GenerationState) : IrElementTransfo
private fun generateInterfaceMethods(irClass: IrClass, descriptor: ClassDescriptor) { private fun generateInterfaceMethods(irClass: IrClass, descriptor: ClassDescriptor) {
val classDescriptor = if (descriptor is DefaultImplsClassDescriptor) descriptor.correspondingInterface else descriptor val classDescriptor = (descriptor as? DefaultImplsClassDescriptor)?.correspondingInterface ?: descriptor
for ((interfaceFun, value) in CodegenUtil.getNonPrivateTraitMethods(classDescriptor)) { for ((interfaceFun, value) in CodegenUtil.getNonPrivateTraitMethods(classDescriptor)) {
//skip java 8 default methods //skip java 8 default methods
if (!interfaceFun.isDefinitelyNotDefaultImplsMethod()) { if (!interfaceFun.isDefinitelyNotDefaultImplsMethod()) {
@@ -83,18 +83,30 @@ class InterfaceDelegationLowering(val state: GenerationState) : IrElementTransfo
val defaultImpls = InterfaceLowering.createDefaultImplsClassDescriptor(interfaceDescriptor) val defaultImpls = InterfaceLowering.createDefaultImplsClassDescriptor(interfaceDescriptor)
val defaultImplFun = val defaultImplFun =
InterfaceLowering.createDefaultImplFunDescriptor(defaultImpls, interfaceFun.original, interfaceDescriptor, state.typeMapper) InterfaceLowering.createDefaultImplFunDescriptor(defaultImpls, interfaceFun.original, interfaceDescriptor, state.typeMapper)
val returnType = inheritedFun.returnType!!
val irCallImpl = val irCallImpl =
IrCallImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, defaultImplFun, null, JvmLoweredStatementOrigin.DEFAULT_IMPLS_DELEGATION) IrCallImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, defaultImplFun, null, JvmLoweredStatementOrigin.DEFAULT_IMPLS_DELEGATION)
irBody.statements.add(IrReturnImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, inheritedFun, irCallImpl)) irBody.statements.add(IrReturnImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, irFunction.symbol, irCallImpl))
var shift = 0 var offset = 0
if (inheritedFun.dispatchReceiverParameter != null) { irFunction.dispatchReceiverParameter?.let {
irCallImpl.putValueArgument(0, IrGetValueImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, interfaceFun.dispatchReceiverParameter!!)) irCallImpl.putValueArgument(
shift = 1 offset,
IrGetValueImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, it.symbol)
)
offset++
} }
inheritedFun.valueParameters.mapIndexed { i, valueParameterDescriptor ->
irCallImpl.putValueArgument(i + shift, IrGetValueImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, valueParameterDescriptor, null)) irFunction.extensionReceiverParameter?.let {
irCallImpl.putValueArgument(
offset,
IrGetValueImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, it.symbol)
)
offset++
}
irFunction.valueParameters.mapIndexed { i, parameter ->
irCallImpl.putValueArgument(i + offset, IrGetValueImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, parameter.symbol, null))
} }
} }
@@ -31,8 +31,10 @@ import org.jetbrains.kotlin.descriptors.impl.SimpleFunctionDescriptorImpl
import org.jetbrains.kotlin.descriptors.impl.ValueParameterDescriptorImpl import org.jetbrains.kotlin.descriptors.impl.ValueParameterDescriptorImpl
import org.jetbrains.kotlin.ir.declarations.IrClass import org.jetbrains.kotlin.ir.declarations.IrClass
import org.jetbrains.kotlin.ir.declarations.IrFunction import org.jetbrains.kotlin.ir.declarations.IrFunction
import org.jetbrains.kotlin.ir.declarations.IrValueParameter
import org.jetbrains.kotlin.ir.declarations.impl.IrClassImpl import org.jetbrains.kotlin.ir.declarations.impl.IrClassImpl
import org.jetbrains.kotlin.ir.declarations.impl.IrFunctionImpl import org.jetbrains.kotlin.ir.declarations.impl.IrFunctionImpl
import org.jetbrains.kotlin.ir.util.createParameterDeclarations
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
import org.jetbrains.kotlin.load.java.JvmAbi import org.jetbrains.kotlin.load.java.JvmAbi
@@ -141,12 +143,13 @@ internal fun createStaticFunctionWithReceivers(
} }
internal fun FunctionDescriptor.createFunctionAndMapVariables(oldFunction: IrFunction) = internal fun FunctionDescriptor.createFunctionAndMapVariables(oldFunction: IrFunction) =
IrFunctionImpl(oldFunction.startOffset, oldFunction.endOffset, oldFunction.origin, this, oldFunction.body).also { IrFunctionImpl(oldFunction.startOffset, oldFunction.endOffset, oldFunction.origin, this, oldFunction.body).apply {
val mapping: Map<ValueDescriptor, ValueDescriptor> = createParameterDeclarations()
val mapping: Map<ValueDescriptor, IrValueParameter> =
( (
listOfNotNull(oldFunction.descriptor.dispatchReceiverParameter!!, oldFunction.descriptor.extensionReceiverParameter) + listOfNotNull(oldFunction.descriptor.dispatchReceiverParameter!!, oldFunction.descriptor.extensionReceiverParameter) +
oldFunction.descriptor.valueParameters oldFunction.descriptor.valueParameters
).zip(this.valueParameters).toMap() ).zip(valueParameters).toMap()
it.body?.transform(VariableRemapper(mapping), null) body?.transform(VariableRemapper(mapping), null)
} }