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) {
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<JetArgument> 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);
@@ -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));
}