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;
@@ -338,7 +347,7 @@ public class ExpressionCodegen extends JetVisitor {
List<JetArgument> args = expression.getValueArguments(); List<JetArgument> args = expression.getValueArguments();
for (int i = 0, argsSize = args.size(); i < argsSize; i++) { for (int i = 0, argsSize = args.size(); i < argsSize; i++) {
JetArgument arg = args.get(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)) { if (method.hasModifierProperty(PsiModifier.STATIC)) {
@@ -349,15 +358,18 @@ public class ExpressionCodegen extends JetVisitor {
} }
else { else {
v.visitMethodInsn(Opcodes.INVOKEVIRTUAL, v.visitMethodInsn(Opcodes.INVOKEVIRTUAL,
jvmName(method.getContainingClass()), jvmName(method.getContainingClass()),
method.getName(), method.getName(),
getMethodDescriptor(method)); getMethodDescriptor(method));
} }
final Type type = psiTypeToAsm(method.getReturnType()); final Type type = psiTypeToAsm(method.getReturnType());
if (type != Type.VOID_TYPE) { if (type != Type.VOID_TYPE) {
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));
} }