Fix for KT-9897: Cannot pop operand off an empty stack" with -= on ArrayList element
#KT-9897 Fixed
This commit is contained in:
@@ -835,7 +835,10 @@ public class AsmUtil {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static void dup(@NotNull InstructionAdapter v, @NotNull Type type) {
|
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) {
|
if (size == 2) {
|
||||||
v.dup2();
|
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) {
|
public static void writeKotlinSyntheticClassAnnotation(@NotNull ClassBuilder v, @NotNull GenerationState state) {
|
||||||
AnnotationVisitor av = v.newAnnotation(asmDescByFqNameWithoutInnerClasses(KOTLIN_SYNTHETIC_CLASS), true);
|
AnnotationVisitor av = v.newAnnotation(asmDescByFqNameWithoutInnerClasses(KOTLIN_SYNTHETIC_CLASS), true);
|
||||||
JvmCodegenUtil.writeAbiVersion(av);
|
JvmCodegenUtil.writeAbiVersion(av);
|
||||||
|
|||||||
@@ -771,12 +771,12 @@ public abstract class StackValue {
|
|||||||
private final boolean isGetter;
|
private final boolean isGetter;
|
||||||
private final ExpressionCodegen codegen;
|
private final ExpressionCodegen codegen;
|
||||||
private final ArgumentGenerator argumentGenerator;
|
private final ArgumentGenerator argumentGenerator;
|
||||||
final List<ResolvedValueArgument> valueArguments;
|
private final List<ResolvedValueArgument> valueArguments;
|
||||||
private final FrameMap frame;
|
private final FrameMap frame;
|
||||||
private final StackValue receiver;
|
private final StackValue receiver;
|
||||||
private final ResolvedCall<FunctionDescriptor> resolvedGetCall;
|
private final ResolvedCall<FunctionDescriptor> resolvedGetCall;
|
||||||
private final ResolvedCall<FunctionDescriptor> resolvedSetCall;
|
private final ResolvedCall<FunctionDescriptor> resolvedSetCall;
|
||||||
DefaultCallMask mask;
|
private DefaultCallMask mask;
|
||||||
|
|
||||||
public CollectionElementReceiver(
|
public CollectionElementReceiver(
|
||||||
@NotNull Callable callable,
|
@NotNull Callable callable,
|
||||||
@@ -1424,6 +1424,11 @@ public abstract class StackValue {
|
|||||||
currentExtensionReceiver
|
currentExtensionReceiver
|
||||||
.moveToTopOfStack(hasExtensionReceiver ? type : currentExtensionReceiver.type, v, dispatchReceiver.type.getSize());
|
.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 {
|
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"
|
||||||
|
}
|
||||||
+12
@@ -3883,6 +3883,18 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
|
|||||||
doTest(fileName);
|
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")
|
@TestMetadata("topLevel.kt")
|
||||||
public void testTopLevel() throws Exception {
|
public void testTopLevel() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/extensionProperties/topLevel.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/extensionProperties/topLevel.kt");
|
||||||
|
|||||||
+6
@@ -2299,6 +2299,12 @@ public class BlackBoxWithStdlibCodegenTestGenerated extends AbstractBlackBoxCode
|
|||||||
doTestWithStdlib(fileName);
|
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")
|
@TestMetadata("postfixInc.kt")
|
||||||
public void testPostfixInc() throws Exception {
|
public void testPostfixInc() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxWithStdlib/jvmStatic/postfixInc.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxWithStdlib/jvmStatic/postfixInc.kt");
|
||||||
|
|||||||
Reference in New Issue
Block a user