Introduce LOCAL_0 constant and some code cleaning
This commit is contained in:
@@ -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
|
||||
|
||||
+2
-2
@@ -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));
|
||||
}
|
||||
|
||||
+1
-1
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user