Call initRuntimeIfNeeded before EnterFrame in interop adapters. (#4672)

This commit is contained in:
Alexander Shabalin
2021-02-02 18:48:54 +03:00
committed by Vasily Levchenko
parent 99dc9e8e0c
commit f312315346
5 changed files with 13 additions and 6 deletions
@@ -361,8 +361,8 @@ private class ExportedElement(val kind: ElementKind,
|
|extern "C" KObjHeader* ${cname}_instance(KObjHeader**);
|static $objectClassC ${cname}_instance_impl(void) {
| KObjHolder result_holder;
| Kotlin_initRuntimeIfNeeded();
| KObjHolder result_holder;
| KObjHeader* result = ${cname}_instance(result_holder.slot());
| return $objectClassC { .pinned = CreateStablePointer(result)};
|}
@@ -379,8 +379,8 @@ private class ExportedElement(val kind: ElementKind,
return """
|extern "C" KObjHeader* $cname(KObjHeader**);
|static $enumClassC ${cname}_impl(void) {
| KObjHolder result_holder;
| Kotlin_initRuntimeIfNeeded();
| KObjHolder result_holder;
| KObjHeader* result = $cname(result_holder.slot());
| return $enumClassC { .pinned = CreateStablePointer(result)};
|}
@@ -996,8 +996,8 @@ internal class CAdapterGenerator(val context: Context) : DeclarationDescriptorVi
val argument = if (needArgument) "value, " else ""
output("extern \"C\" KObjHeader* Kotlin_box${it.shortNameForPredefinedType}($parameter$maybeComma KObjHeader**);")
output("static ${translateType(nullableIt)} ${it.createNullableNameForPredefinedType}Impl($parameter) {")
output("KObjHolder result_holder;", 1)
output("Kotlin_initRuntimeIfNeeded();", 1)
output("KObjHolder result_holder;", 1)
output("KObjHeader* result = Kotlin_box${it.shortNameForPredefinedType}($argument result_holder.slot());", 1)
output("return ${translateType(nullableIt)} { .pinned = CreateStablePointer(result) };", 1)
output("}")
@@ -341,6 +341,10 @@ internal class FunctionGenerationContext(val function: LLVMValueRef,
*/
var forwardingForeignExceptionsTerminatedWith: LLVMValueRef? = null
// Whether the generating function needs to initialize Kotlin runtime before execution. Useful for interop bridges,
// for example.
var needsRuntimeInit = false
init {
irFunction?.let {
if (!irFunction.isExported()) {
@@ -1207,6 +1211,9 @@ internal class FunctionGenerationContext(val function: LLVMValueRef,
internal fun epilogue() {
appendingTo(prologueBb) {
if (needsRuntimeInit) {
call(context.llvm.initRuntimeIfNeeded, emptyList())
}
val slots = if (needSlotsPhi)
LLVMBuildArrayAlloca(builder, kObjHeaderPtr, Int32(slotCount).llvm, "")!!
else
@@ -208,7 +208,7 @@ internal class ObjCExportCodeGenerator(
}
fun FunctionGenerationContext.initRuntimeIfNeeded() {
callFromBridge(context.llvm.initRuntimeIfNeeded, emptyList())
this.needsRuntimeInit = true
}
inline fun FunctionGenerationContext.convertKotlin(
@@ -189,7 +189,7 @@ void AppendToInitializersTail(InitNode *next) {
initTailNode = next;
}
void Kotlin_initRuntimeIfNeeded() {
RUNTIME_NOTHROW void Kotlin_initRuntimeIfNeeded() {
if (!isValidRuntime()) {
initRuntime();
// Register runtime deinit function at thread cleanup.
+1 -1
View File
@@ -33,7 +33,7 @@ enum DestroyRuntimeMode {
DestroyRuntimeMode Kotlin_getDestroyRuntimeMode();
void Kotlin_initRuntimeIfNeeded();
RUNTIME_NOTHROW void Kotlin_initRuntimeIfNeeded();
void Kotlin_deinitRuntimeIfNeeded();
// Can only be called once.