diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ClosureCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/ClosureCodegen.java index b062a56f417..3aa68b5b5ed 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ClosureCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ClosureCodegen.java @@ -1,5 +1,6 @@ /* * @author max + * @author alex.tkachman */ package org.jetbrains.jet.codegen; @@ -16,9 +17,7 @@ import org.objectweb.asm.commons.Method; import org.objectweb.asm.signature.SignatureWriter; import java.util.Arrays; -import java.util.LinkedHashMap; import java.util.List; -import java.util.Map; import static org.objectweb.asm.Opcodes.*; @@ -152,6 +151,9 @@ public class ClosureCodegen extends FunctionOrClosureCodegen { final Method bridge = erasedInvokeSignature(funDescriptor); final Method delegate = invokeSignature(funDescriptor); + if(bridge.getDescriptor().equals(delegate.getDescriptor())) + return; + final MethodVisitor mv = cv.visitMethod(ACC_PUBLIC, "invoke", bridge.getDescriptor(), state.getTypeMapper().genericSignature(funDescriptor), new String[0]); mv.visitCode(); @@ -212,7 +214,8 @@ public class ClosureCodegen extends FunctionOrClosureCodegen { ExpressionCodegen expressionCodegen = new ExpressionCodegen(mv, null, Type.VOID_TYPE, context, state); iv.load(0, Type.getObjectType(funClass)); - expressionCodegen.generateTypeInfo(new ProjectionErasingJetType(returnType)); +// expressionCodegen.generateTypeInfo(new ProjectionErasingJetType(returnType)); + iv.aconst(null); // @todo iv.invokespecial(funClass, "", "(Ljet/typeinfo/TypeInfo;)V"); i = 1; diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java index 1d268c7b10e..a76f5e3d782 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java @@ -313,10 +313,6 @@ public class ExpressionCodegen extends JetVisitor { myContinueTargets.pop(); } - private DeclarationDescriptor contextType() { - return context.getContextClass(); - } - private OwnerKind contextKind() { return context.getContextKind(); } @@ -874,7 +870,7 @@ public class ExpressionCodegen extends JetVisitor { String owner; boolean isInterface; - boolean isInsideClass = containingDeclaration == contextType(); + boolean isInsideClass = containingDeclaration == context.getContextClass(); if (isInsideClass || isStatic) { owner = typeMapper.getOwner(functionDescriptor, contextKind()); isInterface = false; @@ -904,7 +900,7 @@ public class ExpressionCodegen extends JetVisitor { DeclarationDescriptor containingDeclaration = propertyDescriptor.getContainingDeclaration(); boolean isStatic = containingDeclaration instanceof NamespaceDescriptorImpl; propertyDescriptor = propertyDescriptor.getOriginal(); - boolean isInsideClass = !forceInterface && containingDeclaration == contextType(); + boolean isInsideClass = !forceInterface && containingDeclaration == context.getContextClass(); Method getter; Method setter; if (forceField) { @@ -1024,10 +1020,6 @@ public class ExpressionCodegen extends JetVisitor { return funDescriptor; } - public void invokeMethodWithArguments(CallableMethod callableMethod, JetCallElement expression) { - invokeMethodWithArguments(callableMethod, expression, StackValue.none()); - } - public void invokeMethodWithArguments(CallableMethod callableMethod, JetCallElement expression, StackValue receiver) { final Type calleeType = callableMethod.getGenerateCalleeType(); if (calleeType != null && expression instanceof JetCallExpression) { @@ -1053,7 +1045,11 @@ public class ExpressionCodegen extends JetVisitor { } else { if (callableMethod.isNeedsReceiver()) { - receiver.put(JetTypeMapper.TYPE_OBJECT, v); + if (receiver == StackValue.none()) { + v.load(0, JetTypeMapper.TYPE_OBJECT); + } + else + receiver.put(JetTypeMapper.TYPE_OBJECT, v); } } @@ -1812,7 +1808,7 @@ public class ExpressionCodegen extends JetVisitor { } CallableMethod method = typeMapper.mapToCallableMethod((ConstructorDescriptor) constructorDescriptor, OwnerKind.IMPLEMENTATION); - invokeMethodWithArguments(method, expression); + invokeMethodWithArguments(method, expression, StackValue.none()); } } else { @@ -1849,7 +1845,7 @@ public class ExpressionCodegen extends JetVisitor { v.anew(type); v.dup(); final CallableMethod callableMethod = typeMapper.mapToCallableMethod(constructor); - invokeMethodWithArguments(callableMethod, expression); + invokeMethodWithArguments(callableMethod, expression, StackValue.none()); return type; } @@ -2313,12 +2309,12 @@ public class ExpressionCodegen extends JetVisitor { return; } DeclarationDescriptor containingDeclaration = typeParameterDescriptor.getContainingDeclaration(); - if (contextType() instanceof ClassDescriptor) { - ClassDescriptor descriptor = (ClassDescriptor) contextType(); + if (context.getContextClass() instanceof ClassDescriptor) { + ClassDescriptor descriptor = (ClassDescriptor) context.getContextClass(); JetType defaultType = ((ClassDescriptor)containingDeclaration).getDefaultType(); Type ownerType = typeMapper.mapType(defaultType); ownerType = JetTypeMapper.boxType(ownerType); - if (containingDeclaration == contextType()) { + if (containingDeclaration == context.getContextClass()) { if(!CodegenUtil.isInterface(descriptor)) { if (CodegenUtil.hasTypeInfoField(defaultType)) { v.load(0, JetTypeMapper.TYPE_OBJECT); diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java index 97ea22a1428..69df0081b91 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java @@ -461,7 +461,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { } CallableMethod method = state.getTypeMapper().mapToCallableMethod(constructorDescriptor, kind); - codegen.invokeMethodWithArguments(method, constructorCall); + codegen.invokeMethodWithArguments(method, constructorCall, StackValue.none()); } @Override @@ -513,7 +513,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { final JetDelegatorToSuperCall superCall = (JetDelegatorToSuperCall) specifier; ConstructorDescriptor constructorDescriptor = (ConstructorDescriptor) state.getBindingContext().get(BindingContext.REFERENCE_TARGET, superCall.getCalleeExpression().getConstructorReferenceExpression()); CallableMethod method = state.getTypeMapper().mapToCallableMethod(constructorDescriptor, OwnerKind.IMPLEMENTATION); - codegen.invokeMethodWithArguments(method, superCall); + codegen.invokeMethodWithArguments(method, superCall, StackValue.none()); } else { throw new UnsupportedOperationException("unsupported type of enum constant initializer: " + specifier); diff --git a/compiler/testData/codegen/regressions/kt395.jet b/compiler/testData/codegen/regressions/kt395.jet new file mode 100644 index 00000000000..1febc10ffc5 --- /dev/null +++ b/compiler/testData/codegen/regressions/kt395.jet @@ -0,0 +1,12 @@ +fun Any.with(operation : fun Any.() : Any) = operation().toString() + +val f = { (a : Int) :Unit => } + +fun box () : String { + return if(20.with { + this + } == "20") + "OK" + else + "fail" +} diff --git a/compiler/tests/org/jetbrains/jet/codegen/FunctionGenTest.java b/compiler/tests/org/jetbrains/jet/codegen/FunctionGenTest.java index bc3b7ec5397..1bbef086700 100644 --- a/compiler/tests/org/jetbrains/jet/codegen/FunctionGenTest.java +++ b/compiler/tests/org/jetbrains/jet/codegen/FunctionGenTest.java @@ -76,4 +76,8 @@ public class FunctionGenTest extends CodegenTestCase { assertTrue((Boolean) foo.invoke(null, "lala")); assertFalse((Boolean) foo.invoke(null, "mama")); } + + public void testKt395 () { + blackBoxFile("regressions/kt395.jet"); + } }