@@ -159,7 +159,7 @@ private val AbstractInsnNode.isBranchingInst
159159private val AbstractInsnNode .isTerminateInst
160160 get() = this is InsnNode && (this .opcode == Opcodes .ATHROW || this .opcode in Opcodes .IRETURN .. Opcodes .RETURN )
161161
162- private fun LabelNode .isBetween (labelStart : LabelNode , labelEnd : LabelNode ): Boolean {
162+ private fun AbstractInsnNode .isBetween (labelStart : AbstractInsnNode , labelEnd : AbstractInsnNode ): Boolean {
163163 var curNode: AbstractInsnNode ? = this
164164 var left = false
165165 var right = false
@@ -415,7 +415,7 @@ class RawInstListBuilder(
415415 override : Boolean = false
416416 ): JcRawAssignInst ? {
417417 val oldVar = currentFrame.locals[variable]?.let {
418- if (expr.typeName.isPrimitive.xor(it.typeName.isPrimitive)) {
418+ if (expr.typeName.isPrimitive.xor(it.typeName.isPrimitive) && it.typeName.typeName != PredefinedPrimitives . Null ) {
419419 null
420420 } else {
421421 it
@@ -872,7 +872,10 @@ class RawInstListBuilder(
872872 * if some predecessor frames are unknown, we remember them and add required assignment instructions after
873873 * the full construction process is complete, see #buildRequiredAssignments function
874874 */
875- private fun SortedMap <Int , TypeName >.copyLocals (predFrames : Map <AbstractInsnNode , Frame ?>): Map <Int , JcRawValue > =
875+ private fun SortedMap <Int , TypeName >.copyLocals (
876+ predFrames : Map <AbstractInsnNode , Frame ?>,
877+ curLabel : LabelNode
878+ ): Map <Int , JcRawValue > =
876879 when {
877880 // should not happen usually, but sometimes there are some "handing" blocks in the bytecode that are
878881 // not connected to any other part of the code
@@ -912,10 +915,22 @@ class RawInstListBuilder(
912915 // complex case --- we have a multiple predecessor frames and some of them may be unknown
913916 else -> mapNotNull { (variable, type) ->
914917 val options = predFrames.values.map { it?.get(variable) }.toSet()
918+ val actualLocalFromDebugInfo =
919+ methodNode.localVariables
920+ .filter { it.index == variable }
921+ .firstOrNull { curLabel.isBetween(it.start, it.end) }
922+ val isArg =
923+ if (actualLocalFromDebugInfo == null ) {
924+ variable < argCounter
925+ }
926+ else {
927+ actualLocalFromDebugInfo.start == methodNode.instructions.firstOrNull { it is LabelNode }
928+ }
929+
915930 val value = when {
916931 type == TOP -> null
917932 options.size == 1 -> options.singleOrNull()
918- variable < argCounter -> frames.values.mapNotNull { it[variable] }.firstOrNull {
933+ variable < argCounter && isArg -> frames.values.mapNotNull { it[variable] }.firstOrNull {
919934 it is JcRawArgument || it is JcRawThis
920935 }
921936
@@ -1033,12 +1048,12 @@ class RawInstListBuilder(
10331048
10341049 if (catchEntries.isEmpty()) {
10351050 currentFrame = Frame (
1036- lastFrameState.locals.copyLocals(predecessorFrames).toPersistentMap(),
1051+ lastFrameState.locals.copyLocals(predecessorFrames, currentEntry ).toPersistentMap(),
10371052 lastFrameState.stack.copyStack(predecessorFrames).toPersistentList()
10381053 )
10391054 } else {
10401055 currentFrame = Frame (
1041- lastFrameState.locals.copyLocals(predecessorFrames).toPersistentMap(),
1056+ lastFrameState.locals.copyLocals(predecessorFrames, currentEntry ).toPersistentMap(),
10421057 persistentListOf()
10431058 )
10441059
@@ -1226,7 +1241,7 @@ class RawInstListBuilder(
12261241 }
12271242 }
12281243 .toSortedMap()
1229- val newLocals = localTypes.copyLocals(frames).toPersistentMap()
1244+ val newLocals = localTypes.copyLocals(frames, curLabel ).toPersistentMap()
12301245
12311246 val stackIndices = frameSet.flatMap { it.stack.indices }.toSortedSet()
12321247 val stackRanges = stackIndices
@@ -1248,7 +1263,7 @@ class RawInstListBuilder(
12481263 val predecessorFrames = predecessors.mapNotNull { frames[it] }
12491264 if (predecessorFrames.size == 1 ) {
12501265 currentFrame = predecessorFrames.first()
1251- } else if (predecessors.size == predecessorFrames.size) {
1266+ } else {
12521267 currentFrame = mergeFrames(predecessors.zip(predecessorFrames).toMap(), insnNode)
12531268 }
12541269 val catchEntries = methodNode.tryCatchBlocks.filter { it.handler == insnNode }
0 commit comments