[IR] Reworked adapted references building + test
As a side effect, this fixes https://youtrack.jetbrains.com/issue/KT-43887 (cherry picked from commit 387c09e7aed7666f5a178b2ac342fb17ed3cdda3)
This commit is contained in:
+15
-29
@@ -213,30 +213,8 @@ internal class FunctionReferenceLowering(val context: Context): FileLoweringPass
|
||||
|
||||
private val samSuperClass = samSuperType?.let { it.classOrNull ?: error("Expected a class but was: ${it.render()}") }
|
||||
|
||||
private val adapteeCall: IrFunctionAccessExpression? =
|
||||
// TODO: Copied from JVM.
|
||||
if (referencedFunction.origin == IrDeclarationOrigin.ADAPTER_FOR_CALLABLE_REFERENCE) {
|
||||
// The body of a callable reference adapter contains either only a call, or an IMPLICIT_COERCION_TO_UNIT type operator
|
||||
// applied to a call. That call's target is the original function which we need to get owner/name/signature.
|
||||
val call = when (val statement = referencedFunction.body!!.statements.single()) {
|
||||
is IrTypeOperatorCall -> {
|
||||
assert(statement.operator == IrTypeOperator.IMPLICIT_COERCION_TO_UNIT) {
|
||||
"Unexpected type operator in ADAPTER_FOR_CALLABLE_REFERENCE: ${referencedFunction.render()}"
|
||||
}
|
||||
statement.argument
|
||||
}
|
||||
is IrReturn -> statement.value
|
||||
else -> statement
|
||||
}
|
||||
if (call !is IrFunctionAccessExpression) {
|
||||
throw UnsupportedOperationException("Unknown structure of ADAPTER_FOR_CALLABLE_REFERENCE: ${referencedFunction.render()}")
|
||||
}
|
||||
call
|
||||
} else {
|
||||
null
|
||||
}
|
||||
private val adaptedReferenceOriginalTarget: IrFunction? = functionReference.reflectionTarget?.owner
|
||||
|
||||
private val adaptedReferenceOriginalTarget: IrFunction? = adapteeCall?.symbol?.owner
|
||||
private val functionReferenceTarget = adaptedReferenceOriginalTarget ?: referencedFunction
|
||||
|
||||
private val functionReferenceClass: IrClass =
|
||||
@@ -404,13 +382,21 @@ internal class FunctionReferenceLowering(val context: Context): FileLoweringPass
|
||||
}
|
||||
|
||||
private fun hasVarargMappedToElement(): Boolean {
|
||||
if (adapteeCall == null) return false
|
||||
for (i in 0 until adapteeCall.valueArgumentsCount) {
|
||||
val arg = adapteeCall.getValueArgument(i) ?: continue
|
||||
if (arg !is IrVararg) continue
|
||||
for (varargElement in arg.elements) {
|
||||
if (varargElement is IrGetValue) return true
|
||||
if (adaptedReferenceOriginalTarget == null) return false
|
||||
val originalParameters = adaptedReferenceOriginalTarget.allParameters
|
||||
val adaptedParameters = functionReference.symbol.owner.allParameters
|
||||
var index = 0
|
||||
// TODO: There should be similar code somewhere in the resolve.
|
||||
while (index < originalParameters.size && index < adaptedParameters.size) {
|
||||
val originalParameter = originalParameters[index]
|
||||
val adaptedParameter = adaptedParameters[index]
|
||||
if (originalParameter.defaultValue != null) return false
|
||||
if (originalParameter.isVararg) {
|
||||
if (originalParameter.varargElementType!!.erasureForTypeOperation()
|
||||
== adaptedParameter.type.erasureForTypeOperation())
|
||||
return true
|
||||
}
|
||||
++index
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
@@ -2779,6 +2779,10 @@ task funInterface_nonTrivialProjectionInSuperType(type: KonanLocalTest) {
|
||||
source = "codegen/funInterface/nonTrivialProjectionInSuperType.kt"
|
||||
}
|
||||
|
||||
task funInterface_kt43887(type: KonanLocalTest) {
|
||||
source = "codegen/funInterface/kt43887.kt"
|
||||
}
|
||||
|
||||
task objectExpression1(type: KonanLocalTest) {
|
||||
goldValue = "aabb\n"
|
||||
source = "codegen/objectExpression/expr1.kt"
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright 2010-2021 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
||||
* that can be found in the LICENSE file.
|
||||
*/
|
||||
|
||||
package codegen.funInterface.kt43887
|
||||
|
||||
import kotlin.test.*
|
||||
|
||||
import kotlinx.cinterop.*
|
||||
typealias heap_t = IntVar
|
||||
fun heap_create(size: Long): CPointer<heap_t>? = null
|
||||
fun heap_alloc(heap: CPointer<heap_t>?, size: ULong): CPointer<*>? = null
|
||||
fun heap_free(heap: CPointer<heap_t>?, ptr: CPointer<*>?): CPointer<BooleanVar>? = null
|
||||
inline fun Heap(size: Long): CPointer<heap_t>? {
|
||||
return heap_create(size)
|
||||
}
|
||||
inline fun <reified T : CVariable> CPointer<heap_t>?.use(f: (CPointer<T>) -> Unit) {
|
||||
alloc<T>()
|
||||
?.also(f)
|
||||
?.also(::free)
|
||||
}
|
||||
inline fun <reified T : CVariable> CPointer<heap_t>?.alloc(): CPointer<T>? {
|
||||
return heap_alloc(this, sizeOf<T>().toULong())?.reinterpret()
|
||||
}
|
||||
inline fun CPointer<heap_t>?.free(ptr: CPointer<*>?): Boolean {
|
||||
return heap_free(this, ptr)?.pointed?.value ?: false
|
||||
}
|
||||
|
||||
@Test
|
||||
fun runTest(): Unit = memScoped {
|
||||
val heap = Heap(1024)
|
||||
|
||||
heap.use<IntVar> { ptr ->
|
||||
ptr.pointed.value = 40
|
||||
//println("PTR ${ptr.pointed}")
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user