Rework stubs for interop globals passed by value

#KT-21855 Fixed
This commit is contained in:
Svyatoslav Scherbina
2018-01-09 11:54:44 +03:00
committed by SvyatoslavScherbina
parent 670d05a4f3
commit b700f96e0c
5 changed files with 57 additions and 13 deletions
@@ -22,20 +22,20 @@ import org.jetbrains.kotlin.native.interop.indexer.GlobalDecl
class GlobalVariableStub(global: GlobalDecl, stubGenerator: StubGenerator) : KotlinStub, NativeBacked {
val getAddressExpression: KotlinExpression
val header: String
val getter: KotlinExpression
val setter: KotlinExpression?
init {
getAddressExpression = stubGenerator.simpleBridgeGenerator.kotlinToNative(
private val getAddressExpression: KotlinExpression by lazy {
stubGenerator.simpleBridgeGenerator.kotlinToNative(
nativeBacked = this,
returnType = BridgedType.NATIVE_PTR,
kotlinValues = emptyList()
) {
"&${global.name}"
}
}
val header: String
val getter: KotlinExpression
val setter: KotlinExpression?
init {
val kotlinScope = stubGenerator.kotlinFile
// TODO: consider sharing the logic below with field generator.
@@ -50,14 +50,38 @@ class GlobalVariableStub(global: GlobalDecl, stubGenerator: StubGenerator) : Kot
getter = mirror.info.argFromBridged(getAddressExpression, kotlinScope, nativeBacked = this) + "!!"
setter = null
} else {
val pointedTypeName = mirror.pointedType.render(kotlinScope)
val storagePointed = "interpretPointed<$pointedTypeName>($getAddressExpression)"
if (mirror is TypeMirror.ByValue) {
getter = mirror.info.argFromBridged(stubGenerator.simpleBridgeGenerator.kotlinToNative(
nativeBacked = this,
returnType = mirror.info.bridgedType,
kotlinValues = emptyList()
) {
mirror.info.cToBridged(expr = global.name)
}, kotlinScope, nativeBacked = this)
setter = if (global.isConst) {
null
} else {
val bridgedValue = BridgeTypedKotlinValue(mirror.info.bridgedType, mirror.info.argToBridged("value"))
stubGenerator.simpleBridgeGenerator.kotlinToNative(
nativeBacked = this,
returnType = BridgedType.VOID,
kotlinValues = listOf(bridgedValue)
) { nativeValues ->
out("${global.name} = ${mirror.info.cFromBridged(
nativeValues.single(),
scope,
nativeBacked = this@GlobalVariableStub
)};")
""
}
}
kotlinType = mirror.argType
val valueProperty = "$storagePointed.value"
getter = valueProperty
setter = if (global.isConst) null else "$valueProperty = value"
} else {
val pointedTypeName = mirror.pointedType.render(kotlinScope)
val storagePointed = "interpretPointed<$pointedTypeName>($getAddressExpression)"
kotlinType = mirror.pointedType
getter = storagePointed
setter = null
+3 -1
View File
@@ -2324,7 +2324,9 @@ if (isMac()) {
task interop_objc_smoke(type: RunInteropKonanTest) {
disabled = (project.testTarget == 'wasm32') // No interop for wasm yet.
goldValue = "84\nFoo\nHello, World!\nKotlin says: Hello, everybody!\nHello from Kotlin\n2, 1\n" +
"true\ntrue\nDeallocated\nDeallocated\n"
"true\ntrue\n" +
"Global string\nAnother global string\nnull\nglobal object\n" +
"Deallocated\nDeallocated\n"
source = "interop/objc/smoke.kt"
interop = 'objcSmoke'
@@ -52,3 +52,6 @@ void invoke2(void (^block)(void)) {
int (^getSupplier(int x))(void);
Class (^ _Nonnull getClassGetter(NSObject* obj))(void);
extern NSString* globalString;
extern NSObject* globalObject;
@@ -48,6 +48,18 @@ fun run() {
// toString (virtually):
println(map.keys.map { it.toString() }.min() == foo.description())
}
println(globalString)
autoreleasepool {
globalString = "Another global string"
}
println(globalString)
println(globalObject)
globalObject = object : NSObject() {
override fun description() = "global object"
}
println(globalObject)
}
fun MutablePairProtocol.swap() {
@@ -57,3 +57,6 @@ int (^getSupplier(int x))(void) {
Class (^ _Nonnull getClassGetter(NSObject* obj))() {
return ^{ return obj.class; };
}
NSString* globalString = @"Global string";
NSObject* globalObject = nil;