postfix part of KT-471
This commit is contained in:
@@ -2006,19 +2006,36 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
||||
Arrays.asList(expression.getBaseExpression()), receiver);
|
||||
}
|
||||
else {
|
||||
return invokeOperation(expression, (FunctionDescriptor) op, (CallableMethod) callable);
|
||||
DeclarationDescriptor cls = op.getContainingDeclaration();
|
||||
if (isNumberPrimitive(cls) || !(op.getName().equals("inc") || op.getName().equals("dec")) ) {
|
||||
return invokeOperation(expression, (FunctionDescriptor) op, (CallableMethod) callable);
|
||||
}
|
||||
else {
|
||||
ResolvedCall<? extends CallableDescriptor> resolvedCall = bindingContext.get(BindingContext.RESOLVED_CALL, expression.getOperationReference());
|
||||
assert resolvedCall != null;
|
||||
|
||||
StackValue value = gen(expression.getBaseExpression());
|
||||
value.dupReceiver(v);
|
||||
value.dupReceiver(v);
|
||||
|
||||
Type type = expressionType(expression.getBaseExpression());
|
||||
value.put(type, v);
|
||||
((CallableMethod)callable).invoke(v);
|
||||
value.store(v);
|
||||
value.put(type, v);
|
||||
return StackValue.onStack(type);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private StackValue invokeOperation(JetOperationExpression expression, FunctionDescriptor op, CallableMethod callable) {
|
||||
ResolvedCall<? extends CallableDescriptor> resolvedCall = bindingContext.get(BindingContext.RESOLVED_CALL, expression.getOperationReference());
|
||||
assert resolvedCall != null;
|
||||
CallableMethod callableMethod = (CallableMethod) callable;
|
||||
genThisAndReceiverFromResolvedCall(StackValue.none(), resolvedCall, callableMethod);
|
||||
genThisAndReceiverFromResolvedCall(StackValue.none(), resolvedCall, callable);
|
||||
pushTypeArguments(resolvedCall);
|
||||
pushMethodArguments(resolvedCall, callableMethod.getValueParameterTypes());
|
||||
callableMethod.invoke(v);
|
||||
return returnValueAsStackValue((FunctionDescriptor) op, callableMethod.getSignature().getAsmMethod().getReturnType());
|
||||
pushMethodArguments(resolvedCall, callable.getValueParameterTypes());
|
||||
callable.invoke(v);
|
||||
return returnValueAsStackValue(op, callable.getSignature().getAsmMethod().getReturnType());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -2027,19 +2044,63 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
||||
if (op instanceof FunctionDescriptor) {
|
||||
final Type asmType = expressionType(expression);
|
||||
DeclarationDescriptor cls = op.getContainingDeclaration();
|
||||
if (isNumberPrimitive(cls) && (op.getName().equals("inc") || op.getName().equals("dec"))) {
|
||||
receiver.put(receiver.type, v);
|
||||
JetExpression operand = expression.getBaseExpression();
|
||||
if (operand instanceof JetReferenceExpression) {
|
||||
final int index = indexOfLocal((JetReferenceExpression) operand);
|
||||
if (index >= 0 && isIntPrimitive(asmType)) {
|
||||
int increment = op.getName().equals("inc") ? 1 : -1;
|
||||
return StackValue.postIncrement(index, increment);
|
||||
if (op.getName().equals("inc") || op.getName().equals("dec")) {
|
||||
if (isNumberPrimitive(cls)) {
|
||||
receiver.put(receiver.type, v);
|
||||
JetExpression operand = expression.getBaseExpression();
|
||||
if (operand instanceof JetReferenceExpression) {
|
||||
final int index = indexOfLocal((JetReferenceExpression) operand);
|
||||
if (index >= 0 && isIntPrimitive(asmType)) {
|
||||
int increment = op.getName().equals("inc") ? 1 : -1;
|
||||
return StackValue.postIncrement(index, increment);
|
||||
}
|
||||
}
|
||||
gen(operand, asmType); // old value
|
||||
generateIncrement(op, asmType, operand, receiver); // increment in-place
|
||||
return StackValue.onStack(asmType); // old value
|
||||
}
|
||||
else {
|
||||
ResolvedCall<? extends CallableDescriptor> resolvedCall = bindingContext.get(BindingContext.RESOLVED_CALL, expression.getOperationReference());
|
||||
assert resolvedCall != null;
|
||||
|
||||
final Callable callable = resolveToCallable(op, false);
|
||||
|
||||
StackValue value = gen(expression.getBaseExpression());
|
||||
value.dupReceiver(v);
|
||||
|
||||
Type type = expressionType(expression.getBaseExpression());
|
||||
value.put(type, v);
|
||||
|
||||
switch(value.receiverSize()) {
|
||||
case 0:
|
||||
if(type.getSize() == 2)
|
||||
v.dup2();
|
||||
else
|
||||
v.dup();
|
||||
break;
|
||||
|
||||
case 1:
|
||||
if(type.getSize() == 2)
|
||||
v.dup2X1();
|
||||
else
|
||||
v.dupX1();
|
||||
break;
|
||||
|
||||
case 2:
|
||||
if(type.getSize() == 2)
|
||||
v.dup2X2();
|
||||
else
|
||||
v.dupX2();
|
||||
break;
|
||||
|
||||
case -1:
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
((CallableMethod)callable).invoke(v);
|
||||
value.store(v);
|
||||
return StackValue.onStack(type);
|
||||
}
|
||||
gen(operand, asmType); // old value
|
||||
generateIncrement(op, asmType, operand, receiver); // increment in-place
|
||||
return StackValue.onStack(asmType); // old value
|
||||
}
|
||||
}
|
||||
throw new UnsupportedOperationException("Don't know how to generate this prefix expression");
|
||||
|
||||
@@ -51,6 +51,10 @@ public abstract class StackValue {
|
||||
public void dupReceiver(InstructionAdapter v) {
|
||||
}
|
||||
|
||||
public int receiverSize() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public void condJump(Label label, boolean jumpIfFalse, InstructionAdapter v) {
|
||||
if (this.type == Type.BOOLEAN_TYPE) {
|
||||
put(Type.BOOLEAN_TYPE, v);
|
||||
@@ -491,6 +495,10 @@ public abstract class StackValue {
|
||||
public void dupReceiver(InstructionAdapter v) {
|
||||
v.dup2(); // array and index
|
||||
}
|
||||
|
||||
public int receiverSize() {
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
|
||||
private static class CollectionElement extends StackValue {
|
||||
@@ -547,6 +555,15 @@ public abstract class StackValue {
|
||||
((IntrinsicMethod)setter).generate(codegen, v, null, null, null, null);
|
||||
}
|
||||
|
||||
public int receiverSize() {
|
||||
if(isStandardStack(resolvedGetCall) && isStandardStack(resolvedSetCall)) {
|
||||
return 2;
|
||||
}
|
||||
else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dupReceiver(InstructionAdapter v) {
|
||||
if(isStandardStack(resolvedGetCall) && isStandardStack(resolvedSetCall)) {
|
||||
@@ -686,6 +703,9 @@ public abstract class StackValue {
|
||||
}
|
||||
|
||||
private boolean isStandardStack(ResolvedCall call) {
|
||||
if(call == null)
|
||||
return true;
|
||||
|
||||
for (TypeParameterDescriptor typeParameterDescriptor : call.getResultingDescriptor().getTypeParameters()) {
|
||||
if(typeParameterDescriptor.isReified())
|
||||
return false;
|
||||
@@ -736,6 +756,10 @@ public abstract class StackValue {
|
||||
}
|
||||
}
|
||||
|
||||
public int receiverSize() {
|
||||
return isStatic ? 0 : 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void store(InstructionAdapter v) {
|
||||
v.visitFieldInsn(isStatic ? Opcodes.PUTSTATIC : Opcodes.PUTFIELD, owner, name, this.type.getDescriptor());
|
||||
@@ -801,6 +825,10 @@ public abstract class StackValue {
|
||||
v.dup();
|
||||
}
|
||||
}
|
||||
|
||||
public int receiverSize() {
|
||||
return isStatic ? 0 : 1;
|
||||
}
|
||||
}
|
||||
|
||||
private static class Expression extends StackValue {
|
||||
@@ -904,6 +932,10 @@ public abstract class StackValue {
|
||||
v.dup();
|
||||
}
|
||||
|
||||
public int receiverSize() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void put(Type type, InstructionAdapter v) {
|
||||
Type sharedType = sharedTypeForType(this.type);
|
||||
|
||||
Reference in New Issue
Block a user