diff --git a/Interop/StubGenerator/src/main/kotlin/org/jetbrains/kotlin/native/interop/gen/CWrapperGenerator.kt b/Interop/StubGenerator/src/main/kotlin/org/jetbrains/kotlin/native/interop/gen/CWrapperGenerator.kt index 933133b21ad..8de4751a46d 100644 --- a/Interop/StubGenerator/src/main/kotlin/org/jetbrains/kotlin/native/interop/gen/CWrapperGenerator.kt +++ b/Interop/StubGenerator/src/main/kotlin/org/jetbrains/kotlin/native/interop/gen/CWrapperGenerator.kt @@ -75,6 +75,14 @@ internal class CWrappersGenerator(private val context: StubIrContext) { return CCalleeWrapper(wrapper) } + fun generateCGlobalByPointerGetter(globalDecl: GlobalDecl, symbolName: String): CCalleeWrapper { + val wrapperName = generateFunctionWrapperName("${globalDecl.name}_getter") + val returnType = "void*" + val wrapperBody = "return &${globalDecl.name};" + val wrapper = createWrapper(symbolName, wrapperName, returnType, emptyList(), wrapperBody) + return CCalleeWrapper(wrapper) + } + fun generateCGlobalSetter(globalDecl: GlobalDecl, symbolName: String): CCalleeWrapper { val wrapperName = generateFunctionWrapperName("${globalDecl.name}_setter") val globalType = globalDecl.type.getStringRepresentation() diff --git a/Interop/StubGenerator/src/main/kotlin/org/jetbrains/kotlin/native/interop/gen/StubIrBridgeBuilder.kt b/Interop/StubGenerator/src/main/kotlin/org/jetbrains/kotlin/native/interop/gen/StubIrBridgeBuilder.kt index 3efc63fc2a4..647943df5d8 100644 --- a/Interop/StubGenerator/src/main/kotlin/org/jetbrains/kotlin/native/interop/gen/StubIrBridgeBuilder.kt +++ b/Interop/StubGenerator/src/main/kotlin/org/jetbrains/kotlin/native/interop/gen/StubIrBridgeBuilder.kt @@ -205,7 +205,11 @@ class StubIrBridgeBuilder( val extra = builderResult.wrapperGenerationComponents.getterToWrapperInfo.getValue(accessor) val cCallAnnotation = accessor.annotations.firstIsInstanceOrNull() ?: error("external getter for ${extra.global.name} wasn't marked with @CCall") - val wrapper = wrapperGenerator.generateCGlobalGetter(extra.global, cCallAnnotation.symbolName) + val wrapper = if (extra.passViaPointer) { + wrapperGenerator.generateCGlobalByPointerGetter(extra.global, cCallAnnotation.symbolName) + } else { + wrapperGenerator.generateCGlobalGetter(extra.global, cCallAnnotation.symbolName) + } simpleBridgeGenerator.insertNativeBridge(accessor, emptyList(), wrapper.lines) } } diff --git a/Interop/StubGenerator/src/main/kotlin/org/jetbrains/kotlin/native/interop/gen/StubIrBuilder.kt b/Interop/StubGenerator/src/main/kotlin/org/jetbrains/kotlin/native/interop/gen/StubIrBuilder.kt index c0c2dac2ef3..4d25a0102b7 100644 --- a/Interop/StubGenerator/src/main/kotlin/org/jetbrains/kotlin/native/interop/gen/StubIrBuilder.kt +++ b/Interop/StubGenerator/src/main/kotlin/org/jetbrains/kotlin/native/interop/gen/StubIrBuilder.kt @@ -66,7 +66,7 @@ class BridgeGenerationComponentsBuilder { /** * Components that are not passed via StubIr but required for generation of wrappers. */ -class WrapperGenerationInfo(val global: GlobalDecl) +class WrapperGenerationInfo(val global: GlobalDecl, val passViaPointer: Boolean = false) interface WrapperGenerationComponents { val getterToWrapperInfo: Map diff --git a/Interop/StubGenerator/src/main/kotlin/org/jetbrains/kotlin/native/interop/gen/StubIrElementBuilders.kt b/Interop/StubGenerator/src/main/kotlin/org/jetbrains/kotlin/native/interop/gen/StubIrElementBuilders.kt index 3744e5b6a9d..2167068d0f3 100644 --- a/Interop/StubGenerator/src/main/kotlin/org/jetbrains/kotlin/native/interop/gen/StubIrElementBuilders.kt +++ b/Interop/StubGenerator/src/main/kotlin/org/jetbrains/kotlin/native/interop/gen/StubIrElementBuilders.kt @@ -649,7 +649,17 @@ internal class GlobalStubBuilder( } is TypeMirror.ByRef -> { kotlinType = mirror.pointedType - val getter = PropertyAccessor.Getter.InterpretPointed(global.name, kotlinType.toStubIrType()) + val getter = when (context.generationMode) { + GenerationMode.SOURCE_CODE -> { + PropertyAccessor.Getter.InterpretPointed(global.name, kotlinType.toStubIrType()) + } + GenerationMode.METADATA -> { + val cCallAnnotation = AnnotationStub.CCall.Symbol("${context.generateNextUniqueId("knifunptr_")}_${global.name}_getter") + PropertyAccessor.Getter.ExternalGetter(listOf(cCallAnnotation)).also { + context.wrapperComponentsBuilder.getterToWrapperInfo[it] = WrapperGenerationInfo(global, passViaPointer = true) + } + } + } kind = PropertyStub.Kind.Val(getter) } } diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/cgen/CBridgeGen.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/cgen/CBridgeGen.kt index e43967c9fc0..94d58f4649b 100644 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/cgen/CBridgeGen.kt +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/cgen/CBridgeGen.kt @@ -820,6 +820,10 @@ private fun KotlinStubs.mapType( ?: reportUnsupportedType("not a structure or too complex")) } + type.classOrNull?.isSubtypeOfClass(symbols.nativePointed) == true -> { + TrivialValuePassing(type, CTypes.voidPtr) + } + type.isFunction() -> if (variadic){ reportUnsupportedType("not supported as variadic argument") } else {