From dc2e072af2537c1c0464b34874cf3a15a8ec3610 Mon Sep 17 00:00:00 2001 From: Pavel Kunyavskiy Date: Fri, 3 Mar 2023 17:54:48 +0100 Subject: [PATCH] [K/N] Make exception handling in initializers more consistent with jvm ^KT-57091 --- ...LightTreeBlackBoxCodegenTestGenerated.java | 12 +++++++ .../FirPsiBlackBoxCodegenTestGenerated.java | 12 +++++++ .../failInInitializer1.kt | 31 +++++++++++++++++ .../failInInitializer2.kt | 28 ++++++++++++++++ .../failInInitializer3.kt | 32 ++++++++++++++++++ .../failInInitializer4.kt | 33 +++++++++++++++++++ .../codegen/BlackBoxCodegenTestGenerated.java | 12 +++++++ .../IrBlackBoxCodegenTestGenerated.java | 12 +++++++ .../LightAnalysisModeTestGenerated.java | 10 ++++++ .../js/test/JsCodegenBoxTestGenerated.java | 12 +++++++ .../fir/FirJsCodegenBoxTestGenerated.java | 12 +++++++ .../test/ir/IrJsCodegenBoxTestGenerated.java | 12 +++++++ .../ir/IrJsES6CodegenBoxTestGenerated.java | 12 +++++++ .../backend.native/tests/build.gradle | 30 +---------------- .../initializers/failInInitializer1.kt | 18 ---------- .../initializers/failInInitializer1.out | 1 - .../initializers/failInInitializer2.kt | 28 ---------------- .../initializers/failInInitializer2.out | 2 -- .../initializers/failInInitializer3.kt | 31 ----------------- .../initializers/failInInitializer3.out | 2 -- .../initializers/failInInitializer4.kt | 32 ------------------ .../initializers/failInInitializer4.out | 2 -- .../runtime/src/main/cpp/Exceptions.h | 2 +- .../runtime/src/main/cpp/Runtime.cpp | 20 +++++++---- .../src/main/kotlin/kotlin/native/Runtime.kt | 9 ----- .../kotlin/native/internal/RuntimeUtils.kt | 14 ++++++-- .../K2NativeCodegenBoxTestGenerated.java | 24 ++++++++++++++ .../NativeCodegenBoxTestGenerated.java | 24 ++++++++++++++ .../test/IrCodegenBoxWasmTestGenerated.java | 10 ++++++ 29 files changed, 315 insertions(+), 164 deletions(-) create mode 100644 compiler/testData/codegen/box/topLevelInitializtion/failInInitializer1.kt create mode 100644 compiler/testData/codegen/box/topLevelInitializtion/failInInitializer2.kt create mode 100644 compiler/testData/codegen/box/topLevelInitializtion/failInInitializer3.kt create mode 100644 compiler/testData/codegen/box/topLevelInitializtion/failInInitializer4.kt delete mode 100644 kotlin-native/backend.native/tests/codegen/initializers/failInInitializer1.kt delete mode 100644 kotlin-native/backend.native/tests/codegen/initializers/failInInitializer1.out delete mode 100644 kotlin-native/backend.native/tests/codegen/initializers/failInInitializer2.kt delete mode 100644 kotlin-native/backend.native/tests/codegen/initializers/failInInitializer2.out delete mode 100644 kotlin-native/backend.native/tests/codegen/initializers/failInInitializer3.kt delete mode 100644 kotlin-native/backend.native/tests/codegen/initializers/failInInitializer3.out delete mode 100644 kotlin-native/backend.native/tests/codegen/initializers/failInInitializer4.kt delete mode 100644 kotlin-native/backend.native/tests/codegen/initializers/failInInitializer4.out diff --git a/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirLightTreeBlackBoxCodegenTestGenerated.java b/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirLightTreeBlackBoxCodegenTestGenerated.java index ba666377c35..0b4635c7cdc 100644 --- a/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirLightTreeBlackBoxCodegenTestGenerated.java +++ b/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirLightTreeBlackBoxCodegenTestGenerated.java @@ -50572,6 +50572,18 @@ public class FirLightTreeBlackBoxCodegenTestGenerated extends AbstractFirLightTr public void testAllFilesPresentInTopLevelInitializtion() throws Exception { KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/topLevelInitializtion"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true); } + + @Test + @TestMetadata("failInInitializer1.kt") + public void testFailInInitializer1() throws Exception { + runTest("compiler/testData/codegen/box/topLevelInitializtion/failInInitializer1.kt"); + } + + @Test + @TestMetadata("failInInitializer2.kt") + public void testFailInInitializer2() throws Exception { + runTest("compiler/testData/codegen/box/topLevelInitializtion/failInInitializer2.kt"); + } } @Nested diff --git a/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirPsiBlackBoxCodegenTestGenerated.java b/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirPsiBlackBoxCodegenTestGenerated.java index cdc37c39737..b000264daaf 100644 --- a/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirPsiBlackBoxCodegenTestGenerated.java +++ b/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirPsiBlackBoxCodegenTestGenerated.java @@ -50572,6 +50572,18 @@ public class FirPsiBlackBoxCodegenTestGenerated extends AbstractFirPsiBlackBoxCo public void testAllFilesPresentInTopLevelInitializtion() throws Exception { KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/topLevelInitializtion"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true); } + + @Test + @TestMetadata("failInInitializer1.kt") + public void testFailInInitializer1() throws Exception { + runTest("compiler/testData/codegen/box/topLevelInitializtion/failInInitializer1.kt"); + } + + @Test + @TestMetadata("failInInitializer2.kt") + public void testFailInInitializer2() throws Exception { + runTest("compiler/testData/codegen/box/topLevelInitializtion/failInInitializer2.kt"); + } } @Nested diff --git a/compiler/testData/codegen/box/topLevelInitializtion/failInInitializer1.kt b/compiler/testData/codegen/box/topLevelInitializtion/failInInitializer1.kt new file mode 100644 index 00000000000..b9087b00971 --- /dev/null +++ b/compiler/testData/codegen/box/topLevelInitializtion/failInInitializer1.kt @@ -0,0 +1,31 @@ +// IGNORE_BACKEND: JS, JS_IR, JS_IR_ES6, WASM, NATIVE_WITH_LEGACY_MM +// FILE: lib.kt +val x: String = computeX() + +fun computeX(): String = throw IllegalStateException("1") + +// FILE: lib2.kt +val y: String = computeY() + +fun computeY(): String = throw Error("2") + + +// FILE: main.kt +fun box() : String { + try { + x + return "FAIL 1" + } catch(t: Error) { + val cause = t.cause + if (cause !is IllegalStateException) return "FAIL 2" + if (cause.message != "1") return "FAIL 3" + } + try { + y + return "FAIL 4" + } catch(t: Error) { + if (t.cause != null) return "FAIL 5" + if (t.message != "2") return "FAIL 6" + } + return "OK" +} diff --git a/compiler/testData/codegen/box/topLevelInitializtion/failInInitializer2.kt b/compiler/testData/codegen/box/topLevelInitializtion/failInInitializer2.kt new file mode 100644 index 00000000000..c602ac84de6 --- /dev/null +++ b/compiler/testData/codegen/box/topLevelInitializtion/failInInitializer2.kt @@ -0,0 +1,28 @@ +// IGNORE_BACKEND: JS, JS_IR, JS_IR_ES6, WASM, NATIVE_WITH_LEGACY_MM +// FILE: lib.kt +val x: String = computeX() + +fun computeX(): String = throw IllegalStateException("1") + +val y: String = computeY() + +fun computeY(): String = "2" + +// FILE: main.kt +fun box() : String { + try { + x + return "FAIL 1" + } catch(t: Error) { + val cause = t.cause + if (cause !is IllegalStateException) return "FAIL 2" + if (cause.message != "1") return "FAIL 3" + } + try { + y + return "FAIL 4" + } catch(t: Error) { + if (t.cause != null) return "FAIL 5" + } + return "OK" +} diff --git a/compiler/testData/codegen/box/topLevelInitializtion/failInInitializer3.kt b/compiler/testData/codegen/box/topLevelInitializtion/failInInitializer3.kt new file mode 100644 index 00000000000..aa5ec819d9f --- /dev/null +++ b/compiler/testData/codegen/box/topLevelInitializtion/failInInitializer3.kt @@ -0,0 +1,32 @@ +// TARGET_BACKEND: NATIVE +// IGNORE_BACKEND: NATIVE_WITH_LEGACY_MM +// FILE: lib.kt +import kotlin.native.concurrent.* + +@ThreadLocal +val x: String = computeX() + +fun computeX(): String = error("1") + +val y: String = computeY() + +fun computeY(): String = "2" + +// FILE: main.kt +fun box() : String { + try { + x + return "FAIL 1" + } catch(t: Error) { + val cause = t.cause + if (cause !is IllegalStateException) return "FAIL 2" + if (cause.message != "1") return "FAIL 3" + } + try { + y + return "FAIL 4" + } catch(t: Error) { + if (t.cause != null) return "FAIL 5" + } + return "OK" +} diff --git a/compiler/testData/codegen/box/topLevelInitializtion/failInInitializer4.kt b/compiler/testData/codegen/box/topLevelInitializtion/failInInitializer4.kt new file mode 100644 index 00000000000..132bc6d3631 --- /dev/null +++ b/compiler/testData/codegen/box/topLevelInitializtion/failInInitializer4.kt @@ -0,0 +1,33 @@ +// TARGET_BACKEND: NATIVE +// IGNORE_BACKEND: NATIVE_WITH_LEGACY_MM +// FILE: lib.kt +import kotlin.native.concurrent.* + +@ThreadLocal +val x: String = computeX() + +fun computeX(): String = error("1") + +@ThreadLocal +val y: String = computeY() + +fun computeY(): String = "2" + +// FILE: main.kt +fun box() : String { + try { + x + return "FAIL 1" + } catch(t: Error) { + val cause = t.cause + if (cause !is IllegalStateException) return "FAIL 2" + if (cause.message != "1") return "FAIL 3" + } + try { + y + return "FAIL 4" + } catch(t: Error) { + if (t.cause != null) return "FAIL 5" + } + return "OK" +} \ No newline at end of file diff --git a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/BlackBoxCodegenTestGenerated.java b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/BlackBoxCodegenTestGenerated.java index 9770fc58c16..7589860964a 100644 --- a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/BlackBoxCodegenTestGenerated.java +++ b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/BlackBoxCodegenTestGenerated.java @@ -48142,6 +48142,18 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { public void testAllFilesPresentInTopLevelInitializtion() throws Exception { KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/topLevelInitializtion"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM, true); } + + @Test + @TestMetadata("failInInitializer1.kt") + public void testFailInInitializer1() throws Exception { + runTest("compiler/testData/codegen/box/topLevelInitializtion/failInInitializer1.kt"); + } + + @Test + @TestMetadata("failInInitializer2.kt") + public void testFailInInitializer2() throws Exception { + runTest("compiler/testData/codegen/box/topLevelInitializtion/failInInitializer2.kt"); + } } @Nested diff --git a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenTestGenerated.java b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenTestGenerated.java index a181cfecdec..3e56f075c8b 100644 --- a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenTestGenerated.java +++ b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenTestGenerated.java @@ -50572,6 +50572,18 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes public void testAllFilesPresentInTopLevelInitializtion() throws Exception { KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/topLevelInitializtion"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true); } + + @Test + @TestMetadata("failInInitializer1.kt") + public void testFailInInitializer1() throws Exception { + runTest("compiler/testData/codegen/box/topLevelInitializtion/failInInitializer1.kt"); + } + + @Test + @TestMetadata("failInInitializer2.kt") + public void testFailInInitializer2() throws Exception { + runTest("compiler/testData/codegen/box/topLevelInitializtion/failInInitializer2.kt"); + } } @Nested diff --git a/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java b/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java index bf410e10656..da4857101c3 100644 --- a/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java +++ b/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java @@ -39077,6 +39077,16 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes public void testAllFilesPresentInTopLevelInitializtion() throws Exception { KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/topLevelInitializtion"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM, true); } + + @TestMetadata("failInInitializer1.kt") + public void testFailInInitializer1() throws Exception { + runTest("compiler/testData/codegen/box/topLevelInitializtion/failInInitializer1.kt"); + } + + @TestMetadata("failInInitializer2.kt") + public void testFailInInitializer2() throws Exception { + runTest("compiler/testData/codegen/box/topLevelInitializtion/failInInitializer2.kt"); + } } @TestMetadata("compiler/testData/codegen/box/topLevelPrivate") diff --git a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/JsCodegenBoxTestGenerated.java b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/JsCodegenBoxTestGenerated.java index 4e9be57e9a2..59581019bb8 100644 --- a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/JsCodegenBoxTestGenerated.java +++ b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/JsCodegenBoxTestGenerated.java @@ -35640,6 +35640,18 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest { public void testAllFilesPresentInTopLevelInitializtion() throws Exception { KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/topLevelInitializtion"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JS, true); } + + @Test + @TestMetadata("failInInitializer1.kt") + public void testFailInInitializer1() throws Exception { + runTest("compiler/testData/codegen/box/topLevelInitializtion/failInInitializer1.kt"); + } + + @Test + @TestMetadata("failInInitializer2.kt") + public void testFailInInitializer2() throws Exception { + runTest("compiler/testData/codegen/box/topLevelInitializtion/failInInitializer2.kt"); + } } @Nested diff --git a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/fir/FirJsCodegenBoxTestGenerated.java b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/fir/FirJsCodegenBoxTestGenerated.java index 9e25a507086..2204fed25fe 100644 --- a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/fir/FirJsCodegenBoxTestGenerated.java +++ b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/fir/FirJsCodegenBoxTestGenerated.java @@ -35826,6 +35826,18 @@ public class FirJsCodegenBoxTestGenerated extends AbstractFirJsCodegenBoxTest { public void testAllFilesPresentInTopLevelInitializtion() throws Exception { KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/topLevelInitializtion"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JS_IR, true); } + + @Test + @TestMetadata("failInInitializer1.kt") + public void testFailInInitializer1() throws Exception { + runTest("compiler/testData/codegen/box/topLevelInitializtion/failInInitializer1.kt"); + } + + @Test + @TestMetadata("failInInitializer2.kt") + public void testFailInInitializer2() throws Exception { + runTest("compiler/testData/codegen/box/topLevelInitializtion/failInInitializer2.kt"); + } } @Nested diff --git a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/IrJsCodegenBoxTestGenerated.java b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/IrJsCodegenBoxTestGenerated.java index 90d6740cf29..ec8f4830105 100644 --- a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/IrJsCodegenBoxTestGenerated.java +++ b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/IrJsCodegenBoxTestGenerated.java @@ -35826,6 +35826,18 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest { public void testAllFilesPresentInTopLevelInitializtion() throws Exception { KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/topLevelInitializtion"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JS_IR, true); } + + @Test + @TestMetadata("failInInitializer1.kt") + public void testFailInInitializer1() throws Exception { + runTest("compiler/testData/codegen/box/topLevelInitializtion/failInInitializer1.kt"); + } + + @Test + @TestMetadata("failInInitializer2.kt") + public void testFailInInitializer2() throws Exception { + runTest("compiler/testData/codegen/box/topLevelInitializtion/failInInitializer2.kt"); + } } @Nested diff --git a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/IrJsES6CodegenBoxTestGenerated.java b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/IrJsES6CodegenBoxTestGenerated.java index 6ac8b9bb372..80594cd56aa 100644 --- a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/IrJsES6CodegenBoxTestGenerated.java +++ b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/IrJsES6CodegenBoxTestGenerated.java @@ -35826,6 +35826,18 @@ public class IrJsES6CodegenBoxTestGenerated extends AbstractIrJsES6CodegenBoxTes public void testAllFilesPresentInTopLevelInitializtion() throws Exception { KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/topLevelInitializtion"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JS_IR_ES6, true); } + + @Test + @TestMetadata("failInInitializer1.kt") + public void testFailInInitializer1() throws Exception { + runTest("compiler/testData/codegen/box/topLevelInitializtion/failInInitializer1.kt"); + } + + @Test + @TestMetadata("failInInitializer2.kt") + public void testFailInInitializer2() throws Exception { + runTest("compiler/testData/codegen/box/topLevelInitializtion/failInInitializer2.kt"); + } } @Nested diff --git a/kotlin-native/backend.native/tests/build.gradle b/kotlin-native/backend.native/tests/build.gradle index c5724a4515a..a2d0b4d0218 100644 --- a/kotlin-native/backend.native/tests/build.gradle +++ b/kotlin-native/backend.native/tests/build.gradle @@ -1557,34 +1557,6 @@ standaloneTest("initializers_workers2") { useGoldenData = true } -standaloneTest("initializers_failInInitializer1") { - expectedFail = (project.testTarget == 'wasm32') // Uses exceptions. - source = "codegen/initializers/failInInitializer1.kt" - useGoldenData = true - flags = ['-Xir-property-lazy-initialization=enable'] -} - -standaloneTest("initializers_failInInitializer2") { - expectedFail = (project.testTarget == 'wasm32') // Uses exceptions. - source = "codegen/initializers/failInInitializer2.kt" - useGoldenData = true - flags = ['-Xir-property-lazy-initialization=enable'] -} - -standaloneTest("initializers_failInInitializer3") { - expectedFail = (project.testTarget == 'wasm32') // Uses exceptions. - source = "codegen/initializers/failInInitializer3.kt" - useGoldenData = true - flags = ['-Xir-property-lazy-initialization=enable'] -} - -standaloneTest("initializers_failInInitializer4") { - expectedFail = (project.testTarget == 'wasm32') // Uses exceptions. - source = "codegen/initializers/failInInitializer4.kt" - useGoldenData = true - flags = ['-Xir-property-lazy-initialization=enable'] -} - standaloneTest("initializers_when1") { source = "codegen/initializers/when1.kt" useGoldenData = true @@ -2839,7 +2811,7 @@ standaloneTest("exception_in_global_init") { enabled = (project.testTarget != 'wasm32') // Uses exceptions. source = "runtime/exceptions/exception_in_global_init.kt" expectedExitStatusChecker = { it != 0 } - outputChecker = { s -> s.contains("Uncaught Kotlin exception:") && s.coinains("FAIL") && !s.contains("in kotlin main") } + outputChecker = { s -> s.contains("Uncaught Kotlin exception:") && s.contains("FAIL") && !s.contains("in kotlin main") } } task rethrow_exception(type: KonanLocalTest) { diff --git a/kotlin-native/backend.native/tests/codegen/initializers/failInInitializer1.kt b/kotlin-native/backend.native/tests/codegen/initializers/failInInitializer1.kt deleted file mode 100644 index e30f26071d7..00000000000 --- a/kotlin-native/backend.native/tests/codegen/initializers/failInInitializer1.kt +++ /dev/null @@ -1,18 +0,0 @@ -/* - * Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors. - * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. - */ - -// FILE: lib.kt -val x: String = computeX() - -fun computeX(): String = error("zzz") - -// FILE: main.kt -fun main() { - try { - println(x) - } catch(t: IllegalStateException) { - println("caught") - } -} diff --git a/kotlin-native/backend.native/tests/codegen/initializers/failInInitializer1.out b/kotlin-native/backend.native/tests/codegen/initializers/failInInitializer1.out deleted file mode 100644 index cad99e12229..00000000000 --- a/kotlin-native/backend.native/tests/codegen/initializers/failInInitializer1.out +++ /dev/null @@ -1 +0,0 @@ -caught diff --git a/kotlin-native/backend.native/tests/codegen/initializers/failInInitializer2.kt b/kotlin-native/backend.native/tests/codegen/initializers/failInInitializer2.kt deleted file mode 100644 index eab9e0b8bf8..00000000000 --- a/kotlin-native/backend.native/tests/codegen/initializers/failInInitializer2.kt +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors. - * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. - */ - -// FILE: lib.kt -val x: String = computeX() - -fun computeX(): String = error("zzz") - -val y: String = computeY() - -fun computeY(): String = "qzz" - -// FILE: main.kt -@OptIn(ExperimentalStdlibApi::class) -fun main() { - try { - println(x) - } catch(t: IllegalStateException) { - println("caught") - } - try { - println(y) - } catch(t: kotlin.native.FileFailedToInitializeException) { - println("caught2") - } -} diff --git a/kotlin-native/backend.native/tests/codegen/initializers/failInInitializer2.out b/kotlin-native/backend.native/tests/codegen/initializers/failInInitializer2.out deleted file mode 100644 index 4fbc465ea00..00000000000 --- a/kotlin-native/backend.native/tests/codegen/initializers/failInInitializer2.out +++ /dev/null @@ -1,2 +0,0 @@ -caught -caught2 diff --git a/kotlin-native/backend.native/tests/codegen/initializers/failInInitializer3.kt b/kotlin-native/backend.native/tests/codegen/initializers/failInInitializer3.kt deleted file mode 100644 index e9700f6b377..00000000000 --- a/kotlin-native/backend.native/tests/codegen/initializers/failInInitializer3.kt +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors. - * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. - */ - -// FILE: lib.kt -import kotlin.native.concurrent.* - -@ThreadLocal -val x: String = computeX() - -fun computeX(): String = error("zzz") - -val y: String = computeY() - -fun computeY(): String = "qzz" - -// FILE: main.kt -@OptIn(ExperimentalStdlibApi::class) -fun main() { - try { - println(x) - } catch(t: IllegalStateException) { - println("caught") - } - try { - println(y) - } catch(t: kotlin.native.FileFailedToInitializeException) { - println("caught2") - } -} diff --git a/kotlin-native/backend.native/tests/codegen/initializers/failInInitializer3.out b/kotlin-native/backend.native/tests/codegen/initializers/failInInitializer3.out deleted file mode 100644 index 4fbc465ea00..00000000000 --- a/kotlin-native/backend.native/tests/codegen/initializers/failInInitializer3.out +++ /dev/null @@ -1,2 +0,0 @@ -caught -caught2 diff --git a/kotlin-native/backend.native/tests/codegen/initializers/failInInitializer4.kt b/kotlin-native/backend.native/tests/codegen/initializers/failInInitializer4.kt deleted file mode 100644 index ed0917e72af..00000000000 --- a/kotlin-native/backend.native/tests/codegen/initializers/failInInitializer4.kt +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors. - * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. - */ - -// FILE: lib.kt -import kotlin.native.concurrent.* - -@ThreadLocal -val x: String = computeX() - -fun computeX(): String = error("zzz") - -@ThreadLocal -val y: String = computeY() - -fun computeY(): String = "qzz" - -// FILE: main.kt -@OptIn(ExperimentalStdlibApi::class) -fun main() { - try { - println(x) - } catch(t: IllegalStateException) { - println("caught") - } - try { - println(y) - } catch(t: kotlin.native.FileFailedToInitializeException) { - println("caught2") - } -} diff --git a/kotlin-native/backend.native/tests/codegen/initializers/failInInitializer4.out b/kotlin-native/backend.native/tests/codegen/initializers/failInInitializer4.out deleted file mode 100644 index 4fbc465ea00..00000000000 --- a/kotlin-native/backend.native/tests/codegen/initializers/failInInitializer4.out +++ /dev/null @@ -1,2 +0,0 @@ -caught -caught2 diff --git a/kotlin-native/runtime/src/main/cpp/Exceptions.h b/kotlin-native/runtime/src/main/cpp/Exceptions.h index 3d2f84ef39c..9281c08db38 100644 --- a/kotlin-native/runtime/src/main/cpp/Exceptions.h +++ b/kotlin-native/runtime/src/main/cpp/Exceptions.h @@ -44,7 +44,7 @@ void RUNTIME_NORETURN ThrowIllegalArgumentException(); void RUNTIME_NORETURN ThrowIllegalStateException(); void RUNTIME_NORETURN ThrowInvalidMutabilityException(KConstRef where); void RUNTIME_NORETURN ThrowIncorrectDereferenceException(); -void RUNTIME_NORETURN ThrowFileFailedToInitializeException(); +void RUNTIME_NORETURN ThrowFileFailedToInitializeException(KRef reason); void RUNTIME_NORETURN ThrowIllegalObjectSharingException(KConstNativePtr typeInfo, KConstNativePtr address); void RUNTIME_NORETURN ThrowFreezingException(KRef toFreeze, KRef blocker); // Prints out message of Throwable. diff --git a/kotlin-native/runtime/src/main/cpp/Runtime.cpp b/kotlin-native/runtime/src/main/cpp/Runtime.cpp index 4c23a1d084b..d6705c3cd3d 100644 --- a/kotlin-native/runtime/src/main/cpp/Runtime.cpp +++ b/kotlin-native/runtime/src/main/cpp/Runtime.cpp @@ -464,14 +464,14 @@ static void CallInitGlobalAwaitInitialized(int *state) { localState = atomicGetAcquire(state); } while (localState != FILE_INITIALIZED && localState != FILE_FAILED_TO_INITIALIZE); } - if (localState == FILE_FAILED_TO_INITIALIZE) ThrowFileFailedToInitializeException(); + if (localState == FILE_FAILED_TO_INITIALIZE) ThrowFileFailedToInitializeException(nullptr); } NO_INLINE void CallInitGlobalPossiblyLock(int* state, void (*init)()) { int localState = atomicGetAcquire(state); if (localState == FILE_INITIALIZED) return; if (localState == FILE_FAILED_TO_INITIALIZE) - ThrowFileFailedToInitializeException(); + ThrowFileFailedToInitializeException(nullptr); int threadId = konan::currentThreadId(); if ((localState & 3) == FILE_BEING_INITIALIZED) { if ((localState & ~3) != (threadId << 2)) { @@ -485,10 +485,13 @@ NO_INLINE void CallInitGlobalPossiblyLock(int* state, void (*init)()) { init(); #else try { + CurrentFrameGuard guard; init(); - } catch (...) { + } catch (ExceptionObjHolder& e) { + ObjHolder holder; + auto *exception = Kotlin_getExceptionObject(&e, holder.slot()); atomicSetRelease(state, FILE_FAILED_TO_INITIALIZE); - throw; + ThrowFileFailedToInitializeException(exception); } #endif atomicSetRelease(state, FILE_INITIALIZED); @@ -499,16 +502,19 @@ NO_INLINE void CallInitGlobalPossiblyLock(int* state, void (*init)()) { void CallInitThreadLocal(int volatile* globalState, int* localState, void (*init)()) { if (*localState == FILE_FAILED_TO_INITIALIZE || (globalState != nullptr && *globalState == FILE_FAILED_TO_INITIALIZE)) - ThrowFileFailedToInitializeException(); + ThrowFileFailedToInitializeException(nullptr); *localState = FILE_INITIALIZED; #if KONAN_NO_EXCEPTIONS init(); #else try { + CurrentFrameGuard guard; init(); - } catch(...) { + } catch(ExceptionObjHolder& e) { + ObjHolder holder; + auto *exception = Kotlin_getExceptionObject(&e, holder.slot()); *localState = FILE_FAILED_TO_INITIALIZE; - throw; + ThrowFileFailedToInitializeException(exception); } #endif } diff --git a/kotlin-native/runtime/src/main/kotlin/kotlin/native/Runtime.kt b/kotlin-native/runtime/src/main/kotlin/kotlin/native/Runtime.kt index 1e5f5eecdcc..38b7134c380 100644 --- a/kotlin-native/runtime/src/main/kotlin/kotlin/native/Runtime.kt +++ b/kotlin-native/runtime/src/main/kotlin/kotlin/native/Runtime.kt @@ -35,15 +35,6 @@ public class IncorrectDereferenceException : RuntimeException { constructor(message: String) : super(message) } -/** - * Exception thrown when there was an error during file initalization. - */ -@ExperimentalStdlibApi -public class FileFailedToInitializeException : RuntimeException { - constructor() : super() - - constructor(message: String) : super(message) -} /** * Typealias describing custom exception reporting hook. diff --git a/kotlin-native/runtime/src/main/kotlin/kotlin/native/internal/RuntimeUtils.kt b/kotlin-native/runtime/src/main/kotlin/kotlin/native/internal/RuntimeUtils.kt index 01eab11547c..beb0e9f905c 100644 --- a/kotlin-native/runtime/src/main/kotlin/kotlin/native/internal/RuntimeUtils.kt +++ b/kotlin-native/runtime/src/main/kotlin/kotlin/native/internal/RuntimeUtils.kt @@ -107,10 +107,20 @@ internal fun ThrowIncorrectDereferenceException() { "Trying to access top level value not marked as @ThreadLocal or @SharedImmutable from non-main thread") } +internal class FileFailedToInitializeException(message: String?, cause: Throwable?) : Error(message, cause) + @ExportForCppRuntime @OptIn(ExperimentalStdlibApi::class) -internal fun ThrowFileFailedToInitializeException() { - throw FileFailedToInitializeException("There was an error during file initialization") +internal fun ThrowFileFailedToInitializeException(reason: Throwable?) { + if (reason is Error) { + throw reason + } else { + // https://youtrack.jetbrains.com/issue/KT-57134 + // TODO: align exact exception hierarchy with jvm + // in jvm it's NoClassDefFound if reason is null, i.e. this is already failed class + // and ExceptionInInitializerError if it's non-null + throw FileFailedToInitializeException("There was an error during file or class initialization", reason) + } } internal class IrLinkageError(message: String?) : Error(message) diff --git a/native/native.tests/tests-gen/org/jetbrains/kotlin/konan/blackboxtest/K2NativeCodegenBoxTestGenerated.java b/native/native.tests/tests-gen/org/jetbrains/kotlin/konan/blackboxtest/K2NativeCodegenBoxTestGenerated.java index 5747f021abf..77a0694c977 100644 --- a/native/native.tests/tests-gen/org/jetbrains/kotlin/konan/blackboxtest/K2NativeCodegenBoxTestGenerated.java +++ b/native/native.tests/tests-gen/org/jetbrains/kotlin/konan/blackboxtest/K2NativeCodegenBoxTestGenerated.java @@ -39460,6 +39460,30 @@ public class K2NativeCodegenBoxTestGenerated extends AbstractNativeCodegenBoxTes public void testConcurrent() throws Exception { runTest("compiler/testData/codegen/box/topLevelInitializtion/concurrent.kt"); } + + @Test + @TestMetadata("failInInitializer1.kt") + public void testFailInInitializer1() throws Exception { + runTest("compiler/testData/codegen/box/topLevelInitializtion/failInInitializer1.kt"); + } + + @Test + @TestMetadata("failInInitializer2.kt") + public void testFailInInitializer2() throws Exception { + runTest("compiler/testData/codegen/box/topLevelInitializtion/failInInitializer2.kt"); + } + + @Test + @TestMetadata("failInInitializer3.kt") + public void testFailInInitializer3() throws Exception { + runTest("compiler/testData/codegen/box/topLevelInitializtion/failInInitializer3.kt"); + } + + @Test + @TestMetadata("failInInitializer4.kt") + public void testFailInInitializer4() throws Exception { + runTest("compiler/testData/codegen/box/topLevelInitializtion/failInInitializer4.kt"); + } } @Nested diff --git a/native/native.tests/tests-gen/org/jetbrains/kotlin/konan/blackboxtest/NativeCodegenBoxTestGenerated.java b/native/native.tests/tests-gen/org/jetbrains/kotlin/konan/blackboxtest/NativeCodegenBoxTestGenerated.java index f0a103d10f2..5bbe0991c00 100644 --- a/native/native.tests/tests-gen/org/jetbrains/kotlin/konan/blackboxtest/NativeCodegenBoxTestGenerated.java +++ b/native/native.tests/tests-gen/org/jetbrains/kotlin/konan/blackboxtest/NativeCodegenBoxTestGenerated.java @@ -38965,6 +38965,30 @@ public class NativeCodegenBoxTestGenerated extends AbstractNativeCodegenBoxTest public void testConcurrent() throws Exception { runTest("compiler/testData/codegen/box/topLevelInitializtion/concurrent.kt"); } + + @Test + @TestMetadata("failInInitializer1.kt") + public void testFailInInitializer1() throws Exception { + runTest("compiler/testData/codegen/box/topLevelInitializtion/failInInitializer1.kt"); + } + + @Test + @TestMetadata("failInInitializer2.kt") + public void testFailInInitializer2() throws Exception { + runTest("compiler/testData/codegen/box/topLevelInitializtion/failInInitializer2.kt"); + } + + @Test + @TestMetadata("failInInitializer3.kt") + public void testFailInInitializer3() throws Exception { + runTest("compiler/testData/codegen/box/topLevelInitializtion/failInInitializer3.kt"); + } + + @Test + @TestMetadata("failInInitializer4.kt") + public void testFailInInitializer4() throws Exception { + runTest("compiler/testData/codegen/box/topLevelInitializtion/failInInitializer4.kt"); + } } @Nested diff --git a/wasm/wasm.tests/tests-gen/org/jetbrains/kotlin/wasm/test/IrCodegenBoxWasmTestGenerated.java b/wasm/wasm.tests/tests-gen/org/jetbrains/kotlin/wasm/test/IrCodegenBoxWasmTestGenerated.java index cf9971a6ed4..3cc9875dabb 100644 --- a/wasm/wasm.tests/tests-gen/org/jetbrains/kotlin/wasm/test/IrCodegenBoxWasmTestGenerated.java +++ b/wasm/wasm.tests/tests-gen/org/jetbrains/kotlin/wasm/test/IrCodegenBoxWasmTestGenerated.java @@ -32097,6 +32097,16 @@ public class IrCodegenBoxWasmTestGenerated extends AbstractIrCodegenBoxWasmTest public void testAllFilesPresentInTopLevelInitializtion() throws Exception { KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/topLevelInitializtion"), Pattern.compile("^([^_](.+))\\.kt$"), null, TargetBackend.WASM, true); } + + @TestMetadata("failInInitializer1.kt") + public void testFailInInitializer1() throws Exception { + runTest("compiler/testData/codegen/box/topLevelInitializtion/failInInitializer1.kt"); + } + + @TestMetadata("failInInitializer2.kt") + public void testFailInInitializer2() throws Exception { + runTest("compiler/testData/codegen/box/topLevelInitializtion/failInInitializer2.kt"); + } } @TestMetadata("compiler/testData/codegen/box/topLevelPrivate")