Generate initRuntimeIfNeeded() at the beginning of staticCFunction

#KT-44283 Fixed
This commit is contained in:
Svyatoslav Scherbina
2021-06-16 06:39:51 +00:00
committed by Space
parent 6e9739caec
commit e324c9b3fb
4 changed files with 68 additions and 1 deletions
@@ -128,13 +128,22 @@ internal inline fun<R> generateFunction(codegen: CodeGenerator,
code: FunctionGenerationContext.(FunctionGenerationContext) -> R) {
val llvmFunction = codegen.llvmFunction(function)
val isCToKotlinBridge = function.origin == CBridgeOrigin.C_TO_KOTLIN_BRIDGE
val functionGenerationContext = FunctionGenerationContext(
llvmFunction,
codegen,
startLocation,
endLocation,
switchToRunnable = function.origin == CBridgeOrigin.C_TO_KOTLIN_BRIDGE,
switchToRunnable = isCToKotlinBridge,
function)
if (isCToKotlinBridge) {
// Enable initRuntimeIfNeeded for legacy MM too:
functionGenerationContext.needsRuntimeInit = true
// This fixes https://youtrack.jetbrains.com/issue/KT-44283.
}
try {
generateFunctionBody(functionGenerationContext, code)
} finally {
@@ -3806,6 +3806,10 @@ createInterop("kt43265") {
it.defFile 'interop/kt43265/kt43265.def'
}
createInterop("kt44283") {
it.defFile 'interop/kt44283/kt44283.def'
}
createInterop("kt43502") {
it.defFile 'interop/kt43502/kt43502.def'
it.headers "$projectDir/interop/kt43502/kt43502.h"
@@ -4190,6 +4194,14 @@ interopTest("interop_kt43265") {
source = "interop/kt43265/usage.kt"
}
interopTest("interop_kt44283") {
disabled = (project.testTarget == 'wasm32') || // No interop for wasm yet.
project.globalTestArgs.contains('-opt') // Incompatible with -g.
flags = ['-g']
interop = 'kt44283'
source = "interop/kt44283/main.kt"
}
dynamicTest("interop_kt43502") {
disabled = (project.target.name != project.hostName)
interop = "kt43502"
@@ -0,0 +1,25 @@
---
#include <stdlib.h>
#include <pthread.h>
typedef struct {
int d;
} TestStruct;
typedef struct {
void (*f)(TestStruct data);
} ThreadData;
void *dispatch(void *rawArg) {
ThreadData *arg = rawArg;
arg->f((TestStruct) {.d = 1});
return NULL;
}
void invokeFromThread(void (*f)(TestStruct data)) {
pthread_t thread_id;
ThreadData *threadData = malloc(sizeof(ThreadData));
threadData->f = f;
pthread_create(&thread_id, NULL, dispatch, (void *) threadData);
pthread_join(thread_id, NULL);
}
@@ -0,0 +1,21 @@
import kotlinx.cinterop.*
import kt44283.*
import kotlin.native.concurrent.AtomicInt
import kotlin.test.*
val callbackCounter = AtomicInt(0)
fun main() {
val func = staticCFunction<CValue<TestStruct>, Unit> {
kotlin.native.internal.GC.collect() // Helps to ensure that "runtime" is already initialized.
memScoped {
println("Hello, Kotlin/Native! ${it.ptr.pointed.d}")
}
callbackCounter.increment()
}
assertEquals(0, callbackCounter.value)
invokeFromThread(func.reinterpret())
assertEquals(1, callbackCounter.value)
}