[JVM_IR]: Improve stepping for when.
Additionally, use the line number of the class for default interface dispatch methods.
This commit is contained in:
+22
-15
@@ -127,6 +127,7 @@ class ExpressionCodegen(
|
||||
get() = typeMapper.typeSystem
|
||||
|
||||
override var lastLineNumber: Int = -1
|
||||
var noLineNumberScope: Boolean = false
|
||||
|
||||
private val closureReifiedMarkers = hashMapOf<IrClass, ReifiedTypeParametersUsages>()
|
||||
|
||||
@@ -151,6 +152,7 @@ class ExpressionCodegen(
|
||||
private fun getLineNumberForOffset(offset: Int): Int = fileEntry?.getLineNumber(offset)?.plus(1) ?: -1
|
||||
|
||||
private fun IrElement.markLineNumber(startOffset: Boolean) {
|
||||
if (noLineNumberScope) return
|
||||
val offset = if (startOffset) this.startOffset else endOffset
|
||||
if (offset < 0) {
|
||||
return
|
||||
@@ -167,6 +169,13 @@ class ExpressionCodegen(
|
||||
|
||||
fun markLineNumber(element: IrElement) = element.markLineNumber(true)
|
||||
|
||||
fun noLineNumberScope(block: () -> Unit) {
|
||||
val previousState = noLineNumberScope
|
||||
noLineNumberScope = true
|
||||
block()
|
||||
noLineNumberScope = previousState
|
||||
}
|
||||
|
||||
// TODO remove
|
||||
fun gen(expression: IrExpression, type: Type, irType: IrType, data: BlockInfo): StackValue {
|
||||
if (expression.attributeOwnerId === context.fakeContinuation) {
|
||||
@@ -365,7 +374,7 @@ class ExpressionCodegen(
|
||||
private fun visitStatementContainer(container: IrStatementContainer, data: BlockInfo) =
|
||||
container.statements.fold(unitValue) { prev, exp ->
|
||||
prev.discard()
|
||||
exp.accept(this, data).also { (exp as? IrExpression)?.markEndOfStatementIfNeeded() }
|
||||
exp.accept(this, data)
|
||||
}
|
||||
|
||||
override fun visitBlockBody(body: IrBlockBody, data: BlockInfo): PromisedValue {
|
||||
@@ -767,7 +776,18 @@ class ExpressionCodegen(
|
||||
override fun visitWhen(expression: IrWhen, data: BlockInfo): PromisedValue {
|
||||
expression.markLineNumber(startOffset = true)
|
||||
SwitchGenerator(expression, data, this).generate()?.let { return it }
|
||||
|
||||
// When a lookup/table switch instruction is not generate, output a nop
|
||||
// for the line number of the when itself. Otherwise, there will be
|
||||
// no option of breaking on the line of the `when` if there is no
|
||||
// subject:
|
||||
//
|
||||
// when {
|
||||
// cond1 -> exp1
|
||||
// else -> exp2
|
||||
// }
|
||||
if (expression.origin == IrStatementOrigin.WHEN) {
|
||||
mv.nop()
|
||||
}
|
||||
val endLabel = Label()
|
||||
val exhaustive = expression.branches.any { it.condition.isTrueConst() } && !expression.type.isUnit()
|
||||
assert(exhaustive || expression.type.isUnit()) {
|
||||
@@ -849,19 +869,6 @@ class ExpressionCodegen(
|
||||
}
|
||||
}
|
||||
|
||||
private fun IrExpression.markEndOfStatementIfNeeded() {
|
||||
when (this) {
|
||||
is IrWhen -> if (this.branches.size > 1) {
|
||||
this.markLineNumber(false)
|
||||
}
|
||||
is IrTry -> this.markLineNumber(false)
|
||||
is IrContainerExpression -> when (this.origin) {
|
||||
IrStatementOrigin.WHEN, IrStatementOrigin.IF ->
|
||||
this.markLineNumber(false)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun visitWhileLoop(loop: IrWhileLoop, data: BlockInfo): PromisedValue {
|
||||
val continueLabel = markNewLabel()
|
||||
val endLabel = Label()
|
||||
|
||||
+49
-7
@@ -348,7 +348,27 @@ class SwitchGenerator(private val expression: IrWhen, private val data: BlockInf
|
||||
override fun shouldOptimize() = cases.size > 1
|
||||
|
||||
override fun genSwitch() {
|
||||
subject.accept(codegen, data).materialize()
|
||||
// Do not generate line numbers for the table switching. In particular,
|
||||
// the subject is extracted from the condition of the first branch which
|
||||
// will give the wrong stepping behavior for code such as:
|
||||
//
|
||||
// when {
|
||||
// x == 42 -> 1
|
||||
// x == 32 -> 2
|
||||
// x == 24 -> 3
|
||||
// ...
|
||||
// }
|
||||
//
|
||||
// If the subject line number is generated, we will not stop on the line
|
||||
// of the `when` but instead stop on the `x == 42` line. When x is 24,
|
||||
// we would stop on the line `x == 42` and then step to the line `x == 24`.
|
||||
// That is confusing and we prefer to stop on the `when` line and then step
|
||||
// to the `x == 24` line. This is accomplished by ignoring the line number
|
||||
// information for the subject as the `when` line number has already been
|
||||
// emitted.
|
||||
codegen.noLineNumberScope {
|
||||
subject.accept(codegen, data).materialize()
|
||||
}
|
||||
genIntSwitch(cases)
|
||||
}
|
||||
}
|
||||
@@ -419,13 +439,33 @@ class SwitchGenerator(private val expression: IrWhen, private val data: BlockInf
|
||||
|
||||
override fun genSwitch() {
|
||||
with(codegen) {
|
||||
if (subject.type.isNullableString()) {
|
||||
// Do not generate line numbers for the table switching. In particular,
|
||||
// the subject is extracted from the condition of the first branch which
|
||||
// will give the wrong stepping behavior for code such as:
|
||||
//
|
||||
// when {
|
||||
// x == "x" -> 1
|
||||
// x == "y" -> 2
|
||||
// x == "z" -> 3
|
||||
// ...
|
||||
// }
|
||||
//
|
||||
// If the subject line number is generated, we will not stop on the line
|
||||
// of the `when` but instead stop on the `x == "x"` line. When x is "z",
|
||||
// we would stop on the line `x == "x"` and then step to the line `x == "z"`.
|
||||
// That is confusing and we prefer to stop on the `when` line and then step
|
||||
// to the `x == "z"` line. This is accomplished by ignoring the line number
|
||||
// information for the subject as the `when` line number has already been
|
||||
// emitted.
|
||||
noLineNumberScope {
|
||||
if (subject.type.isNullableString()) {
|
||||
subject.accept(codegen, data).materialize()
|
||||
mv.ifnull(cases.find { it.value == null }?.label ?: defaultLabel)
|
||||
}
|
||||
// Reevaluating the subject is fine here because it is a read of a temporary.
|
||||
subject.accept(codegen, data).materialize()
|
||||
mv.ifnull(cases.find { it.value == null }?.label ?: defaultLabel)
|
||||
mv.invokevirtual("java/lang/String", "hashCode", "()I", false)
|
||||
}
|
||||
// Reevaluating the subject is fine here because it is a read of a temporary.
|
||||
subject.accept(codegen, data).materialize()
|
||||
mv.invokevirtual("java/lang/String", "hashCode", "()I", false)
|
||||
genIntSwitch(hashAndSwitchLabels)
|
||||
|
||||
// Multiple strings can be hashed into the same bucket.
|
||||
@@ -433,7 +473,9 @@ class SwitchGenerator(private val expression: IrWhen, private val data: BlockInf
|
||||
for ((hash, switchLabel) in hashAndSwitchLabels) {
|
||||
mv.visitLabel(switchLabel)
|
||||
for ((string, label) in hashToStringAndExprLabels[hash]!!) {
|
||||
subject.accept(codegen, data).materialize()
|
||||
noLineNumberScope {
|
||||
subject.accept(codegen, data).materialize()
|
||||
}
|
||||
mv.aconst(string)
|
||||
mv.invokevirtual("java/lang/String", "equals", "(Ljava/lang/Object;)Z", false)
|
||||
mv.ifne(label)
|
||||
|
||||
+2
-1
@@ -88,7 +88,8 @@ private class InheritedDefaultMethodsOnClassesLowering(val context: JvmBackendCo
|
||||
|
||||
val superMethod = firstSuperMethodFromKotlin(irFunction, interfaceImplementation).owner
|
||||
val defaultImplFun = context.cachedDeclarations.getDefaultImplsFunction(superMethod)
|
||||
context.createIrBuilder(irFunction.symbol, UNDEFINED_OFFSET, UNDEFINED_OFFSET).apply {
|
||||
val classStartOffset = classOverride.parentAsClass.startOffset
|
||||
context.createIrBuilder(irFunction.symbol, classStartOffset, classStartOffset).apply {
|
||||
irFunction.body = irBlockBody {
|
||||
+irReturn(
|
||||
irCall(defaultImplFun.symbol, irFunction.returnType).apply {
|
||||
|
||||
@@ -21,6 +21,5 @@ fun infiniteLoop() {
|
||||
// 1 GOTO L1
|
||||
|
||||
// JVM_IR_TEMPLATES
|
||||
// 1 GOTO L6
|
||||
// 1 GOTO L7
|
||||
// 2 GOTO L6
|
||||
// 1 GOTO L0
|
||||
+113
@@ -0,0 +1,113 @@
|
||||
// FILE: test.kt
|
||||
|
||||
fun stringSwitch(x: String) {
|
||||
val l = when {
|
||||
x == "x" -> 1
|
||||
x == "xy" -> 2
|
||||
x == "xyz" -> 3
|
||||
else -> -1
|
||||
}
|
||||
|
||||
val l2 = when (x) {
|
||||
"x" -> 1
|
||||
"xy" -> 2
|
||||
"xyz" -> 3
|
||||
else -> -1
|
||||
}
|
||||
|
||||
val l3 = when
|
||||
(x)
|
||||
{
|
||||
"x" -> 1
|
||||
"xy" -> 2
|
||||
"xyz" -> 3
|
||||
else -> -1
|
||||
}
|
||||
}
|
||||
|
||||
fun box() {
|
||||
stringSwitch("x")
|
||||
stringSwitch("xy")
|
||||
stringSwitch("xyz")
|
||||
stringSwitch("nope")
|
||||
}
|
||||
|
||||
// JVM_IR uses the line number of the start of the `when` as the line number
|
||||
// for the lookup/table switch. Therefore when the subject and the when is
|
||||
// on separate lines the first step is on the subject, then steop to the when,
|
||||
// then to the right branch.
|
||||
|
||||
// JVM_IR uses optimized lookup/table switches for all these cases. JVM
|
||||
// does not. So on JVM there are steps on each condition evaluation for
|
||||
// the first `when`.
|
||||
|
||||
// LINENUMBERS
|
||||
// test.kt:29 box
|
||||
// test.kt:4 stringSwitch
|
||||
// test.kt:5 stringSwitch
|
||||
// test.kt:4 stringSwitch
|
||||
// test.kt:11 stringSwitch
|
||||
// test.kt:12 stringSwitch
|
||||
// test.kt:11 stringSwitch
|
||||
// test.kt:19 stringSwitch
|
||||
// LINENUMBERS JVM_IR
|
||||
// test.kt:18 stringSwitch
|
||||
// LINENUMBERS
|
||||
// test.kt:21 stringSwitch
|
||||
// test.kt:18 stringSwitch
|
||||
// test.kt:26 stringSwitch
|
||||
// test.kt:30 box
|
||||
// test.kt:4 stringSwitch
|
||||
// LINENUMBERS JVM
|
||||
// test.kt:5 stringSwitch
|
||||
// LINENUMBERS
|
||||
// test.kt:6 stringSwitch
|
||||
// test.kt:4 stringSwitch
|
||||
// test.kt:11 stringSwitch
|
||||
// test.kt:13 stringSwitch
|
||||
// test.kt:11 stringSwitch
|
||||
// test.kt:19 stringSwitch
|
||||
// LINENUMBERS JVM_IR
|
||||
// test.kt:18 stringSwitch
|
||||
// LINENUMBERS
|
||||
// test.kt:22 stringSwitch
|
||||
// test.kt:18 stringSwitch
|
||||
// test.kt:26 stringSwitch
|
||||
// test.kt:31 box
|
||||
// test.kt:4 stringSwitch
|
||||
// LINENUMBERS JVM
|
||||
// test.kt:5 stringSwitch
|
||||
// test.kt:6 stringSwitch
|
||||
// LINENUMBERS
|
||||
// test.kt:7 stringSwitch
|
||||
// test.kt:4 stringSwitch
|
||||
// test.kt:11 stringSwitch
|
||||
// test.kt:14 stringSwitch
|
||||
// test.kt:11 stringSwitch
|
||||
// test.kt:19 stringSwitch
|
||||
// LINENUMBERS JVM_IR
|
||||
// test.kt:18 stringSwitch
|
||||
// LINENUMBERS
|
||||
// test.kt:23 stringSwitch
|
||||
// test.kt:18 stringSwitch
|
||||
// test.kt:26 stringSwitch
|
||||
// test.kt:32 box
|
||||
// test.kt:4 stringSwitch
|
||||
// LINENUMBERS JVM
|
||||
// test.kt:5 stringSwitch
|
||||
// test.kt:6 stringSwitch
|
||||
// test.kt:7 stringSwitch
|
||||
// LINENUMBERS
|
||||
// test.kt:8 stringSwitch
|
||||
// test.kt:4 stringSwitch
|
||||
// test.kt:11 stringSwitch
|
||||
// test.kt:15 stringSwitch
|
||||
// test.kt:11 stringSwitch
|
||||
// test.kt:19 stringSwitch
|
||||
// LINENUMBERS JVM_IR
|
||||
// test.kt:18 stringSwitch
|
||||
// LINENUMBERS
|
||||
// test.kt:24 stringSwitch
|
||||
// test.kt:18 stringSwitch
|
||||
// test.kt:26 stringSwitch
|
||||
// test.kt:33 box
|
||||
@@ -0,0 +1,96 @@
|
||||
// FILE: test.kt
|
||||
|
||||
fun stringSwitch(x: String) {
|
||||
val l = when {
|
||||
x == "x" -> 1
|
||||
x == "xy" -> 2
|
||||
else -> -1
|
||||
}
|
||||
|
||||
val l2 = when (x) {
|
||||
"x" -> 1
|
||||
"xy" -> 2
|
||||
else -> -1
|
||||
}
|
||||
|
||||
val l3 = when
|
||||
(x)
|
||||
{
|
||||
"x" -> 1
|
||||
"xy" -> 2
|
||||
else -> -1
|
||||
}
|
||||
}
|
||||
|
||||
fun box() {
|
||||
stringSwitch("x")
|
||||
stringSwitch("xy")
|
||||
stringSwitch("nope")
|
||||
}
|
||||
|
||||
// JVM_IR uses the line number of the start of the `when` as the line number
|
||||
// for the lookup/table switch. Therefore when the subject and the when is
|
||||
// on separate lines the first step is on the subject, then steop to the when,
|
||||
// then to the right branch.
|
||||
|
||||
// JVM_IR uses unoptimized lookup/table switches for all these cases. JVM
|
||||
// does not. So on JVM there are direct jumps to the right branch for the
|
||||
// last two whens.
|
||||
|
||||
// LINENUMBERS
|
||||
// test.kt:26 box
|
||||
// test.kt:4 stringSwitch
|
||||
// test.kt:5 stringSwitch
|
||||
// test.kt:4 stringSwitch
|
||||
// test.kt:10 stringSwitch
|
||||
// test.kt:11 stringSwitch
|
||||
// test.kt:10 stringSwitch
|
||||
// test.kt:17 stringSwitch
|
||||
// LINENUMBERS JVM_IR
|
||||
// test.kt:16 stringSwitch
|
||||
// LINENUMBERS
|
||||
// test.kt:19 stringSwitch
|
||||
// test.kt:16 stringSwitch
|
||||
// test.kt:23 stringSwitch
|
||||
// test.kt:27 box
|
||||
// test.kt:4 stringSwitch
|
||||
// test.kt:5 stringSwitch
|
||||
// test.kt:6 stringSwitch
|
||||
// test.kt:4 stringSwitch
|
||||
// test.kt:10 stringSwitch
|
||||
// LINENUMBERS JVM_IR
|
||||
// test.kt:11 stringSwitch
|
||||
// LINENUMBERS
|
||||
// test.kt:12 stringSwitch
|
||||
// test.kt:10 stringSwitch
|
||||
// test.kt:17 stringSwitch
|
||||
// LINENUMBERS JVM_IR
|
||||
// test.kt:16 stringSwitch
|
||||
// test.kt:19 stringSwitch
|
||||
// LINENUMBERS
|
||||
// test.kt:20 stringSwitch
|
||||
// test.kt:16 stringSwitch
|
||||
// test.kt:23 stringSwitch
|
||||
// test.kt:28 box
|
||||
// test.kt:4 stringSwitch
|
||||
// test.kt:5 stringSwitch
|
||||
// test.kt:6 stringSwitch
|
||||
// test.kt:7 stringSwitch
|
||||
// test.kt:4 stringSwitch
|
||||
// test.kt:10 stringSwitch
|
||||
// LINENUMBERS JVM_IR
|
||||
// test.kt:11 stringSwitch
|
||||
// test.kt:12 stringSwitch
|
||||
// LINENUMBERS
|
||||
// test.kt:13 stringSwitch
|
||||
// test.kt:10 stringSwitch
|
||||
// test.kt:17 stringSwitch
|
||||
// LINENUMBERS JVM_IR
|
||||
// test.kt:16 stringSwitch
|
||||
// test.kt:19 stringSwitch
|
||||
// test.kt:20 stringSwitch
|
||||
// LINENUMBERS
|
||||
// test.kt:21 stringSwitch
|
||||
// test.kt:16 stringSwitch
|
||||
// test.kt:23 stringSwitch
|
||||
// test.kt:29 box
|
||||
+26
-22
@@ -8,34 +8,38 @@ interface A {
|
||||
}
|
||||
}
|
||||
|
||||
class B : A
|
||||
|
||||
fun box() {
|
||||
(object : A {}).bar()
|
||||
B().bar()
|
||||
}
|
||||
|
||||
// The JVM backend generates non-synthetic overrides of foo and bar
|
||||
// in the object both with line number 12. That means that there will
|
||||
// be steps on line number 12 on entry and exit to both bar and foo.
|
||||
|
||||
// TODO: Is this what we want? Should they be marked as bridges instead?
|
||||
// Doesn't look like the intellij debugger skips non-synthetic bridges?
|
||||
// There seems to be some heuristics in intellij dealing with this as
|
||||
// the stepping behavior with repeated step-into is mostly OK.
|
||||
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
// The JVM_IR backend generates non-synthetic overrides of foo and bar
|
||||
// with no line numbers. That leads to steps on line -1 but only on
|
||||
// exit from bar and foo.
|
||||
// The dispatch methods added to classes directly implementing
|
||||
// interfaces with default methods (forwarding to the actual implementation
|
||||
// on A$DefaultImpls) have the line number of the class declaration.
|
||||
|
||||
// LINENUMBERS
|
||||
// test.kt:12 box
|
||||
// test.kt:12 <init>
|
||||
// test.kt:12 box
|
||||
// test.kt:12 bar
|
||||
// test.kt:14 box
|
||||
// test.kt:14 <init>
|
||||
// test.kt:14 box
|
||||
// test.kt:14 bar
|
||||
// test.kt:7 bar
|
||||
// test.kt:12 foo
|
||||
// test.kt:14 foo
|
||||
// test.kt:4 foo
|
||||
// test.kt:12 foo
|
||||
// test.kt:14 foo
|
||||
// test.kt:7 bar
|
||||
// test.kt:12 bar
|
||||
// test.kt:12 box
|
||||
// test.kt:13 box
|
||||
// test.kt:14 bar
|
||||
// test.kt:14 box
|
||||
// test.kt:15 box
|
||||
// test.kt:11 <init>
|
||||
// test.kt:15 box
|
||||
// test.kt:11 bar
|
||||
// test.kt:7 bar
|
||||
// test.kt:11 foo
|
||||
// test.kt:4 foo
|
||||
// test.kt:11 foo
|
||||
// test.kt:7 bar
|
||||
// test.kt:11 bar
|
||||
// test.kt:15 box
|
||||
// test.kt:16 box
|
||||
+29
-7
@@ -18,41 +18,51 @@ fun box() {
|
||||
foo(21)
|
||||
}
|
||||
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
|
||||
// The JVM_IR backend has line number 8 when leaving the first
|
||||
// when. Also, the stepping is different, probably because the when
|
||||
// is compiled to a switch which it isn't with JVM? The stepping
|
||||
// behavior is likely OK, but should be double checked.
|
||||
// JVM_IR backend optimized the when to a switch in the java bytecode.
|
||||
// Therefore, the stepping for JVM_IR does not step through the evaluation
|
||||
// of each of the conditions, but goes directly to the right body. The
|
||||
// JVM_IR stepping behavior here is the same as for `whenSubject.kt`.
|
||||
|
||||
// LINENUMBERS
|
||||
// test.kt:18 box
|
||||
// test.kt:4 foo
|
||||
// test.kt:5 foo
|
||||
// test.kt:4 foo
|
||||
// LINENUMBERS JVM
|
||||
// test.kt:5 foo
|
||||
// LINENUMBERS
|
||||
// test.kt:6 foo
|
||||
// test.kt:4 foo
|
||||
// LINENUMBERS JVM
|
||||
// test.kt:5 foo
|
||||
// test.kt:6 foo
|
||||
// LINENUMBERS
|
||||
// test.kt:7 foo
|
||||
// test.kt:10 foo
|
||||
// LINENUMBERS JVM
|
||||
// test.kt:11 foo
|
||||
// test.kt:12 foo
|
||||
// LINENUMBERS
|
||||
// test.kt:13 foo
|
||||
// test.kt:10 foo
|
||||
// test.kt:15 foo
|
||||
// test.kt:6 foo
|
||||
// test.kt:10 foo
|
||||
// LINENUMBERS JVM
|
||||
// test.kt:11 foo
|
||||
// LINENUMBERS
|
||||
// test.kt:12 foo
|
||||
// test.kt:4 foo
|
||||
// LINENUMBERS JVM
|
||||
// test.kt:5 foo
|
||||
// test.kt:6 foo
|
||||
// LINENUMBERS
|
||||
// test.kt:7 foo
|
||||
// test.kt:10 foo
|
||||
// LINENUMBERS JVM
|
||||
// test.kt:11 foo
|
||||
// test.kt:12 foo
|
||||
// LINENUMBERS
|
||||
// test.kt:13 foo
|
||||
// test.kt:10 foo
|
||||
// test.kt:15 foo
|
||||
@@ -63,29 +73,41 @@ fun box() {
|
||||
// test.kt:10 foo
|
||||
// test.kt:11 foo
|
||||
// test.kt:4 foo
|
||||
// LINENUMBERS JVM
|
||||
// test.kt:5 foo
|
||||
// LINENUMBERS
|
||||
// test.kt:6 foo
|
||||
// test.kt:4 foo
|
||||
// LINENUMBERS JVM
|
||||
// test.kt:5 foo
|
||||
// test.kt:6 foo
|
||||
// LINENUMBERS
|
||||
// test.kt:7 foo
|
||||
// test.kt:10 foo
|
||||
// LINENUMBERS JVM
|
||||
// test.kt:11 foo
|
||||
// test.kt:12 foo
|
||||
// LINENUMBERS
|
||||
// test.kt:13 foo
|
||||
// test.kt:10 foo
|
||||
// test.kt:15 foo
|
||||
// test.kt:6 foo
|
||||
// test.kt:10 foo
|
||||
// LINENUMBERS JVM
|
||||
// test.kt:11 foo
|
||||
// LINENUMBERS
|
||||
// test.kt:12 foo
|
||||
// test.kt:4 foo
|
||||
// LINENUMBERS JVM
|
||||
// test.kt:5 foo
|
||||
// test.kt:6 foo
|
||||
// LINENUMBERS
|
||||
// test.kt:7 foo
|
||||
// test.kt:10 foo
|
||||
// LINENUMBERS JVM
|
||||
// test.kt:11 foo
|
||||
// test.kt:12 foo
|
||||
// LINENUMBERS
|
||||
// test.kt:13 foo
|
||||
// test.kt:10 foo
|
||||
// test.kt:15 foo
|
||||
@@ -95,4 +117,4 @@ fun box() {
|
||||
// test.kt:11 foo
|
||||
// test.kt:10 foo
|
||||
// test.kt:15 foo
|
||||
// test.kt:19 box
|
||||
// test.kt:19 box
|
||||
@@ -0,0 +1,49 @@
|
||||
// FILE: test.kt
|
||||
|
||||
fun foo(x: Int) {
|
||||
when (val y =
|
||||
when {
|
||||
x == 0 -> 1
|
||||
x == 1 -> 2
|
||||
else -> 0
|
||||
}) {
|
||||
0 -> 3
|
||||
1 -> 4
|
||||
}
|
||||
}
|
||||
|
||||
fun box() {
|
||||
foo(0)
|
||||
foo(1)
|
||||
foo(2)
|
||||
}
|
||||
|
||||
// The JVM_IR backend optimizes the inner when to a switch and therefore goes directly to the
|
||||
// right case without stepping through evaluation of each condition.
|
||||
|
||||
// LINENUMBERS
|
||||
// test.kt:16 box
|
||||
// test.kt:5 foo
|
||||
// test.kt:6 foo
|
||||
// test.kt:4 foo
|
||||
// test.kt:11 foo
|
||||
// test.kt:13 foo
|
||||
// test.kt:17 box
|
||||
// test.kt:5 foo
|
||||
// LINENUMBERS JVM
|
||||
// test.kt:6 foo
|
||||
// LINENUMBERS
|
||||
// test.kt:7 foo
|
||||
// test.kt:4 foo
|
||||
// test.kt:13 foo
|
||||
// test.kt:18 box
|
||||
// test.kt:5 foo
|
||||
// LINENUMBERS JVM
|
||||
// test.kt:6 foo
|
||||
// test.kt:7 foo
|
||||
// LINENUMBERS
|
||||
// test.kt:8 foo
|
||||
// test.kt:4 foo
|
||||
// test.kt:10 foo
|
||||
// test.kt:13 foo
|
||||
// test.kt:19 box
|
||||
@@ -0,0 +1,83 @@
|
||||
// FILE: test.kt
|
||||
|
||||
fun foo(x: Int): Int {
|
||||
when {
|
||||
x == 21 ->
|
||||
1
|
||||
x == 42 ->
|
||||
2
|
||||
else ->
|
||||
3
|
||||
}
|
||||
|
||||
val t = when {
|
||||
x == 21 ->
|
||||
1
|
||||
x == 42 ->
|
||||
2
|
||||
else ->
|
||||
3
|
||||
}
|
||||
|
||||
return t
|
||||
}
|
||||
|
||||
fun box() {
|
||||
foo(21)
|
||||
foo(42)
|
||||
foo(63)
|
||||
}
|
||||
|
||||
// JVM_IR backend optimized the when to a switch in the java bytecode.
|
||||
// Therefore, the stepping for JVM_IR does not step through the evaluation
|
||||
// of each of the conditions, but goes directly to the right body.
|
||||
// JVM_IR stepping behavior here is the same as for `whenMultiLineSubject.kt`.
|
||||
|
||||
// LINENUMBERS
|
||||
// test.kt:26 box
|
||||
// test.kt:4 foo
|
||||
// LINENUMBERS JVM
|
||||
// test.kt:5 foo
|
||||
// LINENUMBERS
|
||||
// test.kt:6 foo
|
||||
// test.kt:13 foo
|
||||
// LINENUMBERS JVM
|
||||
// test.kt:14 foo
|
||||
// LINENUMBERS
|
||||
// test.kt:15 foo
|
||||
// test.kt:13 foo
|
||||
// test.kt:22 foo
|
||||
// test.kt:26 box
|
||||
// test.kt:27 box
|
||||
// test.kt:4 foo
|
||||
// LINENUMBERS JVM
|
||||
// test.kt:5 foo
|
||||
// test.kt:7 foo
|
||||
// LINENUMBERS
|
||||
// test.kt:8 foo
|
||||
// test.kt:13 foo
|
||||
// LINENUMBERS JVM
|
||||
// test.kt:14 foo
|
||||
// test.kt:16 foo
|
||||
// LINENUMBERS
|
||||
// test.kt:17 foo
|
||||
// test.kt:13 foo
|
||||
// test.kt:22 foo
|
||||
// test.kt:27 box
|
||||
// test.kt:28 box
|
||||
// test.kt:4 foo
|
||||
// LINENUMBERS JVM
|
||||
// test.kt:5 foo
|
||||
// test.kt:7 foo
|
||||
// LINENUMBERS
|
||||
// test.kt:10 foo
|
||||
// test.kt:13 foo
|
||||
// LINENUMBERS JVM
|
||||
// test.kt:14 foo
|
||||
// test.kt:16 foo
|
||||
// LINENUMBERS
|
||||
// test.kt:19 foo
|
||||
// test.kt:13 foo
|
||||
// test.kt:22 foo
|
||||
// test.kt:28 box
|
||||
// test.kt:29 box
|
||||
@@ -0,0 +1,56 @@
|
||||
// FILE: test.kt
|
||||
|
||||
fun foo(x: Int): Int {
|
||||
when (x) {
|
||||
21 ->
|
||||
1
|
||||
42 ->
|
||||
2
|
||||
else ->
|
||||
3
|
||||
}
|
||||
|
||||
val t = when (x) {
|
||||
21 ->
|
||||
1
|
||||
42 ->
|
||||
2
|
||||
else ->
|
||||
3
|
||||
}
|
||||
|
||||
return t
|
||||
}
|
||||
|
||||
fun box() {
|
||||
foo(21)
|
||||
foo(42)
|
||||
foo(63)
|
||||
}
|
||||
|
||||
// LINENUMBERS
|
||||
// test.kt:26 box
|
||||
// test.kt:4 foo
|
||||
// test.kt:6 foo
|
||||
// test.kt:13 foo
|
||||
// test.kt:15 foo
|
||||
// test.kt:13 foo
|
||||
// test.kt:22 foo
|
||||
// test.kt:26 box
|
||||
// test.kt:27 box
|
||||
// test.kt:4 foo
|
||||
// test.kt:8 foo
|
||||
// test.kt:13 foo
|
||||
// test.kt:17 foo
|
||||
// test.kt:13 foo
|
||||
// test.kt:22 foo
|
||||
// test.kt:27 box
|
||||
// test.kt:28 box
|
||||
// test.kt:4 foo
|
||||
// test.kt:10 foo
|
||||
// test.kt:13 foo
|
||||
// test.kt:19 foo
|
||||
// test.kt:13 foo
|
||||
// test.kt:22 foo
|
||||
// test.kt:28 box
|
||||
// test.kt:29 box
|
||||
-23
@@ -18,8 +18,6 @@ fun box() {
|
||||
foo(21)
|
||||
}
|
||||
|
||||
// JVM_IR stops on line 8 when exiting the first when.
|
||||
|
||||
// LINENUMBERS
|
||||
// test.kt:18 box
|
||||
// test.kt:4 foo
|
||||
@@ -28,24 +26,15 @@ fun box() {
|
||||
// test.kt:6 foo
|
||||
// test.kt:4 foo
|
||||
// test.kt:7 foo
|
||||
// LINENUMBERS JVM_IR
|
||||
// test.kt:8 foo
|
||||
// LINENUMBERS
|
||||
// test.kt:10 foo
|
||||
// test.kt:13 foo
|
||||
// test.kt:10 foo
|
||||
// test.kt:15 foo
|
||||
// test.kt:6 foo
|
||||
// LINENUMBERS JVM_IR
|
||||
// test.kt:8 foo
|
||||
// LINENUMBERS
|
||||
// test.kt:10 foo
|
||||
// test.kt:12 foo
|
||||
// test.kt:4 foo
|
||||
// test.kt:7 foo
|
||||
// LINENUMBERS JVM_IR
|
||||
// test.kt:8 foo
|
||||
// LINENUMBERS
|
||||
// test.kt:10 foo
|
||||
// test.kt:13 foo
|
||||
// test.kt:10 foo
|
||||
@@ -54,33 +43,21 @@ fun box() {
|
||||
// test.kt:10 foo
|
||||
// test.kt:15 foo
|
||||
// test.kt:5 foo
|
||||
// LINENUMBERS JVM_IR
|
||||
// test.kt:8 foo
|
||||
// LINENUMBERS
|
||||
// test.kt:10 foo
|
||||
// test.kt:11 foo
|
||||
// test.kt:4 foo
|
||||
// test.kt:6 foo
|
||||
// test.kt:4 foo
|
||||
// test.kt:7 foo
|
||||
// LINENUMBERS JVM_IR
|
||||
// test.kt:8 foo
|
||||
// LINENUMBERS
|
||||
// test.kt:10 foo
|
||||
// test.kt:13 foo
|
||||
// test.kt:10 foo
|
||||
// test.kt:15 foo
|
||||
// test.kt:6 foo
|
||||
// LINENUMBERS JVM_IR
|
||||
// test.kt:8 foo
|
||||
// LINENUMBERS
|
||||
// test.kt:10 foo
|
||||
// test.kt:12 foo
|
||||
// test.kt:4 foo
|
||||
// test.kt:7 foo
|
||||
// LINENUMBERS JVM_IR
|
||||
// test.kt:8 foo
|
||||
// LINENUMBERS
|
||||
// test.kt:10 foo
|
||||
// test.kt:13 foo
|
||||
// test.kt:10 foo
|
||||
|
||||
+121
@@ -0,0 +1,121 @@
|
||||
// FILE: test.kt
|
||||
|
||||
fun foo(x: Int) {
|
||||
when
|
||||
(x)
|
||||
{
|
||||
21 -> foo(42)
|
||||
42 -> foo(63)
|
||||
else -> 1
|
||||
}
|
||||
|
||||
val t = when
|
||||
(x)
|
||||
{
|
||||
21 -> foo(42)
|
||||
42 -> foo(63)
|
||||
else -> 2
|
||||
}
|
||||
}
|
||||
|
||||
fun box() {
|
||||
foo(21)
|
||||
}
|
||||
|
||||
// JVM_IR uses the line number of the when for the table switch and therefore,
|
||||
// it stops on the subject line first, then on the when line (line 4 and 12), and
|
||||
// then goes to the right branch.
|
||||
|
||||
// LINENUMBERS
|
||||
// test.kt:22 box
|
||||
// test.kt:5 foo
|
||||
// LINENUMBERS JVM_IR
|
||||
// test.kt:4 foo
|
||||
// LINENUMBERS
|
||||
// test.kt:7 foo
|
||||
// test.kt:5 foo
|
||||
// LINENUMBERS JVM_IR
|
||||
// test.kt:4 foo
|
||||
// LINENUMBERS
|
||||
// test.kt:8 foo
|
||||
// test.kt:5 foo
|
||||
// LINENUMBERS JVM_IR
|
||||
// test.kt:4 foo
|
||||
// LINENUMBERS
|
||||
// test.kt:9 foo
|
||||
// test.kt:13 foo
|
||||
// LINENUMBERS JVM_IR
|
||||
// test.kt:12 foo
|
||||
// LINENUMBERS
|
||||
// test.kt:17 foo
|
||||
// test.kt:12 foo
|
||||
// test.kt:19 foo
|
||||
// test.kt:8 foo
|
||||
// test.kt:13 foo
|
||||
// LINENUMBERS JVM_IR
|
||||
// test.kt:12 foo
|
||||
// LINENUMBERS
|
||||
// test.kt:16 foo
|
||||
// test.kt:5 foo
|
||||
// LINENUMBERS JVM_IR
|
||||
// test.kt:4 foo
|
||||
// LINENUMBERS
|
||||
// test.kt:9 foo
|
||||
// test.kt:13 foo
|
||||
// LINENUMBERS JVM_IR
|
||||
// test.kt:12 foo
|
||||
// LINENUMBERS
|
||||
// test.kt:17 foo
|
||||
// test.kt:12 foo
|
||||
// test.kt:19 foo
|
||||
// test.kt:16 foo
|
||||
// test.kt:12 foo
|
||||
// test.kt:19 foo
|
||||
// test.kt:7 foo
|
||||
// test.kt:13 foo
|
||||
// LINENUMBERS JVM_IR
|
||||
// test.kt:12 foo
|
||||
// LINENUMBERS
|
||||
// test.kt:15 foo
|
||||
// test.kt:5 foo
|
||||
// LINENUMBERS JVM_IR
|
||||
// test.kt:4 foo
|
||||
// LINENUMBERS
|
||||
// test.kt:8 foo
|
||||
// test.kt:5 foo
|
||||
// LINENUMBERS JVM_IR
|
||||
// test.kt:4 foo
|
||||
// LINENUMBERS
|
||||
// test.kt:9 foo
|
||||
// test.kt:13 foo
|
||||
// LINENUMBERS JVM_IR
|
||||
// test.kt:12 foo
|
||||
// LINENUMBERS
|
||||
// test.kt:17 foo
|
||||
// test.kt:12 foo
|
||||
// test.kt:19 foo
|
||||
// test.kt:8 foo
|
||||
// test.kt:13 foo
|
||||
// LINENUMBERS JVM_IR
|
||||
// test.kt:12 foo
|
||||
// LINENUMBERS
|
||||
// test.kt:16 foo
|
||||
// test.kt:5 foo
|
||||
// LINENUMBERS JVM_IR
|
||||
// test.kt:4 foo
|
||||
// LINENUMBERS
|
||||
// test.kt:9 foo
|
||||
// test.kt:13 foo
|
||||
// LINENUMBERS JVM_IR
|
||||
// test.kt:12 foo
|
||||
// LINENUMBERS
|
||||
// test.kt:17 foo
|
||||
// test.kt:12 foo
|
||||
// test.kt:19 foo
|
||||
// test.kt:16 foo
|
||||
// test.kt:12 foo
|
||||
// test.kt:19 foo
|
||||
// test.kt:15 foo
|
||||
// test.kt:12 foo
|
||||
// test.kt:19 foo
|
||||
// test.kt:23 box
|
||||
+1
-1
@@ -85,7 +85,7 @@ abstract class AbstractSteppingTest : AbstractDebugTest() {
|
||||
LINENUMBERS_MARKER -> TargetBackend.ANY
|
||||
JVM_LINENUMBER_MARKER -> TargetBackend.JVM
|
||||
JVM_IR_LINENUMBER_MARKER -> TargetBackend.JVM_IR
|
||||
else -> error("Expected JVM backend")
|
||||
else -> error("Expected JVM backend: $line")
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
+36
@@ -349,6 +349,18 @@ public class IrSteppingTestGenerated extends AbstractIrSteppingTest {
|
||||
runTest("compiler/testData/debug/stepping/smapInlineInIntrinsicArgument.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("stringSwitches.kt")
|
||||
public void testStringSwitches() throws Exception {
|
||||
runTest("compiler/testData/debug/stepping/stringSwitches.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("stringSwitchesSmall.kt")
|
||||
public void testStringSwitchesSmall() throws Exception {
|
||||
runTest("compiler/testData/debug/stepping/stringSwitchesSmall.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("throwException.kt")
|
||||
public void testThrowException() throws Exception {
|
||||
@@ -409,12 +421,36 @@ public class IrSteppingTestGenerated extends AbstractIrSteppingTest {
|
||||
runTest("compiler/testData/debug/stepping/when.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("whenComplicatedSubject.kt")
|
||||
public void testWhenComplicatedSubject() throws Exception {
|
||||
runTest("compiler/testData/debug/stepping/whenComplicatedSubject.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("whenMultiLine.kt")
|
||||
public void testWhenMultiLine() throws Exception {
|
||||
runTest("compiler/testData/debug/stepping/whenMultiLine.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("whenMultiLineSubject.kt")
|
||||
public void testWhenMultiLineSubject() throws Exception {
|
||||
runTest("compiler/testData/debug/stepping/whenMultiLineSubject.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("whenSubject.kt")
|
||||
public void testWhenSubject() throws Exception {
|
||||
runTest("compiler/testData/debug/stepping/whenSubject.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("whenSubject2.kt")
|
||||
public void testWhenSubject2() throws Exception {
|
||||
runTest("compiler/testData/debug/stepping/whenSubject2.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("while.kt")
|
||||
public void testWhile() throws Exception {
|
||||
|
||||
+36
@@ -349,6 +349,18 @@ public class SteppingTestGenerated extends AbstractSteppingTest {
|
||||
runTest("compiler/testData/debug/stepping/smapInlineInIntrinsicArgument.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("stringSwitches.kt")
|
||||
public void testStringSwitches() throws Exception {
|
||||
runTest("compiler/testData/debug/stepping/stringSwitches.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("stringSwitchesSmall.kt")
|
||||
public void testStringSwitchesSmall() throws Exception {
|
||||
runTest("compiler/testData/debug/stepping/stringSwitchesSmall.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("throwException.kt")
|
||||
public void testThrowException() throws Exception {
|
||||
@@ -409,12 +421,36 @@ public class SteppingTestGenerated extends AbstractSteppingTest {
|
||||
runTest("compiler/testData/debug/stepping/when.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("whenComplicatedSubject.kt")
|
||||
public void testWhenComplicatedSubject() throws Exception {
|
||||
runTest("compiler/testData/debug/stepping/whenComplicatedSubject.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("whenMultiLine.kt")
|
||||
public void testWhenMultiLine() throws Exception {
|
||||
runTest("compiler/testData/debug/stepping/whenMultiLine.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("whenMultiLineSubject.kt")
|
||||
public void testWhenMultiLineSubject() throws Exception {
|
||||
runTest("compiler/testData/debug/stepping/whenMultiLineSubject.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("whenSubject.kt")
|
||||
public void testWhenSubject() throws Exception {
|
||||
runTest("compiler/testData/debug/stepping/whenSubject.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("whenSubject2.kt")
|
||||
public void testWhenSubject2() throws Exception {
|
||||
runTest("compiler/testData/debug/stepping/whenSubject2.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("while.kt")
|
||||
public void testWhile() throws Exception {
|
||||
|
||||
+22
-45
@@ -113,8 +113,8 @@ public final class ListOfUsers$$serializer : java/lang/Object, kotlinx/serializa
|
||||
LABEL (L4)
|
||||
ICONST_0
|
||||
ISTORE (3)
|
||||
GOTO (L5)
|
||||
LABEL (L6)
|
||||
GOTO (L2)
|
||||
LABEL (L5)
|
||||
ALOAD (7)
|
||||
ALOAD (2)
|
||||
ICONST_0
|
||||
@@ -131,21 +131,16 @@ public final class ListOfUsers$$serializer : java/lang/Object, kotlinx/serializa
|
||||
ICONST_1
|
||||
IOR
|
||||
ISTORE (5)
|
||||
GOTO (L5)
|
||||
LABEL (L7)
|
||||
GOTO (L2)
|
||||
LABEL (L6)
|
||||
NEW
|
||||
DUP
|
||||
ILOAD (4)
|
||||
INVOKESPECIAL (kotlinx/serialization/UnknownFieldException, <init>, (I)V)
|
||||
ATHROW
|
||||
LABEL (L5)
|
||||
LINENUMBER (13)
|
||||
GOTO (L2)
|
||||
LABEL (L3)
|
||||
ALOAD (7)
|
||||
ALOAD (2)
|
||||
LABEL (L8)
|
||||
LINENUMBER (12)
|
||||
INVOKEINTERFACE (kotlinx/serialization/encoding/CompositeDecoder, endStructure, (Lkotlinx/serialization/descriptors/SerialDescriptor;)V)
|
||||
NEW
|
||||
DUP
|
||||
@@ -156,7 +151,7 @@ public final class ListOfUsers$$serializer : java/lang/Object, kotlinx/serializa
|
||||
CHECKCAST
|
||||
INVOKESPECIAL (ListOfUsers, <init>, (ILjava/util/List;Lkotlinx/serialization/internal/SerializationConstructorMarker;)V)
|
||||
ARETURN
|
||||
LABEL (L9)
|
||||
LABEL (L7)
|
||||
}
|
||||
|
||||
public java.lang.Object deserialize(kotlinx.serialization.encoding.Decoder decoder) {
|
||||
@@ -295,10 +290,8 @@ public final class ListOfUsers : java/lang/Object {
|
||||
ALOAD (0)
|
||||
ALOAD (2)
|
||||
PUTFIELD (list, Ljava/util/List;)
|
||||
LABEL (L2)
|
||||
LINENUMBER (13)
|
||||
RETURN
|
||||
LABEL (L3)
|
||||
LABEL (L2)
|
||||
}
|
||||
|
||||
public final java.util.List getList()
|
||||
@@ -411,8 +404,8 @@ public final class OptionalUser$$serializer : java/lang/Object, kotlinx/serializ
|
||||
LABEL (L4)
|
||||
ICONST_0
|
||||
ISTORE (3)
|
||||
GOTO (L5)
|
||||
LABEL (L6)
|
||||
GOTO (L2)
|
||||
LABEL (L5)
|
||||
ALOAD (7)
|
||||
ALOAD (2)
|
||||
ICONST_0
|
||||
@@ -425,21 +418,16 @@ public final class OptionalUser$$serializer : java/lang/Object, kotlinx/serializ
|
||||
ICONST_1
|
||||
IOR
|
||||
ISTORE (5)
|
||||
GOTO (L5)
|
||||
LABEL (L7)
|
||||
GOTO (L2)
|
||||
LABEL (L6)
|
||||
NEW
|
||||
DUP
|
||||
ILOAD (4)
|
||||
INVOKESPECIAL (kotlinx/serialization/UnknownFieldException, <init>, (I)V)
|
||||
ATHROW
|
||||
LABEL (L5)
|
||||
LINENUMBER (10)
|
||||
GOTO (L2)
|
||||
LABEL (L3)
|
||||
ALOAD (7)
|
||||
ALOAD (2)
|
||||
LABEL (L8)
|
||||
LINENUMBER (9)
|
||||
INVOKEINTERFACE (kotlinx/serialization/encoding/CompositeDecoder, endStructure, (Lkotlinx/serialization/descriptors/SerialDescriptor;)V)
|
||||
NEW
|
||||
DUP
|
||||
@@ -450,7 +438,7 @@ public final class OptionalUser$$serializer : java/lang/Object, kotlinx/serializ
|
||||
CHECKCAST
|
||||
INVOKESPECIAL (OptionalUser, <init>, (ILUser;Lkotlinx/serialization/internal/SerializationConstructorMarker;)V)
|
||||
ARETURN
|
||||
LABEL (L9)
|
||||
LABEL (L7)
|
||||
}
|
||||
|
||||
public java.lang.Object deserialize(kotlinx.serialization.encoding.Decoder decoder) {
|
||||
@@ -636,7 +624,6 @@ public final class OptionalUser : java/lang/Object {
|
||||
ALOAD (2)
|
||||
PUTFIELD (user, LUser;)
|
||||
LABEL (L4)
|
||||
LINENUMBER (10)
|
||||
RETURN
|
||||
LABEL (L5)
|
||||
}
|
||||
@@ -779,8 +766,8 @@ public final class User$$serializer : java/lang/Object, kotlinx/serialization/in
|
||||
LABEL (L4)
|
||||
ICONST_0
|
||||
ISTORE (3)
|
||||
GOTO (L5)
|
||||
LABEL (L6)
|
||||
GOTO (L2)
|
||||
LABEL (L5)
|
||||
ALOAD (8)
|
||||
ALOAD (2)
|
||||
ICONST_0
|
||||
@@ -790,8 +777,8 @@ public final class User$$serializer : java/lang/Object, kotlinx/serialization/in
|
||||
ICONST_1
|
||||
IOR
|
||||
ISTORE (5)
|
||||
GOTO (L5)
|
||||
LABEL (L7)
|
||||
GOTO (L2)
|
||||
LABEL (L6)
|
||||
ALOAD (8)
|
||||
ALOAD (2)
|
||||
ICONST_1
|
||||
@@ -801,21 +788,16 @@ public final class User$$serializer : java/lang/Object, kotlinx/serialization/in
|
||||
ICONST_2
|
||||
IOR
|
||||
ISTORE (5)
|
||||
GOTO (L5)
|
||||
LABEL (L8)
|
||||
GOTO (L2)
|
||||
LABEL (L7)
|
||||
NEW
|
||||
DUP
|
||||
ILOAD (4)
|
||||
INVOKESPECIAL (kotlinx/serialization/UnknownFieldException, <init>, (I)V)
|
||||
ATHROW
|
||||
LABEL (L5)
|
||||
LINENUMBER (7)
|
||||
GOTO (L2)
|
||||
LABEL (L3)
|
||||
ALOAD (8)
|
||||
ALOAD (2)
|
||||
LABEL (L9)
|
||||
LINENUMBER (6)
|
||||
INVOKEINTERFACE (kotlinx/serialization/encoding/CompositeDecoder, endStructure, (Lkotlinx/serialization/descriptors/SerialDescriptor;)V)
|
||||
NEW
|
||||
DUP
|
||||
@@ -826,7 +808,7 @@ public final class User$$serializer : java/lang/Object, kotlinx/serialization/in
|
||||
CHECKCAST
|
||||
INVOKESPECIAL (User, <init>, (ILjava/lang/String;Ljava/lang/String;Lkotlinx/serialization/internal/SerializationConstructorMarker;)V)
|
||||
ARETURN
|
||||
LABEL (L10)
|
||||
LABEL (L8)
|
||||
}
|
||||
|
||||
public java.lang.Object deserialize(kotlinx.serialization.encoding.Decoder decoder) {
|
||||
@@ -973,29 +955,24 @@ public final class User : java/lang/Object {
|
||||
ALOAD (0)
|
||||
ALOAD (2)
|
||||
PUTFIELD (firstName, Ljava/lang/String;)
|
||||
LABEL (L2)
|
||||
LINENUMBER (7)
|
||||
LINENUMBER (6)
|
||||
ILOAD (1)
|
||||
ICONST_2
|
||||
IAND
|
||||
IFNE (L3)
|
||||
IFNE (L2)
|
||||
NEW
|
||||
DUP
|
||||
LDC (lastName)
|
||||
INVOKESPECIAL (kotlinx/serialization/MissingFieldException, <init>, (Ljava/lang/String;)V)
|
||||
ATHROW
|
||||
LABEL (L3)
|
||||
LABEL (L2)
|
||||
ALOAD (0)
|
||||
ALOAD (3)
|
||||
PUTFIELD (lastName, Ljava/lang/String;)
|
||||
LABEL (L4)
|
||||
LINENUMBER (7)
|
||||
RETURN
|
||||
LABEL (L5)
|
||||
LABEL (L3)
|
||||
}
|
||||
|
||||
public final java.lang.String getFirstName()
|
||||
|
||||
public final java.lang.String getLastName()
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user