From 4b8f40b238eae6ff47af16ef53871eb9ee57a03a Mon Sep 17 00:00:00 2001 From: Dmitry Jemerov Date: Thu, 30 Jun 2011 20:30:35 +0200 Subject: [PATCH] use CallableMethod also for Jet constructor calls --- .../jetbrains/jet/codegen/CallableMethod.java | 12 ++++---- .../jet/codegen/ConstructorFrameMap.java | 28 ++----------------- .../jet/codegen/ExpressionCodegen.java | 8 +++--- .../jet/codegen/FunctionCodegen.java | 2 +- .../codegen/ImplementationBodyCodegen.java | 20 +++++++------ .../jetbrains/jet/codegen/JetTypeMapper.java | 13 +++++++-- 6 files changed, 36 insertions(+), 47 deletions(-) diff --git a/idea/src/org/jetbrains/jet/codegen/CallableMethod.java b/idea/src/org/jetbrains/jet/codegen/CallableMethod.java index df5dff3e859..9244ee20890 100644 --- a/idea/src/org/jetbrains/jet/codegen/CallableMethod.java +++ b/idea/src/org/jetbrains/jet/codegen/CallableMethod.java @@ -11,13 +11,13 @@ import java.util.List; */ public class CallableMethod { private final String owner; - private final Method descriptor; + private final Method signature; private final int invokeOpcode; private final List valueParameterTypes; - public CallableMethod(String owner, Method descriptor, int invokeOpcode, List valueParameterTypes) { + public CallableMethod(String owner, Method signature, int invokeOpcode, List valueParameterTypes) { this.owner = owner; - this.descriptor = descriptor; + this.signature = signature; this.invokeOpcode = invokeOpcode; this.valueParameterTypes = valueParameterTypes; } @@ -26,8 +26,8 @@ public class CallableMethod { return owner; } - public Method getDescriptor() { - return descriptor; + public Method getSignature() { + return signature; } public int getInvokeOpcode() { @@ -39,6 +39,6 @@ public class CallableMethod { } void invoke(InstructionAdapter v) { - v.visitMethodInsn(getInvokeOpcode(), getOwner(), getDescriptor().getName(), getDescriptor().getDescriptor()); + v.visitMethodInsn(getInvokeOpcode(), getOwner(), getSignature().getName(), getSignature().getDescriptor()); } } diff --git a/idea/src/org/jetbrains/jet/codegen/ConstructorFrameMap.java b/idea/src/org/jetbrains/jet/codegen/ConstructorFrameMap.java index f0b94c6270b..4ae7b71fd88 100644 --- a/idea/src/org/jetbrains/jet/codegen/ConstructorFrameMap.java +++ b/idea/src/org/jetbrains/jet/codegen/ConstructorFrameMap.java @@ -5,7 +5,6 @@ import org.jetbrains.jet.lang.descriptors.ClassDescriptor; import org.jetbrains.jet.lang.descriptors.ConstructorDescriptor; import org.jetbrains.jet.lang.descriptors.ValueParameterDescriptor; import org.objectweb.asm.Type; -import org.objectweb.asm.commons.Method; import java.util.Collections; import java.util.List; @@ -18,45 +17,28 @@ public class ConstructorFrameMap extends FrameMap { private int myDelegateThisIndex = -1; private int myFirstTypeParameter = -1; private int myTypeParameterCount = 0; - private int myFirstExplicitArgument = 0; - private Type[] myExplicitArgTypes; - - public ConstructorFrameMap(JetTypeMapper typeMapper, @Nullable ConstructorDescriptor descriptor, OwnerKind kind) { - Type[] argTypes = new Type[0]; - if (descriptor != null) { - Method method = typeMapper.mapConstructorSignature(descriptor, kind); - argTypes = method.getArgumentTypes(); - } + public ConstructorFrameMap(CallableMethod callableMethod, @Nullable ConstructorDescriptor descriptor, OwnerKind kind) { enterTemp(); // this ClassDescriptor classDescriptor = null; if (descriptor != null) { classDescriptor = descriptor.getContainingDeclaration(); if (classDescriptor.getContainingDeclaration() instanceof ClassDescriptor) { myOuterThisIndex = enterTemp(); // outer class instance - myFirstExplicitArgument++; } } if (kind == OwnerKind.DELEGATING_IMPLEMENTATION) { myDelegateThisIndex = enterTemp(); // $this - myFirstExplicitArgument++; } - if (myFirstExplicitArgument > 0) { - int explicitArgCount = argTypes.length - myFirstExplicitArgument; - myExplicitArgTypes = new Type[explicitArgCount]; - System.arraycopy(argTypes, myFirstExplicitArgument, myExplicitArgTypes, 0, explicitArgCount); - } - else { - myExplicitArgTypes = argTypes; - } + List explicitArgTypes = callableMethod.getValueParameterTypes(); List paramDescrs = descriptor != null ? descriptor.getValueParameters() : Collections.emptyList(); for (int i = 0; i < paramDescrs.size(); i++) { ValueParameterDescriptor parameter = paramDescrs.get(i); - enter(parameter, myExplicitArgTypes[i].getSize()); + enter(parameter, explicitArgTypes.get(i).getSize()); } @@ -88,8 +70,4 @@ public class ConstructorFrameMap extends FrameMap { public int getTypeParameterCount() { return myTypeParameterCount; } - - public Type[] getExplicitArgTypes() { - return myExplicitArgTypes; - } } diff --git a/idea/src/org/jetbrains/jet/codegen/ExpressionCodegen.java b/idea/src/org/jetbrains/jet/codegen/ExpressionCodegen.java index fdbfc9db56e..9be82e1639b 100644 --- a/idea/src/org/jetbrains/jet/codegen/ExpressionCodegen.java +++ b/idea/src/org/jetbrains/jet/codegen/ExpressionCodegen.java @@ -798,7 +798,7 @@ public class ExpressionCodegen extends JetVisitor { pushMethodArguments(expression, callableMethod.getValueParameterTypes()); pushTypeArguments(expression); callableMethod.invoke(v); - methodDescriptor = callableMethod.getDescriptor(); + methodDescriptor = callableMethod.getSignature(); } else { gen(callee, Type.getObjectType(ClosureCodegen.getInternalClassName(fd))); @@ -1460,11 +1460,11 @@ public class ExpressionCodegen extends JetVisitor { // TODO typechecker must verify that we're the outer class of the instance being created pushOuterClassArguments(classDecl); - Method method = typeMapper.mapConstructorSignature((ConstructorDescriptor) constructorDescriptor, OwnerKind.IMPLEMENTATION); - pushMethodArguments(expression, method); + CallableMethod method = typeMapper.mapToCallableMethod((ConstructorDescriptor) constructorDescriptor, OwnerKind.IMPLEMENTATION); + pushMethodArguments(expression, method.getValueParameterTypes()); pushTypeArguments(expression); - v.invokespecial(JetTypeMapper.jvmNameForImplementation(classDecl), "", method.getDescriptor()); + method.invoke(v); } } else { diff --git a/idea/src/org/jetbrains/jet/codegen/FunctionCodegen.java b/idea/src/org/jetbrains/jet/codegen/FunctionCodegen.java index 940d5991961..c8a73d0d719 100644 --- a/idea/src/org/jetbrains/jet/codegen/FunctionCodegen.java +++ b/idea/src/org/jetbrains/jet/codegen/FunctionCodegen.java @@ -35,7 +35,7 @@ public class FunctionCodegen { public void gen(JetNamedFunction f, OwnerKind kind) { final JetTypeReference receiverTypeRef = f.getReceiverTypeRef(); final JetType receiverType = receiverTypeRef == null ? null : state.getBindingContext().resolveTypeReference(receiverTypeRef); - Method method = state.getTypeMapper().mapToCallableMethod(f).getDescriptor(); + Method method = state.getTypeMapper().mapToCallableMethod(f).getSignature(); final FunctionDescriptor functionDescriptor = state.getBindingContext().getFunctionDescriptor(f); generateMethod(f, kind, method, receiverType, functionDescriptor.getValueParameters(), functionDescriptor.getTypeParameters()); diff --git a/idea/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java b/idea/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java index 4bbbe4aaaea..974bf4cd7ab 100644 --- a/idea/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java +++ b/idea/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java @@ -91,11 +91,14 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { if (constructorDescriptor == null && !(myClass instanceof JetObjectDeclaration)) return; Method method; + CallableMethod callableMethod; if (myClass instanceof JetObjectDeclaration) { method = new Method("", Type.VOID_TYPE, new Type[0]); + callableMethod = new CallableMethod("", method, Opcodes.INVOKESPECIAL, Collections.emptyList()); } else { - method = state.getTypeMapper().mapConstructorSignature(constructorDescriptor, kind); + callableMethod = state.getTypeMapper().mapToCallableMethod(constructorDescriptor, kind); + method = callableMethod.getSignature(); } int flags = Opcodes.ACC_PUBLIC; // TODO final MethodVisitor mv = v.visitMethod(flags, "", method.getDescriptor(), null, null); @@ -106,7 +109,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { ? constructorDescriptor.getValueParameters() : Collections.emptyList(); - ConstructorFrameMap frameMap = new ConstructorFrameMap(state.getTypeMapper(), constructorDescriptor, kind); + ConstructorFrameMap frameMap = new ConstructorFrameMap(callableMethod, constructorDescriptor, kind); final InstructionAdapter iv = new InstructionAdapter(mv); ExpressionCodegen codegen = new ExpressionCodegen(mv, frameMap, Type.VOID_TYPE, @@ -255,15 +258,14 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { iv.load(frameMap.getOuterThisIndex(), state.getTypeMapper().jvmType((ClassDescriptor) descriptor.getContainingDeclaration(), OwnerKind.IMPLEMENTATION)); } - Method method = state.getTypeMapper().mapConstructorSignature(constructorDescriptor, kind); - List valueParameters = constructorDescriptor.getValueParameters(); + CallableMethod method = state.getTypeMapper().mapToCallableMethod(constructorDescriptor, kind); List args = constructorCall.getValueArguments(); for (int i = 0, argsSize = args.size(); i < argsSize; i++) { JetArgument arg = args.get(i); - codegen.gen(arg.getArgumentExpression(), state.getTypeMapper().mapType(valueParameters.get(i).getOutType())); + codegen.gen(arg.getArgumentExpression(), method.getValueParameterTypes().get(i)); } - iv.invokespecial(type.getInternalName(), "", method.getDescriptor()); + method.invoke(iv); } @Override @@ -281,12 +283,12 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { if (constructorDescriptor == null) { throw new UnsupportedOperationException("failed to get descriptor for secondary constructor"); } - Method method = state.getTypeMapper().mapConstructorSignature(constructorDescriptor, kind); + CallableMethod method = state.getTypeMapper().mapToCallableMethod(constructorDescriptor, kind); int flags = Opcodes.ACC_PUBLIC; // TODO - final MethodVisitor mv = v.visitMethod(flags, "", method.getDescriptor(), null, null); + final MethodVisitor mv = v.visitMethod(flags, "", method.getSignature().getDescriptor(), null, null); mv.visitCode(); - ConstructorFrameMap frameMap = new ConstructorFrameMap(state.getTypeMapper(), constructorDescriptor, kind); + ConstructorFrameMap frameMap = new ConstructorFrameMap(method, constructorDescriptor, kind); final InstructionAdapter iv = new InstructionAdapter(mv); ExpressionCodegen codegen = new ExpressionCodegen(mv, frameMap, Type.VOID_TYPE, diff --git a/idea/src/org/jetbrains/jet/codegen/JetTypeMapper.java b/idea/src/org/jetbrains/jet/codegen/JetTypeMapper.java index 261ab98690b..6a2ff81dbe0 100644 --- a/idea/src/org/jetbrains/jet/codegen/JetTypeMapper.java +++ b/idea/src/org/jetbrains/jet/codegen/JetTypeMapper.java @@ -383,7 +383,7 @@ public class JetTypeMapper { return new Method(PropertyCodegen.setterName(descriptor.getName()), Type.VOID_TYPE, new Type[] { paramType }); } - public Method mapConstructorSignature(ConstructorDescriptor descriptor, OwnerKind kind) { + private Method mapConstructorSignature(ConstructorDescriptor descriptor, OwnerKind kind, List valueParameterTypes) { boolean delegate = kind == OwnerKind.DELEGATING_IMPLEMENTATION; List parameters = descriptor.getOriginal().getValueParameters(); List parameterTypes = new ArrayList(); @@ -396,7 +396,9 @@ public class JetTypeMapper { parameterTypes.add(jetInterfaceType(classDescriptor)); } for (ValueParameterDescriptor parameter : parameters) { - parameterTypes.add(mapType(parameter.getOutType())); + final Type type = mapType(parameter.getOutType()); + parameterTypes.add(type); + valueParameterTypes.add(type); } List typeParameters = classDescriptor.getTypeConstructor().getParameters(); @@ -407,6 +409,13 @@ public class JetTypeMapper { return new Method("", Type.VOID_TYPE, parameterTypes.toArray(new Type[parameterTypes.size()])); } + public CallableMethod mapToCallableMethod(ConstructorDescriptor descriptor, OwnerKind kind) { + List valueParameterTypes = new ArrayList(); + final Method method = mapConstructorSignature(descriptor, kind, valueParameterTypes); + String owner = jvmName(descriptor.getContainingDeclaration(), kind); + return new CallableMethod(owner, method, Opcodes.INVOKESPECIAL, valueParameterTypes); + } + static int getAccessModifiers(JetDeclaration p, int defaultFlags) { int flags = 0; if (p.hasModifier(JetTokens.PUBLIC_KEYWORD)) {