Refine AALOAD handling in OptimizationBasicInterpreter

See comment in test data for clarifications

 #KT-13289 Fixed
This commit is contained in:
Denis Zharkov
2016-09-09 18:42:07 +03:00
parent 6269f890c8
commit 6845d0958a
3 changed files with 51 additions and 0 deletions
@@ -65,6 +65,22 @@ public class OptimizationBasicInterpreter extends BasicInterpreter {
return super.newOperation(insn);
}
@Override
public BasicValue binaryOperation(
@NotNull AbstractInsnNode insn,
@NotNull BasicValue value1,
@NotNull BasicValue value2
) throws AnalyzerException {
if (insn.getOpcode() == Opcodes.AALOAD) {
Type arrayType = value1.getType();
if (arrayType != null && arrayType.getSort() == Type.ARRAY) {
return new BasicValue(arrayType.getElementType());
}
}
return super.binaryOperation(insn, value1, value2);
}
@NotNull
@Override
public BasicValue merge(
@@ -0,0 +1,29 @@
class Controller {
suspend fun suspendHere(x: Continuation<String>) {
x.resume("OK")
}
}
fun builder(coroutine c: Controller.() -> Continuation<Unit>) {
c(Controller()).resume(Unit)
}
fun box(): String {
val a = arrayOfNulls<String>(2) as Array<String>
a[0] = "O"
a[1] = "K"
var result = ""
builder {
for (s in a) {
// 's' variable must be spilled before suspension point
// And it's important that it should be treated as a String instance because of 'result += s' after
// But BasicInterpreter just ignores type of argument array for AALOAD opcode (treating it's return type as plain Object),
// so we should refine the relevant part in our intepreter
if (suspendHere() != "OK") throw RuntimeException("fail 1")
result += s
}
}
return result
}
@@ -4402,6 +4402,12 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
doTest(fileName);
}
@TestMetadata("iterateOverArray.kt")
public void testIterateOverArray() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/iterateOverArray.kt");
doTest(fileName);
}
@TestMetadata("kt12958.kt")
public void testKt12958() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/kt12958.kt");