use CallableMethod also for Jet constructor calls
This commit is contained in:
@@ -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<Type> valueParameterTypes;
|
||||
|
||||
public CallableMethod(String owner, Method descriptor, int invokeOpcode, List<Type> valueParameterTypes) {
|
||||
public CallableMethod(String owner, Method signature, int invokeOpcode, List<Type> 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());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<Type> explicitArgTypes = callableMethod.getValueParameterTypes();
|
||||
|
||||
List<ValueParameterDescriptor> paramDescrs = descriptor != null
|
||||
? descriptor.getValueParameters()
|
||||
: Collections.<ValueParameterDescriptor>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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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), "<init>", method.getDescriptor());
|
||||
method.invoke(v);
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
||||
@@ -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());
|
||||
|
||||
@@ -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("<init>", Type.VOID_TYPE, new Type[0]);
|
||||
callableMethod = new CallableMethod("", method, Opcodes.INVOKESPECIAL, Collections.<Type>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, "<init>", method.getDescriptor(), null, null);
|
||||
@@ -106,7 +109,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
? constructorDescriptor.getValueParameters()
|
||||
: Collections.<ValueParameterDescriptor>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<ValueParameterDescriptor> valueParameters = constructorDescriptor.getValueParameters();
|
||||
CallableMethod method = state.getTypeMapper().mapToCallableMethod(constructorDescriptor, kind);
|
||||
List<JetArgument> 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(), "<init>", 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, "<init>", method.getDescriptor(), null, null);
|
||||
final MethodVisitor mv = v.visitMethod(flags, "<init>", 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,
|
||||
|
||||
@@ -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<Type> valueParameterTypes) {
|
||||
boolean delegate = kind == OwnerKind.DELEGATING_IMPLEMENTATION;
|
||||
List<ValueParameterDescriptor> parameters = descriptor.getOriginal().getValueParameters();
|
||||
List<Type> parameterTypes = new ArrayList<Type>();
|
||||
@@ -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<TypeParameterDescriptor> typeParameters = classDescriptor.getTypeConstructor().getParameters();
|
||||
@@ -407,6 +409,13 @@ public class JetTypeMapper {
|
||||
return new Method("<init>", Type.VOID_TYPE, parameterTypes.toArray(new Type[parameterTypes.size()]));
|
||||
}
|
||||
|
||||
public CallableMethod mapToCallableMethod(ConstructorDescriptor descriptor, OwnerKind kind) {
|
||||
List<Type> valueParameterTypes = new ArrayList<Type>();
|
||||
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)) {
|
||||
|
||||
Reference in New Issue
Block a user