Refine types returned by OptimizationBasicInterpreter.newValue
#KT-12958 Fixed
This commit is contained in:
+6
-4
@@ -50,6 +50,7 @@ public class OptimizationBasicInterpreter extends BasicInterpreter {
|
|||||||
case Type.SHORT:
|
case Type.SHORT:
|
||||||
return SHORT_VALUE;
|
return SHORT_VALUE;
|
||||||
case Type.OBJECT:
|
case Type.OBJECT:
|
||||||
|
case Type.ARRAY:
|
||||||
return new BasicValue(type);
|
return new BasicValue(type);
|
||||||
default:
|
default:
|
||||||
return super.newValue(type);
|
return super.newValue(type);
|
||||||
@@ -78,13 +79,10 @@ public class OptimizationBasicInterpreter extends BasicInterpreter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// if merge of two references then `lub` is java/lang/Object
|
// if merge of two references then `lub` is java/lang/Object
|
||||||
// arrays also are BasicValues with reference type's
|
if (isReference(v) && isReference(w)) {
|
||||||
if (v.getType().getSort() == Type.OBJECT && w.getType().getSort() == Type.OBJECT) {
|
|
||||||
return BasicValue.REFERENCE_VALUE;
|
return BasicValue.REFERENCE_VALUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
assert v.getType().getSort() != Type.ARRAY && w.getType().getSort() != Type.ARRAY : "There should not be arrays";
|
|
||||||
|
|
||||||
// if merge of something can be stored in int var (int, char, boolean, byte, character)
|
// if merge of something can be stored in int var (int, char, boolean, byte, character)
|
||||||
if (v.getType().getOpcode(Opcodes.ISTORE) == Opcodes.ISTORE &&
|
if (v.getType().getOpcode(Opcodes.ISTORE) == Opcodes.ISTORE &&
|
||||||
w.getType().getOpcode(Opcodes.ISTORE) == Opcodes.ISTORE) {
|
w.getType().getOpcode(Opcodes.ISTORE) == Opcodes.ISTORE) {
|
||||||
@@ -93,4 +91,8 @@ public class OptimizationBasicInterpreter extends BasicInterpreter {
|
|||||||
|
|
||||||
return BasicValue.UNINITIALIZED_VALUE;
|
return BasicValue.UNINITIALIZED_VALUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static boolean isReference(@NotNull BasicValue v) {
|
||||||
|
return v.getType().getSort() == Type.OBJECT || v.getType().getSort() == Type.ARRAY;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,36 @@
|
|||||||
|
class Controller {
|
||||||
|
var result = "fail"
|
||||||
|
suspend fun <V> suspendHere(v: V, x: Continuation<V>) {
|
||||||
|
x.resume(v)
|
||||||
|
}
|
||||||
|
|
||||||
|
operator fun handleResult(x: String, c: Continuation<Nothing>) {
|
||||||
|
result = x
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun builder(coroutine c: Controller.() -> Continuation<Unit>): String {
|
||||||
|
val controller = Controller()
|
||||||
|
c(controller).resume(Unit)
|
||||||
|
|
||||||
|
return controller.result
|
||||||
|
}
|
||||||
|
|
||||||
|
fun foo(): String = builder {
|
||||||
|
// A piece of code for next statement:
|
||||||
|
// INVOKEVIRTUAL suspendHere
|
||||||
|
// CHECKCAST [B
|
||||||
|
//
|
||||||
|
// Analyzer uses `newValue` method for estimation of type generated by CHECKCAST insn,
|
||||||
|
// but for arrays `newValue` returned just Basic.REFERENCE_VALUE, thus we didn't add necessary checkcasts
|
||||||
|
// for variables spilled into fields
|
||||||
|
val data2 = suspendHere(ByteArray(2))
|
||||||
|
|
||||||
|
suspendHere("<ignored>")
|
||||||
|
data2.size.toString()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun box(): String {
|
||||||
|
if (foo() != "2") return "fail 1"
|
||||||
|
return "OK"
|
||||||
|
}
|
||||||
@@ -4201,6 +4201,12 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
|
|||||||
doTest(fileName);
|
doTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("kt12958.kt")
|
||||||
|
public void testKt12958() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/kt12958.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("lambdaParameters.kt")
|
@TestMetadata("lambdaParameters.kt")
|
||||||
public void testLambdaParameters() throws Exception {
|
public void testLambdaParameters() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/lambdaParameters.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/lambdaParameters.kt");
|
||||||
|
|||||||
Reference in New Issue
Block a user