generate prefix ++ and -- as intrinsics
This commit is contained in:
@@ -1006,7 +1006,7 @@ public class ExpressionCodegen extends JetVisitor {
|
||||
return typeMapper.mapType(bindingContext.getExpressionType(expr));
|
||||
}
|
||||
|
||||
private int indexOfLocal(JetReferenceExpression lhs) {
|
||||
public int indexOfLocal(JetReferenceExpression lhs) {
|
||||
final DeclarationDescriptor declarationDescriptor = bindingContext.resolveReferenceExpression(lhs);
|
||||
return lookupLocal(declarationDescriptor);
|
||||
}
|
||||
@@ -1317,12 +1317,21 @@ public class ExpressionCodegen extends JetVisitor {
|
||||
@Override
|
||||
public void visitPrefixExpression(JetPrefixExpression expression) {
|
||||
DeclarationDescriptor op = bindingContext.resolveReferenceExpression(expression.getOperationSign());
|
||||
if (op instanceof FunctionDescriptor) {
|
||||
final Type asmType = expressionType(expression);
|
||||
generateUnaryOp(op, asmType, expression);
|
||||
return;
|
||||
final Callable callable = resolveToCallable(op);
|
||||
if (callable instanceof IntrinsicMethod) {
|
||||
IntrinsicMethod intrinsic = (IntrinsicMethod) callable;
|
||||
myStack.push(intrinsic.generate(this, v, expressionType(expression), expression,
|
||||
Arrays.asList(expression.getBaseExpression()), false));
|
||||
}
|
||||
else {
|
||||
CallableMethod callableMethod = (CallableMethod) callable;
|
||||
genToJVMStack(expression.getBaseExpression());
|
||||
callableMethod.invoke(v);
|
||||
final StackValue value = returnValueAsStackValue((FunctionDescriptor) op, callableMethod.getSignature().getReturnType());
|
||||
if (value != null) {
|
||||
myStack.push(value);
|
||||
}
|
||||
}
|
||||
throw new UnsupportedOperationException("Don't know how to generate this prefix expression");
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -1348,30 +1357,6 @@ public class ExpressionCodegen extends JetVisitor {
|
||||
throw new UnsupportedOperationException("Don't know how to generate this prefix expression");
|
||||
}
|
||||
|
||||
private void generateUnaryOp(DeclarationDescriptor op, Type asmType, final JetUnaryExpression unaryExpression) {
|
||||
final JetExpression operand = unaryExpression.getBaseExpression();
|
||||
if (isNumberPrimitive(asmType) && (op.getName().equals("inc") || op.getName().equals("dec"))) {
|
||||
myStack.push(generateIncrement(op, asmType, operand));
|
||||
return;
|
||||
}
|
||||
|
||||
final Callable callable = resolveToCallable(op);
|
||||
if (callable instanceof IntrinsicMethod) {
|
||||
IntrinsicMethod intrinsic = (IntrinsicMethod) callable;
|
||||
myStack.push(intrinsic.generate(this, v, expressionType(unaryExpression), unaryExpression,
|
||||
Arrays.asList(unaryExpression.getBaseExpression()), false));
|
||||
}
|
||||
else {
|
||||
CallableMethod callableMethod = (CallableMethod) callable;
|
||||
genToJVMStack(unaryExpression.getBaseExpression());
|
||||
callableMethod.invoke(v);
|
||||
final StackValue value = returnValueAsStackValue((FunctionDescriptor) op, callableMethod.getSignature().getReturnType());
|
||||
if (value != null) {
|
||||
myStack.push(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private StackValue generateIncrement(DeclarationDescriptor op, Type asmType, JetExpression operand) {
|
||||
int increment = op.getName().equals("inc") ? 1 : -1;
|
||||
if (operand instanceof JetReferenceExpression) {
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
package org.jetbrains.jet.codegen.intrinsics;
|
||||
|
||||
import com.intellij.psi.PsiElement;
|
||||
import org.jetbrains.jet.codegen.ExpressionCodegen;
|
||||
import org.jetbrains.jet.codegen.JetTypeMapper;
|
||||
import org.jetbrains.jet.codegen.StackValue;
|
||||
import org.jetbrains.jet.lang.psi.JetExpression;
|
||||
import org.jetbrains.jet.lang.psi.JetReferenceExpression;
|
||||
import org.objectweb.asm.Type;
|
||||
import org.objectweb.asm.commons.InstructionAdapter;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author yole
|
||||
*/
|
||||
public class Increment implements IntrinsicMethod {
|
||||
private final int myDelta;
|
||||
|
||||
public Increment(int delta) {
|
||||
myDelta = delta;
|
||||
}
|
||||
|
||||
@Override
|
||||
public StackValue generate(ExpressionCodegen codegen, InstructionAdapter v, Type expectedType, PsiElement element, List<JetExpression> arguments, boolean haveReceiver) {
|
||||
final JetExpression operand = arguments.get(0);
|
||||
if (operand instanceof JetReferenceExpression) {
|
||||
final int index = codegen.indexOfLocal((JetReferenceExpression) operand);
|
||||
if (index >= 0 && JetTypeMapper.isIntPrimitive(expectedType)) {
|
||||
v.iinc(index, myDelta);
|
||||
return StackValue.local(index, expectedType);
|
||||
}
|
||||
}
|
||||
StackValue value = codegen.generateIntermediateValue(operand);
|
||||
value.dupReceiver(v, 0);
|
||||
value.put(expectedType, v);
|
||||
if (expectedType == Type.LONG_TYPE) {
|
||||
v.aconst(Long.valueOf(myDelta));
|
||||
}
|
||||
else if (expectedType == Type.FLOAT_TYPE) {
|
||||
v.aconst(Float.valueOf(myDelta));
|
||||
}
|
||||
else if (expectedType == Type.DOUBLE_TYPE) {
|
||||
v.aconst(Double.valueOf(myDelta));
|
||||
}
|
||||
else {
|
||||
v.aconst(myDelta);
|
||||
}
|
||||
v.add(expectedType);
|
||||
value.store(v);
|
||||
return value;
|
||||
}
|
||||
}
|
||||
@@ -25,6 +25,8 @@ public class IntrinsicMethods {
|
||||
private static final IntrinsicMethod TYPEINFO = new TypeInfo();
|
||||
private static final IntrinsicMethod VALUE_TYPEINFO = new ValueTypeInfo();
|
||||
private static final IntrinsicMethod RANGE_TO = new RangeTo();
|
||||
private static final IntrinsicMethod INC = new Increment(1);
|
||||
private static final IntrinsicMethod DEC = new Increment(-1);
|
||||
|
||||
private static final List<String> PRIMITIVE_NUMBER_TYPES = ImmutableList.of("Boolean", "Byte", "Char", "Short", "Int", "Float", "Long", "Double");
|
||||
|
||||
@@ -45,6 +47,8 @@ public class IntrinsicMethods {
|
||||
declareIntrinsicFunction(type, "minus", 0, UNARY_MINUS);
|
||||
declareIntrinsicFunction(type, "inv", 0, INV);
|
||||
declareIntrinsicFunction(type, "rangeTo", 1, RANGE_TO);
|
||||
declareIntrinsicFunction(type, "inc", 0, INC);
|
||||
declareIntrinsicFunction(type, "dec", 0, DEC);
|
||||
}
|
||||
|
||||
final FunctionGroup typeInfoFunctionGroup = stdlib.getTypeInfoFunctionGroup();
|
||||
|
||||
Reference in New Issue
Block a user