From a0b5eda0ae9fd3cc50a45ad8177cf046063f57b8 Mon Sep 17 00:00:00 2001 From: Ivan Kylchik Date: Wed, 11 Aug 2021 14:26:49 +0300 Subject: [PATCH] Interpret getter with null body separately from common function --- .../kotlin/ir/interpreter/CallInterceptor.kt | 13 ++++--------- .../kotlin/ir/interpreter/IrTreeBuildUtils.kt | 6 ++++++ .../org/jetbrains/kotlin/ir/interpreter/Utils.kt | 6 +++++- 3 files changed, 15 insertions(+), 10 deletions(-) diff --git a/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/CallInterceptor.kt b/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/CallInterceptor.kt index 94ac16e5e90..f95ff34e421 100644 --- a/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/CallInterceptor.kt +++ b/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/CallInterceptor.kt @@ -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)) } - } } diff --git a/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/IrTreeBuildUtils.kt b/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/IrTreeBuildUtils.kt index aa9bbcd5471..03747a00804 100644 --- a/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/IrTreeBuildUtils.kt +++ b/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/IrTreeBuildUtils.kt @@ -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.wrapWithBlockBody(): IrBlockBody { return IrBlockBodyImpl(SYNTHETIC_OFFSET, SYNTHETIC_OFFSET, this) } diff --git a/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/Utils.kt b/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/Utils.kt index d2dc248ebf6..00d1a144fd8 100644 --- a/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/Utils.kt +++ b/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/Utils.kt @@ -291,9 +291,13 @@ internal fun IrClass.getSingleAbstractMethod(): IrFunction { return declarations.filterIsInstance().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() == "" } + +internal fun IrFunction.isAccessorOfPropertyWithBackingField(): Boolean { + return this is IrSimpleFunction && this.correspondingPropertySymbol?.owner?.backingField != null +}