From 07b65a92c71f8b8bb97f6144dbfd3ca850f85a9d Mon Sep 17 00:00:00 2001 From: Alexey Andreev Date: Thu, 14 May 2015 17:38:07 +0400 Subject: [PATCH] Fix https://github.com/konsoletyper/teavm/issues/109 --- .../teavm/javascript/OptimizingVisitor.java | 36 +++++++++++++++++++ .../java/org/teavm/javascript/Renderer.java | 2 +- .../org/teavm/classlib/java/lang/VMTest.java | 7 ++++ 3 files changed, 44 insertions(+), 1 deletion(-) diff --git a/teavm-core/src/main/java/org/teavm/javascript/OptimizingVisitor.java b/teavm-core/src/main/java/org/teavm/javascript/OptimizingVisitor.java index 036630fe5..ca2ef6a0c 100644 --- a/teavm-core/src/main/java/org/teavm/javascript/OptimizingVisitor.java +++ b/teavm-core/src/main/java/org/teavm/javascript/OptimizingVisitor.java @@ -54,6 +54,11 @@ class OptimizingVisitor implements StatementVisitor, ExprVisitor { } expr.getSecondOperand().acceptVisitor(this); Expr b = resultExpr; + if (b instanceof ConstantExpr && expr.getOperation() == BinaryOperation.SUBTRACT) { + if (tryMakePositive((ConstantExpr)b)) { + expr.setOperation(BinaryOperation.ADD); + } + } expr.getFirstOperand().acceptVisitor(this); Expr a = resultExpr; Expr p = a; @@ -96,10 +101,41 @@ class OptimizingVisitor implements StatementVisitor, ExprVisitor { public void visit(UnaryExpr expr) { expr.getOperand().acceptVisitor(this); Expr operand = resultExpr; + if (expr.getOperation() == UnaryOperation.NEGATE && operand instanceof ConstantExpr) { + ConstantExpr constantExpr = (ConstantExpr)operand; + if (tryMakePositive(constantExpr)) { + resultExpr = expr; + return; + } + } expr.setOperand(operand); resultExpr = expr; } + private boolean tryMakePositive(ConstantExpr constantExpr) { + Object value = constantExpr.getValue(); + if (value instanceof Integer && (Integer)value < 0) { + constantExpr.setValue(-(Integer)value); + return true; + } else if (value instanceof Float && (Float)value < 0) { + constantExpr.setValue(-(Float)value); + return true; + } else if (value instanceof Byte && (Byte)value < 0) { + constantExpr.setValue(-(Byte)value); + return true; + } else if (value instanceof Short && (Short)value < 0) { + constantExpr.setValue(-(Short)value); + return true; + } else if (value instanceof Long && (Long)value < 0) { + constantExpr.setValue(-(Long)value); + return true; + } else if (value instanceof Double && (Double)value < 0) { + constantExpr.setValue(-(Double)value); + return true; + } + return false; + } + @Override public void visit(ConditionalExpr expr) { expr.getCondition().acceptVisitor(this); diff --git a/teavm-core/src/main/java/org/teavm/javascript/Renderer.java b/teavm-core/src/main/java/org/teavm/javascript/Renderer.java index d73b28581..f0b5b7e05 100644 --- a/teavm-core/src/main/java/org/teavm/javascript/Renderer.java +++ b/teavm-core/src/main/java/org/teavm/javascript/Renderer.java @@ -1532,7 +1532,7 @@ public class Renderer implements ExprVisitor, StatementVisitor, RenderingContext } String str = constantToString(expr.getValue()); if (str.startsWith("-")) { - enterPriority(Priority.MULTIPLICATION, Associativity.RIGHT, true); + enterPriority(Priority.MULTIPLICATION, Associativity.NONE, true); } writer.append(str); if (str.startsWith("-")) { diff --git a/teavm-tests/src/test/java/org/teavm/classlib/java/lang/VMTest.java b/teavm-tests/src/test/java/org/teavm/classlib/java/lang/VMTest.java index bc77f5f6b..5b5ecb216 100644 --- a/teavm-tests/src/test/java/org/teavm/classlib/java/lang/VMTest.java +++ b/teavm-tests/src/test/java/org/teavm/classlib/java/lang/VMTest.java @@ -84,6 +84,13 @@ public class VMTest { assertEquals(0xDDC2, "a\uDDC2b".charAt(1)); } + @Test + public void subtractingNegativeWorks() { + int a = 23; + int b = a - 0xFFFFFFFF; + assertEquals(24, b); + } + @Test public void separatesExceptionAndVariable() { int n = foo();