[K/JS] Capture stackTrace before the init function call ^Fixed KT-55315
This commit is contained in:
@@ -279,6 +279,12 @@ private val removeInlineDeclarationsWithReifiedTypeParametersLoweringPhase = mak
|
|||||||
prerequisite = setOf(functionInliningPhase)
|
prerequisite = setOf(functionInliningPhase)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
private val captureStackTraceInThrowablesPhase = makeBodyLoweringPhase(
|
||||||
|
::CaptureStackTraceInThrowables,
|
||||||
|
name = "CaptureStackTraceInThrowables",
|
||||||
|
description = "Capture stack trace in Throwable constructors"
|
||||||
|
)
|
||||||
|
|
||||||
private val throwableSuccessorsLoweringPhase = makeBodyLoweringPhase(
|
private val throwableSuccessorsLoweringPhase = makeBodyLoweringPhase(
|
||||||
{ context ->
|
{ context ->
|
||||||
context.run {
|
context.run {
|
||||||
@@ -289,7 +295,8 @@ private val throwableSuccessorsLoweringPhase = makeBodyLoweringPhase(
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
name = "ThrowableLowering",
|
name = "ThrowableLowering",
|
||||||
description = "Link kotlin.Throwable and JavaScript Error together to provide proper interop between language and platform exceptions"
|
description = "Link kotlin.Throwable and JavaScript Error together to provide proper interop between language and platform exceptions",
|
||||||
|
prerequisite = setOf(captureStackTraceInThrowablesPhase)
|
||||||
)
|
)
|
||||||
|
|
||||||
private val tailrecLoweringPhase = makeBodyLoweringPhase(
|
private val tailrecLoweringPhase = makeBodyLoweringPhase(
|
||||||
@@ -783,12 +790,6 @@ private val objectUsageLoweringPhase = makeBodyLoweringPhase(
|
|||||||
description = "Transform IrGetObjectValue into instance generator call"
|
description = "Transform IrGetObjectValue into instance generator call"
|
||||||
)
|
)
|
||||||
|
|
||||||
private val captureStackTraceInThrowablesPhase = makeBodyLoweringPhase(
|
|
||||||
::CaptureStackTraceInThrowables,
|
|
||||||
name = "CaptureStackTraceInThrowables",
|
|
||||||
description = "Capture stack trace in Throwable constructors"
|
|
||||||
)
|
|
||||||
|
|
||||||
private val escapedIdentifiersLowering = makeBodyLoweringPhase(
|
private val escapedIdentifiersLowering = makeBodyLoweringPhase(
|
||||||
::EscapedIdentifiersLowering,
|
::EscapedIdentifiersLowering,
|
||||||
name = "EscapedIdentifiersLowering",
|
name = "EscapedIdentifiersLowering",
|
||||||
@@ -901,6 +902,7 @@ val loweringList = listOf<Lowering>(
|
|||||||
defaultArgumentPatchOverridesPhase,
|
defaultArgumentPatchOverridesPhase,
|
||||||
defaultParameterInjectorPhase,
|
defaultParameterInjectorPhase,
|
||||||
defaultParameterCleanerPhase,
|
defaultParameterCleanerPhase,
|
||||||
|
captureStackTraceInThrowablesPhase,
|
||||||
throwableSuccessorsLoweringPhase,
|
throwableSuccessorsLoweringPhase,
|
||||||
es6AddInternalParametersToConstructorPhase,
|
es6AddInternalParametersToConstructorPhase,
|
||||||
es6ConstructorLowering,
|
es6ConstructorLowering,
|
||||||
@@ -921,7 +923,6 @@ val loweringList = listOf<Lowering>(
|
|||||||
objectDeclarationLoweringPhase,
|
objectDeclarationLoweringPhase,
|
||||||
invokeStaticInitializersPhase,
|
invokeStaticInitializersPhase,
|
||||||
objectUsageLoweringPhase,
|
objectUsageLoweringPhase,
|
||||||
captureStackTraceInThrowablesPhase,
|
|
||||||
callsLoweringPhase,
|
callsLoweringPhase,
|
||||||
escapedIdentifiersLowering,
|
escapedIdentifiersLowering,
|
||||||
implicitlyExportedDeclarationsMarkingLowering,
|
implicitlyExportedDeclarationsMarkingLowering,
|
||||||
|
|||||||
+6
-2
@@ -13,6 +13,7 @@ import org.jetbrains.kotlin.ir.declarations.IrConstructor
|
|||||||
import org.jetbrains.kotlin.ir.declarations.IrDeclaration
|
import org.jetbrains.kotlin.ir.declarations.IrDeclaration
|
||||||
import org.jetbrains.kotlin.ir.expressions.IrBlockBody
|
import org.jetbrains.kotlin.ir.expressions.IrBlockBody
|
||||||
import org.jetbrains.kotlin.ir.expressions.IrBody
|
import org.jetbrains.kotlin.ir.expressions.IrBody
|
||||||
|
import org.jetbrains.kotlin.ir.expressions.IrDelegatingConstructorCall
|
||||||
import org.jetbrains.kotlin.ir.expressions.impl.IrRawFunctionReferenceImpl
|
import org.jetbrains.kotlin.ir.expressions.impl.IrRawFunctionReferenceImpl
|
||||||
import org.jetbrains.kotlin.ir.util.isSubclassOf
|
import org.jetbrains.kotlin.ir.util.isSubclassOf
|
||||||
import org.jetbrains.kotlin.ir.util.parentAsClass
|
import org.jetbrains.kotlin.ir.util.parentAsClass
|
||||||
@@ -30,12 +31,15 @@ class CaptureStackTraceInThrowables(val context: JsIrBackendContext) : BodyLower
|
|||||||
if (!klass.isSubclassOf(context.irBuiltIns.throwableClass.owner))
|
if (!klass.isSubclassOf(context.irBuiltIns.throwableClass.owner))
|
||||||
return
|
return
|
||||||
|
|
||||||
(irBody as IrBlockBody).statements += JsIrBuilder.buildCall(context.intrinsics.captureStack).also { call ->
|
val statements = (irBody as IrBlockBody).statements
|
||||||
|
val delegatingConstructorCallIndex = statements.indexOfLast { it is IrDelegatingConstructorCall }
|
||||||
|
|
||||||
|
statements.add(delegatingConstructorCallIndex + 1, JsIrBuilder.buildCall(context.intrinsics.captureStack).also { call ->
|
||||||
call.putValueArgument(0, JsIrBuilder.buildGetValue(klass.thisReceiver!!.symbol))
|
call.putValueArgument(0, JsIrBuilder.buildGetValue(klass.thisReceiver!!.symbol))
|
||||||
call.putValueArgument(
|
call.putValueArgument(
|
||||||
1,
|
1,
|
||||||
IrRawFunctionReferenceImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, context.irBuiltIns.anyType, container.symbol)
|
IrRawFunctionReferenceImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, context.irBuiltIns.anyType, container.symbol)
|
||||||
)
|
)
|
||||||
}
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3627,6 +3627,12 @@ public class BoxJsTestGenerated extends AbstractBoxJsTest {
|
|||||||
runTest("js/js.translator/testData/box/expression/misc/safeCallComputesExpressionOnlyOnce.kt");
|
runTest("js/js.translator/testData/box/expression/misc/safeCallComputesExpressionOnlyOnce.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("stackTraceAccessInsideInitBlock.kt")
|
||||||
|
public void testStackTraceAccessInsideInitBlock() throws Exception {
|
||||||
|
runTest("js/js.translator/testData/box/expression/misc/stackTraceAccessInsideInitBlock.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("stackTraceCapturing.kt")
|
@TestMetadata("stackTraceCapturing.kt")
|
||||||
public void testStackTraceCapturing() throws Exception {
|
public void testStackTraceCapturing() throws Exception {
|
||||||
|
|||||||
+6
@@ -4249,6 +4249,12 @@ public class FirJsBoxTestGenerated extends AbstractFirJsBoxTest {
|
|||||||
runTest("js/js.translator/testData/box/expression/misc/safeCallComputesExpressionOnlyOnce.kt");
|
runTest("js/js.translator/testData/box/expression/misc/safeCallComputesExpressionOnlyOnce.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("stackTraceAccessInsideInitBlock.kt")
|
||||||
|
public void testStackTraceAccessInsideInitBlock() throws Exception {
|
||||||
|
runTest("js/js.translator/testData/box/expression/misc/stackTraceAccessInsideInitBlock.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("stackTraceCapturing.kt")
|
@TestMetadata("stackTraceCapturing.kt")
|
||||||
public void testStackTraceCapturing() throws Exception {
|
public void testStackTraceCapturing() throws Exception {
|
||||||
|
|||||||
+6
@@ -4249,6 +4249,12 @@ public class IrBoxJsTestGenerated extends AbstractIrBoxJsTest {
|
|||||||
runTest("js/js.translator/testData/box/expression/misc/safeCallComputesExpressionOnlyOnce.kt");
|
runTest("js/js.translator/testData/box/expression/misc/safeCallComputesExpressionOnlyOnce.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("stackTraceAccessInsideInitBlock.kt")
|
||||||
|
public void testStackTraceAccessInsideInitBlock() throws Exception {
|
||||||
|
runTest("js/js.translator/testData/box/expression/misc/stackTraceAccessInsideInitBlock.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("stackTraceCapturing.kt")
|
@TestMetadata("stackTraceCapturing.kt")
|
||||||
public void testStackTraceCapturing() throws Exception {
|
public void testStackTraceCapturing() throws Exception {
|
||||||
|
|||||||
+32
@@ -0,0 +1,32 @@
|
|||||||
|
// EXPECTED_REACHABLE_NODES: 1462
|
||||||
|
// KJS_WITH_FULL_RUNTIME
|
||||||
|
// IGNORE_BACKEND: JS
|
||||||
|
// KT-55315
|
||||||
|
|
||||||
|
var stackTrace: String = ""
|
||||||
|
|
||||||
|
open class MyOwnException1: Throwable("Test message 1") {
|
||||||
|
init {
|
||||||
|
stackTrace = asDynamic().stack
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class MyOwnException2: MyOwnException1() {
|
||||||
|
init {
|
||||||
|
stackTrace = asDynamic().stack
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun box(): String {
|
||||||
|
try {
|
||||||
|
throw MyOwnException1()
|
||||||
|
} catch (e: Throwable) {
|
||||||
|
if (!stackTrace.contains("MyOwnException1: Test message 1\n")) return "fail"
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
throw MyOwnException2()
|
||||||
|
} catch (e: Throwable) {
|
||||||
|
if (!stackTrace.contains("MyOwnException2: Test message 1\n")) return "fail"
|
||||||
|
}
|
||||||
|
return "OK"
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user