Workaround incomplete inline for interop's readValue
This commit is contained in:
committed by
SvyatoslavScherbina
parent
c4cc91d880
commit
716efe7310
@@ -203,9 +203,9 @@ fun <T : CVariable> CPointed.readValues(size: Int, align: Int): CValues<T> {
|
||||
inline fun <reified T : CVariable> T.readValues(count: Int): CValues<T> =
|
||||
this.readValues<T>(size = count * sizeOf<T>().toInt(), align = alignOf<T>())
|
||||
|
||||
fun <T : CVariable> CPointed.readValue(size: Int, align: Int): CValue<T> {
|
||||
val bytes = ByteArray(size)
|
||||
nativeMemUtils.getByteArray(this, bytes, size)
|
||||
fun <T : CVariable> CPointed.readValue(size: Long, align: Int): CValue<T> {
|
||||
val bytes = ByteArray(size.toInt())
|
||||
nativeMemUtils.getByteArray(this, bytes, size.toInt())
|
||||
return object : CValue<T>() {
|
||||
override fun getPointer(placement: NativePlacement): CPointer<T> = placement.placeBytes(bytes, align)
|
||||
override val size get() = bytes.size
|
||||
@@ -214,7 +214,7 @@ fun <T : CVariable> CPointed.readValue(size: Int, align: Int): CValue<T> {
|
||||
|
||||
// Note: can't be declared as property due to possible clash with a struct field.
|
||||
// TODO: find better name.
|
||||
inline fun <reified T : CStructVar> T.readValue(): CValue<T> = this.readValue(sizeOf<T>().toInt(), alignOf<T>())
|
||||
inline fun <reified T : CStructVar> T.readValue(): CValue<T> = this.readValue(sizeOf<T>(), alignOf<T>())
|
||||
|
||||
// TODO: optimize
|
||||
fun <T : CVariable> CValues<T>.getBytes(): ByteArray = memScoped {
|
||||
|
||||
+8
@@ -103,6 +103,14 @@ internal class InteropBuiltIns(builtIns: KonanBuiltIns) {
|
||||
it.valueParameters.size == 0
|
||||
}
|
||||
|
||||
val readValue = packageScope.getContributedFunctions("readValue").single {
|
||||
it.valueParameters.size == 0
|
||||
}
|
||||
|
||||
val readValueBySizeAndAlign = packageScope.getContributedFunctions("readValue").single {
|
||||
it.valueParameters.size == 2
|
||||
}
|
||||
|
||||
val typeOf = packageScope.getContributedFunctions("typeOf").single()
|
||||
|
||||
val variableTypeClass =
|
||||
|
||||
+23
@@ -32,6 +32,7 @@ import org.jetbrains.kotlin.ir.builders.irCall
|
||||
import org.jetbrains.kotlin.ir.builders.irGet
|
||||
import org.jetbrains.kotlin.ir.declarations.IrFile
|
||||
import org.jetbrains.kotlin.ir.expressions.*
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.IrCallImpl
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.IrCallableReferenceImpl
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.IrConstImpl
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.IrGetObjectValueImpl
|
||||
@@ -179,6 +180,21 @@ private class InteropTransformer(val context: Context, val irFile: IrFile) : IrB
|
||||
return alloc(placement, size, align)
|
||||
}
|
||||
|
||||
private fun IrBuilderWithScope.readValue(receiver: IrExpression, typeArgument: KotlinType): IrCallImpl? {
|
||||
val size = sizeOf(typeArgument) ?: return null
|
||||
val align = alignOf(typeArgument) ?: return null
|
||||
|
||||
val callee = interop.readValueBySizeAndAlign
|
||||
val typeParameter = callee.typeParameters.single()
|
||||
val typeArguments = mapOf(typeParameter to typeArgument)
|
||||
|
||||
return irCall(callee, typeArguments).apply {
|
||||
extensionReceiver = receiver
|
||||
putValueArgument(0, size)
|
||||
putValueArgument(1, align)
|
||||
}
|
||||
}
|
||||
|
||||
override fun visitCall(expression: IrCall): IrExpression {
|
||||
|
||||
expression.transformChildrenVoid(this)
|
||||
@@ -252,6 +268,13 @@ private class InteropTransformer(val context: Context, val irFile: IrFile) : IrB
|
||||
}
|
||||
}
|
||||
|
||||
interop.readValue -> {
|
||||
val typeArgument = expression.getSingleTypeArgument()
|
||||
val receiver = expression.extensionReceiver!!
|
||||
|
||||
builder.readValue(receiver, typeArgument) ?: expression
|
||||
}
|
||||
|
||||
interop.staticCFunction -> {
|
||||
val argument = expression.getValueArgument(0)!!
|
||||
if (argument !is IrCallableReference || argument.getArguments().isNotEmpty()) {
|
||||
|
||||
+18
@@ -16,6 +16,8 @@
|
||||
|
||||
package org.jetbrains.kotlin.ir.builders
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.ValueDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.VariableDescriptor
|
||||
import org.jetbrains.kotlin.ir.expressions.IrExpression
|
||||
@@ -23,6 +25,8 @@ import org.jetbrains.kotlin.ir.expressions.IrLoop
|
||||
import org.jetbrains.kotlin.ir.expressions.IrStatementOrigin
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.*
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.types.TypeProjectionImpl
|
||||
import org.jetbrains.kotlin.types.TypeSubstitutor
|
||||
|
||||
inline fun IrBuilderWithScope.irLetSequence(
|
||||
value: IrExpression,
|
||||
@@ -50,3 +54,17 @@ fun IrBuilderWithScope.irTrue() = IrConstImpl.boolean(startOffset, endOffset, co
|
||||
|
||||
fun IrBuilderWithScope.irGet(value: ValueDescriptor) =
|
||||
IrGetValueImpl(startOffset, endOffset, value)
|
||||
|
||||
fun IrBuilderWithScope.irCall(
|
||||
callee: CallableDescriptor,
|
||||
typeArguments: Map<TypeParameterDescriptor, KotlinType>
|
||||
): IrCallImpl {
|
||||
val substitutionContext = typeArguments.map { (typeParameter, typeArgument) ->
|
||||
typeParameter.typeConstructor to TypeProjectionImpl(typeArgument)
|
||||
}.toMap()
|
||||
|
||||
val substitutor = TypeSubstitutor.create(substitutionContext)
|
||||
val substitutedCallee = callee.substitute(substitutor)!!
|
||||
|
||||
return IrCallImpl(this.startOffset, this.endOffset, substitutedCallee, typeArguments)
|
||||
}
|
||||
Reference in New Issue
Block a user