somehow generate .inv() (not really robust)
This commit is contained in:
@@ -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));
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user