Interpret getter with null body separately from common function

This commit is contained in:
Ivan Kylchik
2021-08-11 14:26:49 +03:00
committed by Space
parent 9e7d8808bd
commit a0b5eda0ae
3 changed files with 15 additions and 10 deletions
@@ -65,8 +65,10 @@ internal class DefaultCallInterceptor(override val interpreter: IrInterpreter) :
handleIntrinsicMethods(irFunction) -> return
receiver.mustBeHandledAsReflection(call) -> Wrapper.getReflectionMethod(irFunction).invokeMethod(irFunction, args)
receiver is Primitive<*> -> calculateBuiltIns(irFunction, args) // check for js char, js long and get field for primitives
irFunction.body == null ->
irFunction.trySubstituteFunctionBody() ?: irFunction.tryCalculateLazyConst() ?: calculateBuiltIns(irFunction, args)
// TODO try to save fields in Primitive -> then it is possible to move up next branch
// TODO try to create backing field if it is missing
irFunction.body == null && irFunction.isAccessorOfPropertyWithBackingField() -> callStack.pushInstruction(CompoundInstruction(irFunction.createGetField()))
irFunction.body == null -> irFunction.trySubstituteFunctionBody() ?: calculateBuiltIns(irFunction, args)
else -> defaultAction()
}
}
@@ -209,11 +211,4 @@ internal class DefaultCallInterceptor(override val interpreter: IrInterpreter) :
callStack.pushInstruction(CompoundInstruction(this))
return body
}
// TODO fix in FIR2IR; const val getter must have body with IrGetField node
private fun IrFunction.tryCalculateLazyConst(): IrExpression? {
if (this !is IrSimpleFunction) return null
val expression = this.correspondingPropertySymbol?.owner?.backingField?.initializer?.expression
return expression?.apply { callStack.pushInstruction(CompoundInstruction(this)) }
}
}
@@ -137,6 +137,12 @@ internal fun createTempClass(name: Name, origin: IrDeclarationOrigin = TEMP_CLAS
)
}
internal fun IrFunction.createGetField(): IrExpression {
val backingField = (this as IrSimpleFunction).correspondingPropertySymbol?.owner?.backingField!!
val receiver = dispatchReceiverParameter ?: extensionReceiverParameter
return IrGetFieldImpl(SYNTHETIC_OFFSET, SYNTHETIC_OFFSET, backingField.symbol, backingField.type, receiver?.createGetValue())
}
internal fun List<IrStatement>.wrapWithBlockBody(): IrBlockBody {
return IrBlockBodyImpl(SYNTHETIC_OFFSET, SYNTHETIC_OFFSET, this)
}
@@ -291,9 +291,13 @@ internal fun IrClass.getSingleAbstractMethod(): IrFunction {
return declarations.filterIsInstance<IrSimpleFunction>().single { it.modality == Modality.ABSTRACT }
}
fun IrGetValue.isAccessToObject(): Boolean {
internal fun IrGetValue.isAccessToObject(): Boolean {
val owner = this.symbol.owner
val expectedClass = this.type.classOrNull?.owner
if (expectedClass == null || !expectedClass.isObject) return false
return owner.origin == IrDeclarationOrigin.INSTANCE_RECEIVER || owner.name.asString() == "<this>"
}
internal fun IrFunction.isAccessorOfPropertyWithBackingField(): Boolean {
return this is IrSimpleFunction && this.correspondingPropertySymbol?.owner?.backingField != null
}