diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/AsmUtil.java b/compiler/backend/src/org/jetbrains/jet/codegen/AsmUtil.java index c70d8049951..eabb8cf293f 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/AsmUtil.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/AsmUtil.java @@ -653,10 +653,10 @@ public class AsmUtil { if (!state.isCallAssertionsEnabled()) return stackValue; if (approximationInfo == null || !TypesPackage.assertNotNull(approximationInfo)) return stackValue; - return new StackValue.StackValueWithoutReceiver(stackValue.type) { + return new StackValue(stackValue.type) { @Override - public void put(@NotNull Type type, @NotNull InstructionAdapter v) { + public void putSelector(@NotNull Type type, @NotNull InstructionAdapter v) { stackValue.put(type, v); if (type.getSort() == Type.OBJECT || type.getSort() == Type.ARRAY) { v.dup(); diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java index 77f99830864..d102b7110ca 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java @@ -1894,7 +1894,7 @@ public class ExpressionCodegen extends JetVisitor implem return stackValueForLocal(descriptor, index); } - return context.lookupInContext(descriptor, StackValue.thiz(), state, false); + return context.lookupInContext(descriptor, StackValue.LOCAL_0, state, false); } @@ -2342,7 +2342,7 @@ public class ExpressionCodegen extends JetVisitor implem if (DescriptorUtils.isClassObject(receiverDescriptor)) { CallableMemberDescriptor contextDescriptor = context.getContextDescriptor(); if (contextDescriptor instanceof FunctionDescriptor && receiverDescriptor == contextDescriptor.getContainingDeclaration()) { - return StackValue.thiz(); + return StackValue.LOCAL_0; } else { return StackValue.singleton(receiverDescriptor, typeMapper); @@ -2384,7 +2384,7 @@ public class ExpressionCodegen extends JetVisitor implem // SCRIPT: generate script, move to ScriptingUtil private StackValue generateScript(@NotNull ScriptReceiver receiver) { CodegenContext cur = context; - StackValue result = StackValue.thiz(); + StackValue result = StackValue.LOCAL_0; boolean inStartConstructorContext = cur instanceof ConstructorContext; while (cur != null) { if (!inStartConstructorContext) { @@ -2788,7 +2788,7 @@ public class ExpressionCodegen extends JetVisitor implem StackValue receiverValue = generateExpressionWithNullFallback(receiver, ifNull); //Do not optimize for primitives cause in case of safe call extension receiver should be generated before dispatch one - StackValue newReceiver = new StackValue.Safe(receiverType, receiverValue, isPrimitive(receiverType) ? null : ifNull); + StackValue newReceiver = new StackValue.SafeCall(receiverType, receiverValue, isPrimitive(receiverType) ? null : ifNull); return genQualified(newReceiver, selector); } @@ -2855,7 +2855,7 @@ public class ExpressionCodegen extends JetVisitor implem } } - private StackValue generateIn(final StackValue leftValue, final JetExpression rangeExpression, final JetSimpleNameExpression operationReference) { + private StackValue generateIn(final StackValue leftValue, JetExpression rangeExpression, final JetSimpleNameExpression operationReference) { final JetExpression deparenthesized = JetPsiUtil.deparenthesize(rangeExpression); return StackValue.operation(Type.BOOLEAN_TYPE, new Function1() { @Override @@ -3220,7 +3220,7 @@ public class ExpressionCodegen extends JetVisitor implem } @Override - public StackValue visitPostfixExpression(@NotNull final JetPostfixExpression expression, final StackValue receiver) { + public StackValue visitPostfixExpression(@NotNull final JetPostfixExpression expression, StackValue receiver) { if (expression.getOperationReference().getReferencedNameElementType() == JetTokens.EXCLEXCL) { final StackValue base = genQualified(receiver, expression.getBaseExpression()); if (isPrimitive(base.type)) { @@ -3307,7 +3307,7 @@ public class ExpressionCodegen extends JetVisitor implem @Override public StackValue visitProperty(@NotNull JetProperty property, StackValue receiver) { - final JetExpression initializer = property.getInitializer(); + JetExpression initializer = property.getInitializer(); if (initializer == null) { return StackValue.none(); } @@ -3325,15 +3325,15 @@ public class ExpressionCodegen extends JetVisitor implem Type initializerAsmType = asmType(initializerType); - final TransientReceiver initializerAsReceiver = new TransientReceiver(initializerType); + TransientReceiver initializerAsReceiver = new TransientReceiver(initializerType); int tempVarIndex = myFrameMap.enterTemp(initializerAsmType); gen(initializer, initializerAsmType); v.store(tempVarIndex, initializerAsmType); - final StackValue.Local local = StackValue.local(tempVarIndex, initializerAsmType); + StackValue.Local local = StackValue.local(tempVarIndex, initializerAsmType); - for (final JetMultiDeclarationEntry variableDeclaration : multiDeclaration.getEntries()) { + for (JetMultiDeclarationEntry variableDeclaration : multiDeclaration.getEntries()) { ResolvedCall resolvedCall = bindingContext.get(COMPONENT_RESOLVED_CALL, variableDeclaration); assert resolvedCall != null : "Resolved call is null for " + variableDeclaration.getText(); Call call = makeFakeCall(initializerAsReceiver); @@ -3375,7 +3375,7 @@ public class ExpressionCodegen extends JetVisitor implem JetScript scriptPsi = JetPsiUtil.getScript(variableDeclaration); assert scriptPsi != null; Type scriptClassType = asmTypeForScriptPsi(bindingContext, scriptPsi); - storeTo = StackValue.field(varType, scriptClassType, variableDeclaration.getName(), false, StackValue.thiz()); + storeTo = StackValue.field(varType, scriptClassType, variableDeclaration.getName(), false, StackValue.LOCAL_0); } else if (sharedVarType == null) { storeTo = StackValue.local(index, varType); @@ -3433,7 +3433,7 @@ public class ExpressionCodegen extends JetVisitor implem return generateNewArray(expression, arrayType); } - private StackValue generateNewArray(@NotNull final JetCallExpression expression, @NotNull final JetType arrayType) { + private StackValue generateNewArray(@NotNull JetCallExpression expression, @NotNull final JetType arrayType) { final List < JetExpression > args = new ArrayList(); for (ValueArgument va : expression.getValueArguments()) { diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/IStackValue.java b/compiler/backend/src/org/jetbrains/jet/codegen/IStackValue.java index 9a00e784c70..73551382c32 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/IStackValue.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/IStackValue.java @@ -25,14 +25,8 @@ public interface IStackValue { void moveToTopOfStack(@NotNull Type type, @NotNull InstructionAdapter v, int depth); - void put(@NotNull Type type, @NotNull InstructionAdapter v); - void put(@NotNull Type type, @NotNull InstructionAdapter v, boolean skipReceiver); - void storeSelector(@NotNull Type topOfStackType, @NotNull InstructionAdapter v); - - void store(@NotNull StackValue value, @NotNull InstructionAdapter v); - void store(@NotNull StackValue value, @NotNull InstructionAdapter v, boolean skipReceiver); void condJump(@NotNull Label label, boolean jumpIfFalse, @NotNull InstructionAdapter v); diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java index e0aaba7be3a..4e89fd8a237 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java @@ -800,7 +800,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { : "Function container should be annotated with [data]: " + function; PropertyDescriptor property = bindingContext.get(BindingContext.VALUE_PARAMETER_AS_PROPERTY, valueParameter); assert property != null : "Copy function doesn't correspond to any property: " + function; - return codegen.intermediateValueForProperty(property, false, null, StackValue.thiz()); + return codegen.intermediateValueForProperty(property, false, null, StackValue.LOCAL_0); } }, null @@ -1134,7 +1134,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { } if (isObject(descriptor)) { - StackValue.singleton(descriptor, typeMapper).store(StackValue.thiz(), iv); + StackValue.singleton(descriptor, typeMapper).store(StackValue.LOCAL_0, iv); } for (JetDelegationSpecifier specifier : myClass.getDelegationSpecifiers()) { @@ -1299,7 +1299,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { } else return; - constructorContext.lookupInContext(toLookup, StackValue.thiz(), state, true); + constructorContext.lookupInContext(toLookup, StackValue.LOCAL_0, state, true); } @Override @@ -1308,7 +1308,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { assert descriptor instanceof CallableDescriptor || descriptor instanceof ClassDescriptor : "'This' reference target should be class or callable descriptor but was " + descriptor; if (descriptor instanceof ClassDescriptor) { - context.lookupInContext(descriptor, StackValue.thiz(), state, true); + context.lookupInContext(descriptor, StackValue.LOCAL_0, state, true); } if (descriptor instanceof CallableDescriptor) { @@ -1343,7 +1343,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { ResolvedCall resolvedCall = CallUtilPackage.getResolvedCallWithAssert(superCall, bindingContext); ClassDescriptor superClass = ((ConstructorDescriptor) resolvedCall.getResultingDescriptor()).getContainingDeclaration(); if (superClass.isInner()) { - constructorContext.lookupInContext(superClass.getContainingDeclaration(), StackValue.thiz(), state, true); + constructorContext.lookupInContext(superClass.getContainingDeclaration(), StackValue.LOCAL_0, state, true); } if (!isAnonymousObject(descriptor)) { diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/MemberCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/MemberCodegen.java index 908d5fad306..e8fc2cf7c5e 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/MemberCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/MemberCodegen.java @@ -50,7 +50,6 @@ import java.util.ArrayList; import java.util.Collections; import java.util.List; -import static org.jetbrains.jet.codegen.AsmUtil.boxType; import static org.jetbrains.jet.codegen.AsmUtil.isPrimitive; import static org.jetbrains.jet.lang.descriptors.CallableMemberDescriptor.Kind.SYNTHESIZED; import static org.jetbrains.jet.lang.descriptors.SourceElement.NO_SOURCE; @@ -236,7 +235,8 @@ public abstract class MemberCodegen { new ExpressionCodegen(mv, frameMap, Type.VOID_TYPE, methodContext, state, this).gen(scriptDeclaration.getBlockExpression()); if (stackValue.type != Type.VOID_TYPE) { StackValue.Field resultValue = StackValue - .field(blockType, classType, ScriptDescriptor.LAST_EXPRESSION_VALUE_FIELD_NAME, false, StackValue.thiz()); + .field(blockType, classType, ScriptDescriptor.LAST_EXPRESSION_VALUE_FIELD_NAME, false, StackValue.LOCAL_0); resultValue.store(stackValue, iv); } else { stackValue.put(blockType, iv); diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/StackValue.java b/compiler/backend/src/org/jetbrains/jet/codegen/StackValue.java index ce16307a85f..dfc5d2d9d14 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/StackValue.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/StackValue.java @@ -56,6 +56,15 @@ public abstract class StackValue implements IStackValue { public static final int RECEIVER_READ = 0; public static final int RECEIVER_WRITE = 1; + public static final StackValue.Local LOCAL_0 = local(0, OBJECT_TYPE); + private static final StackValue UNIT = operation(UNIT_TYPE, new Function1() { + @Override + public Unit invoke(InstructionAdapter v) { + v.visitFieldInsn(GETSTATIC, UNIT_TYPE.getInternalName(), JvmAbi.INSTANCE_FIELD, UNIT_TYPE.getDescriptor()); + return null; + } + }); + @NotNull public final Type type; @@ -76,11 +85,15 @@ public abstract class StackValue implements IStackValue { put(type, v); } - @Override public void put(@NotNull Type type, @NotNull InstructionAdapter v) { put(type, v, false); } + @Override + public void put(@NotNull Type type, @NotNull InstructionAdapter v, boolean skipReceiver) { + putSelector(type, v); + } + @Override public void dup(@NotNull InstructionAdapter v, boolean withReceiver) { switch (type.getSize()) { @@ -92,18 +105,18 @@ public abstract class StackValue implements IStackValue { } } - @Override public void storeSelector(@NotNull Type topOfStackType, @NotNull InstructionAdapter v) { throw new UnsupportedOperationException("cannot store to value " + this); } + public abstract void putSelector(@NotNull Type type, @NotNull InstructionAdapter v); + @Override public void store(@NotNull StackValue value, @NotNull InstructionAdapter v, boolean skipReceiver) { value.put(value.type, v); storeSelector(value.type, v); } - @Override public void store(@NotNull StackValue value, @NotNull InstructionAdapter v) { store(value, v, false); } @@ -125,10 +138,6 @@ public abstract class StackValue implements IStackValue { return new Local(index, type); } - public static Local thiz() { - return local(0, OBJECT_TYPE); - } - @NotNull public static StackValue shared(int index, @NotNull Type type) { return new Shared(index, type); @@ -345,7 +354,11 @@ public abstract class StackValue implements IStackValue { } public static void putUnitInstance(@NotNull InstructionAdapter v) { - v.visitFieldInsn(GETSTATIC, UNIT_TYPE.getInternalName(), JvmAbi.INSTANCE_FIELD, UNIT_TYPE.getDescriptor()); + unit().put(UNIT_TYPE, v); + } + + public static StackValue unit() { + return UNIT; } @Override @@ -450,7 +463,7 @@ public abstract class StackValue implements IStackValue { return value instanceof Local || value instanceof Constant; } - private static class None extends StackValueWithoutReceiver { + private static class None extends StackValue { public static final None INSTANCE = new None(); private None() { @@ -458,12 +471,12 @@ public abstract class StackValue implements IStackValue { } @Override - public void put(@NotNull Type type, @NotNull InstructionAdapter v) { + public void putSelector(@NotNull Type type, @NotNull InstructionAdapter v) { coerceTo(type, v); } } - public static class Local extends StackValueWithoutReceiver { + public static class Local extends StackValue { public final int index; private Local(int index, Type type) { @@ -476,7 +489,7 @@ public abstract class StackValue implements IStackValue { } @Override - public void put(@NotNull Type type, @NotNull InstructionAdapter v) { + public void putSelector(@NotNull Type type, @NotNull InstructionAdapter v) { v.load(index, this.type); coerceTo(type, v); // TODO unbox @@ -489,13 +502,13 @@ public abstract class StackValue implements IStackValue { } } - public static class OnStack extends StackValueWithoutReceiver { + public static class OnStack extends StackValue { public OnStack(Type type) { super(type); } @Override - public void put(@NotNull Type type, @NotNull InstructionAdapter v) { + public void putSelector(@NotNull Type type, @NotNull InstructionAdapter v) { coerceTo(type, v); } @@ -523,7 +536,7 @@ public abstract class StackValue implements IStackValue { } } - public static class Constant extends StackValueWithoutReceiver { + public static class Constant extends StackValue { @Nullable private final Object value; @@ -533,7 +546,7 @@ public abstract class StackValue implements IStackValue { } @Override - public void put(@NotNull Type type, @NotNull InstructionAdapter v) { + public void putSelector(@NotNull Type type, @NotNull InstructionAdapter v) { if (value instanceof Integer) { v.iconst((Integer) value); } @@ -567,7 +580,7 @@ public abstract class StackValue implements IStackValue { } } - private static class NumberCompare extends StackValueWithoutReceiver { + private static class NumberCompare extends StackValue { protected final IElementType opToken; protected final Type operandType; protected final StackValue left; @@ -582,7 +595,7 @@ public abstract class StackValue implements IStackValue { } @Override - public void put(@NotNull Type type, @NotNull InstructionAdapter v) { + public void putSelector(@NotNull Type type, @NotNull InstructionAdapter v) { putAsBoolean(v); coerceTo(type, v); } @@ -654,7 +667,7 @@ public abstract class StackValue implements IStackValue { } } - private static class Invert extends StackValueWithoutReceiver { + private static class Invert extends StackValue { private final StackValue myOperand; private Invert(StackValue operand) { @@ -666,7 +679,7 @@ public abstract class StackValue implements IStackValue { } @Override - public void put(@NotNull Type type, @NotNull InstructionAdapter v) { + public void putSelector(@NotNull Type type, @NotNull InstructionAdapter v) { putAsBoolean(v); coerceTo(type, v); } @@ -705,7 +718,7 @@ public abstract class StackValue implements IStackValue { } } - public static class CollectionElementReceiver extends ReadOnlyValue { + public static class CollectionElementReceiver extends StackValue { private final Callable callable; private final boolean isGetter; private final ExpressionCodegen codegen; @@ -752,7 +765,7 @@ public abstract class StackValue implements IStackValue { } @Override - public void put( + public void putSelector( @NotNull Type type, @NotNull InstructionAdapter v ) { ResolvedCall call = isGetter ? resolvedGetCall : resolvedSetCall; @@ -1106,7 +1119,7 @@ public abstract class StackValue implements IStackValue { } } - private static class Expression extends StackValueWithoutReceiver { + private static class Expression extends StackValue { private final JetExpression expression; private final ExpressionCodegen generator; @@ -1117,7 +1130,7 @@ public abstract class StackValue implements IStackValue { } @Override - public void put(@NotNull Type type, @NotNull InstructionAdapter v) { + public void putSelector(@NotNull Type type, @NotNull InstructionAdapter v) { generator.gen(expression, type); } } @@ -1222,7 +1235,7 @@ public abstract class StackValue implements IStackValue { } } - private static class ThisOuter extends StackValueWithoutReceiver { + private static class ThisOuter extends StackValue { private final ExpressionCodegen codegen; private final ClassDescriptor descriptor; private final boolean isSuper; @@ -1237,13 +1250,13 @@ public abstract class StackValue implements IStackValue { } @Override - public void put(@NotNull Type type, @NotNull InstructionAdapter v) { + public void putSelector(@NotNull Type type, @NotNull InstructionAdapter v) { StackValue stackValue = codegen.generateThisOrOuter(descriptor, isSuper); stackValue.put(coerceType ? type : stackValue.type, v); } } - private static class PostIncrement extends StackValueWithoutReceiver { + private static class PostIncrement extends StackValue { private final int index; private final int increment; @@ -1254,7 +1267,7 @@ public abstract class StackValue implements IStackValue { } @Override - public void put(@NotNull Type type, @NotNull InstructionAdapter v) { + public void putSelector(@NotNull Type type, @NotNull InstructionAdapter v) { if (!type.equals(Type.VOID_TYPE)) { v.load(index, Type.INT_TYPE); coerceTo(type, v); @@ -1263,7 +1276,7 @@ public abstract class StackValue implements IStackValue { } } - private static class PreIncrementForLocalVar extends StackValueWithoutReceiver { + private static class PreIncrementForLocalVar extends StackValue { private final int index; private final int increment; @@ -1274,7 +1287,7 @@ public abstract class StackValue implements IStackValue { } @Override - public void put(@NotNull Type type, @NotNull InstructionAdapter v) { + public void putSelector(@NotNull Type type, @NotNull InstructionAdapter v) { v.iinc(index, increment); if (!type.equals(Type.VOID_TYPE)) { v.load(index, Type.INT_TYPE); @@ -1283,7 +1296,7 @@ public abstract class StackValue implements IStackValue { } } - private static class PrefixIncrement extends StackValueWithoutReceiver { + private static class PrefixIncrement extends StackValue { private final int delta; private final Callable callable; private final ResolvedCall resolvedCall; @@ -1307,7 +1320,7 @@ public abstract class StackValue implements IStackValue { } @Override - public void put(@NotNull Type type, @NotNull InstructionAdapter v) { + public void putSelector(@NotNull Type type, @NotNull InstructionAdapter v) { value = StackValue.complexReceiver(value, RECEIVER_READ, RECEIVER_WRITE, RECEIVER_READ); value.put(this.type, v); @@ -1324,7 +1337,7 @@ public abstract class StackValue implements IStackValue { } } - public static class CallReceiver extends StackValueWithoutReceiver { + public static class CallReceiver extends StackValue { private final ResolvedCall resolvedCall; private final StackValue receiver; private final ExpressionCodegen codegen; @@ -1370,7 +1383,7 @@ public abstract class StackValue implements IStackValue { } @Override - public void put(@NotNull Type type, @NotNull InstructionAdapter v) { + public void putSelector(@NotNull Type type, @NotNull InstructionAdapter v) { CallableDescriptor descriptor = resolvedCall.getResultingDescriptor(); ReceiverValue dispatchReceiver = resolvedCall.getDispatchReceiver(); @@ -1378,7 +1391,7 @@ public abstract class StackValue implements IStackValue { int depth = 0; StackValue currentReceiver = receiver; - if (putReceiverArgumentOnStack && extensionReceiver.exists() && receiver instanceof StackValue.Safe) { + if (putReceiverArgumentOnStack && extensionReceiver.exists() && receiver instanceof SafeCall) { currentReceiver.put(currentReceiver.type, v); currentReceiver = StackValue.onStack(currentReceiver.type); } @@ -1449,6 +1462,14 @@ public abstract class StackValue implements IStackValue { } + @Override + public void put(@NotNull Type type, @NotNull InstructionAdapter v, boolean skipReceiver) { + if (!skipReceiver) { + putReceiver(v, true); + } + putSelector(type, v); + } + @Override public void putReceiver(@NotNull InstructionAdapter v, boolean isRead) { if (hasReceiver(isRead)) { @@ -1472,17 +1493,10 @@ public abstract class StackValue implements IStackValue { } @Override - public void put(@NotNull Type type, @NotNull InstructionAdapter v, boolean skipReceiver) { - if (!skipReceiver) { - putReceiver(v, true); - } - putSelector(type, v); - } + public abstract void put(@NotNull Type type, @NotNull InstructionAdapter v, boolean skipReceiver); public abstract void putReceiver(@NotNull InstructionAdapter v, boolean isRead); - public abstract void putSelector(@NotNull Type type, @NotNull InstructionAdapter v); - public abstract boolean hasReceiver(boolean isRead); public int receiverSize() { @@ -1536,35 +1550,19 @@ public abstract class StackValue implements IStackValue { } } - public abstract static class StackValueWithoutReceiver extends StackValue { + static class ComplexReceiver extends StackValue { - public StackValueWithoutReceiver(@NotNull Type type) { - super(type); - } - - @Override - public abstract void put(@NotNull Type type, @NotNull InstructionAdapter v); - - @Override - public void put(@NotNull Type type, @NotNull InstructionAdapter v, boolean skipReceiver) { - put(type, v); - } - } - - - static class ComplexReceiver extends ReadOnlyValue { - - private final StackValueWithSimpleReceiver originalValueWithReceiver; + private final StackValueWithReceiver originalValueWithReceiver; private final int[] operations; - public ComplexReceiver(StackValueWithSimpleReceiver value, int [] operations) { + public ComplexReceiver(StackValueWithReceiver value, int [] operations) { super(value.type); this.originalValueWithReceiver = value; this.operations = operations; } @Override - public void put( + public void putSelector( @NotNull Type type, @NotNull InstructionAdapter v ) { boolean wasPutted = false; @@ -1582,7 +1580,7 @@ public abstract class StackValue implements IStackValue { } } - public static class Receiver extends StackValueWithoutReceiver { + public static class Receiver extends StackValue { private final StackValue[] instructions; @@ -1592,7 +1590,7 @@ public abstract class StackValue implements IStackValue { } @Override - public void put( + public void putSelector( @NotNull Type type, @NotNull InstructionAdapter v ) { for (StackValue instruction : instructions) { @@ -1603,11 +1601,11 @@ public abstract class StackValue implements IStackValue { public static class Delegated extends StackValueWithSimpleReceiver { - public final StackValueWithSimpleReceiver originalValue; + public final StackValueWithReceiver originalValue; public Delegated( @NotNull Type type, - @NotNull StackValueWithSimpleReceiver originalValue, + @NotNull StackValueWithReceiver originalValue, @NotNull StackValue receiver ) { super(type, !originalValue.hasReceiver(true), !originalValue.hasReceiver(false), receiver); @@ -1639,25 +1637,21 @@ public abstract class StackValue implements IStackValue { } private static StackValue complexReceiver(StackValue stackValue, int ... operations) { - if (stackValue instanceof StackValueWithoutReceiver) { - return stackValue; + if (stackValue instanceof StackValueWithReceiver) { + return new Delegated(stackValue.type, (StackValueWithReceiver) stackValue, + new ComplexReceiver((StackValueWithSimpleReceiver) stackValue, operations)); } else { - if (stackValue instanceof StackValueWithSimpleReceiver) { - return new Delegated(stackValue.type, (StackValueWithSimpleReceiver) stackValue, - new ComplexReceiver((StackValueWithSimpleReceiver) stackValue, operations)); - } else { - throw new UnsupportedOperationException(); - } + return stackValue; } } - static class Safe extends StackValueWithoutReceiver { + static class SafeCall extends StackValue { @NotNull private final Type type; private final StackValue receiver; @Nullable private final Label ifNull; - public Safe(@NotNull Type type, @NotNull StackValue value, @Nullable Label ifNull) { + public SafeCall(@NotNull Type type, @NotNull StackValue value, @Nullable Label ifNull) { super(type); this.type = type; this.receiver = value; @@ -1665,7 +1659,7 @@ public abstract class StackValue implements IStackValue { } @Override - public void put(@NotNull Type type, @NotNull InstructionAdapter v) { + public void putSelector(@NotNull Type type, @NotNull InstructionAdapter v) { receiver.put(this.type, v); if (ifNull != null) { //not a primitive diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/StackValue.kt b/compiler/backend/src/org/jetbrains/jet/codegen/StackValue.kt index a8e06a2e854..ff1660ce3e5 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/StackValue.kt +++ b/compiler/backend/src/org/jetbrains/jet/codegen/StackValue.kt @@ -20,14 +20,17 @@ import org.jetbrains.org.objectweb.asm.Type import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter import org.jetbrains.org.objectweb.asm.Label import org.jetbrains.jet.codegen.StackValue.StackValueWithReceiver -import org.jetbrains.jet.codegen.StackValue.StackValueWithoutReceiver import org.jetbrains.jet.codegen.StackValue.StackValueWithSimpleReceiver public fun coercion(value: StackValue, castType: Type): StackValue { return if (value is StackValueWithReceiver) CoercionValueWithReceiver(value, castType) else CoercionValue(value, castType) } -class CoercionValue(val value: StackValue, val castType: Type) : StackValueWithoutReceiver(castType), IStackValue by value +class CoercionValue(val value: StackValue, val castType: Type) : StackValue(castType), IStackValue by value { + override fun putSelector(type: Type, v: InstructionAdapter) { + value.putSelector(type, v) + } +} class CoercionValueWithReceiver( val value: StackValueWithReceiver, @@ -85,23 +88,12 @@ public class StackValueWithLeaveTask( } } -public abstract class ReadOnlyValue(type: Type) : StackValueWithoutReceiver(type) { +open class OperationStackValue(val resultType: Type, val lambda: (v: InstructionAdapter)-> Unit) : StackValue(resultType) { - override fun storeSelector(topOfStackType: Type, v: InstructionAdapter) { - throw UnsupportedOperationException("Read only value could not be stored") - } -} - -open class OperationStackValue(val resultType: Type, val lambda: (v: InstructionAdapter)-> Unit) : ReadOnlyValue(resultType) { - - override fun put(type: Type, v: InstructionAdapter) { + override fun putSelector(type: Type, v: InstructionAdapter) { lambda(v) coerceTo(type, v) } - - override fun storeSelector(topOfStackType: Type, v: InstructionAdapter) { - throw UnsupportedOperationException(); - } } class FunctionCallStackValue(resultType: Type, lambda: (v: InstructionAdapter)-> Unit) : OperationStackValue(resultType, lambda) \ No newline at end of file diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/context/CodegenContext.java b/compiler/backend/src/org/jetbrains/jet/codegen/context/CodegenContext.java index c02715e1f58..e8915ee28bf 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/context/CodegenContext.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/context/CodegenContext.java @@ -26,7 +26,6 @@ import org.jetbrains.jet.codegen.state.JetTypeMapper; import org.jetbrains.jet.lang.descriptors.*; import org.jetbrains.jet.lang.resolve.BindingContext; import org.jetbrains.jet.lang.resolve.DescriptorUtils; -import org.jetbrains.jet.lang.resolve.java.AsmTypeConstants; import org.jetbrains.jet.lang.types.JetType; import org.jetbrains.jet.storage.LockBasedStorageManager; import org.jetbrains.jet.storage.NullableLazyValue; @@ -269,7 +268,7 @@ public abstract class CodegenContext { return canHaveOuter(typeMapper.getBindingContext(), classDescriptor) ? StackValue.field(typeMapper.mapType(enclosingClass), typeMapper.mapType(classDescriptor), - CAPTURED_THIS_FIELD, false, StackValue.thiz()) + CAPTURED_THIS_FIELD, false, StackValue.LOCAL_0) : null; } }); diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/context/LocalLookup.java b/compiler/backend/src/org/jetbrains/jet/codegen/context/LocalLookup.java index 0cf1c02c969..c3dbbd16882 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/context/LocalLookup.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/context/LocalLookup.java @@ -24,7 +24,6 @@ import org.jetbrains.jet.codegen.binding.MutableClosure; import org.jetbrains.jet.codegen.state.GenerationState; import org.jetbrains.jet.lang.descriptors.*; import org.jetbrains.jet.lang.resolve.BindingContext; -import org.jetbrains.jet.lang.resolve.java.AsmTypeConstants; import org.jetbrains.jet.lang.resolve.java.JvmAbi; import org.jetbrains.jet.lang.types.JetType; import org.jetbrains.org.objectweb.asm.Type; @@ -60,7 +59,7 @@ public interface LocalLookup { Type type = sharedVarType != null ? sharedVarType : localType; String fieldName = "$" + vd.getName(); - StackValue.Local thiz = StackValue.thiz(); + StackValue.Local thiz = StackValue.LOCAL_0; StackValue.StackValueWithSimpleReceiver innerValue = sharedVarType != null ? StackValue.fieldForSharedVar(localType, classType, fieldName, thiz) : StackValue.field(type, classType, fieldName, false, thiz); @@ -98,11 +97,12 @@ public interface LocalLookup { if (localFunClosure != null && JvmCodegenUtil.isConst(localFunClosure)) { // This is an optimization: we can obtain an instance of a const closure simply by GETSTATIC ...$instance // (instead of passing this instance to the constructor and storing as a field) - return StackValue.field(localType, localType, JvmAbi.INSTANCE_FIELD, true, StackValue.thiz()); + return StackValue.field(localType, localType, JvmAbi.INSTANCE_FIELD, true, StackValue.LOCAL_0); } String fieldName = "$" + vd.getName(); - StackValue.StackValueWithSimpleReceiver innerValue = StackValue.field(localType, classType, fieldName, false, StackValue.thiz()); + StackValue.StackValueWithSimpleReceiver innerValue = StackValue.field(localType, classType, fieldName, false, + StackValue.LOCAL_0); closure.recordField(fieldName, localType); closure.captureVariable(new EnclosedValueDescriptor(fieldName, d, innerValue, localType)); @@ -131,7 +131,8 @@ public interface LocalLookup { JetType receiverType = closure.getEnclosingReceiverDescriptor().getType(); Type type = state.getTypeMapper().mapType(receiverType); - StackValue.StackValueWithSimpleReceiver innerValue = StackValue.field(type, classType, CAPTURED_RECEIVER_FIELD, false, StackValue.thiz()); + StackValue.StackValueWithSimpleReceiver innerValue = StackValue.field(type, classType, CAPTURED_RECEIVER_FIELD, false, + StackValue.LOCAL_0); closure.setCaptureReceiver(); return innerValue; diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/context/MethodContext.java b/compiler/backend/src/org/jetbrains/jet/codegen/context/MethodContext.java index 9897437adbc..636bec7ff33 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/context/MethodContext.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/context/MethodContext.java @@ -26,12 +26,9 @@ import org.jetbrains.jet.codegen.binding.MutableClosure; import org.jetbrains.jet.codegen.state.GenerationState; import org.jetbrains.jet.codegen.state.JetTypeMapper; import org.jetbrains.jet.lang.descriptors.*; -import org.jetbrains.jet.lang.resolve.java.AsmTypeConstants; import org.jetbrains.org.objectweb.asm.Label; import org.jetbrains.org.objectweb.asm.Type; -import static org.jetbrains.jet.lang.resolve.java.AsmTypeConstants.OBJECT_TYPE; - public class MethodContext extends CodegenContext { private final boolean isInliningLambda; private Label methodStartLabel; @@ -65,7 +62,7 @@ public class MethodContext extends CodegenContext { @Override public StackValue lookupInContext(DeclarationDescriptor d, @Nullable StackValue result, GenerationState state, boolean ignoreNoOuter) { if (getContextDescriptor() == d) { - return result != null ? result : StackValue.thiz(); + return result != null ? result : StackValue.LOCAL_0; } return getParentContext().lookupInContext(d, result, state, ignoreNoOuter); @@ -77,7 +74,7 @@ public class MethodContext extends CodegenContext { return getReceiverExpression(state.getTypeMapper()); } ReceiverParameterDescriptor parameter = descriptor.getExtensionReceiverParameter(); - return lookupInContext(parameter, StackValue.thiz(), state, ignoreNoOuter); + return lookupInContext(parameter, StackValue.LOCAL_0, state, ignoreNoOuter); } @Override diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/inline/AnonymousObjectTransformer.java b/compiler/backend/src/org/jetbrains/jet/codegen/inline/AnonymousObjectTransformer.java index 2ecc1a9f822..54749beba10 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/inline/AnonymousObjectTransformer.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/inline/AnonymousObjectTransformer.java @@ -254,7 +254,7 @@ public class AnonymousObjectTransformer { oldObjectType, fake.getNewFieldName(), false, - StackValue.thiz()); + StackValue.LOCAL_0); fake.setRemapValue(composed); } } @@ -397,7 +397,7 @@ public class AnonymousObjectTransformer { oldObjectType, /*TODO owner type*/ recapturedParamInfo.getNewFieldName(), false, - StackValue.thiz()); + StackValue.LOCAL_0); recapturedParamInfo.setRemapValue(composed); allRecapturedParameters.add(desc); diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/inline/LambdaInfo.java b/compiler/backend/src/org/jetbrains/jet/codegen/inline/LambdaInfo.java index d8e7d06a668..48911b779b6 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/inline/LambdaInfo.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/inline/LambdaInfo.java @@ -112,7 +112,7 @@ public class LambdaInfo implements CapturedParamOwner, LabelOwner { new EnclosedValueDescriptor(AsmUtil.CAPTURED_THIS_FIELD, null, StackValue.field(type, closureClassType, AsmUtil.CAPTURED_THIS_FIELD, false, - StackValue.thiz()), + StackValue.LOCAL_0), type); capturedVars.add(getCapturedParamInfo(descriptor)); } @@ -124,7 +124,7 @@ public class LambdaInfo implements CapturedParamOwner, LabelOwner { AsmUtil.CAPTURED_RECEIVER_FIELD, null, StackValue.field(type, closureClassType, AsmUtil.CAPTURED_RECEIVER_FIELD, false, - StackValue.thiz()), + StackValue.LOCAL_0), type); capturedVars.add(getCapturedParamInfo(descriptor)); } diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/inline/RegeneratedLambdaFieldRemapper.java b/compiler/backend/src/org/jetbrains/jet/codegen/inline/RegeneratedLambdaFieldRemapper.java index 39583c271c4..0ed4db4f395 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/inline/RegeneratedLambdaFieldRemapper.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/inline/RegeneratedLambdaFieldRemapper.java @@ -94,7 +94,7 @@ public class RegeneratedLambdaFieldRemapper extends FieldRemapper { StackValue result = StackValue.field(field.getType(), Type.getObjectType(newOwnerType), /*TODO owner type*/ field.getNewFieldName(), false, - prefix == null ? StackValue.thiz() : prefix); + prefix == null ? StackValue.LOCAL_0 : prefix); return searchInParent ? parent.getFieldForInline(node, result) : result; }