Added thiz constant in StackValue, some refactorings

This commit is contained in:
Michael Bogdanov
2014-11-10 19:26:07 +03:00
parent 62cb586397
commit 4cb3d30e5b
20 changed files with 122 additions and 155 deletions
@@ -204,7 +204,7 @@ public class ClosureCodegen extends ParentCodegenAware {
}
@NotNull
public StackValue putInstanceOnStack(@NotNull InstructionAdapter v, @NotNull final ExpressionCodegen codegen) {
public StackValue putInstanceOnStack(@NotNull final ExpressionCodegen codegen) {
return StackValue.operation(asmType, new Function1<InstructionAdapter, Unit>() {
@Override
public Unit invoke(InstructionAdapter v) {
@@ -215,8 +215,8 @@ public class ClosureCodegen extends ParentCodegenAware {
v.anew(asmType);
v.dup();
codegen.pushClosureOnStack(classDescriptor, true, codegen.defaultCallGenerator);
v.invokespecial(asmType.getInternalName(), "<init>", constructor.getDescriptor(), false);
codegen.pushClosureOnStack(classDescriptor, true, codegen.defaultCallGenerator);
v.invokespecial(asmType.getInternalName(), "<init>", constructor.getDescriptor(), false);
}
return Unit.INSTANCE$;
}
@@ -24,7 +24,6 @@ import com.intellij.psi.tree.IElementType;
import com.intellij.util.ArrayUtil;
import com.intellij.util.Function;
import com.intellij.util.containers.Stack;
import jet.runtime.typeinfo.JetValueParameter;
import kotlin.*;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -246,9 +245,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
@NotNull ClassDescriptor required
) {
if (!isInterface(provided) && isInterface(required)) {
//TODO: is needed double wrapping?
Type type = asmType(required.getDefaultType());
return StackValue.lazyCast(StackValue.lazyCast(inner, OBJECT_TYPE), type);
return StackValue.coercion(inner, asmType(required.getDefaultType()));
}
return inner;
@@ -307,7 +304,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
public StackValue genLazy(JetElement expr, Type type) {
StackValue value = gen(expr);
return StackValue.lazyCast(value, type);
return StackValue.coercion(value, type);
}
private StackValue genStatement(JetElement statement) {
@@ -421,7 +418,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
if (isEmptyExpression(thenExpression)) {
if (isEmptyExpression(elseExpression)) {
return StackValue.lazyCast(condition, asmType);
return StackValue.coercion(condition, asmType);
}
return generateSingleBranchIf(condition, expression, elseExpression, false, isStatement);
}
@@ -433,7 +430,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
return StackValue.operation(asmType, new Function1<InstructionAdapter, Unit>() {
@Override
public Unit invoke(@JetValueParameter(name = "p1") InstructionAdapter adapter) {
public Unit invoke(InstructionAdapter v) {
Label elseLabel = new Label();
condition.condJump(elseLabel, true, v); // == 0, i.e. false
@@ -783,7 +780,8 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
LOOP_RANGE_HAS_NEXT_RESOLVED_CALL, loopRange,
"No hasNext() function " + DiagnosticUtils.atLocation(loopRange));
@SuppressWarnings("ConstantConditions") Call fakeCall = makeFakeCall(new TransientReceiver(iteratorCall.getResultingDescriptor().getReturnType()));
invokeFunctionNotLazy(fakeCall, hasNextCall, StackValue.local(iteratorVarIndex, asmTypeForIterator));
StackValue result = invokeFunction(fakeCall, hasNextCall, StackValue.local(iteratorVarIndex, asmTypeForIterator));
result.put(result.type, v);
JetType type = hasNextCall.getResultingDescriptor().getReturnType();
assert type != null && JetTypeChecker.DEFAULT.isSubtypeOf(type, KotlinBuiltIns.getInstance().getBooleanType());
@@ -1246,7 +1244,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
Type targetType = isStatement ? Type.VOID_TYPE : expressionType(ifExpression);
return StackValue.operation(targetType, new Function1<InstructionAdapter, Unit>() {
@Override
public Unit invoke(InstructionAdapter adapter) {
public Unit invoke(InstructionAdapter v) {
Label elseLabel = new Label();
condition.condJump(elseLabel, inverse, v);
@@ -1318,7 +1316,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
else {
return StackValue.operation(AsmTypeConstants.JAVA_STRING_TYPE, new Function1<InstructionAdapter, Unit>() {
@Override
public Unit invoke(InstructionAdapter adapter) {
public Unit invoke(InstructionAdapter v) {
genStringBuilderConstructor(v);
for (JetStringTemplateEntry entry : entries) {
if (entry instanceof JetStringTemplateEntryWithExpression) {
@@ -1408,7 +1406,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
parentCodegen.setWereReifierMarkers(true);
}
return closureCodegen.putInstanceOnStack(v, this);
return closureCodegen.putInstanceOnStack(this);
}
@Override
@@ -1830,7 +1828,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
IntrinsicMethod intrinsic = state.getIntrinsics().getIntrinsic(memberDescriptor);
if (intrinsic != null) {
Type returnType = typeMapper.mapType(memberDescriptor);
return intrinsic.generate(this, v, returnType, expression, Collections.<JetExpression>emptyList(), receiver);
return intrinsic.generate(this, returnType, expression, Collections.<JetExpression>emptyList(), receiver);
}
}
@@ -1882,7 +1880,6 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
ValueParameterDescriptor valueParameterDescriptor = (ValueParameterDescriptor) descriptor;
ClassDescriptor scriptClass = bindingContext.get(CLASS_FOR_SCRIPT, scriptDescriptor);
StackValue script = StackValue.thisOrOuter(this, scriptClass, false, false);
//script.put(script.type, v);
Type fieldType = typeMapper.mapType(valueParameterDescriptor);
return StackValue.field(fieldType, scriptClassType, valueParameterDescriptor.getName().getIdentifier(), false, script);
}
@@ -1897,7 +1894,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
return stackValueForLocal(descriptor, index);
}
return context.lookupInContext(descriptor, StackValue.local(0, OBJECT_TYPE), state, false);
return context.lookupInContext(descriptor, StackValue.thiz(), state, false);
}
@@ -2146,17 +2143,6 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
return invokeFunction(resolvedCall.getCall(), resolvedCall, receiver);
}
@NotNull
public void invokeFunctionNotLazy(@NotNull ResolvedCall<?> resolvedCall, @NotNull StackValue receiver) {
StackValue result = invokeFunction(resolvedCall.getCall(), resolvedCall, receiver);
result.put(result.type, v);
}
public void invokeFunctionNotLazy(@NotNull Call call, @NotNull ResolvedCall<?> resolvedCall, @NotNull StackValue receiver) {
StackValue result = invokeFunction(call, resolvedCall, receiver);
result.put(result.type, v);
}
@NotNull
public StackValue invokeFunction(@NotNull Call call, @NotNull final ResolvedCall<?> resolvedCall, @NotNull final StackValue receiver) {
if (resolvedCall instanceof VariableAsFunctionResolvedCall) {
@@ -2182,7 +2168,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
if (callable instanceof CallableMethod) {
return StackValue.functionCall(returnType, new Function1<InstructionAdapter, Unit>() {
@Override
public Unit invoke(InstructionAdapter adapter) {
public Unit invoke(InstructionAdapter v) {
CallableMethod callableMethod = (CallableMethod) callable;
invokeMethodWithArguments(callableMethod, resolvedCall, receiver);
@@ -2199,7 +2185,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
args.add(argument.getArgumentExpression());
}
return ((IntrinsicMethod) callable).generate(this, v, returnType, call.getCallElement(), args, newReceiver);
return ((IntrinsicMethod) callable).generate(this, returnType, call.getCallElement(), args, newReceiver);
}
}
@@ -2357,7 +2343,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.local(0, OBJECT_TYPE);
return StackValue.thiz();
}
else {
return StackValue.singleton(receiverDescriptor, typeMapper);
@@ -2399,7 +2385,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.local(0, OBJECT_TYPE);
StackValue result = StackValue.thiz();
boolean inStartConstructorContext = cur instanceof ConstructorContext;
while (cur != null) {
if (!inStartConstructorContext) {
@@ -2568,7 +2554,6 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
FunctionDescriptor functionDescriptor = bindingContext.get(FUNCTION, expression);
if (functionDescriptor != null) {
CallableReferenceGenerationStrategy strategy = new CallableReferenceGenerationStrategy(state, functionDescriptor, resolvedCall);
return genClosure(expression, functionDescriptor, strategy, null, KotlinSyntheticClass.Kind.CALLABLE_REFERENCE_WRAPPER);
}
@@ -2616,7 +2601,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
return StackValue.operation(factoryMethod.getReturnType(), new Function1<InstructionAdapter, Unit>() {
@Override
public Unit invoke(InstructionAdapter adapter) {
public Unit invoke(InstructionAdapter v) {
v.visitLdcInsn(descriptor.getName().asString());
v.getstatic(packageClassInternalName, JvmAbi.KOTLIN_PACKAGE_FIELD_NAME, K_PACKAGE_IMPL_TYPE.getDescriptor());
@@ -2789,7 +2774,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
Type type = expressionType(expression);
if (expression instanceof JetSafeQualifiedExpression && !isPrimitive(type)) {
return StackValue.lazyCast(generateSafeQualifiedExpression((JetSafeQualifiedExpression) expression, ifnull), type);
return StackValue.coercion(generateSafeQualifiedExpression((JetSafeQualifiedExpression) expression, ifnull), type);
}
else {
return genLazy(expression, type);
@@ -2803,6 +2788,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
Type receiverType = expressionType(receiver);
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);
return genQualified(newReceiver, selector);
}
@@ -2813,13 +2799,12 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
Type type = boxType(expressionType(expression));
StackValue value = generateSafeQualifiedExpression(expression, ifnull);
StackValue newReceiver = StackValue.lazyCast(value, type);
StackValue newReceiver = StackValue.coercion(value, type);
StackValue result;
if (!isPrimitive(expressionType(expression.getReceiverExpression()))) {
result = new StackValue.SafeFallback(type, ifnull, newReceiver);
} else {
//TODO safefallbacl
result = newReceiver;
}
@@ -2863,7 +2848,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
Callable callable = resolveToCallable(descriptor, false);
if (callable instanceof IntrinsicMethod) {
Type returnType = typeMapper.mapType(descriptor);
return ((IntrinsicMethod) callable).generate(this, v, returnType, expression,
return ((IntrinsicMethod) callable).generate(this, returnType, expression,
Arrays.asList(expression.getLeft(), expression.getRight()), receiver);
}
@@ -2875,13 +2860,14 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
final JetExpression deparenthesized = JetPsiUtil.deparenthesize(rangeExpression);
return StackValue.operation(Type.BOOLEAN_TYPE, new Function1<InstructionAdapter, Unit>() {
@Override
public Unit invoke(InstructionAdapter adapter) {
public Unit invoke(InstructionAdapter v) {
if (isIntRangeExpr(deparenthesized)) {
genInIntRange(leftValue, (JetBinaryExpression) deparenthesized);
}
else {
ResolvedCall<? extends CallableDescriptor> resolvedCall = getResolvedCallWithAssert(operationReference, bindingContext);
invokeFunctionNotLazy(resolvedCall, StackValue.none());
StackValue result = invokeFunction(resolvedCall.getCall(), resolvedCall, StackValue.none());
result.put(result.type, v);
}
if (operationReference.getReferencedNameElementType() == JetTokens.NOT_IN) {
genInvertBoolean(v);
@@ -2930,7 +2916,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
private StackValue generateBooleanAnd(final JetBinaryExpression expression) {
return StackValue.operation(Type.BOOLEAN_TYPE, new Function1<InstructionAdapter, Unit>() {
@Override
public Unit invoke(InstructionAdapter adapter) {
public Unit invoke(InstructionAdapter v) {
gen(expression.getLeft(), Type.BOOLEAN_TYPE);
Label ifFalse = new Label();
v.ifeq(ifFalse);
@@ -2948,7 +2934,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
private StackValue generateBooleanOr(final JetBinaryExpression expression) {
return StackValue.operation(Type.BOOLEAN_TYPE, new Function1<InstructionAdapter, Unit>() {
@Override
public Unit invoke(InstructionAdapter adapter) {
public Unit invoke(InstructionAdapter v) {
gen(expression.getLeft(), Type.BOOLEAN_TYPE);
Label ifTrue = new Label();
v.ifne(ifTrue);
@@ -2999,7 +2985,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
private StackValue genCmpWithZero(final JetExpression exp, final Type expType, final IElementType opToken) {
return StackValue.operation(Type.BOOLEAN_TYPE, new Function1<InstructionAdapter, Unit>() {
@Override
public Unit invoke(InstructionAdapter adapter) {
public Unit invoke(InstructionAdapter v) {
gen(exp, expType);
Label trueLabel = new Label();
Label afterLabel = new Label();
@@ -3105,7 +3091,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
}
else {
type = Type.INT_TYPE;
leftValue = StackValue.lazyCast(invokeFunction(resolvedCall, receiver), type);
leftValue = StackValue.coercion(invokeFunction(resolvedCall, receiver), type);
rightValue = StackValue.constant(0, type);
}
return StackValue.cmp(expression.getOperationToken(), type, leftValue, rightValue);
@@ -3135,7 +3121,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
value.put(lhsType, v); // receiver lhs
Type returnType = typeMapper.mapType(descriptor);
StackValue rightSide = ((IntrinsicMethod) callable).generate(this, v, returnType, expression,
StackValue rightSide = ((IntrinsicMethod) callable).generate(this, returnType, expression,
Collections.singletonList(expression.getRight()), StackValue.onStack(lhsType));
value.store(rightSide, v, true);
return StackValue.none();
@@ -3220,7 +3206,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
Callable callable = resolveToCallable((FunctionDescriptor) op, false);
if (callable instanceof IntrinsicMethod) {
Type returnType = typeMapper.mapType(op);
return ((IntrinsicMethod) callable).generate(this, v, returnType, expression,
return ((IntrinsicMethod) callable).generate(this, returnType, expression,
Collections.singletonList(expression.getBaseExpression()), receiver);
}
@@ -3296,7 +3282,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
return StackValue.operation(asmResultType, new Function1<InstructionAdapter, Unit>() {
@Override
public Unit invoke(InstructionAdapter adapter) {
public Unit invoke(InstructionAdapter v) {
StackValue value = gen(expression.getBaseExpression());
value = StackValue.complexWriteReadReceiver(value);
@@ -3364,7 +3350,8 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
ResolvedCall<FunctionDescriptor> resolvedCall = bindingContext.get(COMPONENT_RESOLVED_CALL, variableDeclaration);
assert resolvedCall != null : "Resolved call is null for " + variableDeclaration.getText();
Call call = makeFakeCall(initializerAsReceiver);
invokeFunctionNotLazy(call, resolvedCall, local);
StackValue result = invokeFunction(call, resolvedCall, local);
result.put(result.type, v);
return null;
}
});
@@ -3480,7 +3467,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
return StackValue.operation(type, new Function1<InstructionAdapter, Unit>() {
@Override
public Unit invoke(InstructionAdapter adapter) {
public Unit invoke(InstructionAdapter v) {
gen(args.get(0), Type.INT_TYPE);
newArrayInstruction(arrayType);
@@ -3664,7 +3651,7 @@ The "returned" value of try expression with no finally is either the last expres
return StackValue.operation(expectedAsmType, new Function1<InstructionAdapter, Unit>() {
@Override
public Unit invoke(InstructionAdapter adapter) {
public Unit invoke(InstructionAdapter v) {
JetFinallySection finallyBlock = expression.getFinallyBlock();
FinallyBlockStackElement finallyBlockStackElement = null;
@@ -3815,7 +3802,7 @@ The "returned" value of try expression with no finally is either the last expres
return StackValue.operation(rightTypeAsm, new Function1<InstructionAdapter, Unit>() {
@Override
public Unit invoke(InstructionAdapter adapter) {
public Unit invoke(InstructionAdapter v) {
value.put(boxType(value.type), v);
if (opToken != JetTokens.AS_SAFE) {
@@ -3875,7 +3862,7 @@ The "returned" value of try expression with no finally is either the last expres
condType = OBJECT_TYPE;
}
StackValue condition = genLazy(patternExpression, condType);
return genEqualsForExpressionsOnStack(JetTokens.EQEQ, StackValue.lazyCast(expressionToMatch, subjectType), condition);
return genEqualsForExpressionsOnStack(JetTokens.EQEQ, StackValue.coercion(expressionToMatch, subjectType), condition);
}
else {
return gen(patternExpression);
@@ -3957,7 +3944,7 @@ The "returned" value of try expression with no finally is either the last expres
return StackValue.operation(resultType, new Function1<InstructionAdapter, Unit>() {
@Override
public Unit invoke(InstructionAdapter adapter) {
public Unit invoke(InstructionAdapter v) {
SwitchCodegen switchCodegen =
SwitchCodegenUtil.buildAppropriateSwitchCodegenIfPossible(expression, isStatement, ExpressionCodegen.this);
if (switchCodegen != null) {
@@ -21,12 +21,14 @@ import org.jetbrains.org.objectweb.asm.Label;
import org.jetbrains.org.objectweb.asm.Type;
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter;
public interface StackValueI {
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 store(@NotNull Type topOfStackType, @NotNull InstructionAdapter v);
void store(@NotNull StackValue value, @NotNull InstructionAdapter v);
@@ -800,10 +800,9 @@ 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;
codegen.v.load(0, thisDescriptorType);
Type propertyType = typeMapper.mapType(property);
codegen.intermediateValueForProperty(property, false, null, StackValue.none())
.putNoReceiver(propertyType, codegen.v);
codegen.intermediateValueForProperty(property, false, null, StackValue.thiz())
.put(propertyType, codegen.v);
}
},
null
@@ -899,7 +898,9 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
public void doGenerateBody(@NotNull ExpressionCodegen codegen, @NotNull JvmMethodSignature signature) {
boolean forceField = AsmUtil.isPropertyWithBackingFieldInOuterClass(original) &&
!isClassObject(bridge.getContainingDeclaration());
StackValue property = codegen.intermediateValueForProperty(original, forceField, null, MethodKind.SYNTHETIC_ACCESSOR, StackValue.none());
StackValue property =
codegen.intermediateValueForProperty(original, forceField, null, MethodKind.SYNTHETIC_ACCESSOR,
StackValue.none());
InstructionAdapter iv = codegen.v;
@@ -1135,7 +1136,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
}
if (isObject(descriptor)) {
StackValue.singleton(descriptor, typeMapper).store(StackValue.local(0, classAsmType), iv);
StackValue.singleton(descriptor, typeMapper).store(StackValue.thiz(), iv);
}
for (JetDelegationSpecifier specifier : myClass.getDelegationSpecifiers()) {
@@ -1301,7 +1302,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
}
else return;
constructorContext.lookupInContext(toLookup, StackValue.local(0, OBJECT_TYPE), state, true);
constructorContext.lookupInContext(toLookup, StackValue.thiz(), state, true);
}
@Override
@@ -1310,7 +1311,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.local(0, OBJECT_TYPE), state, true);
context.lookupInContext(descriptor, StackValue.thiz(), state, true);
}
if (descriptor instanceof CallableDescriptor) {
@@ -1345,7 +1346,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.local(0, OBJECT_TYPE), state, true);
constructorContext.lookupInContext(superClass.getContainingDeclaration(), StackValue.thiz(), state, true);
}
if (!isAnonymousObject(descriptor)) {
@@ -238,7 +238,7 @@ public abstract class MemberCodegen<T extends JetElement/* TODO: & JetDeclaratio
JetType jetType = getPropertyOrDelegateType(property, propertyDescriptor);
StackValue.Property propValue = codegen.intermediateValueForProperty(propertyDescriptor, true, null, MethodKind.INITIALIZER, StackValue.local(0, OBJECT_TYPE));
StackValue.Property propValue = codegen.intermediateValueForProperty(propertyDescriptor, true, null, MethodKind.INITIALIZER, StackValue.thiz());
Type type = codegen.expressionType(initializer);
if (jetType.isNullable()) {
@@ -380,7 +380,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.local(0, OBJECT_TYPE));
StackValue property = codegen.intermediateValueForProperty(propertyDescriptor, true, null, StackValue.thiz());
if (callableDescriptor instanceof PropertyGetterDescriptor) {
Type type = signature.getReturnType();
@@ -436,7 +436,7 @@ public class PropertyCodegen {
}
);
StackValue delegatedProperty = codegen.intermediateValueForProperty(propertyDescriptor, true, null, StackValue.local(0, OBJECT_TYPE));
StackValue delegatedProperty = codegen.intermediateValueForProperty(propertyDescriptor, true, null, StackValue.thiz());
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.local(0, classType));
.field(blockType, classType, ScriptDescriptor.LAST_EXPRESSION_VALUE_FIELD_NAME, false, StackValue.thiz());
resultValue.store(stackValue, iv);
} else {
stackValue.put(blockType, iv);
@@ -47,7 +47,7 @@ import static org.jetbrains.jet.codegen.AsmUtil.*;
import static org.jetbrains.jet.lang.resolve.java.AsmTypeConstants.*;
import static org.jetbrains.org.objectweb.asm.Opcodes.*;
public abstract class StackValue implements StackValueI {
public abstract class StackValue implements IStackValue {
private static final String NULLABLE_BYTE_TYPE_NAME = "java/lang/Byte";
private static final String NULLABLE_SHORT_TYPE_NAME = "java/lang/Short";
@@ -77,7 +77,9 @@ public abstract class StackValue implements StackValueI {
}
@Override
public abstract void put(@NotNull Type type, @NotNull InstructionAdapter v);
public void put(@NotNull Type type, @NotNull InstructionAdapter v) {
put(type, v, false);
}
@Override
public void dup(@NotNull InstructionAdapter v, boolean withReceiver) {
@@ -126,6 +128,10 @@ public abstract class StackValue implements StackValueI {
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);
@@ -373,8 +379,8 @@ public abstract class StackValue implements StackValueI {
return new FieldForSharedVar(field.type, field.owner, field.name, newSharedVarReceiver);
}
public static StackValue lazyCast(@NotNull StackValue receiver, @NotNull Type type) {
return CodegenPackage.castValue(receiver, type);
public static StackValue coercion(@NotNull StackValue receiver, @NotNull Type type) {
return CodegenPackage.coercion(receiver, type);
}
public static StackValue thisOrOuter(@NotNull ExpressionCodegen codegen, @NotNull ClassDescriptor descriptor, boolean isSuper, boolean isExplicit) {
@@ -929,7 +935,7 @@ public abstract class StackValue implements StackValueI {
((CallableMethod) getter).invokeWithNotNullAssertion(v, state, resolvedGetCall);
}
else {
StackValue result = ((IntrinsicMethod) getter).generate(codegen, v, this.type, null, null, null);
StackValue result = ((IntrinsicMethod) getter).generate(codegen, this.type, null, null, null);
result.put(result.type, v);
}
coerceTo(type, v);
@@ -994,7 +1000,7 @@ public abstract class StackValue implements StackValueI {
}
else {
//noinspection ConstantConditions
StackValue result = ((IntrinsicMethod) setter).generate(codegen, v, null, null, null, null);
StackValue result = ((IntrinsicMethod) setter).generate(codegen, null, null, null, null);
result.put(result.type, v);
}
}
@@ -1311,7 +1317,7 @@ public abstract class StackValue implements StackValueI {
value.store(StackValue.onStack(this.type), v, true);
}
putNoReceiver(value, this.type, v);
value.put(this.type, v, true);
coerceTo(type, v);
}
}
@@ -1440,16 +1446,6 @@ public abstract class StackValue implements StackValueI {
this.isStaticStore = isStaticStore;
}
@Override
public void put(
@NotNull Type type, @NotNull InstructionAdapter v
) {
putReceiver(v, true);
putNoReceiver(type, v);
}
@Override
public abstract void putNoReceiver(@NotNull Type type, @NotNull InstructionAdapter v);
@Override
public void putReceiver(@NotNull InstructionAdapter v, boolean isRead) {
@@ -1473,6 +1469,14 @@ public abstract class StackValue implements StackValueI {
this.receiver = receiver;
}
@Override
public void put(@NotNull Type type, @NotNull InstructionAdapter v, boolean skipReceiver) {
if (!skipReceiver) {
putReceiver(v, true);
}
putNoReceiver(type, v);
}
public abstract void putReceiver(@NotNull InstructionAdapter v, boolean isRead);
public abstract void putNoReceiver(@NotNull Type type, @NotNull InstructionAdapter v);
@@ -1530,25 +1534,19 @@ public abstract class StackValue implements StackValueI {
}
}
public abstract static class ReadOnlyValue extends StackValueWithoutReceiver {
public ReadOnlyValue(@NotNull Type type) {
super(type);
}
@Override
public void store(
@NotNull Type topOfStackType, @NotNull InstructionAdapter v
) {
throw new UnsupportedOperationException("Read only value could be stored");
}
}
public abstract static class StackValueWithoutReceiver 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);
}
}
@@ -1582,7 +1580,7 @@ public abstract class StackValue implements StackValueI {
}
}
public static class Receiver extends StackValue {
public static class Receiver extends StackValueWithoutReceiver {
private final StackValue[] instructions;
@@ -1651,14 +1649,6 @@ public abstract class StackValue implements StackValueI {
}
}
private static void putNoReceiver(StackValue value, Type type, InstructionAdapter iv) {
if (value instanceof StackValueWithSimpleReceiver) {
((StackValueWithSimpleReceiver) value).putNoReceiver(type, iv);
} else {
value.put(type, iv);
}
}
static class Safe extends StackValueWithoutReceiver {
@NotNull private final Type type;
@@ -23,14 +23,16 @@ import org.jetbrains.jet.codegen.StackValue.StackValueWithReceiver
import org.jetbrains.jet.codegen.StackValue.StackValueWithoutReceiver
import org.jetbrains.jet.codegen.StackValue.StackValueWithSimpleReceiver
public fun castValue(value: StackValue, castType: Type): StackValue {
return if (value is StackValueWithReceiver) CastValueWithReceiver(value, castType) else CastValue(value, castType)
public fun coercion(value: StackValue, castType: Type): StackValue {
return if (value is StackValueWithReceiver) CoercionValueWithReceiver(value, castType) else CoercionValue(value, castType)
}
class CastValueWithReceiver(val value: StackValueWithReceiver, val castType: Type) : StackValueWithSimpleReceiver(castType, !value.hasReceiver(true), !value.hasReceiver(false), value.receiver), StackValueI by value {
class CoercionValue(val value: StackValue, val castType: Type) : StackValueWithoutReceiver(castType), IStackValue by value
class CoercionValueWithReceiver(val value: StackValueWithReceiver, val castType: Type) : StackValueWithSimpleReceiver(castType, !value.hasReceiver(true), !value.hasReceiver(false), value.receiver), IStackValue by value {
override fun putReceiver(v: InstructionAdapter, isRead: Boolean) {
value.putReceiver(v, isRead )
value.putReceiver(v, isRead)
}
override fun putNoReceiver(type: Type, v: InstructionAdapter) {
@@ -42,23 +44,8 @@ class CastValueWithReceiver(val value: StackValueWithReceiver, val castType: Typ
}
}
class CastValue(val value: StackValue, val castType: Type) : StackValueWithoutReceiver(castType), StackValueI by value {
}
class FunctionCallStackValue(val resultType: Type, val lambda: (v: InstructionAdapter)-> Unit) : StackValueWithoutReceiver(resultType) {
override fun put(type: Type, v: InstructionAdapter) {
lambda(v)
coerceTo(type, v)
}
override fun store(topOfStackType: Type, v: InstructionAdapter) {
throw UnsupportedOperationException();
}
}
public class StackValueWithLeaveTask(val stackValue: StackValue, val leaveTasks: StackValueWithLeaveTask.()-> Unit) : StackValueWithReceiver(stackValue.type, if (stackValue is StackValueWithReceiver) stackValue.receiver else StackValue.none()), StackValueI by stackValue {
public class StackValueWithLeaveTask(val stackValue: StackValue, val leaveTasks: StackValueWithLeaveTask.()-> Unit) : StackValueWithReceiver(stackValue.type, if (stackValue is StackValueWithReceiver) stackValue.receiver else StackValue.none()), IStackValue by stackValue {
override fun put(type: Type, v: InstructionAdapter) {
stackValue.put(type, v)
@@ -89,7 +76,14 @@ public class StackValueWithLeaveTask(val stackValue: StackValue, val leaveTasks:
}
}
class OperationStackValue(val resultType: Type, val lambda: (v: InstructionAdapter)-> Unit) : StackValueWithoutReceiver(resultType) {
public abstract class ReadOnlyValue(type: Type) : StackValueWithoutReceiver(type) {
override fun store(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) {
lambda(v)
@@ -99,4 +93,6 @@ class OperationStackValue(val resultType: Type, val lambda: (v: InstructionAdapt
override fun store(topOfStackType: Type, v: InstructionAdapter) {
throw UnsupportedOperationException();
}
}
}
class FunctionCallStackValue(resultType: Type, lambda: (v: InstructionAdapter)-> Unit) : OperationStackValue(resultType, lambda)
@@ -269,7 +269,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.local(0, AsmTypeConstants.OBJECT_TYPE))
CAPTURED_THIS_FIELD, false, StackValue.thiz())
: null;
}
});
@@ -291,7 +291,6 @@ public abstract class CodegenContext<T extends DeclarationDescriptor> {
break;
}
else {
//return result == null ? innerValue : composedOrStatic(result, innerValue);
return StackValue.changeReceiverForFieldAndSharedVar(innerValue, result);
}
}
@@ -442,14 +441,6 @@ public abstract class CodegenContext<T extends DeclarationDescriptor> {
return childContexts == null ? null : childContexts.get(child);
}
//@NotNull
//private static StackValue composedOrStatic(@NotNull StackValue prefix, @NotNull StackValue suffix) {
// if (isStaticField(suffix)) {
// return suffix;
// }
// return StackValue.composed(prefix, suffix);
//}
private static boolean isStaticField(@NotNull StackValue value) {
return value instanceof StackValue.Field && ((StackValue.Field) value).isStaticPut;
}
@@ -60,7 +60,7 @@ public interface LocalLookup {
Type type = sharedVarType != null ? sharedVarType : localType;
String fieldName = "$" + vd.getName();
StackValue.Local thiz = StackValue.local(0, AsmTypeConstants.OBJECT_TYPE);
StackValue.Local thiz = StackValue.thiz();
StackValue.StackValueWithSimpleReceiver innerValue = sharedVarType != null
? StackValue.fieldForSharedVar(localType, classType, fieldName, thiz)
: StackValue.field(type, classType, fieldName, false, thiz);
@@ -98,11 +98,11 @@ 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.local(0, AsmTypeConstants.OBJECT_TYPE));
return StackValue.field(localType, localType, JvmAbi.INSTANCE_FIELD, true, StackValue.thiz());
}
String fieldName = "$" + vd.getName();
StackValue.StackValueWithSimpleReceiver innerValue = StackValue.field(localType, classType, fieldName, false, StackValue.local(0, AsmTypeConstants.OBJECT_TYPE));
StackValue.StackValueWithSimpleReceiver innerValue = StackValue.field(localType, classType, fieldName, false, StackValue.thiz());
closure.recordField(fieldName, localType);
closure.captureVariable(new EnclosedValueDescriptor(fieldName, d, innerValue, localType));
@@ -131,7 +131,7 @@ 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.local(0, AsmTypeConstants.OBJECT_TYPE));
StackValue.StackValueWithSimpleReceiver innerValue = StackValue.field(type, classType, CAPTURED_RECEIVER_FIELD, false, StackValue.thiz());
closure.setCaptureReceiver();
return innerValue;
@@ -65,7 +65,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.local(0, AsmTypeConstants.OBJECT_TYPE);
return result != null ? result : StackValue.thiz();
}
return getParentContext().lookupInContext(d, result, state, ignoreNoOuter);
@@ -77,7 +77,7 @@ public class MethodContext extends CodegenContext<CallableMemberDescriptor> {
return getReceiverExpression(state.getTypeMapper());
}
ReceiverParameterDescriptor parameter = descriptor.getExtensionReceiverParameter();
return lookupInContext(parameter, StackValue.local(0, OBJECT_TYPE), state, ignoreNoOuter);
return lookupInContext(parameter, StackValue.thiz(), state, ignoreNoOuter);
}
@Override
@@ -254,7 +254,7 @@ public class AnonymousObjectTransformer {
oldObjectType,
fake.getNewFieldName(),
false,
StackValue.local(0, oldObjectType));
StackValue.thiz());
fake.setRemapValue(composed);
}
}
@@ -397,7 +397,7 @@ public class AnonymousObjectTransformer {
oldObjectType, /*TODO owner type*/
recapturedParamInfo.getNewFieldName(),
false,
StackValue.local(0, oldObjectType));
StackValue.thiz());
recapturedParamInfo.setRemapValue(composed);
allRecapturedParameters.add(desc);
@@ -339,7 +339,8 @@ public class InlineCodegen implements CallGenerator {
StackValue receiver = null;
if (stackValue instanceof StackValue.Field) {
receiver = ((StackValue.Field) stackValue).receiver;
} else if(stackValue instanceof StackValue.FieldForSharedVar) {
}
else if (stackValue instanceof StackValue.FieldForSharedVar) {
receiver = ((StackValue.Field) ((StackValue.FieldForSharedVar) stackValue).receiver).receiver;
}
@@ -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.local(0, AsmTypeConstants.OBJECT_TYPE)),
StackValue.thiz()),
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.local(0, AsmTypeConstants.OBJECT_TYPE)),
StackValue.thiz()),
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.local(0, Type.getObjectType(getLambdaInternalName())) : prefix);
prefix == null ? StackValue.thiz() : prefix);
return searchInParent ? parent.getFieldForInline(node, result) : result;
}
@@ -45,7 +45,7 @@ public class Equals extends IntrinsicMethod {
StackValue leftExpr;
JetExpression rightExpr;
if (element instanceof JetCallExpression) {
leftExpr = StackValue.lazyCast(receiver, OBJECT_TYPE);
leftExpr = StackValue.coercion(receiver, OBJECT_TYPE);
rightExpr = arguments.get(0);
}
else {
@@ -45,7 +45,7 @@ public class IdentityEquals extends IntrinsicMethod {
StackValue left;
StackValue right;
if (element instanceof JetCallExpression) {
left = StackValue.lazyCast(receiver, OBJECT_TYPE);
left = StackValue.coercion(receiver, OBJECT_TYPE);
right = codegen.genLazy(arguments.get(0), OBJECT_TYPE);
}
else {
@@ -33,7 +33,6 @@ import java.util.List;
public abstract class IntrinsicMethod implements Callable {
public final StackValue generate(
@NotNull final ExpressionCodegen codegen,
@NotNull final InstructionAdapter v,
@NotNull final Type returnType,
@Nullable final PsiElement element,
@Nullable final List<JetExpression> arguments,
@@ -42,7 +41,7 @@ public abstract class IntrinsicMethod implements Callable {
return StackValue.operation(returnType, new Function1<InstructionAdapter, Unit>() {
@Override
public Unit invoke(InstructionAdapter adapter) {
public Unit invoke(InstructionAdapter v) {
Type actualType = generateImpl(codegen, v, returnType, element, arguments, receiver);
StackValue.coerce(actualType, returnType, v);
return Unit.INSTANCE$;
@@ -44,7 +44,7 @@ public class Not extends IntrinsicMethod {
else {
stackValue = receiver;
}
StackValue.not(StackValue.lazyCast(stackValue, Type.BOOLEAN_TYPE)).put(returnType, v);
StackValue.not(StackValue.coercion(stackValue, Type.BOOLEAN_TYPE)).put(returnType, v);
return returnType;
}
}