[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 samSuperClass = samSuperType?.let { it.classOrNull ?: error("Expected a class but was: ${it.render()}") }
|
||||||
|
|
||||||
private val adapteeCall: IrFunctionAccessExpression? =
|
private val adaptedReferenceOriginalTarget: IrFunction? = functionReference.reflectionTarget?.owner
|
||||||
// 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? = adapteeCall?.symbol?.owner
|
|
||||||
private val functionReferenceTarget = adaptedReferenceOriginalTarget ?: referencedFunction
|
private val functionReferenceTarget = adaptedReferenceOriginalTarget ?: referencedFunction
|
||||||
|
|
||||||
private val functionReferenceClass: IrClass =
|
private val functionReferenceClass: IrClass =
|
||||||
@@ -404,13 +382,21 @@ internal class FunctionReferenceLowering(val context: Context): FileLoweringPass
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun hasVarargMappedToElement(): Boolean {
|
private fun hasVarargMappedToElement(): Boolean {
|
||||||
if (adapteeCall == null) return false
|
if (adaptedReferenceOriginalTarget == null) return false
|
||||||
for (i in 0 until adapteeCall.valueArgumentsCount) {
|
val originalParameters = adaptedReferenceOriginalTarget.allParameters
|
||||||
val arg = adapteeCall.getValueArgument(i) ?: continue
|
val adaptedParameters = functionReference.symbol.owner.allParameters
|
||||||
if (arg !is IrVararg) continue
|
var index = 0
|
||||||
for (varargElement in arg.elements) {
|
// TODO: There should be similar code somewhere in the resolve.
|
||||||
if (varargElement is IrGetValue) return true
|
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
|
return false
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2779,6 +2779,10 @@ task funInterface_nonTrivialProjectionInSuperType(type: KonanLocalTest) {
|
|||||||
source = "codegen/funInterface/nonTrivialProjectionInSuperType.kt"
|
source = "codegen/funInterface/nonTrivialProjectionInSuperType.kt"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
task funInterface_kt43887(type: KonanLocalTest) {
|
||||||
|
source = "codegen/funInterface/kt43887.kt"
|
||||||
|
}
|
||||||
|
|
||||||
task objectExpression1(type: KonanLocalTest) {
|
task objectExpression1(type: KonanLocalTest) {
|
||||||
goldValue = "aabb\n"
|
goldValue = "aabb\n"
|
||||||
source = "codegen/objectExpression/expr1.kt"
|
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