Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

avoid coercing 'this' to a supertype; cleaner handling of stackvalues…

… for 'this' and 'super' (KT-2395)
  • Loading branch information...
commit de3f5d0e2d06be42fa41b8f64fd0c9bcad69b1b4 1 parent 739a1f8
@yole yole authored
View
4 compiler/backend/src/org/jetbrains/jet/codegen/ClosureAnnotator.java
@@ -127,7 +127,7 @@ public void registerClassNameForScript(@NotNull JetScript jetScript, @NotNull Jv
}
@NotNull
- public ClassDescriptor classDescriptorForScrpitDescriptor(@NotNull ScriptDescriptor scriptDescriptor) {
+ public ClassDescriptor classDescriptorForScriptDescriptor(@NotNull ScriptDescriptor scriptDescriptor) {
ClassDescriptorImpl classDescriptor = classesForFunctions.get(scriptDescriptor);
if (classDescriptor == null) {
throw new IllegalStateException("Class for script is not registered: " + scriptDescriptor);
@@ -146,7 +146,7 @@ public JvmClassName classNameForScriptPsi(@NotNull JetScript script) {
@NotNull
public JvmClassName classNameForScriptDescriptor(@NotNull ScriptDescriptor scriptDescriptor) {
- return classNameForClassDescriptor(classDescriptorForScrpitDescriptor(scriptDescriptor));
+ return classNameForClassDescriptor(classDescriptorForScriptDescriptor(scriptDescriptor));
}
private void mapFilesToNamespaces(Collection<JetFile> files) {
View
50 compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java
@@ -35,11 +35,7 @@
import org.jetbrains.jet.lang.resolve.calls.*;
import org.jetbrains.jet.lang.resolve.constants.CompileTimeConstant;
import org.jetbrains.jet.lang.resolve.java.JvmClassName;
-import org.jetbrains.jet.lang.resolve.scopes.receivers.ClassReceiver;
-import org.jetbrains.jet.lang.resolve.scopes.receivers.ExpressionReceiver;
-import org.jetbrains.jet.lang.resolve.scopes.receivers.ExtensionReceiver;
-import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
-import org.jetbrains.jet.lang.resolve.scopes.receivers.ScriptReceiver;
+import org.jetbrains.jet.lang.resolve.scopes.receivers.*;
import org.jetbrains.jet.lang.types.JetType;
import org.jetbrains.jet.lang.types.lang.JetStandardClasses;
import org.jetbrains.jet.lang.types.lang.JetStandardLibraryNames;
@@ -136,7 +132,10 @@ StackValue castToRequiredTypeOfInterfaceIfNeeded(StackValue inner, DeclarationDe
assert provided instanceof ClassDescriptor;
if (!CodegenUtil.isInterface(provided) && CodegenUtil.isInterface(required)) {
- v.checkcast(asmType(required.getDefaultType()));
+ inner.put(TYPE_OBJECT, v);
+ final Type type = asmType(required.getDefaultType());
+ v.checkcast(type);
+ return StackValue.onStack(type);
}
return inner;
@@ -199,7 +198,7 @@ public StackValue visitExpression(JetExpression expression, StackValue receiver)
public StackValue visitSuperExpression(JetSuperExpression expression, StackValue data) {
final DeclarationDescriptor descriptor = bindingContext.get(BindingContext.REFERENCE_TARGET, expression.getInstanceReference());
if (descriptor instanceof ClassDescriptor) {
- return generateThisOrOuter((ClassDescriptor) descriptor);
+ return StackValue.thisOrOuter(this, (ClassDescriptor) descriptor);
}
else {
JetType type = context.getThisDescriptor().getDefaultType();
@@ -1161,9 +1160,12 @@ public StackValue visitSimpleNameExpression(JetSimpleNameExpression expression,
if (descriptor instanceof ValueParameterDescriptor && descriptor.getContainingDeclaration() instanceof ScriptDescriptor) {
ScriptDescriptor scriptDescriptor = (ScriptDescriptor) descriptor.getContainingDeclaration();
- JvmClassName scriptClassName = state.getInjector().getClosureAnnotator().classNameForScriptDescriptor(scriptDescriptor);
+ final ClosureAnnotator closureAnnotator = state.getInjector().getClosureAnnotator();
+ JvmClassName scriptClassName = closureAnnotator.classNameForScriptDescriptor(scriptDescriptor);
ValueParameterDescriptor valueParameterDescriptor = (ValueParameterDescriptor) descriptor;
- generateThisOrOuter(state.getInjector().getClosureAnnotator().classDescriptorForScrpitDescriptor(scriptDescriptor));
+ final ClassDescriptor scriptClass = closureAnnotator.classDescriptorForScriptDescriptor(scriptDescriptor);
+ final StackValue script = StackValue.thisOrOuter(this, scriptClass);
+ script.put(script.type, v);
Type fieldType = typeMapper.mapType(valueParameterDescriptor.getType(), MapTypeMode.VALUE);
return StackValue.field(fieldType, scriptClassName, valueParameterDescriptor.getName().getIdentifier(), false);
}
@@ -1513,27 +1515,23 @@ public void generateFromResolvedCall(@NotNull ReceiverDescriptor descriptor, @No
} else {
v.getstatic(classObjType.getInternalName(), "$classobj", exprType.getDescriptor());
}
+ StackValue.onStack(exprType).put(type, v);
}
else {
- generateThisOrOuter(classReceiverDeclarationDescriptor).put(exprType, v);
+ StackValue.thisOrOuter(this, classReceiverDeclarationDescriptor).put(type, v);
}
- StackValue.onStack(exprType).put(type, v);
}
else if (descriptor instanceof ScriptReceiver) {
generateScript((ScriptReceiver) descriptor);
}
else if (descriptor instanceof ExtensionReceiver) {
- Type exprType = asmType(descriptor.getType());
ExtensionReceiver extensionReceiver = (ExtensionReceiver) descriptor;
- generateReceiver(extensionReceiver.getDeclarationDescriptor()).put(exprType, v);
- StackValue.onStack(exprType).put(type, v);
+ generateReceiver(extensionReceiver.getDeclarationDescriptor()).put(type, v);
}
else if (descriptor instanceof ExpressionReceiver) {
ExpressionReceiver expressionReceiver = (ExpressionReceiver) descriptor;
JetExpression expr = expressionReceiver.getExpression();
- Type exprType = asmType(expressionReceiver.getType());
- gen(expr, exprType);
- StackValue.onStack(exprType).put(type, v);
+ gen(expr, type);
}
else if (descriptor instanceof AutoCastReceiver) {
AutoCastReceiver autoCastReceiver = (AutoCastReceiver) descriptor;
@@ -1602,25 +1600,23 @@ private void generateScript(@NotNull ScriptReceiver receiver) {
cur = cur.getParentContext();
}
- throw new UnsupportedOperationException(); }
-
- public StackValue generateThisOrOuter(@NotNull ClassDescriptor calleeContainingClass) {
- CodegenContext cur = context;
+ throw new UnsupportedOperationException();
+ }
+ public StackValue generateThisOrOuter(@NotNull final ClassDescriptor calleeContainingClass) {
PsiElement psiElement = BindingContextUtils.classDescriptorToDeclaration(bindingContext, calleeContainingClass);
boolean isObject = psiElement instanceof JetClassOrObject && CodegenUtil.isNonLiteralObject((JetClassOrObject) psiElement);
- cur = context;
- StackValue result = StackValue.local(0, TYPE_OBJECT);
+ CodegenContext cur = context;
+ Type type = asmType(calleeContainingClass.getDefaultType());
+ StackValue result = StackValue.local(0, type);
while (cur != null) {
if (cur instanceof CodegenContexts.MethodContext && !(cur instanceof CodegenContexts.ConstructorContext))
cur = cur.getParentContext();
if (DescriptorUtils.isSubclass(cur.getThisDescriptor(), calleeContainingClass)) {
- Type type = asmType(calleeContainingClass.getDefaultType());
if (!isObject || (cur.getThisDescriptor() == calleeContainingClass)) {
- result.put(TYPE_OBJECT, v);
- return castToRequiredTypeOfInterfaceIfNeeded(StackValue.onStack(type), cur.getThisDescriptor(), calleeContainingClass);
+ return castToRequiredTypeOfInterfaceIfNeeded(result, cur.getThisDescriptor(), calleeContainingClass);
}
else {
v.getstatic(type.getInternalName(), "$instance", type.getDescriptor());
@@ -2697,7 +2693,7 @@ public StackValue visitThrowExpression(JetThrowExpression expression, StackValue
public StackValue visitThisExpression(JetThisExpression expression, StackValue receiver) {
final DeclarationDescriptor descriptor = bindingContext.get(BindingContext.REFERENCE_TARGET, expression.getInstanceReference());
if (descriptor instanceof ClassDescriptor) {
- return generateThisOrOuter((ClassDescriptor) descriptor);
+ return StackValue.thisOrOuter(this, (ClassDescriptor) descriptor);
}
else {
if (descriptor instanceof FunctionDescriptor || descriptor instanceof PropertyDescriptor) {
View
2  compiler/backend/src/org/jetbrains/jet/codegen/JetTypeMapper.java
@@ -953,7 +953,7 @@ public JvmMethodSignature mapScriptSignature(@NotNull ScriptDescriptor script, @
for (ScriptDescriptor importedScript : importedScripts) {
signatureWriter.writeParameterType(JvmMethodParameterKind.VALUE);
- mapType(closureAnnotator.classDescriptorForScrpitDescriptor(importedScript).getDefaultType(), signatureWriter, MapTypeMode.VALUE);
+ mapType(closureAnnotator.classDescriptorForScriptDescriptor(importedScript).getDefaultType(), signatureWriter, MapTypeMode.VALUE);
signatureWriter.writeParameterTypeEnd();
}
View
3  compiler/backend/src/org/jetbrains/jet/codegen/ScriptCodegen.java
@@ -35,7 +35,6 @@
import org.objectweb.asm.commons.InstructionAdapter;
import javax.inject.Inject;
-import java.util.Collections;
import java.util.List;
/**
@@ -99,7 +98,7 @@ public void generate(JetScript scriptDeclaration) {
ScriptDescriptor scriptDescriptor = (ScriptDescriptor) state.getBindingContext().get(BindingContext.SCRIPT, scriptDeclaration);
- ClassDescriptor classDescriptorForScript = closureAnnotator.classDescriptorForScrpitDescriptor(scriptDescriptor);
+ ClassDescriptor classDescriptorForScript = closureAnnotator.classDescriptorForScriptDescriptor(scriptDescriptor);
CodegenContexts.ScriptContext context = (CodegenContexts.ScriptContext) CodegenContexts.STATIC.intoScript(scriptDescriptor, classDescriptorForScript);
View
3  compiler/backend/src/org/jetbrains/jet/codegen/StackValue.java
@@ -1087,7 +1087,8 @@ public ThisOuter(ExpressionCodegen codegen, ClassDescriptor descriptor) {
@Override
public void put(Type type, InstructionAdapter v) {
- codegen.generateThisOrOuter(descriptor);
+ final StackValue stackValue = codegen.generateThisOrOuter(descriptor);
+ stackValue.put(stackValue.type, v); // no coercion here
}
}
View
11 compiler/testData/codegen/regressions/kt2395.kt
@@ -0,0 +1,11 @@
+import java.util.AbstractList
+
+class MyList(): AbstractList<String>() {
+ public fun getModificationCount(): Int = modCount
+ public override fun get(index: Int): String? = ""
+ public override fun size(): Int = 0
+}
+
+fun box(): String {
+ return if (MyList().getModificationCount() == 0) "OK" else "fail"
+}
View
5 compiler/tests/org/jetbrains/jet/codegen/ClassGenTest.java
@@ -471,4 +471,9 @@ public void testKt2060() {
createEnvironmentWithMockJdkAndIdeaAnnotations(ConfigurationKind.JDK_ONLY);
blackBoxMultiFile("regressions/kt2060_1.kt", "regressions/kt2060.kt");
}
+
+ public void testKt2395() {
+ createEnvironmentWithMockJdkAndIdeaAnnotations(ConfigurationKind.JDK_ONLY);
+ blackBoxMultiFile("regressions/kt2395.kt");
+ }
}
Please sign in to comment.
Something went wrong with that request. Please try again.