diff --git a/idea/src/org/jetbrains/jet/codegen/ExpressionCodegen.java b/idea/src/org/jetbrains/jet/codegen/ExpressionCodegen.java index c1a60ec6101..8ff67e12aac 100644 --- a/idea/src/org/jetbrains/jet/codegen/ExpressionCodegen.java +++ b/idea/src/org/jetbrains/jet/codegen/ExpressionCodegen.java @@ -784,16 +784,17 @@ public class ExpressionCodegen extends JetVisitor { generateConstructorCall(expression, (JetSimpleNameExpression) callee); } else if (funDescriptor instanceof FunctionDescriptor) { - final DeclarationDescriptor functionParent = funDescriptor.getContainingDeclaration(); - if (isNumberPrimitive(functionParent)) { - if (funDescriptor.getName().equals("inv")) { - final StackValue value = myStack.pop(); // HACK we rely on the dot reference handler to put it on the stack - final Type asmType = expressionType(expression); - value.put(asmType, v); - generateInv(asmType); - return; + final IntrinsicMethod intrinsic = intrinsics.getIntrinsic(funDescriptor); + if (intrinsic != null) { + List args = new ArrayList(); + for (JetArgument argument : expression.getValueArguments()) { + args.add(argument.getArgumentExpression()); } + myStack.push(intrinsic.generate(this, v, expressionType(expression), expression, args)); + return; } + + final DeclarationDescriptor functionParent = funDescriptor.getContainingDeclaration(); if (state.getStandardLibrary().getTypeInfoFunctionGroup().getFunctionDescriptors().contains(funDescriptor.getOriginal())) { generateTypeInfoCall(expression); return; @@ -1453,12 +1454,6 @@ public class ExpressionCodegen extends JetVisitor { return value; } - private void generateInv(Type asmType) { - v.aconst(-1); - v.xor(asmType); - myStack.push(StackValue.onStack(asmType)); - } - @Override public void visitProperty(JetProperty property) { VariableDescriptor variableDescriptor = bindingContext.getVariableDescriptor(property); diff --git a/idea/src/org/jetbrains/jet/codegen/intrinsics/IntrinsicMethods.java b/idea/src/org/jetbrains/jet/codegen/intrinsics/IntrinsicMethods.java index 67ff080c9bf..af1e8306024 100644 --- a/idea/src/org/jetbrains/jet/codegen/intrinsics/IntrinsicMethods.java +++ b/idea/src/org/jetbrains/jet/codegen/intrinsics/IntrinsicMethods.java @@ -16,51 +16,50 @@ public class IntrinsicMethods { private static final IntrinsicMethod UNARY_MINUS = new UnaryMinus(); private static final IntrinsicMethod NUMBER_CAST = new NumberCast(); private static final IntrinsicMethod ARRAY_SIZE = new ArraySize(); + private static final IntrinsicMethod INV = new Inv(); + private final JetStandardLibrary myStdLib; private final Map myMethods = new HashMap(); public IntrinsicMethods(JetStandardLibrary stdlib) { + myStdLib = stdlib; List primitiveCastMethods = ImmutableList.of("dbl", "flt", "lng", "int", "chr", "sht", "byt"); for (String method : primitiveCastMethods) { - declareIntrinsicProperty(stdlib, "Number", method, NUMBER_CAST); + declareIntrinsicProperty("Number", method, NUMBER_CAST); } - declareIntrinsicProperty(stdlib, "Array", "size", ARRAY_SIZE); - - List primitiveNumberTypes = ImmutableList.of( - stdlib.getBoolean(), - stdlib.getByte(), - stdlib.getChar(), - stdlib.getShort(), - stdlib.getInt(), - stdlib.getFloat(), - stdlib.getLong(), - stdlib.getDouble() - ); - - for (ClassDescriptor primitiveNumberType : primitiveNumberTypes) { - final JetScope memberScope = primitiveNumberType.getMemberScope(Collections.emptyList()); - - final FunctionGroup minus = memberScope.getFunctionGroup("minus"); - for (FunctionDescriptor descriptor : minus.getFunctionDescriptors()) { - if (descriptor.getValueParameters().isEmpty()) { - myMethods.put(descriptor, UNARY_MINUS); - } - } - + declareIntrinsicProperty("Array", "size", ARRAY_SIZE); + List primitiveNumberTypes = ImmutableList.of("Boolean", "Byte", "Char", "Short", "Int", "Float", "Long", "Double"); + for (String primitiveNumberType : primitiveNumberTypes) { + declareIntrinsicFunction(primitiveNumberType, "minus", 0, UNARY_MINUS); + declareIntrinsicFunction(primitiveNumberType, "inv", 0, INV); } } - private void declareIntrinsicProperty(JetStandardLibrary stdlib, String className, String methodName, IntrinsicMethod implementation) { - final ClassDescriptor descriptor = (ClassDescriptor) stdlib.getLibraryScope().getClassifier(className); + private void declareIntrinsicProperty(String className, String methodName, IntrinsicMethod implementation) { + final JetScope numberScope = getClassMemberScope(className); + final VariableDescriptor variable = numberScope.getVariable(methodName); + myMethods.put(variable.getOriginal(), implementation); + } + + private void declareIntrinsicFunction(String className, String functionName, int arity, IntrinsicMethod implementation) { + JetScope memberScope = getClassMemberScope(className); + final FunctionGroup minus = memberScope.getFunctionGroup(functionName); + for (FunctionDescriptor descriptor : minus.getFunctionDescriptors()) { + if (descriptor.getValueParameters().size() == arity) { + myMethods.put(descriptor, implementation); + } + } + } + + private JetScope getClassMemberScope(String className) { + final ClassDescriptor descriptor = (ClassDescriptor) myStdLib.getLibraryScope().getClassifier(className); final List typeParameterDescriptors = descriptor.getTypeConstructor().getParameters(); List typeParameters = new ArrayList(); for (TypeParameterDescriptor typeParameterDescriptor : typeParameterDescriptors) { typeParameters.add(new TypeProjection(JetStandardClasses.getAnyType())); } - final JetScope numberScope = descriptor.getMemberScope(typeParameters); - final VariableDescriptor variable = numberScope.getVariable(methodName); - myMethods.put(variable.getOriginal(), implementation); + return descriptor.getMemberScope(typeParameters); } public IntrinsicMethod getIntrinsic(DeclarationDescriptor descriptor) { diff --git a/idea/src/org/jetbrains/jet/codegen/intrinsics/Inv.java b/idea/src/org/jetbrains/jet/codegen/intrinsics/Inv.java new file mode 100644 index 00000000000..2f391e4bf08 --- /dev/null +++ b/idea/src/org/jetbrains/jet/codegen/intrinsics/Inv.java @@ -0,0 +1,23 @@ +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 Inv implements IntrinsicMethod { + @Override + public StackValue generate(ExpressionCodegen codegen, InstructionAdapter v, Type expectedType, PsiElement element, List arguments) { + codegen.putTopOfStack(expectedType); + v.aconst(-1); + v.xor(expectedType); + return StackValue.onStack(expectedType); + } +}