binary operations on numbers are intrinsics
This commit is contained in:
@@ -1079,13 +1079,14 @@ public class ExpressionCodegen extends JetVisitor {
|
||||
else {
|
||||
DeclarationDescriptor op = bindingContext.resolveReferenceExpression(expression.getOperationReference());
|
||||
if (op instanceof FunctionDescriptor) {
|
||||
DeclarationDescriptor cls = op.getContainingDeclaration();
|
||||
if (isNumberPrimitive(cls)) {
|
||||
int opcode = opcodeForMethod(op.getName());
|
||||
generateBinaryOp(expression, (FunctionDescriptor) op, opcode);
|
||||
final IntrinsicMethod intrinsic = intrinsics.getIntrinsic(op);
|
||||
if (intrinsic != null) {
|
||||
myStack.push(intrinsic.generate(this, v, expressionType(expression), expression,
|
||||
Arrays.asList(expression.getLeft(), expression.getRight())));
|
||||
return;
|
||||
}
|
||||
else if (isClass(cls, "String") && op.getName().equals("plus")) {
|
||||
DeclarationDescriptor cls = op.getContainingDeclaration();
|
||||
if (isClass(cls, "String") && op.getName().equals("plus")) {
|
||||
generateConcatenation(expression);
|
||||
return;
|
||||
}
|
||||
@@ -1240,21 +1241,6 @@ public class ExpressionCodegen extends JetVisitor {
|
||||
throw new UnsupportedOperationException("Don't know how to generate binary op method " + name);
|
||||
}
|
||||
|
||||
private void generateBinaryOp(JetBinaryExpression expression, FunctionDescriptor op, int opcode) {
|
||||
JetType returnType = op.getReturnType();
|
||||
final Type asmType = typeMapper.mapType(returnType);
|
||||
if (asmType == Type.INT_TYPE || asmType == Type.LONG_TYPE ||
|
||||
asmType == Type.FLOAT_TYPE || asmType == Type.DOUBLE_TYPE) {
|
||||
gen(expression.getLeft(), asmType);
|
||||
gen(expression.getRight(), asmType);
|
||||
v.visitInsn(asmType.getOpcode(opcode));
|
||||
myStack.push(StackValue.onStack(asmType));
|
||||
}
|
||||
else {
|
||||
throw new UnsupportedOperationException("Don't know how to generate binary op with return type " + returnType);
|
||||
}
|
||||
}
|
||||
|
||||
private void generateCompareOp(JetExpression left, JetExpression right, IElementType opToken, Type operandType) {
|
||||
gen(left, operandType);
|
||||
gen(right, operandType);
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
package org.jetbrains.jet.codegen.intrinsics;
|
||||
|
||||
import com.intellij.psi.PsiElement;
|
||||
import org.jetbrains.jet.codegen.ExpressionCodegen;
|
||||
import org.jetbrains.jet.codegen.StackValue;
|
||||
import org.jetbrains.jet.lang.psi.JetExpression;
|
||||
import org.objectweb.asm.Type;
|
||||
import org.objectweb.asm.commons.InstructionAdapter;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author yole
|
||||
*/
|
||||
public class BinaryOp implements IntrinsicMethod {
|
||||
private final int opcode;
|
||||
|
||||
public BinaryOp(int opcode) {
|
||||
this.opcode = opcode;
|
||||
}
|
||||
|
||||
@Override
|
||||
public StackValue generate(ExpressionCodegen codegen, InstructionAdapter v, Type expectedType, PsiElement element, List<JetExpression> arguments) {
|
||||
codegen.gen(arguments.get(0), expectedType);
|
||||
codegen.gen(arguments.get(1), expectedType);
|
||||
v.visitInsn(expectedType.getOpcode(opcode));
|
||||
return StackValue.onStack(expectedType);
|
||||
}
|
||||
}
|
||||
@@ -6,8 +6,12 @@ import org.jetbrains.jet.lang.resolve.JetScope;
|
||||
import org.jetbrains.jet.lang.types.JetStandardClasses;
|
||||
import org.jetbrains.jet.lang.types.JetStandardLibrary;
|
||||
import org.jetbrains.jet.lang.types.TypeProjection;
|
||||
import org.objectweb.asm.Opcodes;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author yole
|
||||
@@ -20,6 +24,8 @@ public class IntrinsicMethods {
|
||||
private static final IntrinsicMethod TYPEINFO = new TypeInfo();
|
||||
private static final IntrinsicMethod VALUE_TYPEINFO = new ValueTypeInfo();
|
||||
|
||||
private static final List<String> PRIMITIVE_NUMBER_TYPES = ImmutableList.of("Boolean", "Byte", "Char", "Short", "Int", "Float", "Long", "Double");
|
||||
|
||||
private final JetStandardLibrary myStdLib;
|
||||
private final Map<DeclarationDescriptor, IntrinsicMethod> myMethods = new HashMap<DeclarationDescriptor, IntrinsicMethod>();
|
||||
|
||||
@@ -31,8 +37,7 @@ public class IntrinsicMethods {
|
||||
}
|
||||
declareIntrinsicProperty("Array", "size", ARRAY_SIZE);
|
||||
|
||||
List<String> primitiveNumberTypes = ImmutableList.of("Boolean", "Byte", "Char", "Short", "Int", "Float", "Long", "Double");
|
||||
for (String primitiveNumberType : primitiveNumberTypes) {
|
||||
for (String primitiveNumberType : PRIMITIVE_NUMBER_TYPES) {
|
||||
declareIntrinsicFunction(primitiveNumberType, "minus", 0, UNARY_MINUS);
|
||||
declareIntrinsicFunction(primitiveNumberType, "inv", 0, INV);
|
||||
}
|
||||
@@ -40,6 +45,25 @@ public class IntrinsicMethods {
|
||||
final FunctionGroup typeInfoFunctionGroup = stdlib.getTypeInfoFunctionGroup();
|
||||
declareOverload(typeInfoFunctionGroup, 0, TYPEINFO);
|
||||
declareOverload(typeInfoFunctionGroup, 1, VALUE_TYPEINFO);
|
||||
|
||||
declareBinaryOp("plus", Opcodes.IADD);
|
||||
declareBinaryOp("minus", Opcodes.ISUB);
|
||||
declareBinaryOp("times", Opcodes.IMUL);
|
||||
declareBinaryOp("div", Opcodes.IDIV);
|
||||
declareBinaryOp("mod", Opcodes.IREM);
|
||||
declareBinaryOp("shl", Opcodes.ISHL);
|
||||
declareBinaryOp("shr", Opcodes.ISHR);
|
||||
declareBinaryOp("ushr", Opcodes.IUSHR);
|
||||
declareBinaryOp("and", Opcodes.IAND);
|
||||
declareBinaryOp("or", Opcodes.IOR);
|
||||
declareBinaryOp("xor", Opcodes.IXOR);
|
||||
}
|
||||
|
||||
private void declareBinaryOp(String methodName, int opcode) {
|
||||
BinaryOp op = new BinaryOp(opcode);
|
||||
for (String type : PRIMITIVE_NUMBER_TYPES) {
|
||||
declareIntrinsicFunction(type, methodName, 1, op);
|
||||
}
|
||||
}
|
||||
|
||||
private void declareIntrinsicProperty(String className, String methodName, IntrinsicMethod implementation) {
|
||||
|
||||
Reference in New Issue
Block a user