diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/CallableMethod.java b/compiler/backend/src/org/jetbrains/jet/codegen/CallableMethod.java index 74a523bbe39..8f284c416fc 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/CallableMethod.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/CallableMethod.java @@ -81,9 +81,14 @@ public class CallableMethod implements Callable { public void invokeWithDefault(InstructionAdapter v, int mask) { v.iconst(mask); String desc = getSignature().getDescriptor().replace(")", "I)"); - if(getInvokeOpcode() != Opcodes.INVOKESTATIC) - desc = desc.replace("(", "(L" + getOwner() + ";"); - v.visitMethodInsn(Opcodes.INVOKESTATIC, getInvokeOpcode() == Opcodes.INVOKEINTERFACE ? getOwner() + "$$TImpl" : getOwner(), getSignature().getName() + "$default", desc); + if("".equals(getSignature().getName())) { + v.visitMethodInsn(Opcodes.INVOKESPECIAL, getOwner(), "", desc); + } + else { + if(getInvokeOpcode() != Opcodes.INVOKESTATIC) + desc = desc.replace("(", "(L" + getOwner() + ";"); + v.visitMethodInsn(Opcodes.INVOKESTATIC, getInvokeOpcode() == Opcodes.INVOKEINTERFACE ? getOwner() + "$$TImpl" : getOwner(), getSignature().getName() + "$default", desc); + } } public boolean isNeedsThis() { diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/FunctionCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/FunctionCodegen.java index 857765785c8..b8c95e26d29 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/FunctionCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/FunctionCodegen.java @@ -1,6 +1,7 @@ package org.jetbrains.jet.codegen; import com.intellij.psi.PsiElement; +import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.lang.descriptors.*; import org.jetbrains.jet.lang.psi.*; import org.jetbrains.jet.lang.resolve.BindingContext; @@ -226,7 +227,7 @@ public class FunctionCodegen { } } - static void generateDefaultIfNeeded(CodegenContext.MethodContext owner, GenerationState state, ClassBuilder v, Method jvmSignature, FunctionDescriptor functionDescriptor, OwnerKind kind) { + static void generateDefaultIfNeeded(CodegenContext.MethodContext owner, GenerationState state, ClassBuilder v, Method jvmSignature, @Nullable FunctionDescriptor functionDescriptor, OwnerKind kind) { DeclarationDescriptor contextClass = owner.getContextDescriptor().getContainingDeclaration(); if(kind != OwnerKind.TRAIT_IMPL) { @@ -242,15 +243,18 @@ public class FunctionCodegen { } boolean needed = false; - for (ValueParameterDescriptor parameterDescriptor : functionDescriptor.getValueParameters()) { - if(parameterDescriptor.hasDefaultValue()) { - needed = true; - break; + if(functionDescriptor != null) { + for (ValueParameterDescriptor parameterDescriptor : functionDescriptor.getValueParameters()) { + if(parameterDescriptor.hasDefaultValue()) { + needed = true; + break; + } } } if(needed) { - boolean hasReceiver = functionDescriptor.getReceiverParameter().exists(); + ReceiverDescriptor receiverParameter = functionDescriptor.getReceiverParameter(); + boolean hasReceiver = receiverParameter.exists(); boolean isStatic = kind == OwnerKind.NAMESPACE; if(kind == OwnerKind.TRAIT_IMPL) { @@ -265,9 +269,10 @@ public class FunctionCodegen { state.getTypeMapper().mapType(((ClassDescriptor) contextClass).getDefaultType(), OwnerKind.IMPLEMENTATION).getInternalName(); String descriptor = jvmSignature.getDescriptor().replace(")","I)"); - if(!isStatic) + boolean isConstructor = "".equals(jvmSignature.getName()); + if(!isStatic && !isConstructor) descriptor = descriptor.replace("(","(L" + ownerInternalName + ";"); - final MethodVisitor mv = v.newMethod(null, flags | ACC_STATIC, jvmSignature.getName() + "$default", descriptor, null, null); + final MethodVisitor mv = v.newMethod(null, flags | (isConstructor ? 0 : ACC_STATIC), isConstructor ? "" : jvmSignature.getName() + "$default", descriptor, null, null); InstructionAdapter iv = new InstructionAdapter(mv); if (v.generateCode()) { mv.visitCode(); @@ -278,33 +283,28 @@ public class FunctionCodegen { int var = 0; if(!isStatic) { - frameMap.enterTemp(); var++; } + Type receiverType = receiverParameter.exists() ? state.getTypeMapper().mapType(receiverParameter.getType()) : Type.DOUBLE_TYPE; if(hasReceiver) { - frameMap.enterTemp(); - var++; + var += receiverType.getSize(); } List typeParameters = functionDescriptor.getTypeParameters(); for (final TypeParameterDescriptor typeParameterDescriptor : typeParameters) { - int slot = frameMap.enterTemp(); - codegen.addTypeParameter(typeParameterDescriptor, StackValue.local(slot, JetTypeMapper.TYPE_TYPEINFO)); - var++; + if(typeParameterDescriptor.isReified()) { + codegen.addTypeParameter(typeParameterDescriptor, StackValue.local(var++, JetTypeMapper.TYPE_TYPEINFO)); + } } Type[] argTypes = jvmSignature.getArgumentTypes(); List paramDescrs = functionDescriptor.getValueParameters(); for (int i = 0; i < paramDescrs.size(); i++) { - ValueParameterDescriptor parameter = paramDescrs.get(i); int size = argTypes[i + (hasReceiver ? 1 : 0)].getSize(); var += size; - frameMap.enter(parameter, size); } - frameMap.enterTemp(); - int maskIndex = var; var = 0; @@ -313,7 +313,8 @@ public class FunctionCodegen { } if(hasReceiver) { - mv.visitVarInsn(ALOAD, var++); // todo - Long etc. + iv.load(var, receiverType); + var += receiverType.getSize(); } int extra = hasReceiver ? 1 : 0; diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java index c3fe305c016..d9a6678e5f2 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java @@ -269,7 +269,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { CodegenContext.ConstructorContext constructorContext = context.intoConstructor(constructorDescriptor); - Method method; + Method constructorMethod; CallableMethod callableMethod; if (constructorDescriptor == null) { List parameterTypes = new ArrayList(); @@ -282,17 +282,17 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { parameterTypes.add(JetTypeMapper.TYPE_TYPEINFO); } - method = new Method("", Type.VOID_TYPE, parameterTypes.toArray(new Type[parameterTypes.size()])); - callableMethod = new CallableMethod("", method, Opcodes.INVOKESPECIAL, Collections.emptyList()); + constructorMethod = new Method("", Type.VOID_TYPE, parameterTypes.toArray(new Type[parameterTypes.size()])); + callableMethod = new CallableMethod("", constructorMethod, Opcodes.INVOKESPECIAL, Collections.emptyList()); } else { callableMethod = typeMapper.mapToCallableMethod(constructorDescriptor, kind); - method = callableMethod.getSignature(); + constructorMethod = callableMethod.getSignature(); } ObjectOrClosureCodegen closure = context.closure; if(closure != null) { - final List consArgTypes = new LinkedList(Arrays.asList(method.getArgumentTypes())); + final List consArgTypes = new LinkedList(Arrays.asList(constructorMethod.getArgumentTypes())); int insert = 0; if(closure.captureThis) { @@ -319,11 +319,11 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { } } - method = new Method("", Type.VOID_TYPE, consArgTypes.toArray(new Type[consArgTypes.size()])); + constructorMethod = new Method("", Type.VOID_TYPE, consArgTypes.toArray(new Type[consArgTypes.size()])); } int flags = Opcodes.ACC_PUBLIC; // TODO - final MethodVisitor mv = v.newMethod(myClass, flags, "", method.getDescriptor(), null, null); + final MethodVisitor mv = v.newMethod(myClass, flags, "", constructorMethod.getDescriptor(), null, null); if (!v.generateCode()) return; mv.visitCode(); @@ -470,6 +470,8 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { mv.visitInsn(Opcodes.RETURN); mv.visitMaxs(0, 0); mv.visitEnd(); + + FunctionCodegen.generateDefaultIfNeeded(constructorContext, state, v, constructorMethod, constructorDescriptor, OwnerKind.IMPLEMENTATION ); } private void generateTraitMethods(ExpressionCodegen codegen) {