From 3fc2e5d20c70370d0b69f8a8912d40f9c5900b85 Mon Sep 17 00:00:00 2001 From: "Natalia.Ukhorskaya" Date: Tue, 20 Nov 2012 13:35:30 +0400 Subject: [PATCH] Attempt to split long or double on the stack exception #KT-3042 Fixed --- .../org/jetbrains/jet/codegen/AsmUtil.java | 18 ++++++ .../org/jetbrains/jet/codegen/StackValue.java | 2 +- .../swap/swapRefToSharedVarInt.kt | 11 ++++ .../swap/swapRefToSharedVarLong.kt | 13 ++++ .../generated/AbstractCodegenTest.java | 38 ++++++++++++ .../generated/InstructionsTestGenerated.java | 61 +++++++++++++++++++ .../jet/generators/tests/GenerateTests.java | 8 +++ 7 files changed, 150 insertions(+), 1 deletion(-) create mode 100644 compiler/testData/codegen/instructions/swap/swapRefToSharedVarInt.kt create mode 100644 compiler/testData/codegen/instructions/swap/swapRefToSharedVarLong.kt create mode 100644 compiler/tests/org/jetbrains/jet/codegen/generated/AbstractCodegenTest.java create mode 100644 compiler/tests/org/jetbrains/jet/codegen/generated/InstructionsTestGenerated.java diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/AsmUtil.java b/compiler/backend/src/org/jetbrains/jet/codegen/AsmUtil.java index fb97efda39e..f53ed8c3efe 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/AsmUtil.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/AsmUtil.java @@ -443,6 +443,24 @@ public class AsmUtil { genMethodThrow(mv, STUB_EXCEPTION, STUB_EXCEPTION_MESSAGE); } + public static void swap(InstructionAdapter v, Type stackTop, Type afterTop) { + if (stackTop.getSize() == 1) { + if (afterTop.getSize() == 1) { + v.swap(); + } else { + v.dupX2(); + v.pop(); + } + } else { + if (afterTop.getSize() == 1) { + v.dup2X1(); + } else { + v.dup2X2(); + } + v.pop2(); + } + } + public static void genNotNullAssertionsForParameters( @NotNull InstructionAdapter v, @NotNull GenerationState state, diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/StackValue.java b/compiler/backend/src/org/jetbrains/jet/codegen/StackValue.java index 247fc76ed9e..33d98219573 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/StackValue.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/StackValue.java @@ -1062,7 +1062,7 @@ public abstract class StackValue { public void store(Type topOfStackType, InstructionAdapter v) { coerceFrom(topOfStackType, v); v.load(index, OBJECT_TYPE); - v.swap(); + AsmUtil.swap(v, sharedTypeForType(this.type), topOfStackType); Type refType = refType(this.type); Type sharedType = sharedTypeForType(this.type); v.visitFieldInsn(PUTFIELD, sharedType.getInternalName(), "ref", refType.getDescriptor()); diff --git a/compiler/testData/codegen/instructions/swap/swapRefToSharedVarInt.kt b/compiler/testData/codegen/instructions/swap/swapRefToSharedVarInt.kt new file mode 100644 index 00000000000..619bfd3a800 --- /dev/null +++ b/compiler/testData/codegen/instructions/swap/swapRefToSharedVarInt.kt @@ -0,0 +1,11 @@ +fun box(): String { + var a: Int + a = 12 + fun f() { + foo(a) + } + + return "OK" +} + +fun foo(l: Int) {} \ No newline at end of file diff --git a/compiler/testData/codegen/instructions/swap/swapRefToSharedVarLong.kt b/compiler/testData/codegen/instructions/swap/swapRefToSharedVarLong.kt new file mode 100644 index 00000000000..7340eb15d14 --- /dev/null +++ b/compiler/testData/codegen/instructions/swap/swapRefToSharedVarLong.kt @@ -0,0 +1,13 @@ +//KT-3042 Attempt to split long or double on the stack excepion + +fun box(): String { + var a: Long + a = 12.toLong() + fun f() { + foo(a) + } + + return "OK" +} + +fun foo(l: Long) {} \ No newline at end of file diff --git a/compiler/tests/org/jetbrains/jet/codegen/generated/AbstractCodegenTest.java b/compiler/tests/org/jetbrains/jet/codegen/generated/AbstractCodegenTest.java new file mode 100644 index 00000000000..3a0a33d080f --- /dev/null +++ b/compiler/tests/org/jetbrains/jet/codegen/generated/AbstractCodegenTest.java @@ -0,0 +1,38 @@ +/* + * Copyright 2010-2012 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.jet.codegen.generated; + +import org.jetbrains.jet.ConfigurationKind; +import org.jetbrains.jet.codegen.CodegenTestCase; + +import java.io.IOException; + +public abstract class AbstractCodegenTest extends CodegenTestCase { + + private static final String REDUNDANT_PATH_PREFIX = "compiler/testData/codegen"; + + @Override + public void setUp() throws Exception { + super.setUp(); + createEnvironmentWithMockJdkAndIdeaAnnotations(ConfigurationKind.JDK_ONLY); + } + + protected void doTest(String path) throws IOException { + String relativePath = path.substring(REDUNDANT_PATH_PREFIX.length()); + blackBoxFile(relativePath); + } +} diff --git a/compiler/tests/org/jetbrains/jet/codegen/generated/InstructionsTestGenerated.java b/compiler/tests/org/jetbrains/jet/codegen/generated/InstructionsTestGenerated.java new file mode 100644 index 00000000000..b61c5180370 --- /dev/null +++ b/compiler/tests/org/jetbrains/jet/codegen/generated/InstructionsTestGenerated.java @@ -0,0 +1,61 @@ +/* + * Copyright 2010-2012 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jetbrains.jet.codegen.generated; + +import junit.framework.Assert; +import junit.framework.Test; +import junit.framework.TestSuite; + +import java.io.File; +import org.jetbrains.jet.JetTestUtils; +import org.jetbrains.jet.test.InnerTestClasses; +import org.jetbrains.jet.test.TestMetadata; + +import org.jetbrains.jet.codegen.generated.AbstractCodegenTest; + +/** This class is generated by {@link org.jetbrains.jet.generators.tests.GenerateTests}. DO NOT MODIFY MANUALLY */ +@TestMetadata("compiler/testData/codegen/instructions") +@InnerTestClasses({InstructionsTestGenerated.Swap.class}) +public class InstructionsTestGenerated extends AbstractCodegenTest { + public void testAllFilesPresentInInstructions() throws Exception { + JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("compiler/testData/codegen/instructions"), "kt", true); + } + + @TestMetadata("compiler/testData/codegen/instructions/swap") + public static class Swap extends AbstractCodegenTest { + public void testAllFilesPresentInSwap() throws Exception { + JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("compiler/testData/codegen/instructions/swap"), "kt", true); + } + + @TestMetadata("swapRefToSharedVarInt.kt") + public void testSwapRefToSharedVarInt() throws Exception { + doTest("compiler/testData/codegen/instructions/swap/swapRefToSharedVarInt.kt"); + } + + @TestMetadata("swapRefToSharedVarLong.kt") + public void testSwapRefToSharedVarLong() throws Exception { + doTest("compiler/testData/codegen/instructions/swap/swapRefToSharedVarLong.kt"); + } + + } + + public static Test suite() { + TestSuite suite = new TestSuite("InstructionsTestGenerated"); + suite.addTestSuite(InstructionsTestGenerated.class); + suite.addTestSuite(Swap.class); + return suite; + } +} diff --git a/generators/org/jetbrains/jet/generators/tests/GenerateTests.java b/generators/org/jetbrains/jet/generators/tests/GenerateTests.java index f6a5d37650d..14e3dea217e 100644 --- a/generators/org/jetbrains/jet/generators/tests/GenerateTests.java +++ b/generators/org/jetbrains/jet/generators/tests/GenerateTests.java @@ -20,6 +20,7 @@ import junit.framework.TestCase; import org.jetbrains.annotations.NotNull; import org.jetbrains.jet.checkers.AbstractDiagnosticsTestWithEagerResolve; import org.jetbrains.jet.checkers.AbstractJetPsiCheckerTest; +import org.jetbrains.jet.codegen.generated.AbstractCodegenTest; import org.jetbrains.jet.codegen.AbstractDataClassCodegenTest; import org.jetbrains.jet.codegen.AbstractIntrinsicsTestCase; import org.jetbrains.jet.codegen.AbstractMultiDeclTestCase; @@ -100,6 +101,13 @@ public class GenerateTests { testModel("compiler/testData/codegen/label") ); + generateTest( + "compiler/tests/", + "InstructionsTestGenerated", + AbstractCodegenTest.class, + testModel("compiler/testData/codegen/instructions") + ); + generateTest( "compiler/tests/", "ExtensionPropertiesTestGenerated",