Introduce LOCAL_0 constant and some code cleaning

This commit is contained in:
Michael Bogdanov
2014-11-11 17:29:30 +03:00
parent f00700b58d
commit fe1c6a0ca6
15 changed files with 119 additions and 143 deletions
@@ -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();
@@ -1894,7 +1894,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> 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<StackValue, StackValue> 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<StackValue, StackValue> 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<StackValue, StackValue> 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<StackValue, StackValue> 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<InstructionAdapter, Unit>() {
@Override
@@ -3220,7 +3220,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> 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<StackValue, StackValue> 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<StackValue, StackValue> 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<FunctionDescriptor> 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<StackValue, StackValue> 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<StackValue, StackValue> 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<JetExpression>();
for (ValueArgument va : expression.getValueArguments()) {
@@ -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);
@@ -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)) {
@@ -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<T extends JetElement/* TODO: & JetDeclaratio
JetExpression initializer = property.getDelegateExpressionOrInitializer();
assert initializer != null : "shouldInitializeProperty must return false if initializer is null";
StackValue.Property propValue = codegen.intermediateValueForProperty(propertyDescriptor, true, null, MethodKind.INITIALIZER, StackValue.thiz());
StackValue.Property propValue = codegen.intermediateValueForProperty(propertyDescriptor, true, null, MethodKind.INITIALIZER,
StackValue.LOCAL_0);
propValue.store(codegen.gen(initializer), codegen.v);
@@ -49,7 +49,6 @@ import static org.jetbrains.jet.codegen.JvmCodegenUtil.isInterface;
import static org.jetbrains.jet.codegen.JvmSerializationBindings.*;
import static org.jetbrains.jet.lang.resolve.DescriptorUtils.isClassObject;
import static org.jetbrains.jet.lang.resolve.DescriptorUtils.isTrait;
import static org.jetbrains.jet.lang.resolve.java.AsmTypeConstants.OBJECT_TYPE;
import static org.jetbrains.jet.lang.resolve.java.AsmTypeConstants.PROPERTY_METADATA_TYPE;
import static org.jetbrains.jet.lang.resolve.java.diagnostics.DiagnosticsPackage.OtherOrigin;
import static org.jetbrains.org.objectweb.asm.Opcodes.*;
@@ -380,7 +379,7 @@ public class PropertyCodegen {
public void doGenerateBody(@NotNull ExpressionCodegen codegen, @NotNull JvmMethodSignature signature) {
InstructionAdapter v = codegen.v;
PropertyDescriptor propertyDescriptor = callableDescriptor.getCorrespondingProperty();
StackValue property = codegen.intermediateValueForProperty(propertyDescriptor, true, null, StackValue.thiz());
StackValue property = codegen.intermediateValueForProperty(propertyDescriptor, true, null, StackValue.LOCAL_0);
if (callableDescriptor instanceof PropertyGetterDescriptor) {
Type type = signature.getReturnType();
@@ -425,9 +424,9 @@ public class PropertyCodegen {
codegen.tempVariables.put(
resolvedCall.getCall().getValueArguments().get(propertyMetadataArgumentIndex).asElement(),
new StackValue.StackValueWithoutReceiver(PROPERTY_METADATA_TYPE) {
new StackValue(PROPERTY_METADATA_TYPE) {
@Override
public void put(@NotNull Type type, @NotNull InstructionAdapter v) {
public void putSelector(@NotNull Type type, @NotNull InstructionAdapter v) {
Field array = StackValue
.field(Type.getType("[" + PROPERTY_METADATA_TYPE), owner, JvmAbi.PROPERTY_METADATA_ARRAY_NAME, true,
StackValue.none());
@@ -436,7 +435,7 @@ public class PropertyCodegen {
}
);
StackValue delegatedProperty = codegen.intermediateValueForProperty(propertyDescriptor, true, null, StackValue.thiz());
StackValue delegatedProperty = codegen.intermediateValueForProperty(propertyDescriptor, true, null, StackValue.LOCAL_0);
return codegen.invokeFunction(resolvedCall, delegatedProperty);
}
@@ -195,7 +195,7 @@ public class ScriptCodegen extends MemberCodegen<JetScript> {
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);
@@ -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<InstructionAdapter, Unit>() {
@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
@@ -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)
@@ -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<T extends DeclarationDescriptor> {
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;
}
});
@@ -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;
@@ -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<CallableMemberDescriptor> {
private final boolean isInliningLambda;
private Label methodStartLabel;
@@ -65,7 +62,7 @@ public class MethodContext extends CodegenContext<CallableMemberDescriptor> {
@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<CallableMemberDescriptor> {
return getReceiverExpression(state.getTypeMapper());
}
ReceiverParameterDescriptor parameter = descriptor.getExtensionReceiverParameter();
return lookupInContext(parameter, StackValue.thiz(), state, ignoreNoOuter);
return lookupInContext(parameter, StackValue.LOCAL_0, state, ignoreNoOuter);
}
@Override
@@ -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);
@@ -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));
}
@@ -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;
}