ObjCExport: use terminatingExceptionHandler by default
If something called from an ObjCExport bridge throws a Kotlin exception, treat it as fatal by default and terminate the process. This affects * Runtime calls (managing and converting Kotlin and Obj-C references and other types), that shouldn't throw such exceptions anyway * User code (Kotlin function object throws Kotlin exception when called from Swift/Obj-C). If an exception should be handled non-fatally (e.g. forwarded to the caller), this intention should be expressed in the code generator explicitly. ^KT-50830 This change makes the code more simple and efficient, and the control flow -- more explicit.
This commit is contained in:
committed by
Space
parent
bc2cc026db
commit
35cb897bdd
+1
-1
@@ -500,7 +500,7 @@ internal class Llvm(val context: Context, val llvmModule: LLVMModuleRef) : Runti
|
|||||||
val Kotlin_ObjCExport_AbstractClassConstructorCalled by lazyRtFunction
|
val Kotlin_ObjCExport_AbstractClassConstructorCalled by lazyRtFunction
|
||||||
val Kotlin_ObjCExport_RethrowExceptionAsNSError by lazyRtFunction
|
val Kotlin_ObjCExport_RethrowExceptionAsNSError by lazyRtFunction
|
||||||
val Kotlin_ObjCExport_WrapExceptionToNSError by lazyRtFunction
|
val Kotlin_ObjCExport_WrapExceptionToNSError by lazyRtFunction
|
||||||
val Kotlin_ObjCExport_RethrowNSErrorAsException by lazyRtFunction
|
val Kotlin_ObjCExport_NSErrorAsException by lazyRtFunction
|
||||||
val Kotlin_ObjCExport_AllocInstanceWithAssociatedObject by lazyRtFunction
|
val Kotlin_ObjCExport_AllocInstanceWithAssociatedObject by lazyRtFunction
|
||||||
val Kotlin_ObjCExport_createContinuationArgument by lazyRtFunction
|
val Kotlin_ObjCExport_createContinuationArgument by lazyRtFunction
|
||||||
val Kotlin_ObjCExport_createUnitContinuationArgument by lazyRtFunction
|
val Kotlin_ObjCExport_createUnitContinuationArgument by lazyRtFunction
|
||||||
|
|||||||
+8
-10
@@ -169,19 +169,13 @@ internal open class ObjCExportCodeGeneratorBase(codegen: CodeGenerator) : ObjCCo
|
|||||||
return callFromBridge(llvmDeclarations, args, resultLifetime)
|
return callFromBridge(llvmDeclarations, args, resultLifetime)
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: currently bridges don't have any custom `landingpad`s,
|
|
||||||
// so it is correct to use [callAtFunctionScope] here.
|
|
||||||
// However, exception handling probably should be refactored
|
|
||||||
// (e.g. moved from `IrToBitcode.kt` to [FunctionGenerationContext]).
|
|
||||||
fun ObjCExportFunctionGenerationContext.callFromBridge(
|
fun ObjCExportFunctionGenerationContext.callFromBridge(
|
||||||
function: LlvmCallable,
|
function: LlvmCallable,
|
||||||
args: List<LLVMValueRef>,
|
args: List<LLVMValueRef>,
|
||||||
resultLifetime: Lifetime = Lifetime.IRRELEVANT,
|
resultLifetime: Lifetime = Lifetime.IRRELEVANT,
|
||||||
): LLVMValueRef {
|
): LLVMValueRef {
|
||||||
|
// All calls that actually do need to forward exceptions to callers should express this explicitly.
|
||||||
// TODO: it is required only for Kotlin-to-Objective-C bridges.
|
val exceptionHandler = terminatingExceptionHandler
|
||||||
this.forwardingForeignExceptionsTerminatedWith = objcTerminate
|
|
||||||
val exceptionHandler = ExceptionHandler.Caller
|
|
||||||
|
|
||||||
return call(function, args, resultLifetime, exceptionHandler)
|
return call(function, args, resultLifetime, exceptionHandler)
|
||||||
}
|
}
|
||||||
@@ -1251,8 +1245,12 @@ private fun ObjCExportCodeGenerator.generateKotlinToObjCBridge(
|
|||||||
|
|
||||||
fun rethrow() {
|
fun rethrow() {
|
||||||
val error = load(errorOutPtr!!)
|
val error = load(errorOutPtr!!)
|
||||||
callFromBridge(context.llvm.Kotlin_ObjCExport_RethrowNSErrorAsException, listOf(error))
|
val exception = callFromBridge(
|
||||||
unreachable()
|
context.llvm.Kotlin_ObjCExport_NSErrorAsException,
|
||||||
|
listOf(error),
|
||||||
|
resultLifetime = Lifetime.THROW
|
||||||
|
)
|
||||||
|
ExceptionHandler.Caller.genThrow(this, exception)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun genKotlinBaseMethodResult(
|
fun genKotlinBaseMethodResult(
|
||||||
|
|||||||
@@ -138,12 +138,6 @@ extern "C" OBJ_GETTER(Kotlin_ObjCExport_NSErrorAsException, id error) {
|
|||||||
RETURN_RESULT_OF(Kotlin_ObjCExport_NSErrorAsExceptionImpl, message, kotlinError);
|
RETURN_RESULT_OF(Kotlin_ObjCExport_NSErrorAsExceptionImpl, message, kotlinError);
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" void Kotlin_ObjCExport_RethrowNSErrorAsException(id error) {
|
|
||||||
ObjHolder holder;
|
|
||||||
KRef exception = Kotlin_ObjCExport_NSErrorAsException(error, holder.slot());
|
|
||||||
ThrowException(exception);
|
|
||||||
}
|
|
||||||
|
|
||||||
@interface NSError (NSErrorKotlinException)
|
@interface NSError (NSErrorKotlinException)
|
||||||
@end;
|
@end;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user