Fix bytecode optimisations for consequent boxing
This commit is contained in:
+22
-5
@@ -69,6 +69,19 @@ open class BoxingInterpreter(
|
|||||||
|
|
||||||
return when {
|
return when {
|
||||||
insn.isBoxing(generationState) -> {
|
insn.isBoxing(generationState) -> {
|
||||||
|
/*
|
||||||
|
* It's possible to have chain of several boxings and it's important to retain these boxing methods, consider:
|
||||||
|
*
|
||||||
|
* inline class AsAny(val a: Any)
|
||||||
|
*
|
||||||
|
* fun takeAny(a: Any)
|
||||||
|
*
|
||||||
|
* fun foo() {
|
||||||
|
* takeAny(AsAny(42)) // valueOf -> AsAny$Erased.box
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* */
|
||||||
|
values.markBoxedArgumentValues()
|
||||||
createNewBoxing(insn, value.type, null)
|
createNewBoxing(insn, value.type, null)
|
||||||
}
|
}
|
||||||
insn.isUnboxing(generationState) && firstArg is BoxedBasicValue -> {
|
insn.isUnboxing(generationState) && firstArg is BoxedBasicValue -> {
|
||||||
@@ -94,16 +107,20 @@ open class BoxingInterpreter(
|
|||||||
// N-ary operation should be a method call or multinewarray.
|
// N-ary operation should be a method call or multinewarray.
|
||||||
// Arguments for multinewarray could be only numeric,
|
// Arguments for multinewarray could be only numeric,
|
||||||
// so if there are boxed values in args, it's not a case of multinewarray.
|
// so if there are boxed values in args, it's not a case of multinewarray.
|
||||||
for (arg in values) {
|
values.markBoxedArgumentValues()
|
||||||
if (arg is BoxedBasicValue) {
|
|
||||||
onMethodCallWithBoxedValue(arg)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
value
|
value
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun List<BasicValue>.markBoxedArgumentValues() {
|
||||||
|
for (arg in this) {
|
||||||
|
if (arg is BoxedBasicValue) {
|
||||||
|
onMethodCallWithBoxedValue(arg)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override fun unaryOperation(insn: AbstractInsnNode, value: BasicValue): BasicValue? {
|
override fun unaryOperation(insn: AbstractInsnNode, value: BasicValue): BasicValue? {
|
||||||
checkUsedValue(value)
|
checkUsedValue(value)
|
||||||
|
|
||||||
|
|||||||
Vendored
+3
-3
@@ -6,11 +6,11 @@ fun test() {
|
|||||||
val a = Result<Int>(1) // valueOf
|
val a = Result<Int>(1) // valueOf
|
||||||
val b = Result<String>("sample")
|
val b = Result<String>("sample")
|
||||||
|
|
||||||
val c = Result<Result<Int>>(a) // box
|
val c = Result<Result<Int>>(a)
|
||||||
val d = Result<Result<Int>>(Result<Int>(1)) // valueOf, box
|
val d = Result<Result<Int>>(Result<Int>(1)) // valueOf
|
||||||
}
|
}
|
||||||
|
|
||||||
// 2 INVOKESTATIC Result\$Erased.box
|
// 0 INVOKESTATIC Result\$Erased.box
|
||||||
// 0 INVOKEVIRTUAL Result.unbox
|
// 0 INVOKEVIRTUAL Result.unbox
|
||||||
|
|
||||||
// 2 valueOf
|
// 2 valueOf
|
||||||
|
|||||||
Reference in New Issue
Block a user