JVM_IR wrap function into a proxy if indy SAM-conversion becomes valid

This commit is contained in:
Dmitry Petrov
2021-10-06 18:53:29 +03:00
committed by teamcityserver
parent 9ad62eb1fd
commit 40fe67880b
21 changed files with 583 additions and 66 deletions
@@ -341,11 +341,13 @@ private val jvmFilePhases = listOf(
propertyReferencePhase,
arrayConstructorPhase,
constPhase1,
// TODO: merge the next three phases together, as visitors behave incorrectly between them
// (backing fields moved out of companion objects are reachable by two paths):
moveOrCopyCompanionObjectFieldsPhase,
propertiesPhase,
remapObjectFieldAccesses,
anonymousObjectSuperConstructorPhase,
jvmStandardLibraryBuiltInsPhase,
@@ -16,10 +16,7 @@ import org.jetbrains.kotlin.backend.jvm.JvmLoweredDeclarationOrigin
import org.jetbrains.kotlin.backend.jvm.JvmLoweredStatementOrigin
import org.jetbrains.kotlin.backend.jvm.JvmSymbols
import org.jetbrains.kotlin.backend.jvm.ir.*
import org.jetbrains.kotlin.backend.jvm.lower.indy.LambdaMetafactoryArguments
import org.jetbrains.kotlin.backend.jvm.lower.indy.LambdaMetafactoryArgumentsBuilder
import org.jetbrains.kotlin.backend.jvm.lower.indy.SamDelegatingLambdaBlock
import org.jetbrains.kotlin.backend.jvm.lower.indy.SamDelegatingLambdaBuilder
import org.jetbrains.kotlin.backend.jvm.lower.indy.*
import org.jetbrains.kotlin.config.JvmClosureGenerationScheme
import org.jetbrains.kotlin.descriptors.DescriptorVisibilities
import org.jetbrains.kotlin.descriptors.Modality
@@ -28,9 +25,11 @@ import org.jetbrains.kotlin.ir.builders.*
import org.jetbrains.kotlin.ir.builders.declarations.*
import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.declarations.impl.IrFunctionImpl
import org.jetbrains.kotlin.ir.declarations.impl.IrVariableImpl
import org.jetbrains.kotlin.ir.expressions.*
import org.jetbrains.kotlin.ir.expressions.impl.*
import org.jetbrains.kotlin.ir.symbols.IrFunctionSymbol
import org.jetbrains.kotlin.ir.symbols.impl.IrVariableSymbolImpl
import org.jetbrains.kotlin.ir.types.*
import org.jetbrains.kotlin.ir.util.*
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
@@ -88,10 +87,11 @@ internal class FunctionReferenceLowering(private val context: JvmBackendContext)
if (shouldGenerateIndyLambdas) {
val lambdaMetafactoryArguments =
LambdaMetafactoryArgumentsBuilder(context, crossinlineLambdas)
.getLambdaMetafactoryArgumentsOrNull(reference, reference.type, true)
if (lambdaMetafactoryArguments != null) {
.getLambdaMetafactoryArguments(reference, reference.type, true)
if (lambdaMetafactoryArguments is LambdaMetafactoryArguments) {
return wrapLambdaReferenceWithIndySamConversion(expression, reference, lambdaMetafactoryArguments)
}
// TODO MetafactoryArgumentsResult.Failure.FunctionHazard?
}
return FunctionReferenceBuilder(reference).build()
@@ -254,8 +254,13 @@ internal class FunctionReferenceLowering(private val context: JvmBackendContext)
val lambdaBlock = SamDelegatingLambdaBuilder(context)
.build(invokable, samSuperType, currentScope!!.scope.scopeOwnerSymbol, getDeclarationParentForDelegatingLambda())
val lambdaMetafactoryArguments = LambdaMetafactoryArgumentsBuilder(context, crossinlineLambdas)
.getLambdaMetafactoryArgumentsOrNull(lambdaBlock.ref, samSuperType, false)
?: return super.visitTypeOperator(expression)
.getLambdaMetafactoryArguments(lambdaBlock.ref, samSuperType, false)
if (lambdaMetafactoryArguments !is LambdaMetafactoryArguments) {
// TODO MetafactoryArgumentsResult.Failure.FunctionHazard?
return super.visitTypeOperator(expression)
}
invokable.transformChildrenVoid()
return wrapSamDelegatingLambdaWithIndySamConversion(samSuperType, lambdaBlock, lambdaMetafactoryArguments)
} else {
@@ -267,9 +272,25 @@ internal class FunctionReferenceLowering(private val context: JvmBackendContext)
if (shouldGenerateIndySamConversions) {
val lambdaMetafactoryArguments =
LambdaMetafactoryArgumentsBuilder(context, crossinlineLambdas)
.getLambdaMetafactoryArgumentsOrNull(reference, samSuperType, false)
if (lambdaMetafactoryArguments != null) {
return wrapSamConversionArgumentWithIndySamConversion(expression, lambdaMetafactoryArguments)
.getLambdaMetafactoryArguments(reference, samSuperType, false)
if (lambdaMetafactoryArguments is LambdaMetafactoryArguments) {
return wrapSamConversionArgumentWithIndySamConversion(expression) { samType ->
wrapWithIndySamConversion(samType, lambdaMetafactoryArguments)
}
} else if (lambdaMetafactoryArguments is MetafactoryArgumentsResult.Failure.FunctionHazard) {
// Try wrapping function with a proxy local function and see if that helps.
val proxyLocalFunBlock = createProxyLocalFunctionForIndySamConversion(reference)
val proxyLocalFunRef = proxyLocalFunBlock.statements[proxyLocalFunBlock.statements.size - 1] as IrFunctionReference
val proxyLambdaMetafactoryArguments = LambdaMetafactoryArgumentsBuilder(context, crossinlineLambdas)
.getLambdaMetafactoryArguments(proxyLocalFunRef, samSuperType, false)
if (proxyLambdaMetafactoryArguments is LambdaMetafactoryArguments) {
return wrapSamConversionArgumentWithIndySamConversion(expression) { samType ->
proxyLocalFunBlock.statements[proxyLocalFunBlock.statements.size - 1] =
wrapWithIndySamConversion(samType, proxyLambdaMetafactoryArguments)
proxyLocalFunBlock.type = samType
proxyLocalFunBlock
}
}
}
}
@@ -280,6 +301,152 @@ internal class FunctionReferenceLowering(private val context: JvmBackendContext)
return FunctionReferenceBuilder(reference, erasedSamSuperType).build()
}
private fun createProxyLocalFunctionForIndySamConversion(reference: IrFunctionReference): IrBlock {
val startOffset = reference.startOffset
val endOffset = reference.endOffset
val targetFun = reference.symbol.owner
// For a function reference with possibly bound value parameters
// [ dispatchReceiver = ..., extensionReceiver = ..., ... ]::foo
// create a proxy wrapper:
// {
// val tmp_proxy_0 = <bound_argument_value_0>
// ...
// val tmp_proxy_N = <bound_argument_value_N>
// fun `$proxy`(p_0: TP_0, ..., p_M: TP_M): TR =
// foo(... arg_J ...)
// // here for each J arg_J is either 'tmp_proxy_K' or 'p_K' for some K
// ::`$proxy`
// }
val temporaryVals = ArrayList<IrVariable>()
val targetCall: IrFunctionAccessExpression =
when (targetFun) {
is IrSimpleFunction ->
IrCallImpl.fromSymbolOwner(startOffset, endOffset, targetFun.symbol)
is IrConstructor ->
IrConstructorCallImpl.fromSymbolOwner(startOffset, endOffset, targetFun.returnType, targetFun.symbol)
else ->
throw AssertionError("Unexpected callable reference target: ${targetFun.render()}")
}
val proxyFun = context.irFactory.buildFun {
name = Name.identifier("\$proxy")
returnType = targetFun.returnType
visibility = DescriptorVisibilities.LOCAL
modality = Modality.FINAL
isSuspend = false
isInline = false
origin = JvmLoweredDeclarationOrigin.PROXY_FUN_FOR_INDY_SAM_CONVESION
}.also { proxyFun ->
proxyFun.parent = currentDeclarationParent
?: throw AssertionError("No declaration parent when processing $reference")
var temporaryValIndex = 0
var proxyParameterIndex = 0
fun addAndGetTemporaryVal(initializer: IrExpression): IrGetValue {
val tmpVal = IrVariableImpl(
startOffset, endOffset,
IrDeclarationOrigin.IR_TEMPORARY_VARIABLE,
IrVariableSymbolImpl(),
Name.identifier("tmp_proxy_${temporaryValIndex++}"),
initializer.type,
isVar = false, isConst = false, isLateinit = false
)
tmpVal.initializer = initializer
temporaryVals.add(tmpVal)
return IrGetValueImpl(startOffset, endOffset, tmpVal.symbol)
}
fun addAndGetProxyValueParameter(originalParameter: IrValueParameter): IrGetValue {
val proxyParameter = buildValueParameter(proxyFun) {
updateFrom(originalParameter)
name = Name.identifier("p$proxyParameterIndex\$${originalParameter.name.asString()}")
index = proxyParameterIndex
proxyParameterIndex++
}.apply {
parent = proxyFun
}
proxyFun.valueParameters += proxyParameter
return IrGetValueImpl(startOffset, endOffset, proxyParameter.symbol)
}
fun getTargetCallArgument(boundValue: IrExpression?, originalParameter: IrValueParameter?): IrExpression? =
when {
boundValue != null ->
addAndGetTemporaryVal(boundValue)
originalParameter != null ->
addAndGetProxyValueParameter(originalParameter)
else ->
null
}
targetCall.dispatchReceiver = getTargetCallArgument(reference.dispatchReceiver, targetFun.dispatchReceiverParameter)
targetCall.extensionReceiver = getTargetCallArgument(reference.extensionReceiver, targetFun.extensionReceiverParameter)
for ((valueParameterIndex, valueParameter) in targetFun.valueParameters.withIndex()) {
targetCall.putValueArgument(
valueParameterIndex,
getTargetCallArgument(
reference.getValueArgument(valueParameterIndex),
valueParameter
)
)
}
val proxyFunBody = IrBlockBodyImpl(startOffset, endOffset).also { proxyFun.body = it }
when {
targetFun.isArrayOf() -> {
// Lower arrayOf-like function in place.
// TODO it seems that VarargLowering does a little bit too much.
// Maybe worth decomposing it into varargs part and arrayOf intrinsics part.
val varargParameter = proxyFun.valueParameters.singleOrNull { it.isVararg }
?: throw AssertionError(
"Proxy for *arrayOf should have single vararg parameter:\n" +
proxyFun.valueParameters.joinToString(separator = "\n") { it.dump() }
)
proxyFunBody.statements.add(
IrReturnImpl(
startOffset, endOffset,
context.irBuiltIns.nothingType,
proxyFun.symbol,
IrGetValueImpl(startOffset, endOffset, varargParameter.symbol, null)
)
)
}
targetFun.returnType.isUnit() -> {
proxyFunBody.statements.add(targetCall)
}
else -> {
proxyFunBody.statements.add(
IrReturnImpl(
startOffset, endOffset,
context.irBuiltIns.nothingType,
proxyFun.symbol,
targetCall
)
)
}
}
}
val proxyFunRef = IrFunctionReferenceImpl(
startOffset, endOffset,
reference.type,
proxyFun.symbol,
0, // TODO generic function reference?
proxyFun.valueParameters.size
)
return IrBlockImpl(
startOffset, endOffset,
reference.type,
origin = null,
temporaryVals + proxyFun + proxyFunRef
)
}
private fun canGenerateIndySamConversionOnFunctionalExpression(samSuperType: IrType, expression: IrExpression): Boolean {
val samClass = samSuperType.classOrNull
?: throw AssertionError("Class type expected: ${samSuperType.render()}")
@@ -302,24 +469,24 @@ internal class FunctionReferenceLowering(private val context: JvmBackendContext)
private fun wrapSamConversionArgumentWithIndySamConversion(
expression: IrTypeOperatorCall,
lambdaMetafactoryArguments: LambdaMetafactoryArguments
produceSamConversion: (IrType) -> IrExpression
): IrExpression {
val samType = expression.typeOperand
return when (val argument = expression.argument) {
is IrFunctionReference ->
wrapWithIndySamConversion(samType, lambdaMetafactoryArguments)
produceSamConversion(samType)
is IrBlock ->
wrapFunctionReferenceInsideBlockWithIndySamConversion(samType, lambdaMetafactoryArguments, argument)
wrapFunctionReferenceInsideBlockWithIndySamConversion(samType, argument, produceSamConversion)
else -> throw AssertionError("Block or function reference expected: ${expression.render()}")
}
}
private fun wrapFunctionReferenceInsideBlockWithIndySamConversion(
samType: IrType,
lambdaMetafactoryArguments: LambdaMetafactoryArguments,
block: IrBlock
block: IrBlock,
produceSamConversion: (IrType) -> IrExpression
): IrExpression {
val indySamConversion = wrapWithIndySamConversion(samType, lambdaMetafactoryArguments)
val indySamConversion = produceSamConversion(samType)
block.statements[block.statements.size - 1] = indySamConversion
block.type = indySamConversion.type
return block
@@ -9,6 +9,7 @@ import org.jetbrains.kotlin.backend.common.ir.allOverridden
import org.jetbrains.kotlin.backend.common.lower.VariableRemapper
import org.jetbrains.kotlin.backend.common.lower.parents
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
import org.jetbrains.kotlin.backend.jvm.JvmLoweredDeclarationOrigin
import org.jetbrains.kotlin.backend.jvm.ir.erasedUpperBound
import org.jetbrains.kotlin.backend.jvm.ir.findSuperDeclaration
import org.jetbrains.kotlin.backend.jvm.ir.getSingleAbstractMethod
@@ -34,12 +35,49 @@ import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.types.Variance
import org.jetbrains.kotlin.utils.addIfNotNull
internal sealed class MetafactoryArgumentsResult {
abstract val isSuccess: Boolean
abstract class Success : MetafactoryArgumentsResult() {
override val isSuccess: Boolean
get() = true
}
abstract class Failure : MetafactoryArgumentsResult() {
override val isSuccess: Boolean
get() = false
// Objects produced by j.l.invoke.LambdaMetafactory have different semantics (e.g., different 'equals' method)
// that prevents using them in place of objects of corresponding Kotlin classes.
// TODO might use Kotlin-specific metafactory if there would be one.
object LambdaMetafactorySemanticsHazard : Failure()
// There's an ABI incompatibility between classes generated by j.l.invoke.LambdaMetafactory and classes generatede by Kotlin.
// TODO might use Kotlin-specific metafactory if there would be one.
object LambdaMetafactoryAbiHazard : Failure()
// An object would be created inside an inline function, which currently doesn't work well with 'invokedynamic'.
// TODO make sure indy and Kotlin bytecode inliner work well together
object InliningHazard : Failure()
// Resulting object should be Serializable.
// TODO implement serialization support required by j.l.invoke.LambdaMetafactory
object SerializationHazard : Failure()
// There's something special about a function we are referencing.
// Wrapping it into a proxy local function might help.
object FunctionHazard : Failure()
}
}
internal class LambdaMetafactoryArguments(
val samMethod: IrSimpleFunction,
val fakeInstanceMethod: IrSimpleFunction,
val implMethodReference: IrFunctionReference,
val extraOverriddenMethods: List<IrSimpleFunction>
)
) : MetafactoryArgumentsResult.Success()
internal class LambdaMetafactoryArgumentsBuilder(
private val context: JvmBackendContext,
@@ -48,34 +86,44 @@ internal class LambdaMetafactoryArgumentsBuilder(
/**
* @see java.lang.invoke.LambdaMetafactory
*/
fun getLambdaMetafactoryArgumentsOrNull(
fun getLambdaMetafactoryArguments(
reference: IrFunctionReference,
samType: IrType,
plainLambda: Boolean
): LambdaMetafactoryArguments? {
): MetafactoryArgumentsResult {
val samClass = samType.getClass()
?: throw AssertionError("SAM type is not a class: ${samType.render()}")
var semanticsHazard = false
var abiHazard = false
var inliningHazard = false
var shouldBeSerializable = false
var functionHazard = false
// Can't use JDK LambdaMetafactory for function references by default (because of 'equals').
// TODO special mode that would generate indy everywhere?
if (!reference.origin.isLambda && !samClass.isFromJava())
return null
if (!reference.origin.isLambda && !samClass.isFromJava()) {
semanticsHazard = true
}
// Don't use JDK LambdaMetafactory for serializable lambdas
// TODO implement support for serializable lambdas with LambdaMetafactory (requires additional code for deserialization)
if (samClass.isInheritedFromSerializable())
return null
if (samClass.isInheritedFromSerializable()) {
shouldBeSerializable = true
}
val samMethod = samClass.getSingleAbstractMethod()
?: throw AssertionError("SAM class has no single abstract method: ${samClass.render()}")
// Can't use JDK LambdaMetafactory for fun interface with suspend fun.
if (samMethod.isSuspend)
return null
if (samMethod.isSuspend) {
abiHazard = true
}
// Can't use JDK LambdaMetafactory for fun interfaces that require delegation to $DefaultImpls.
if (samClass.requiresDelegationToDefaultImpls())
return null
if (samClass.requiresDelegationToDefaultImpls()) {
abiHazard = true
}
// TODO in cases where LambdaMetafactory is unusable directly due to problems with the implementation function,
// we can still avoid generating an entire class by converting the function reference into a lambda first;
@@ -83,32 +131,38 @@ internal class LambdaMetafactoryArgumentsBuilder(
val implFun = reference.symbol.owner
if (implFun.typeParameters.any { it.isReified }) {
// TODO support reified type parameters in proxy wrappers somehow?
abiHazard = true
}
// Don't generate references to intrinsic functions as invokedynamic (no such method exists at run-time).
if (context.irIntrinsics.getIntrinsic(implFun.symbol) != null)
return null
if (context.irIntrinsics.getIntrinsic(implFun.symbol) != null) {
functionHazard = true
}
// Can't use invokedynamic if the referenced function has to be inlined for correct semantics
// Also in some cases like `private inline fun` we'd need accessors, which `SyntheticAccessorLowering`
// won't generate under the assumption that the inline function will be inlined. Plus if the function
// is in a different module we should probably copy it anyway (and regenerate all objects in it).
if (implFun.isInline)
return null
if (implFun.isInline) {
functionHazard = true
}
if (implFun is IrConstructor && DescriptorVisibilities.isPrivate(implFun.visibility)) {
// Kotlin generates constructor accessors differently from Java.
// TODO more precise accessibility check (see SyntheticAccessorLowering::isAccessible)
return null
// We don't do exact accessibility check here, just
functionHazard = true
}
// It's possible to reference through a child class a method declared in a package-private base Java class.
// In this case the corresponding method might be inaccessible in the context where it's referenced (see KT-48954).
// For now, just prohibit referencing methods from package-private Java classes through indy (without precise accessibility check).
// TODO wrap into lambda?
if (implFun is IrSimpleFunction) {
val baseFun = findSuperDeclaration(implFun, false, context.state.jvmDefaultMode)
val baseFunClass = baseFun.parent as? IrClass
if (baseFunClass != null && baseFunClass.visibility == JavaDescriptorVisibilities.PACKAGE_VISIBILITY) {
return null
functionHazard = true
}
}
@@ -117,40 +171,52 @@ internal class LambdaMetafactoryArgumentsBuilder(
// LambdaMetafactory treats multifile class part members as non-accessible,
// even if the member is referenced via facade,
// because corresponding part class is non-accessible
return null
functionHazard = true
}
// Can't use JDK LambdaMetafactory for annotated lambdas.
// JDK LambdaMetafactory doesn't copy annotations from implementation method to an instance method in a
// corresponding synthetic class, which doesn't look like a binary compatible change.
// TODO relaxed mode?
if (reference.origin.isLambda && implFun.annotations.isNotEmpty())
return null
if (reference.origin.isLambda && implFun.annotations.isNotEmpty()) {
abiHazard = true
}
// Don't use JDK LambdaMetafactory for big arity lambdas.
if (plainLambda) {
var parametersCount = implFun.valueParameters.size
if (implFun.extensionReceiverParameter != null) ++parametersCount
if (parametersCount >= BuiltInFunctionArity.BIG_ARITY)
return null
abiHazard = true
}
// Can't use indy-based SAM conversion inside inline fun (Ok in inline lambda).
if (implFun.parents.any { it.isInlineFunction() || it.isCrossinlineLambda() })
return null
if (implFun.parents.any { it.isInlineFunction() || it.isCrossinlineLambda() }) {
inliningHazard = true
}
// Don't try to use indy on SAM types with non-invariant projections because buildFakeOverrideMember doesn't support such supertypes
// (and rightly so: supertypes in Kotlin can't have projections in immediate type arguments). This can happen for example in case
// the SAM type is instantiated with an intersection type in arguments, which is approximated to an out-projection in psi2ir.
if (samType is IrSimpleType) {
if (samType.arguments.any { it is IrStarProjection || it is IrTypeProjection && it.variance != Variance.INVARIANT })
return null
if (samType.arguments.any { it is IrStarProjection || it is IrTypeProjection && it.variance != Variance.INVARIANT }) {
abiHazard = true
}
}
when {
semanticsHazard -> return MetafactoryArgumentsResult.Failure.LambdaMetafactorySemanticsHazard
abiHazard -> return MetafactoryArgumentsResult.Failure.LambdaMetafactoryAbiHazard
inliningHazard -> return MetafactoryArgumentsResult.Failure.InliningHazard
shouldBeSerializable -> return MetafactoryArgumentsResult.Failure.SerializationHazard
functionHazard -> return MetafactoryArgumentsResult.Failure.FunctionHazard
}
// Do the hard work of matching Kotlin functional interface hierarchy against LambdaMetafactory constraints.
// Briefly: sometimes we have to force boxing on the primitive and inline class values, sometimes we have to keep them unboxed.
// If this results in conflicting requirements, we can't use INVOKEDYNAMIC with LambdaMetafactory for creating a closure.
return getLambdaMetafactoryArgsOrNullInner(reference, samMethod, samType, implFun)
?: MetafactoryArgumentsResult.Failure.FunctionHazard
}
private val javaIoSerializableFqn =
@@ -258,7 +324,7 @@ internal class LambdaMetafactoryArgumentsBuilder(
return null
adaptFakeInstanceMethodSignature(fakeInstanceMethod, signatureAdaptationConstraints)
if (implFun.origin == IrDeclarationOrigin.LOCAL_FUNCTION_FOR_LAMBDA) {
if (implFun.origin in adaptableFunctionOrigins) {
adaptLambdaSignature(implFun as IrSimpleFunction, fakeInstanceMethod, signatureAdaptationConstraints)
} else if (
!checkMethodSignatureCompliance(implFun, fakeInstanceMethod, signatureAdaptationConstraints, reference)
@@ -319,13 +385,18 @@ internal class LambdaMetafactoryArgumentsBuilder(
TypeAdaptationConstraint.CONFLICT -> false
}
private val adaptableFunctionOrigins = setOf(
IrDeclarationOrigin.LOCAL_FUNCTION_FOR_LAMBDA,
JvmLoweredDeclarationOrigin.PROXY_FUN_FOR_INDY_SAM_CONVESION
)
private fun adaptLambdaSignature(
implFun: IrSimpleFunction,
fakeInstanceMethod: IrSimpleFunction,
constraints: SignatureAdaptationConstraints
) {
if (implFun.origin != IrDeclarationOrigin.LOCAL_FUNCTION_FOR_LAMBDA) {
throw AssertionError("Can't adapt non-lambda function signature: ${implFun.render()}")
if (implFun.origin !in adaptableFunctionOrigins) {
throw AssertionError("Function origin should be one of ${adaptableFunctionOrigins}: ${implFun.dump()}")
}
val implParameters = collectValueParameters(implFun)
@@ -37,7 +37,7 @@ interface JvmLoweredDeclarationOrigin : IrDeclarationOrigin {
object INTERFACE_COMPANION_PRIVATE_INSTANCE : IrDeclarationOriginImpl("INTERFACE_COMPANION_PRIVATE_INSTANCE", isSynthetic = true)
object POLYMORPHIC_SIGNATURE_INSTANTIATION : IrDeclarationOriginImpl("POLYMORPHIC_SIGNATURE_INSTANTIATION", isSynthetic = true)
object ENUM_CONSTRUCTOR_SYNTHETIC_PARAMETER : IrDeclarationOriginImpl("ENUM_CONSTRUCTOR_SYNTHETIC_PARAMETER", isSynthetic = true)
object OBJECT_SUPER_CONSTRUCTOR_PARAMETER : IrDeclarationOriginImpl("OBJECT_SUPER_CONSTURCTOR_PARAMETER", isSynthetic = true)
object OBJECT_SUPER_CONSTRUCTOR_PARAMETER : IrDeclarationOriginImpl("OBJECT_SUPER_CONSTRUCTOR_PARAMETER", isSynthetic = true)
object CONTINUATION_CLASS : IrDeclarationOriginImpl("CONTINUATION_CLASS")
object SUSPEND_LAMBDA : IrDeclarationOriginImpl("SUSPEND_LAMBDA")
object FOR_INLINE_STATE_MACHINE_TEMPLATE : IrDeclarationOriginImpl("FOR_INLINE_TEMPLATE")
@@ -48,4 +48,5 @@ interface JvmLoweredDeclarationOrigin : IrDeclarationOrigin {
object ABSTRACT_BRIDGE_STUB : IrDeclarationOriginImpl("ABSTRACT_BRIDGE_STUB")
object INVOVEDYNAMIC_CALL_TARGET : IrDeclarationOriginImpl("INVOVEDYNAMIC_CALL_TARGET")
object INLINE_LAMBDA : IrDeclarationOriginImpl("INLINE_LAMBDA")
object PROXY_FUN_FOR_INDY_SAM_CONVESION : IrDeclarationOriginImpl("PROXY_FUN_FOR_INDY_SAM_CONVESION")
}