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));
|
return typeMapper.mapType(bindingContext.getExpressionType(expr));
|
||||||
}
|
}
|
||||||
|
|
||||||
private int indexOfLocal(JetReferenceExpression lhs) {
|
public int indexOfLocal(JetReferenceExpression lhs) {
|
||||||
final DeclarationDescriptor declarationDescriptor = bindingContext.resolveReferenceExpression(lhs);
|
final DeclarationDescriptor declarationDescriptor = bindingContext.resolveReferenceExpression(lhs);
|
||||||
return lookupLocal(declarationDescriptor);
|
return lookupLocal(declarationDescriptor);
|
||||||
}
|
}
|
||||||
@@ -1317,12 +1317,21 @@ public class ExpressionCodegen extends JetVisitor {
|
|||||||
@Override
|
@Override
|
||||||
public void visitPrefixExpression(JetPrefixExpression expression) {
|
public void visitPrefixExpression(JetPrefixExpression expression) {
|
||||||
DeclarationDescriptor op = bindingContext.resolveReferenceExpression(expression.getOperationSign());
|
DeclarationDescriptor op = bindingContext.resolveReferenceExpression(expression.getOperationSign());
|
||||||
if (op instanceof FunctionDescriptor) {
|
final Callable callable = resolveToCallable(op);
|
||||||
final Type asmType = expressionType(expression);
|
if (callable instanceof IntrinsicMethod) {
|
||||||
generateUnaryOp(op, asmType, expression);
|
IntrinsicMethod intrinsic = (IntrinsicMethod) callable;
|
||||||
return;
|
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
|
@Override
|
||||||
@@ -1348,30 +1357,6 @@ public class ExpressionCodegen extends JetVisitor {
|
|||||||
throw new UnsupportedOperationException("Don't know how to generate this prefix expression");
|
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) {
|
private StackValue generateIncrement(DeclarationDescriptor op, Type asmType, JetExpression operand) {
|
||||||
int increment = op.getName().equals("inc") ? 1 : -1;
|
int increment = op.getName().equals("inc") ? 1 : -1;
|
||||||
if (operand instanceof JetReferenceExpression) {
|
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 TYPEINFO = new TypeInfo();
|
||||||
private static final IntrinsicMethod VALUE_TYPEINFO = new ValueTypeInfo();
|
private static final IntrinsicMethod VALUE_TYPEINFO = new ValueTypeInfo();
|
||||||
private static final IntrinsicMethod RANGE_TO = new RangeTo();
|
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");
|
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, "minus", 0, UNARY_MINUS);
|
||||||
declareIntrinsicFunction(type, "inv", 0, INV);
|
declareIntrinsicFunction(type, "inv", 0, INV);
|
||||||
declareIntrinsicFunction(type, "rangeTo", 1, RANGE_TO);
|
declareIntrinsicFunction(type, "rangeTo", 1, RANGE_TO);
|
||||||
|
declareIntrinsicFunction(type, "inc", 0, INC);
|
||||||
|
declareIntrinsicFunction(type, "dec", 0, DEC);
|
||||||
}
|
}
|
||||||
|
|
||||||
final FunctionGroup typeInfoFunctionGroup = stdlib.getTypeInfoFunctionGroup();
|
final FunctionGroup typeInfoFunctionGroup = stdlib.getTypeInfoFunctionGroup();
|
||||||
|
|||||||
Reference in New Issue
Block a user