diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/AsmUtil.java b/compiler/backend/src/org/jetbrains/jet/codegen/AsmUtil.java index ce05e888687..202053b1d23 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/AsmUtil.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/AsmUtil.java @@ -154,6 +154,11 @@ public class AsmUtil { return Type.getType(internalName.substring(1)); } + @NotNull + public static Method method(@NotNull String name, @NotNull Type returnType, @NotNull Type... parameterTypes) { + return new Method(name, Type.getMethodDescriptor(returnType, parameterTypes)); + } + public static boolean isAbstractMethod(FunctionDescriptor functionDescriptor, OwnerKind kind) { return (functionDescriptor.getModality() == Modality.ABSTRACT || isInterface(functionDescriptor.getContainingDeclaration())) diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java index 4dedb68bf2b..92a0a2c1856 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java @@ -2430,42 +2430,49 @@ public class ExpressionCodegen extends JetVisitor implem ReceiverParameterDescriptor receiverParameter = descriptor.getReceiverParameter(); String reflectionFieldOwner; - Type propertyType; Type ownerType; String reflectionFieldName; + Method factory; DeclarationDescriptor containingDeclaration = descriptor.getContainingDeclaration(); if (containingDeclaration instanceof PackageFragmentDescriptor) { reflectionFieldOwner = PackageClassUtils.getPackageClassInternalName(((PackageFragmentDescriptor) containingDeclaration).getFqName()); - if (receiverParameter != null) { - propertyType = descriptor.isVar() ? K_MUTABLE_EXTENSION_PROPERTY_IMPL_TYPE : K_EXTENSION_PROPERTY_IMPL_TYPE; - } - else { - propertyType = descriptor.isVar() ? K_MUTABLE_TOP_LEVEL_PROPERTY_IMPL_TYPE : K_TOP_LEVEL_PROPERTY_IMPL_TYPE; - } - ownerType = K_PACKAGE_IMPL_TYPE; reflectionFieldName = JvmAbi.KOTLIN_PACKAGE_FIELD_NAME; + + if (receiverParameter != null) { + factory = descriptor.isVar() + ? method("mutableExtensionProperty", K_MUTABLE_EXTENSION_PROPERTY_IMPL_TYPE, JAVA_STRING_TYPE, ownerType, + getType(Class.class)) + : method("extensionProperty", K_EXTENSION_PROPERTY_IMPL_TYPE, JAVA_STRING_TYPE, ownerType, + getType(Class.class)); + } + else { + factory = descriptor.isVar() + ? method("mutableTopLevelProperty", K_MUTABLE_TOP_LEVEL_PROPERTY_IMPL_TYPE, JAVA_STRING_TYPE, ownerType) + : method("topLevelProperty", K_TOP_LEVEL_PROPERTY_IMPL_TYPE, JAVA_STRING_TYPE, ownerType); + } } else if (containingDeclaration instanceof ClassDescriptor) { reflectionFieldOwner = typeMapper.mapClass((ClassDescriptor) containingDeclaration).getInternalName(); - propertyType = descriptor.isVar() ? K_MUTABLE_MEMBER_PROPERTY_IMPL_TYPE : K_MEMBER_PROPERTY_IMPL_TYPE; ownerType = K_CLASS_IMPL_TYPE; reflectionFieldName = JvmAbi.KOTLIN_CLASS_FIELD_NAME; + + factory = descriptor.isVar() + ? method("mutableMemberProperty", K_MUTABLE_MEMBER_PROPERTY_IMPL_TYPE, JAVA_STRING_TYPE, ownerType) + : method("memberProperty", K_MEMBER_PROPERTY_IMPL_TYPE, JAVA_STRING_TYPE, ownerType); } else { throw new UnsupportedOperationException("Unsupported callable reference container: " + containingDeclaration); } - v.anew(propertyType); - v.dup(); v.visitLdcInsn(descriptor.getName().asString()); if (containingDeclaration instanceof JavaClassDescriptor) { v.aconst(Type.getObjectType(reflectionFieldOwner)); - v.invokestatic("kotlin/reflect/jvm/internal/InternalPackage", "foreignKotlinClass", + v.invokestatic(REFLECTION_INTERNAL_PACKAGE, "foreignKotlinClass", Type.getMethodDescriptor(K_CLASS_IMPL_TYPE, getType(Class.class)), false); } else { @@ -2473,17 +2480,12 @@ public class ExpressionCodegen extends JetVisitor implem v.getstatic(reflectionFieldOwner, reflectionFieldName, ownerType.getDescriptor()); } - String constructorDesc; if (receiverParameter != null) { putJavaLangClassInstance(v, typeMapper.mapType(receiverParameter)); - constructorDesc = Type.getMethodDescriptor(Type.VOID_TYPE, JAVA_STRING_TYPE, ownerType, getType(Class.class)); - } - else { - constructorDesc = Type.getMethodDescriptor(Type.VOID_TYPE, JAVA_STRING_TYPE, ownerType); } - v.invokespecial(propertyType.getInternalName(), "", constructorDesc, false); - return StackValue.onStack(propertyType); + v.invokestatic(REFLECTION_INTERNAL_PACKAGE, factory.getName(), factory.getDescriptor(), false); + return StackValue.onStack(factory.getReturnType()); } throw new UnsupportedOperationException("Unsupported callable reference expression: " + expression.getText()); diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java index a125ab0f0f2..70456a08250 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java @@ -473,8 +473,8 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { return; } - generateReflectionObjectField(state, classAsmType, v, K_CLASS_IMPL_TYPE, JvmAbi.KOTLIN_CLASS_FIELD_NAME, - createOrGetClInitCodegen().v); + generateReflectionObjectField(state, classAsmType, v, method("kClass", K_CLASS_IMPL_TYPE, getType(Class.class)), + JvmAbi.KOTLIN_CLASS_FIELD_NAME, createOrGetClInitCodegen().v); generatePropertyMetadataArrayFieldIfNeeded(classAsmType); } diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/MemberCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/MemberCodegen.java index 622b710fe57..910cd303da0 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/MemberCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/MemberCodegen.java @@ -43,6 +43,7 @@ import org.jetbrains.jet.storage.NotNullLazyValue; import org.jetbrains.org.objectweb.asm.MethodVisitor; import org.jetbrains.org.objectweb.asm.Type; import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter; +import org.jetbrains.org.objectweb.asm.commons.Method; import java.util.ArrayList; import java.util.Collections; @@ -320,21 +321,19 @@ public abstract class MemberCodegen", "(Ljava/lang/Class;)V", false); - v.putstatic(thisAsmType.getInternalName(), fieldName, kImplType.getDescriptor()); + v.invokestatic(REFLECTION_INTERNAL_PACKAGE, factory.getName(), factory.getDescriptor(), false); + v.putstatic(thisAsmType.getInternalName(), fieldName, type); } protected void generatePropertyMetadataArrayFieldIfNeeded(@NotNull Type thisAsmType) { diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/PackageCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/PackageCodegen.java index 24a8e07baf2..2356350d5fc 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/PackageCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/PackageCodegen.java @@ -57,12 +57,15 @@ import org.jetbrains.org.objectweb.asm.AnnotationVisitor; import org.jetbrains.org.objectweb.asm.MethodVisitor; import org.jetbrains.org.objectweb.asm.Type; import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter; +import org.jetbrains.org.objectweb.asm.commons.Method; import java.util.*; import static org.jetbrains.jet.codegen.AsmUtil.asmDescByFqNameWithoutInnerClasses; +import static org.jetbrains.jet.codegen.AsmUtil.method; import static org.jetbrains.jet.descriptors.serialization.NameSerializationUtil.createNameResolver; import static org.jetbrains.jet.lang.resolve.java.AsmTypeConstants.K_PACKAGE_IMPL_TYPE; +import static org.jetbrains.jet.lang.resolve.java.AsmTypeConstants.getType; import static org.jetbrains.jet.lang.resolve.java.PackageClassUtils.getPackageClassFqName; import static org.jetbrains.jet.lang.resolve.java.diagnostics.DiagnosticsPackage.*; import static org.jetbrains.jet.lang.resolve.java.diagnostics.JvmDeclarationOrigin.NO_ORIGIN; @@ -243,10 +246,11 @@ public class PackageCodegen { private void generateKotlinPackageReflectionField() { MethodVisitor mv = v.newMethod(NO_ORIGIN, ACC_STATIC, "", "()V", null, null); - MemberCodegen.generateReflectionObjectField(state, packageClassType, v, K_PACKAGE_IMPL_TYPE, JvmAbi.KOTLIN_PACKAGE_FIELD_NAME, - new InstructionAdapter(mv)); - mv.visitInsn(RETURN); - FunctionCodegen.endVisit(mv, "static initializer", null); + Method method = method("kPackage", K_PACKAGE_IMPL_TYPE, getType(Class.class)); + InstructionAdapter iv = new InstructionAdapter(mv); + MemberCodegen.generateReflectionObjectField(state, packageClassType, v, method, JvmAbi.KOTLIN_PACKAGE_FIELD_NAME, iv); + iv.areturn(Type.VOID_TYPE); + FunctionCodegen.endVisit(mv, "package facade static initializer", null); } private void writeKotlinPackageAnnotationIfNeeded(@NotNull JvmSerializationBindings bindings) { diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/AsmTypeConstants.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/AsmTypeConstants.java index 5ec815ea374..e1099d1dbc6 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/AsmTypeConstants.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/AsmTypeConstants.java @@ -47,6 +47,8 @@ public class AsmTypeConstants { public static final Type K_EXTENSION_PROPERTY_IMPL_TYPE = reflectInternal("KExtensionPropertyImpl"); public static final Type K_MUTABLE_EXTENSION_PROPERTY_IMPL_TYPE = reflectInternal("KMutableExtensionPropertyImpl"); + public static final String REFLECTION_INTERNAL_PACKAGE = reflectInternal("InternalPackage").getInternalName(); + public static final Type OBJECT_REF_TYPE = Type.getObjectType("kotlin/jvm/internal/Ref$ObjectRef"); @NotNull diff --git a/core/runtime.jvm/src/kotlin/reflect/jvm/internal/factory.kt b/core/runtime.jvm/src/kotlin/reflect/jvm/internal/factory.kt new file mode 100644 index 00000000000..1979953a35c --- /dev/null +++ b/core/runtime.jvm/src/kotlin/reflect/jvm/internal/factory.kt @@ -0,0 +1,43 @@ +/* + * Copyright 2010-2014 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 kotlin.reflect.jvm.internal + + +fun kClass(jClass: Class): KClassImpl = + KClassImpl(jClass) + +fun kPackage(jClass: Class<*>): KPackageImpl = + KPackageImpl(jClass) + +fun topLevelProperty(name: String, owner: KPackageImpl): KTopLevelPropertyImpl = + KTopLevelPropertyImpl(name, owner) + +fun mutableTopLevelProperty(name: String, owner: KPackageImpl): KMutableTopLevelPropertyImpl = + KMutableTopLevelPropertyImpl(name, owner) + +fun extensionProperty(name: String, owner: KPackageImpl, receiver: Class): KExtensionPropertyImpl = + KExtensionPropertyImpl(name, owner, receiver) + +fun mutableExtensionProperty(name: String, owner: KPackageImpl, receiver: Class): KMutableExtensionPropertyImpl = + KMutableExtensionPropertyImpl(name, owner, receiver) + +fun memberProperty(name: String, owner: KClassImpl): KMemberPropertyImpl = + KMemberPropertyImpl(name, owner) + +fun mutableMemberProperty(name: String, owner: KClassImpl): KMutableMemberPropertyImpl = + KMutableMemberPropertyImpl(name, owner) +