Generate CHECKCAST Object inside the markers
otherwise, the unboxing interferes with bytecode analysis.
This commit is contained in:
+5
-4
@@ -602,11 +602,12 @@ class CoroutineTransformerMethodVisitor(
|
||||
}
|
||||
|
||||
private fun dropUnboxInlineClassMarkers(methodNode: MethodNode, suspensionPoints: List<SuspensionPoint>) {
|
||||
for (marker in methodNode.instructions.asSequence()
|
||||
.filter { isBeforeUnboxInlineClassMarker(it) || isAfterUnboxInlineClassMarker(it) }.toList()
|
||||
) {
|
||||
for (marker in methodNode.instructions.asSequence().filter { isBeforeUnboxInlineClassMarker(it) }.toList()) {
|
||||
methodNode.instructions.removeAll(listOf(marker.previous, marker))
|
||||
}
|
||||
for (marker in methodNode.instructions.asSequence().filter { isAfterUnboxInlineClassMarker(it) }.toList()) {
|
||||
methodNode.instructions.removeAll(listOf(marker.previous.previous, marker.previous, marker))
|
||||
}
|
||||
for (suspension in suspensionPoints) {
|
||||
methodNode.instructions.removeAll(suspension.unboxInlineClassInstructions)
|
||||
}
|
||||
@@ -1142,7 +1143,7 @@ internal class SuspensionPoint(
|
||||
if (!isBeforeUnboxInlineClassMarker(beforeMarker)) return emptyList()
|
||||
val afterMarker = beforeMarker.findNextOrNull { isAfterUnboxInlineClassMarker(it) }
|
||||
?: error("Before unbox inline class marker without after unbox inline class marker")
|
||||
return InsnSequence(beforeMarker.next, afterMarker.previous).toList()
|
||||
return InsnSequence(beforeMarker.next, afterMarker.previous.previous).toList()
|
||||
}
|
||||
|
||||
operator fun contains(insn: AbstractInsnNode): Boolean {
|
||||
|
||||
@@ -416,6 +416,11 @@ internal fun addUnboxInlineClassMarkersIfNeeded(v: InstructionAdapter, descripto
|
||||
if (inlineClass != null) {
|
||||
addBeforeUnboxInlineClassMarker(v)
|
||||
StackValue.unboxInlineClass(AsmTypes.OBJECT_TYPE, inlineClass, v)
|
||||
// Suspend functions always returns Any?, but the unboxing disrupts type analysis of the bytecode.
|
||||
// For example, if the underlying type is String, CHECKCAST String is removed.
|
||||
// However, the unboxing is moved to the resume path, the direct path still has Any?, but now, without the CHECKCAST.
|
||||
// Thus, we add CHECKCAST Object, which we remove, after we copy the unboxing to the resume path.
|
||||
v.checkcast(AsmTypes.OBJECT_TYPE)
|
||||
addAfterUnboxInlineClassMarker(v)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user