somehow generate .inv() (not really robust)

This commit is contained in:
Dmitry Jemerov
2011-04-08 15:58:16 +02:00
parent 3b080bba14
commit 018bb9d701
2 changed files with 25 additions and 13 deletions
@@ -330,6 +330,15 @@ public class ExpressionCodegen extends JetVisitor {
if (callee instanceof JetSimpleNameExpression) { if (callee instanceof JetSimpleNameExpression) {
DeclarationDescriptor funDescriptor = bindingContext.resolveReferenceExpression((JetSimpleNameExpression) callee); DeclarationDescriptor funDescriptor = bindingContext.resolveReferenceExpression((JetSimpleNameExpression) callee);
if (funDescriptor instanceof FunctionDescriptor) { 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); PsiElement declarationPsiElement = bindingContext.getDeclarationPsiElement(funDescriptor);
if (declarationPsiElement instanceof PsiMethod) { if (declarationPsiElement instanceof PsiMethod) {
PsiMethod method = (PsiMethod) declarationPsiElement; PsiMethod method = (PsiMethod) declarationPsiElement;
@@ -358,6 +367,9 @@ public class ExpressionCodegen extends JetVisitor {
myStack.push(StackValue.onStack(type)); myStack.push(StackValue.onStack(type));
} }
} }
else {
throw new UnsupportedOperationException("don't know how to generate call to " + declarationPsiElement);
}
} }
else { else {
throw new CompilationException(); throw new CompilationException();
@@ -612,13 +624,6 @@ public class ExpressionCodegen extends JetVisitor {
myStack.push(StackValue.onStack(asmType)); myStack.push(StackValue.onStack(asmType));
return true; 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")) { else if (op.getName().equals("inc") || op.getName().equals("dec")) {
if (!(operand instanceof JetReferenceExpression)) { if (!(operand instanceof JetReferenceExpression)) {
throw new UnsupportedOperationException("cannot increment or decrement a non-lvalue"); throw new UnsupportedOperationException("cannot increment or decrement a non-lvalue");
@@ -655,6 +660,12 @@ public class ExpressionCodegen extends JetVisitor {
return false; return false;
} }
private void generateInv(Type asmType) {
v.aconst(-1);
v.xor(asmType);
myStack.push(StackValue.onStack(asmType));
}
@Override @Override
public void visitProperty(JetProperty property) { public void visitProperty(JetProperty property) {
PropertyDescriptor propertyDescriptor = bindingContext.getPropertyDescriptor(property); PropertyDescriptor propertyDescriptor = bindingContext.getPropertyDescriptor(property);
@@ -398,8 +398,9 @@ public class NamespaceGenTest extends LightCodeInsightFixtureTestCase {
binOpTest("fun foo(a: Int, b: Int): Int = a xor b", 0x70, 0x1f, 0x6f); binOpTest("fun foo(a: Int, b: Int): Int = a xor b", 0x70, 0x1f, 0x6f);
} }
public void _testBitInv() throws Exception { public void testBitInv() throws Exception {
loadText("fun foo(a: Int): Int = ~a"); loadText("fun foo(a: Int): Int = a.inv()");
System.out.println(generateToText());
final Method main = generateFunction(); final Method main = generateFunction();
assertEquals(0xffff0000, main.invoke(null, 0x0000ffff)); assertEquals(0xffff0000, main.invoke(null, 0x0000ffff));
} }