Track current exception (#4701)
This commit is contained in:
committed by
Vasily Levchenko
parent
a38e64a7c8
commit
3a5c6480a3
+5
-12
@@ -461,7 +461,7 @@ private class ExportedElement(val kind: ElementKind,
|
||||
"result", cfunction[0], Direction.KOTLIN_TO_C, builder)
|
||||
builder.append(" return $result;\n")
|
||||
}
|
||||
builder.append(" } catch (ExceptionObjHolder& e) { TerminateWithUnhandledException(e.obj()); } \n")
|
||||
builder.append(" } catch (ExceptionObjHolder& e) { TerminateWithUnhandledException(e.GetExceptionObject()); } \n")
|
||||
|
||||
builder.append("}\n")
|
||||
|
||||
@@ -905,7 +905,6 @@ internal class CAdapterGenerator(val context: Context) : DeclarationDescriptorVi
|
||||
|#define RUNTIME_NORETURN __attribute__((noreturn))
|
||||
|
|
||||
|extern "C" {
|
||||
|void UpdateHeapRef(KObjHeader**, const KObjHeader*) RUNTIME_NOTHROW;
|
||||
|void UpdateStackRef(KObjHeader**, const KObjHeader*) RUNTIME_NOTHROW;
|
||||
|KObjHeader* AllocInstance(const KTypeInfo*, KObjHeader**) RUNTIME_NOTHROW;
|
||||
|KObjHeader* DerefStablePointer(void*, KObjHeader**) RUNTIME_NOTHROW;
|
||||
@@ -951,16 +950,10 @@ internal class CAdapterGenerator(val context: Context) : DeclarationDescriptorVi
|
||||
|};
|
||||
|
|
||||
|class ExceptionObjHolder {
|
||||
| public:
|
||||
| explicit ExceptionObjHolder(const KObjHeader* obj): obj_(nullptr) {
|
||||
| ::UpdateHeapRef(&obj_, obj);
|
||||
| }
|
||||
| ~ExceptionObjHolder() {
|
||||
| UpdateHeapRef(&obj_, nullptr);
|
||||
| }
|
||||
| KObjHeader* obj() { return obj_; }
|
||||
| private:
|
||||
| KObjHeader* obj_;
|
||||
|public:
|
||||
| virtual ~ExceptionObjHolder() = default;
|
||||
|
|
||||
| KObjHeader* GetExceptionObject() noexcept;
|
||||
|};
|
||||
|
|
||||
|static void DisposeStablePointerImpl(${prefix}_KNativePtr ptr) {
|
||||
|
||||
+2
-6
@@ -862,14 +862,10 @@ internal class FunctionGenerationContext(val function: LLVMValueRef,
|
||||
val beginCatch = context.llvm.cxaBeginCatchFunction
|
||||
val exceptionRawPtr = call(beginCatch, listOf(exceptionRecord))
|
||||
|
||||
// Pointer to KotlinException instance:
|
||||
val exceptionPtrPtr = bitcast(codegen.kObjHeaderPtrPtr, exceptionRawPtr, "")
|
||||
|
||||
// Pointer to Kotlin exception object:
|
||||
// We do need a slot here, as otherwise exception instance could be freed by _cxa_end_catch.
|
||||
val exceptionPtr = loadSlot(exceptionPtrPtr, true, "exception")
|
||||
val exceptionPtr = call(context.llvm.Kotlin_getExceptionObject, listOf(exceptionRawPtr), Lifetime.GLOBAL)
|
||||
|
||||
// __cxa_end_catch performs some C++ cleanup, including calling `KotlinException` class destructor.
|
||||
// __cxa_end_catch performs some C++ cleanup, including calling `ExceptionObjHolder` class destructor.
|
||||
val endCatch = context.llvm.cxaEndCatchFunction
|
||||
call(endCatch, listOf())
|
||||
|
||||
|
||||
+1
@@ -516,6 +516,7 @@ internal class Llvm(val context: Context, val llvmModule: LLVMModuleRef) {
|
||||
val checkLifetimesConstraint = importRtFunction("CheckLifetimesConstraint")
|
||||
val freezeSubgraph = importRtFunction("FreezeSubgraph")
|
||||
val checkGlobalsAccessible = importRtFunction("CheckGlobalsAccessible")
|
||||
val Kotlin_getExceptionObject = importRtFunction("Kotlin_getExceptionObject")
|
||||
|
||||
val kRefSharedHolderInitLocal = importRtFunction("KRefSharedHolder_initLocal")
|
||||
val kRefSharedHolderInit = importRtFunction("KRefSharedHolder_init")
|
||||
|
||||
@@ -2545,6 +2545,16 @@ standaloneTest("exception_in_global_init") {
|
||||
outputChecker = { s -> s.contains("Uncaught Kotlin exception: kotlin.IllegalStateException: FAIL") && !s.contains("in kotlin main") }
|
||||
}
|
||||
|
||||
task rethrow_exception(type: KonanLocalTest) {
|
||||
enabled = (project.testTarget != 'wasm32') // Uses exceptions.
|
||||
source = "runtime/exceptions/rethrow.kt"
|
||||
}
|
||||
|
||||
task throw_from_catch(type: KonanLocalTest) {
|
||||
enabled = (project.testTarget != 'wasm32') // Uses exceptions.
|
||||
source = "runtime/exceptions/throw_from_catch.kt"
|
||||
}
|
||||
|
||||
standaloneTest("runtime_math_exceptions") {
|
||||
enabled = (project.testTarget != 'wasm32')
|
||||
source = "stdlib_external/numbers/MathExceptionTest.kt"
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
/*
|
||||
* Copyright 2010-2021 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
||||
* that can be found in the LICENSE file.
|
||||
*/
|
||||
|
||||
package runtime.exceptions.rethtow
|
||||
|
||||
import kotlin.test.*
|
||||
|
||||
@Test
|
||||
fun runTest() {
|
||||
assertFailsWith<IllegalStateException>("My error") {
|
||||
try {
|
||||
error("My error")
|
||||
} catch (e: Throwable) {
|
||||
throw e
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
/*
|
||||
* Copyright 2010-2021 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
||||
* that can be found in the LICENSE file.
|
||||
*/
|
||||
|
||||
package runtime.exceptions.throw_from_catch
|
||||
|
||||
import kotlin.test.*
|
||||
|
||||
@Test
|
||||
fun runTest() {
|
||||
assertFailsWith<IllegalStateException>("My another error") {
|
||||
try {
|
||||
error("My error")
|
||||
} catch (e: Throwable) {
|
||||
error("My another error")
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user