You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by he...@apache.org on 2019/03/29 14:34:51 UTC

[commons-jexl] branch master updated: JEXL-295: cache constant unary plus/minus number literal only after checking deterministic guard Task #JEXL-295 - Add unary plus operator

This is an automated email from the ASF dual-hosted git repository.

henrib pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/commons-jexl.git


The following commit(s) were added to refs/heads/master by this push:
     new 781f3bb  JEXL-295: cache constant unary plus/minus number literal only after checking deterministic guard Task #JEXL-295 - Add unary plus operator
781f3bb is described below

commit 781f3bb566d81bc1c8d4b36b1e01cccbd1e60458
Author: henrib <he...@apache.org>
AuthorDate: Fri Mar 29 15:34:06 2019 +0100

    JEXL-295: cache constant unary plus/minus number literal only after checking deterministic guard
    Task #JEXL-295 - Add unary plus operator
---
 .../org/apache/commons/jexl3/JexlArithmetic.java   | 26 +++++++++++++++++++++-
 .../apache/commons/jexl3/internal/Interpreter.java | 12 ++++++----
 2 files changed, 33 insertions(+), 5 deletions(-)

diff --git a/src/main/java/org/apache/commons/jexl3/JexlArithmetic.java b/src/main/java/org/apache/commons/jexl3/JexlArithmetic.java
index 5a2c015..9ff61c4 100644
--- a/src/main/java/org/apache/commons/jexl3/JexlArithmetic.java
+++ b/src/main/java/org/apache/commons/jexl3/JexlArithmetic.java
@@ -823,13 +823,26 @@ public class JexlArithmetic {
         } else if (val instanceof AtomicBoolean) {
             return ((AtomicBoolean) val).get() ? Boolean.FALSE : Boolean.TRUE;
         }
-        throw new ArithmeticException("Object negation:(" + val + ")");
+        throw new ArithmeticException("Object negate:(" + val + ")");
+    }
+    
+    /**
+     * Whether negate called with a given argument will always return the same result.
+     * <p>This is used to determine whether negate results on number literals can be cached.
+     * If the result on calling negate with the same constant argument may change between calls,
+     * which means the function is not deterministic, this method must return false.
+     * @see #isNegateStable() 
+     * @return true if negate is idempotent, false otherwise
+     */
+    public boolean isNegateStable() {
+        return true;
     }
 
     /**
      * Positivize value (unary plus for numbers).
      * <p>C/C++/C#/Java perform integral promotion of the operand, ie
      * cast to int if type can represented as int without loss of precision.
+     * @see #isPositivizeStable()
      * @param val the value to positivize
      * @return the positive value
      */
@@ -854,6 +867,17 @@ public class JexlArithmetic {
         }
         throw new ArithmeticException("Object positivize:(" + val + ")");
     }
+        
+    /**
+     * Whether positivize called with a given argument will always return the same result.
+     * <p>This is used to determine whether positivize results on number literals can be cached.
+     * If the result on calling positivize with the same constant argument may change between calls,
+     * which means the function is not deterministic, this method must return false.
+     * @return true if positivize is idempotent, false otherwise
+     */
+    public boolean isPositivizeStable() {
+        return true;
+    }
     
     /**
      * Test if left contains right (right matches/in left).
diff --git a/src/main/java/org/apache/commons/jexl3/internal/Interpreter.java b/src/main/java/org/apache/commons/jexl3/internal/Interpreter.java
index 8b5b284..6582cd8 100644
--- a/src/main/java/org/apache/commons/jexl3/internal/Interpreter.java
+++ b/src/main/java/org/apache/commons/jexl3/internal/Interpreter.java
@@ -597,10 +597,12 @@ public class Interpreter extends InterpreterBase {
             Object number = arithmetic.negate(val);
             // attempt to recoerce to literal class
             if ((number instanceof Number)) {
-                // cache it
-                if (valNode instanceof ASTNumberLiteral) {
+                // cache if number literal and negate is idempotent
+                if (valNode instanceof ASTNumberLiteral ) {
                     number = arithmetic.narrowNumber((Number) number, ((ASTNumberLiteral) valNode).getLiteralClass());
-                    node.jjtSetValue(number);
+                    if (arithmetic.isNegateStable()) {
+                        node.jjtSetValue(number);
+                    }
                 }
             }
             return number;
@@ -624,7 +626,9 @@ public class Interpreter extends InterpreterBase {
                 return result;
             }
             Object number = arithmetic.positivize(val);
-            if (valNode instanceof ASTNumberLiteral && number instanceof Number) {
+            if (valNode instanceof ASTNumberLiteral
+                && number instanceof Number
+                && arithmetic.isPositivizeStable()) {
                 node.jjtSetValue(number);
             }
             return number;