Generate initRuntimeIfNeeded() at the beginning of staticCFunction
#KT-44283 Fixed
This commit is contained in:
committed by
Space
parent
6e9739caec
commit
e324c9b3fb
+10
-1
@@ -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)
|
||||
}
|
||||
Reference in New Issue
Block a user