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_RethrowExceptionAsNSError 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_createContinuationArgument 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)
|
||||
}
|
||||
|
||||
// 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(
|
||||
function: LlvmCallable,
|
||||
args: List<LLVMValueRef>,
|
||||
resultLifetime: Lifetime = Lifetime.IRRELEVANT,
|
||||
): LLVMValueRef {
|
||||
|
||||
// TODO: it is required only for Kotlin-to-Objective-C bridges.
|
||||
this.forwardingForeignExceptionsTerminatedWith = objcTerminate
|
||||
val exceptionHandler = ExceptionHandler.Caller
|
||||
// All calls that actually do need to forward exceptions to callers should express this explicitly.
|
||||
val exceptionHandler = terminatingExceptionHandler
|
||||
|
||||
return call(function, args, resultLifetime, exceptionHandler)
|
||||
}
|
||||
@@ -1251,8 +1245,12 @@ private fun ObjCExportCodeGenerator.generateKotlinToObjCBridge(
|
||||
|
||||
fun rethrow() {
|
||||
val error = load(errorOutPtr!!)
|
||||
callFromBridge(context.llvm.Kotlin_ObjCExport_RethrowNSErrorAsException, listOf(error))
|
||||
unreachable()
|
||||
val exception = callFromBridge(
|
||||
context.llvm.Kotlin_ObjCExport_NSErrorAsException,
|
||||
listOf(error),
|
||||
resultLifetime = Lifetime.THROW
|
||||
)
|
||||
ExceptionHandler.Caller.genThrow(this, exception)
|
||||
}
|
||||
|
||||
fun genKotlinBaseMethodResult(
|
||||
|
||||
@@ -138,12 +138,6 @@ extern "C" OBJ_GETTER(Kotlin_ObjCExport_NSErrorAsException, id error) {
|
||||
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)
|
||||
@end;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user