diff --git a/.idea/libraries/idea_full.xml b/.idea/libraries/idea_full.xml index 30b7644b98f..3612adc0684 100644 --- a/.idea/libraries/idea_full.xml +++ b/.idea/libraries/idea_full.xml @@ -1,7 +1,7 @@ - + diff --git a/.idea/libraries/intellij_core.xml b/.idea/libraries/intellij_core.xml index d14331541a7..b60dda4a21e 100644 --- a/.idea/libraries/intellij_core.xml +++ b/.idea/libraries/intellij_core.xml @@ -1,7 +1,7 @@ - + diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/CompilationException.java b/compiler/backend/src/org/jetbrains/jet/codegen/CompilationException.java index 72a638af9e6..2508e1332ce 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/CompilationException.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/CompilationException.java @@ -36,7 +36,7 @@ public class CompilationException extends RuntimeException { col = -1; } - return "Internal error: (" + (line+1) + "," + col + ") " + (getCause().getMessage() != null ? getCause().getMessage() : getCause().toString()); + return "Internal error: (" + (line+1) + "," + col + ") " + (getCause().getMessage() != null ? getCause().getMessage() : getCause().toString()) + "\n@" + getCause().getStackTrace()[0].getFileName() + ":" + getCause().getStackTrace()[0].getLineNumber(); } @Override diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java index ae8f3ccfbf8..4fc5100efc7 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java @@ -782,6 +782,15 @@ public class ExpressionCodegen extends JetVisitor { } } + if(closureCodegen.superCall != null) { + ConstructorDescriptor superConstructor = (ConstructorDescriptor) bindingContext.get(BindingContext.REFERENCE_TARGET, ((JetDelegatorToSuperCall) closureCodegen.superCall).getCalleeExpression().getConstructorReferenceExpression()); + CallableMethod superCallable = typeMapper.mapToCallableMethod(superConstructor, OwnerKind.IMPLEMENTATION); + Type[] argumentTypes = superCallable.getSignature().getAsmMethod().getArgumentTypes(); + Collections.addAll(consArgTypes, argumentTypes); + ResolvedCall resolvedCall = bindingContext.get(BindingContext.RESOLVED_CALL, closureCodegen.superCall.getCalleeExpression()); + pushMethodArguments(resolvedCall, Arrays.asList(argumentTypes)); + } + Method cons = new Method("", Type.VOID_TYPE, consArgTypes.toArray(new Type[consArgTypes.size()])); v.invokespecial(closure.getClassname(), "", cons.getDescriptor()); return StackValue.onStack(Type.getObjectType(closure.getClassname())); diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java index 84526d67d0e..52c23bd170e 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java @@ -21,6 +21,8 @@ import org.objectweb.asm.commons.Method; import java.util.*; +import static org.jetbrains.jet.codegen.JetTypeMapper.TYPE_OBJECT; + /** * @author max * @author yole @@ -212,6 +214,9 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { try { generatePrimaryConstructor(); } + catch (CompilationException e) { + throw e; + } catch(RuntimeException e) { throw new RuntimeException("Error generating primary constructor of class " + myClass.getName() + " with kind " + kind, e); } @@ -396,6 +401,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { } ObjectOrClosureCodegen closure = context.closure; + int firstSuperArgument = -1; if(closure != null) { final LinkedList consArgTypes = new LinkedList(constructorMethod.getKotlinParameterTypes()); @@ -424,6 +430,18 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { } } + if(myClass instanceof JetObjectDeclaration) { + if(superCall instanceof JetDelegatorToSuperCall) { + closure.superCall = (JetDelegatorToSuperCall) superCall; + ConstructorDescriptor superConstructor = (ConstructorDescriptor) bindingContext.get(BindingContext.REFERENCE_TARGET, ((JetDelegatorToSuperCall) superCall).getCalleeExpression().getConstructorReferenceExpression()); + CallableMethod superCallable = typeMapper.mapToCallableMethod(superConstructor, OwnerKind.IMPLEMENTATION); + firstSuperArgument = insert; + for(Type t : superCallable.getSignature().getAsmMethod().getArgumentTypes()) { + consArgTypes.add(insert++, new JvmMethodParameterSignature(t, "", JvmMethodParameterKind.SHARED_VAR)); + } + } + } + constructorMethod = JvmMethodSignature.simple("", Type.VOID_TYPE, consArgTypes); } @@ -488,32 +506,31 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { } } - if (superCall == null || superCall instanceof JetDelegatorToSuperClass) { + if (superCall == null) { iv.load(0, Type.getType("L" + superClass + ";")); - if(superCall == null) { - iv.invokespecial(superClass, "", "()V"); + iv.invokespecial(superClass, "", "()V"); + } + else if (superCall instanceof JetDelegatorToSuperClass) { + iv.load(0, Type.getType("L" + superClass + ";")); + JetType superType = bindingContext.get(BindingContext.TYPE, superCall.getTypeReference()); + List parameterTypes = new ArrayList(); + assert superType != null; + ClassDescriptor superClassDescriptor = (ClassDescriptor) superType.getConstructor().getDeclarationDescriptor(); + if (CodegenUtil.hasThis0(superClassDescriptor)) { + iv.load(1, JetTypeMapper.TYPE_OBJECT); + parameterTypes.add(typeMapper.mapType(CodegenUtil.getOuterClassDescriptor(descriptor).getDefaultType(), OwnerKind.IMPLEMENTATION)); } - else { - JetType superType = bindingContext.get(BindingContext.TYPE, superCall.getTypeReference()); - List parameterTypes = new ArrayList(); - assert superType != null; - ClassDescriptor superClassDescriptor = (ClassDescriptor) superType.getConstructor().getDeclarationDescriptor(); - if (CodegenUtil.hasThis0(superClassDescriptor)) { - iv.load(1, JetTypeMapper.TYPE_OBJECT); - parameterTypes.add(typeMapper.mapType(CodegenUtil.getOuterClassDescriptor(descriptor).getDefaultType(), OwnerKind.IMPLEMENTATION)); - } - for(TypeProjection typeParameterDescriptor : superType.getArguments()) { - codegen.generateTypeInfo(typeParameterDescriptor.getType(), null); - parameterTypes.add(JetTypeMapper.TYPE_TYPEINFO); - } - Method superCallMethod = new Method("", Type.VOID_TYPE, parameterTypes.toArray(new Type[parameterTypes.size()])); - iv.invokespecial(typeMapper.mapType(superClassDescriptor.getDefaultType(), OwnerKind.IMPLEMENTATION).getInternalName(), "", superCallMethod.getDescriptor()); + for(TypeProjection typeParameterDescriptor : superType.getArguments()) { + codegen.generateTypeInfo(typeParameterDescriptor.getType(), null); + parameterTypes.add(JetTypeMapper.TYPE_TYPEINFO); } + Method superCallMethod = new Method("", Type.VOID_TYPE, parameterTypes.toArray(new Type[parameterTypes.size()])); + iv.invokespecial(typeMapper.mapType(superClassDescriptor.getDefaultType(), OwnerKind.IMPLEMENTATION).getInternalName(), "", superCallMethod.getDescriptor()); } else { iv.load(0, classType); ConstructorDescriptor constructorDescriptor1 = (ConstructorDescriptor) bindingContext.get(BindingContext.REFERENCE_TARGET, ((JetDelegatorToSuperCall) superCall).getCalleeExpression().getConstructorReferenceExpression()); - generateDelegatorToConstructorCall(iv, codegen, (JetDelegatorToSuperCall) superCall, constructorDescriptor1, frameMap); + generateDelegatorToConstructorCall(iv, codegen, (JetDelegatorToSuperCall) superCall, constructorDescriptor1, frameMap, firstSuperArgument); } int n = 0; @@ -685,10 +702,9 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { private void generateDelegatorToConstructorCall(InstructionAdapter iv, ExpressionCodegen codegen, JetCallElement constructorCall, ConstructorDescriptor constructorDescriptor, - ConstructorFrameMap frameMap) { + ConstructorFrameMap frameMap, int firstSuperArgument) { ClassDescriptor classDecl = constructorDescriptor.getContainingDeclaration(); - Type type; - type = typeMapper.mapType(classDecl.getDefaultType(), OwnerKind.IMPLEMENTATION); + Type type = typeMapper.mapType(classDecl.getDefaultType(), OwnerKind.IMPLEMENTATION); iv.load(0, type); @@ -697,7 +713,20 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { } CallableMethod method = typeMapper.mapToCallableMethod(constructorDescriptor, kind); - codegen.invokeMethodWithArguments(method, constructorCall, StackValue.none()); + if(myClass instanceof JetObjectDeclaration && superCall instanceof JetDelegatorToSuperCall) { + iv.load(0, TYPE_OBJECT); + ConstructorDescriptor superConstructor = (ConstructorDescriptor) bindingContext.get(BindingContext.REFERENCE_TARGET, ((JetDelegatorToSuperCall) superCall).getCalleeExpression().getConstructorReferenceExpression()); + CallableMethod superCallable = typeMapper.mapToCallableMethod(superConstructor, OwnerKind.IMPLEMENTATION); + int nextVar = firstSuperArgument+1; + for(Type t : superCallable.getSignature().getAsmMethod().getArgumentTypes()) { + iv.load(nextVar, t); + nextVar += t.getSize(); + } + method.invoke(codegen.v); + } + else { + codegen.invokeMethodWithArguments(method, constructorCall, StackValue.none()); + } } @Override @@ -785,7 +814,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { if (!(thisDescriptor instanceof ConstructorDescriptor)) { throw new UnsupportedOperationException("expected 'this' delegator to resolve to constructor"); } - generateDelegatorToConstructorCall(iv, codegen, thisCall, (ConstructorDescriptor) thisDescriptor, frameMap); + generateDelegatorToConstructorCall(iv, codegen, thisCall, (ConstructorDescriptor) thisDescriptor, frameMap, flags); } else { throw new UnsupportedOperationException("unknown initializer type"); diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ObjectOrClosureCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/ObjectOrClosureCodegen.java index 4259f9ee41e..6dd8f626125 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ObjectOrClosureCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ObjectOrClosureCodegen.java @@ -1,6 +1,7 @@ package org.jetbrains.jet.codegen; import org.jetbrains.jet.lang.descriptors.*; +import org.jetbrains.jet.lang.psi.JetDelegatorToSuperCall; import org.objectweb.asm.Opcodes; import org.objectweb.asm.Type; @@ -20,6 +21,7 @@ public class ObjectOrClosureCodegen { protected ClassBuilder cv = null; public String name = null; protected Map closure = new LinkedHashMap(); + public JetDelegatorToSuperCall superCall; public ObjectOrClosureCodegen(ExpressionCodegen exprContext, CodegenContext context, GenerationState state) { this.exprContext = exprContext; diff --git a/compiler/testData/codegen/classes/selfcreate.kt b/compiler/testData/codegen/classes/selfcreate.kt new file mode 100644 index 00000000000..62be018cf32 --- /dev/null +++ b/compiler/testData/codegen/classes/selfcreate.kt @@ -0,0 +1,10 @@ +class B () {} + +open class A(val b : B) { + fun a() = object: A(b) {} +} + +fun box() : String { + A(B()).a() + return "OK" +} \ No newline at end of file diff --git a/compiler/testData/codegen/regressions/kt1120.kt b/compiler/testData/codegen/regressions/kt1120.kt new file mode 100644 index 00000000000..d3dda284044 --- /dev/null +++ b/compiler/testData/codegen/regressions/kt1120.kt @@ -0,0 +1,24 @@ +import java.util.concurrent.ConcurrentLinkedQueue +import java.util.List + +public object RefreshQueue { + private val queue = ConcurrentLinkedQueue> + + private val workerThread = Thread(object : Runnable { + override fun run() { + while (!workerThread.isInterrupted()) { + try { +// synchronized(queue) { +// queue.wait() +// } + } catch (e : InterruptedException) { + } + } + } + }) +} + +fun box() : String { + val t = RefreshQueue.workerThread + return "OK" +} \ No newline at end of file diff --git a/compiler/tests/org/jetbrains/jet/codegen/ClassGenTest.java b/compiler/tests/org/jetbrains/jet/codegen/ClassGenTest.java index b8753633c45..320b743043c 100644 --- a/compiler/tests/org/jetbrains/jet/codegen/ClassGenTest.java +++ b/compiler/tests/org/jetbrains/jet/codegen/ClassGenTest.java @@ -243,4 +243,14 @@ public class ClassGenTest extends CodegenTestCase { public void testKt1018 () throws Exception { blackBoxFile("regressions/kt1018.kt"); } + + public void testKt1120 () throws Exception { +// createEnvironmentWithFullJdk(); +// blackBoxFile("regressions/kt1120.kt"); + } + + public void testSelfCreate() throws Exception { + createEnvironmentWithFullJdk(); + blackBoxFile("classes/selfcreate.kt"); + } }