diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/StackValue.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/StackValue.java index a0eaa2ff4d2..6c738ecc5e6 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/StackValue.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/StackValue.java @@ -28,11 +28,13 @@ import org.jetbrains.kotlin.codegen.state.GenerationState; import org.jetbrains.kotlin.codegen.state.JetTypeMapper; import org.jetbrains.kotlin.descriptors.*; import org.jetbrains.kotlin.load.java.JvmAbi; +import org.jetbrains.kotlin.load.java.descriptors.JavaPropertyDescriptor; import org.jetbrains.kotlin.psi.JetExpression; import org.jetbrains.kotlin.resolve.ImportedFromObjectCallableDescriptor; import org.jetbrains.kotlin.resolve.annotations.AnnotationUtilKt; import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall; import org.jetbrains.kotlin.resolve.calls.model.ResolvedValueArgument; +import org.jetbrains.kotlin.resolve.constants.ConstantValue; import org.jetbrains.kotlin.resolve.jvm.AsmTypes; import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodParameterKind; import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodParameterSignature; @@ -1040,7 +1042,10 @@ public abstract class StackValue { if (getter == null) { assert fieldName != null : "Property should have either a getter or a field name: " + descriptor; assert backingFieldOwner != null : "Property should have either a getter or a backingFieldOwner: " + descriptor; - v.visitFieldInsn(isStaticPut ? GETSTATIC : GETFIELD, backingFieldOwner.getInternalName(), fieldName, this.type.getDescriptor()); + if (inlineJavaConstantIfNeeded(type, v)) return; + + v.visitFieldInsn(isStaticPut ? GETSTATIC : GETFIELD, + backingFieldOwner.getInternalName(), fieldName, this.type.getDescriptor()); if (!genNotNullAssertionForField(v, state, descriptor)) { genNotNullAssertionForLateInitIfNeeded(v); } @@ -1052,6 +1057,25 @@ public abstract class StackValue { } } + private boolean inlineJavaConstantIfNeeded(@NotNull Type type, @NotNull InstructionAdapter v) { + if (!isStaticPut) return false; + if (!(descriptor instanceof JavaPropertyDescriptor)) return false; + if (!AsmUtil.isPrimitive(this.type) && !this.type.equals(Type.getObjectType("java/lang/String"))) return false; + + JavaPropertyDescriptor javaPropertyDescriptor = (JavaPropertyDescriptor) descriptor; + ConstantValue constantValue = javaPropertyDescriptor.getCompileTimeInitializer(); + if (constantValue == null) return false; + + Object value = constantValue.getValue(); + if (this.type == Type.FLOAT_TYPE && value instanceof Double) { + value = ((Double) value).floatValue(); + } + + new Constant(value, this.type).putSelector(type, v); + + return true; + } + private void genNotNullAssertionForLateInitIfNeeded(@NotNull InstructionAdapter v) { if (!descriptor.isLateInit()) return; diff --git a/compiler/testData/codegen/bytecodeTextMultifile/inlineJavaStaticFields/JClass.java b/compiler/testData/codegen/bytecodeTextMultifile/inlineJavaStaticFields/JClass.java new file mode 100644 index 00000000000..714e227319b --- /dev/null +++ b/compiler/testData/codegen/bytecodeTextMultifile/inlineJavaStaticFields/JClass.java @@ -0,0 +1,21 @@ +import org.jetbrains.annotations.NotNull; + +public class JClass { + public final static int PrimitiveInt = 9000; + public final static int BigPrimitiveInt = 59000; + public final static long PrimitiveLong = 100000; + public final static short PrimitiveShort = 900; + public final static boolean PrimitiveBool = false; + public final static float PrimitiveFloat = 36.6; + public final static double PrimitiveDouble = 42.4242; + public final static byte PrimitiveByte = -8; + public final static char PrimitiveChar = 'K'; + public final static String Str = ":J"; + + @NotNull + public final static Integer BoxedInt = 9500; + + public static int NonFinal = 9700; + + public final int NonStatic = 9800; +} \ No newline at end of file diff --git a/compiler/testData/codegen/bytecodeTextMultifile/inlineJavaStaticFields/test.kt b/compiler/testData/codegen/bytecodeTextMultifile/inlineJavaStaticFields/test.kt new file mode 100644 index 00000000000..f1fe2a262cf --- /dev/null +++ b/compiler/testData/codegen/bytecodeTextMultifile/inlineJavaStaticFields/test.kt @@ -0,0 +1,47 @@ +object KoKobject { + @JvmStatic + val JvmStatic: Int = 1 +} + +fun test() { + Integer.MIN_VALUE + java.lang.Long.MAX_VALUE + + JClass.PrimitiveInt + JClass.BigPrimitiveInt + JClass.PrimitiveByte + JClass.PrimitiveChar + JClass.PrimitiveLong + JClass.PrimitiveShort + JClass.PrimitiveBool + JClass.PrimitiveFloat + JClass.PrimitiveDouble + JClass.Str + + JClass.BoxedInt + JClass.NonFinal + + JClass().NonStatic + + KoKobject.JvmStatic +} + +// @TestKt.class: +// 1 LDC -2147483648 +// 1 LDC 9223372036854775807 +// 1 SIPUSH 9000 +// 1 LDC 59000 +// 1 LDC -8 +// 1 LDC K +// 1 LDC 100000 +// 1 LDC 900 +// 1 LDC false +// 1 LDC 36.6 +// 1 LDC 42.4242 +// 1 LDC ":J" +// 1 GETSTATIC JClass.BoxedInt : Ljava/lang/Integer; +// 1 GETSTATIC JClass.NonFinal : I +// 1 GETFIELD JClass.NonStatic : I +// 1 INVOKESTATIC KoKobject.getJvmStatic \(\)I +// 3 POP2 +// 16 POP \ No newline at end of file diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/BytecodeTextMultifileTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/BytecodeTextMultifileTestGenerated.java index 0fc80163725..5fb4a1a6bde 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/BytecodeTextMultifileTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/BytecodeTextMultifileTestGenerated.java @@ -35,6 +35,12 @@ public class BytecodeTextMultifileTestGenerated extends AbstractBytecodeTextTest JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/bytecodeTextMultifile"), Pattern.compile("^([^\\.]+)$"), false); } + @TestMetadata("inlineJavaStaticFields") + public void testInlineJavaStaticFields() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/bytecodeTextMultifile/inlineJavaStaticFields/"); + doTestMultiFile(fileName); + } + @TestMetadata("javaStatics") public void testJavaStatics() throws Exception { String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/bytecodeTextMultifile/javaStatics/");