From 6845d0958a2e62cd4453ccf5db9b026a4dcbfdd6 Mon Sep 17 00:00:00 2001 From: Denis Zharkov Date: Fri, 9 Sep 2016 18:42:07 +0300 Subject: [PATCH] Refine AALOAD handling in OptimizationBasicInterpreter See comment in test data for clarifications #KT-13289 Fixed --- .../common/OptimizationBasicInterpreter.java | 16 ++++++++++ .../box/coroutines/iterateOverArray.kt | 29 +++++++++++++++++++ .../codegen/BlackBoxCodegenTestGenerated.java | 6 ++++ 3 files changed, 51 insertions(+) create mode 100644 compiler/testData/codegen/box/coroutines/iterateOverArray.kt diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/optimization/common/OptimizationBasicInterpreter.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/optimization/common/OptimizationBasicInterpreter.java index edf964bc907..494fea25ba3 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/optimization/common/OptimizationBasicInterpreter.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/optimization/common/OptimizationBasicInterpreter.java @@ -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( diff --git a/compiler/testData/codegen/box/coroutines/iterateOverArray.kt b/compiler/testData/codegen/box/coroutines/iterateOverArray.kt new file mode 100644 index 00000000000..7fbfb772254 --- /dev/null +++ b/compiler/testData/codegen/box/coroutines/iterateOverArray.kt @@ -0,0 +1,29 @@ +class Controller { + suspend fun suspendHere(x: Continuation) { + x.resume("OK") + } +} + +fun builder(coroutine c: Controller.() -> Continuation) { + c(Controller()).resume(Unit) +} + +fun box(): String { + val a = arrayOfNulls(2) as Array + 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 +} diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java index 0a6012724ec..2f22f769cc0 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java @@ -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");