diff --git a/idea/src/org/jetbrains/jet/codegen/ExpressionCodegen.java b/idea/src/org/jetbrains/jet/codegen/ExpressionCodegen.java index d7b61afc830..116c5b06d2d 100644 --- a/idea/src/org/jetbrains/jet/codegen/ExpressionCodegen.java +++ b/idea/src/org/jetbrains/jet/codegen/ExpressionCodegen.java @@ -330,6 +330,15 @@ public class ExpressionCodegen extends JetVisitor { if (callee instanceof JetSimpleNameExpression) { DeclarationDescriptor funDescriptor = bindingContext.resolveReferenceExpression((JetSimpleNameExpression) callee); if (funDescriptor instanceof FunctionDescriptor) { + if (isNumberPrimitive(funDescriptor.getContainingDeclaration())) { + 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; + } + } PsiElement declarationPsiElement = bindingContext.getDeclarationPsiElement(funDescriptor); if (declarationPsiElement instanceof PsiMethod) { PsiMethod method = (PsiMethod) declarationPsiElement; @@ -338,7 +347,7 @@ public class ExpressionCodegen extends JetVisitor { List args = expression.getValueArguments(); for (int i = 0, argsSize = args.size(); i < argsSize; i++) { JetArgument arg = args.get(i); - gen(arg.getArgumentExpression(), psiTypeToAsm(parameters [i].getType())); + gen(arg.getArgumentExpression(), psiTypeToAsm(parameters[i].getType())); } if (method.hasModifierProperty(PsiModifier.STATIC)) { @@ -349,15 +358,18 @@ public class ExpressionCodegen extends JetVisitor { } else { v.visitMethodInsn(Opcodes.INVOKEVIRTUAL, - jvmName(method.getContainingClass()), - method.getName(), - getMethodDescriptor(method)); + jvmName(method.getContainingClass()), + method.getName(), + getMethodDescriptor(method)); } final Type type = psiTypeToAsm(method.getReturnType()); if (type != Type.VOID_TYPE) { myStack.push(StackValue.onStack(type)); } } + else { + throw new UnsupportedOperationException("don't know how to generate call to " + declarationPsiElement); + } } else { throw new CompilationException(); @@ -612,13 +624,6 @@ public class ExpressionCodegen extends JetVisitor { myStack.push(StackValue.onStack(asmType)); return true; } - else if (op.getName().equals("inv")) { - gen(operand, asmType); - v.aconst(-1); - v.xor(asmType); - myStack.push(StackValue.onStack(asmType)); - return true; - } else if (op.getName().equals("inc") || op.getName().equals("dec")) { if (!(operand instanceof JetReferenceExpression)) { throw new UnsupportedOperationException("cannot increment or decrement a non-lvalue"); @@ -655,6 +660,12 @@ public class ExpressionCodegen extends JetVisitor { return false; } + private void generateInv(Type asmType) { + v.aconst(-1); + v.xor(asmType); + myStack.push(StackValue.onStack(asmType)); + } + @Override public void visitProperty(JetProperty property) { PropertyDescriptor propertyDescriptor = bindingContext.getPropertyDescriptor(property); diff --git a/idea/tests/org/jetbrains/jet/codegen/NamespaceGenTest.java b/idea/tests/org/jetbrains/jet/codegen/NamespaceGenTest.java index 8c89c63b3d8..c44f06049a0 100644 --- a/idea/tests/org/jetbrains/jet/codegen/NamespaceGenTest.java +++ b/idea/tests/org/jetbrains/jet/codegen/NamespaceGenTest.java @@ -398,8 +398,9 @@ public class NamespaceGenTest extends LightCodeInsightFixtureTestCase { binOpTest("fun foo(a: Int, b: Int): Int = a xor b", 0x70, 0x1f, 0x6f); } - public void _testBitInv() throws Exception { - loadText("fun foo(a: Int): Int = ~a"); + public void testBitInv() throws Exception { + loadText("fun foo(a: Int): Int = a.inv()"); + System.out.println(generateToText()); final Method main = generateFunction(); assertEquals(0xffff0000, main.invoke(null, 0x0000ffff)); }