提交 686d4cae 编写于 作者: A Alex Tkachman

postfix part of KT-471

上级 8d39594b
......@@ -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);
......
import java.util.ArrayList
class MyNumber(val i: Int) {
fun inc(): MyNumber = MyNumber(i+1)
}
class MNR(var ref: MyNumber) {}
fun test1() : Boolean {
var m = MyNumber(42)
m++
if (m.i != 43) return false
return true
}
fun test2() : Boolean {
var m = MyNumber(44)
var m2 = m++
if (m2.i != 44) return false
if (m.i != 45) return false
return true
}
fun test3() : Boolean {
var mnr = MNR(MyNumber(42))
mnr.ref++
if (mnr.ref.i != 43) return false
return true
}
fun test4() : Boolean {
var mnr = MNR(MyNumber(42))
val m3 = mnr.ref++
if (m3.i != 42) return false
return true
}
fun test5() : Boolean {
var mnr = Array<MyNumber>(2,{MyNumber(42)})
mnr[0]++
if (mnr[0].i != 43) return false
return true
}
fun test6() : Boolean {
var mnr = Array<MyNumber>(2,{it -> MyNumber(42-it)})
mnr[1] = mnr[0]++
if (mnr[0].i != 43) return false
if (mnr[1].i != 42) return false
return true
}
/*
fun test7() : Boolean {
var mnr = ArrayList<MyNumber>()
mnr.add(MyNumber(42))
mnr[0]++
if (mnr[0].i != 43) return false
return true
}
fun test8() : Boolean {
var mnr = ArrayList<MyNumber>()
mnr.add(MyNumber(42))
mnr.add(MyNumber(41))
mnr[1] = mnr[0]++
if (mnr[0].i != 43) return false
if (mnr[1].i != 42) return false
return true
}
*/
fun box() : String {
var m = MyNumber(42)
if (!test1()) return "fail test 1"
if (!test2()) return "fail test 2"
if (!test3()) return "fail test 3"
if (!test4()) return "fail test 4"
if (!test5()) return "fail test 5"
if (!test6()) return "fail test 6"
/*
if (!test7()) return "fail test 7"
if (!test8()) return "fail test 8"
++m
if (m.i != 44) return "fail 0"
var m1 = ++m
if (m1.i != 46) return "fail 3"
if (m.i != 46) return "fail 4"
*/
return "OK"
}
......@@ -261,4 +261,8 @@ public class ClassGenTest extends CodegenTestCase {
public void testkt1157() throws Exception {
blackBoxFile("regressions/kt1157.kt");
}
public void testkt471() throws Exception {
blackBoxFile("regressions/kt471.kt");
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册