JVM represent uninitialized values explicitly in stack normalization

This commit is contained in:
Dmitry Petrov
2021-07-20 08:02:34 +03:00
committed by teamcityserver
parent bb202318ee
commit 91afa3335c
3 changed files with 9 additions and 7 deletions
@@ -19,7 +19,6 @@ package org.jetbrains.kotlin.codegen.optimization.fixStack
import com.intellij.util.containers.Stack import com.intellij.util.containers.Stack
import org.jetbrains.kotlin.codegen.inline.isAfterInlineMarker import org.jetbrains.kotlin.codegen.inline.isAfterInlineMarker
import org.jetbrains.kotlin.codegen.inline.isBeforeInlineMarker import org.jetbrains.kotlin.codegen.inline.isBeforeInlineMarker
import org.jetbrains.kotlin.codegen.inline.isMarkedReturn
import org.jetbrains.kotlin.codegen.pseudoInsns.PseudoInsn import org.jetbrains.kotlin.codegen.pseudoInsns.PseudoInsn
import org.jetbrains.kotlin.utils.SmartList import org.jetbrains.kotlin.utils.SmartList
import org.jetbrains.org.objectweb.asm.Opcodes import org.jetbrains.org.objectweb.asm.Opcodes
@@ -132,10 +131,8 @@ internal class FixStackAnalyzer(
executeBeforeInlineCallMarker(insn) executeBeforeInlineCallMarker(insn)
isAfterInlineMarker(insn) -> isAfterInlineMarker(insn) ->
executeAfterInlineCallMarker(insn) executeAfterInlineCallMarker(insn)
isMarkedReturn(insn) -> { insn.opcode == Opcodes.RETURN ->
// KT-9644: might throw "Incompatible return type" on non-local return, in fact we don't care. return
if (insn.opcode == Opcodes.RETURN) return
}
} }
super.execute(insn, interpreter) super.execute(insn, interpreter)
@@ -151,6 +148,9 @@ internal class FixStackAnalyzer(
} }
override fun push(value: FixStackValue) { override fun push(value: FixStackValue) {
if (value == FixStackValue.UNINITIALIZED) {
throw AnalyzerException(null, "Uninitialized value on stack")
}
if (super.getStackSize() < maxStackSize) { if (super.getStackSize() < maxStackSize) {
super.push(value) super.push(value)
} else { } else {
@@ -14,8 +14,9 @@ import org.jetbrains.org.objectweb.asm.tree.analysis.Interpreter
open class FixStackInterpreter : Interpreter<FixStackValue>(API_VERSION) { open class FixStackInterpreter : Interpreter<FixStackValue>(API_VERSION) {
override fun newValue(type: Type?): FixStackValue? = override fun newValue(type: Type?): FixStackValue =
type?.toFixStackValue() type?.toFixStackValue()
?: FixStackValue.UNINITIALIZED
override fun newOperation(insn: AbstractInsnNode): FixStackValue? = override fun newOperation(insn: AbstractInsnNode): FixStackValue? =
when (insn.opcode) { when (insn.opcode) {
@@ -19,7 +19,8 @@ enum class FixStackValue(
LONG(2, Opcodes.LLOAD, Opcodes.LSTORE, Opcodes.POP2), LONG(2, Opcodes.LLOAD, Opcodes.LSTORE, Opcodes.POP2),
FLOAT(1, Opcodes.FLOAD, Opcodes.FSTORE, Opcodes.POP), FLOAT(1, Opcodes.FLOAD, Opcodes.FSTORE, Opcodes.POP),
DOUBLE(2, Opcodes.DLOAD, Opcodes.DSTORE, Opcodes.POP2), DOUBLE(2, Opcodes.DLOAD, Opcodes.DSTORE, Opcodes.POP2),
OBJECT(1, Opcodes.ALOAD, Opcodes.ASTORE, Opcodes.POP) OBJECT(1, Opcodes.ALOAD, Opcodes.ASTORE, Opcodes.POP),
UNINITIALIZED(1, -1, -1, -1)
; ;
override fun getSize(): Int = _size override fun getSize(): Int = _size