Fix for KT-9897: Cannot pop operand off an empty stack" with -= on ArrayList element

#KT-9897 Fixed
This commit is contained in:
Michael Bogdanov
2015-11-09 10:01:32 +03:00
parent 4943a9fb35
commit 7147c84396
7 changed files with 179 additions and 3 deletions
@@ -835,7 +835,10 @@ public class AsmUtil {
}
public static void dup(@NotNull InstructionAdapter v, @NotNull Type type) {
int size = type.getSize();
dup(v, type.getSize());
}
private static void dup(@NotNull InstructionAdapter v, int size) {
if (size == 2) {
v.dup2();
}
@@ -847,6 +850,36 @@ public class AsmUtil {
}
}
public static void dup(@NotNull InstructionAdapter v, @NotNull Type topOfStack, @NotNull Type afterTop) {
if (topOfStack.getSize() == 0 && afterTop.getSize() == 0) {
return;
}
if (topOfStack.getSize() == 0) {
dup(v, afterTop);
}
else if (afterTop.getSize() == 0) {
dup(v, topOfStack);
}
else if (afterTop.getSize() == 1) {
if (topOfStack.getSize() == 1) {
dup(v, 2);
}
else {
v.dup2X1();
v.pop2();
v.dupX2();
v.dupX2();
v.pop();
v.dup2X1();
}
}
else {
//Note: it's possible to write dup3 and dup4
throw new UnsupportedOperationException("Don't know how generate dup3/dup4 for: " + topOfStack + " and " + afterTop);
}
}
public static void writeKotlinSyntheticClassAnnotation(@NotNull ClassBuilder v, @NotNull GenerationState state) {
AnnotationVisitor av = v.newAnnotation(asmDescByFqNameWithoutInnerClasses(KOTLIN_SYNTHETIC_CLASS), true);
JvmCodegenUtil.writeAbiVersion(av);
@@ -771,12 +771,12 @@ public abstract class StackValue {
private final boolean isGetter;
private final ExpressionCodegen codegen;
private final ArgumentGenerator argumentGenerator;
final List<ResolvedValueArgument> valueArguments;
private final List<ResolvedValueArgument> valueArguments;
private final FrameMap frame;
private final StackValue receiver;
private final ResolvedCall<FunctionDescriptor> resolvedGetCall;
private final ResolvedCall<FunctionDescriptor> resolvedSetCall;
DefaultCallMask mask;
private DefaultCallMask mask;
public CollectionElementReceiver(
@NotNull Callable callable,
@@ -1424,6 +1424,11 @@ public abstract class StackValue {
currentExtensionReceiver
.moveToTopOfStack(hasExtensionReceiver ? type : currentExtensionReceiver.type, v, dispatchReceiver.type.getSize());
}
@Override
public void dup(@NotNull InstructionAdapter v, boolean withReceiver) {
AsmUtil.dup(v, extensionReceiver.type, dispatchReceiver.type);
}
}
public abstract static class StackValueWithSimpleReceiver extends StackValue {
@@ -0,0 +1,41 @@
object Test {
var z = "0"
var l = 0L
fun changeObject(): String {
"1".someProperty += 1
return z
}
fun changeLong(): Long {
2L.someProperty -= 1
return l
}
var String.someProperty: Int
get() {
return this.length
}
set(left) {
z += this + left
}
var Long.someProperty: Long
get() {
return l
}
set(left) {
l += this + left
}
}
fun box(): String {
val changeObject = Test.changeObject()
if (changeObject != "012") return "fail 1: $changeObject"
val changeLong = Test.changeLong()
if (changeLong != 1L) return "fail 1: $changeLong"
return "OK"
}
@@ -0,0 +1,38 @@
var z = "0"
var l = 0L
fun changeObject(): String {
"1".someProperty += 1
return z
}
fun changeLong(): Long {
2L.someProperty -= 1
return l
}
var String.someProperty: Int
get() {
return this.length
}
set(left) {
z += this + left
}
var Long.someProperty: Long
get() {
return l
}
set(left) {
l += this + left
}
fun box(): String {
val changeObject = changeObject()
if (changeObject != "012") return "fail 1: $changeObject"
val changeLong = changeLong()
if (changeLong != 1L) return "fail 1: $changeLong"
return "OK"
}
@@ -0,0 +1,41 @@
object Test {
var z = "0"
var l = 0L
fun changeObject(): String {
"1".someProperty += 1
return z
}
fun changeLong(): Long {
2L.someProperty -= 1
return l
}
@JvmStatic var String.someProperty: Int
get() {
return this.length
}
set(left) {
z += this + left
}
@JvmStatic var Long.someProperty: Long
get() {
return l
}
set(left) {
l += this + left
}
}
fun box(): String {
val changeObject = Test.changeObject()
if (changeObject != "012") return "fail 1: $changeObject"
val changeLong = Test.changeLong()
if (changeLong != 1L) return "fail 1: $changeLong"
return "OK"
}
@@ -3883,6 +3883,18 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
doTest(fileName);
}
@TestMetadata("kt9897.kt")
public void testKt9897() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/extensionProperties/kt9897.kt");
doTest(fileName);
}
@TestMetadata("kt9897_topLevel.kt")
public void testKt9897_topLevel() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/extensionProperties/kt9897_topLevel.kt");
doTest(fileName);
}
@TestMetadata("topLevel.kt")
public void testTopLevel() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/extensionProperties/topLevel.kt");
@@ -2299,6 +2299,12 @@ public class BlackBoxWithStdlibCodegenTestGenerated extends AbstractBlackBoxCode
doTestWithStdlib(fileName);
}
@TestMetadata("kt9897_static.kt")
public void testKt9897_static() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxWithStdlib/jvmStatic/kt9897_static.kt");
doTestWithStdlib(fileName);
}
@TestMetadata("postfixInc.kt")
public void testPostfixInc() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxWithStdlib/jvmStatic/postfixInc.kt");