diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/CompilerSettings.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/CompilerSettings.java
index 9ec26bf345a..4cafe32bb56 100644
--- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/CompilerSettings.java
+++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/CompilerSettings.java
@@ -24,47 +24,16 @@ package org.elasticsearch.painless;
*/
public final class CompilerSettings {
- /**
- * Constant to be used when specifying numeric overflow when compiling a script.
- */
- public static final String NUMERIC_OVERFLOW = "numeric_overflow";
-
/**
* Constant to be used when specifying the maximum loop counter when compiling a script.
*/
public static final String MAX_LOOP_COUNTER = "max_loop_counter";
- /**
- * Whether or not to allow numeric values to overflow without exception.
- */
- private boolean numericOverflow = true;
-
/**
* The maximum number of statements allowed to be run in a loop.
*/
private int maxLoopCounter = 10000;
- /**
- * Returns {@code true} if numeric operations should overflow, {@code false}
- * if they should signal an exception.
- *
- * If this value is {@code true} (default), then things behave like java:
- * overflow for integer types can result in unexpected values / unexpected
- * signs, and overflow for floating point types can result in infinite or
- * {@code NaN} values.
- */
- public final boolean getNumericOverflow() {
- return numericOverflow;
- }
-
- /**
- * Set {@code true} for numerics to overflow, false to deliver exceptions.
- * @see #getNumericOverflow
- */
- public final void setNumericOverflow(boolean allow) {
- this.numericOverflow = allow;
- }
-
/**
* Returns the value for the cumulative total number of statements that can be made in all loops
* in a script before an exception is thrown. This attempts to prevent infinite loops. Note if
diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/MethodWriter.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/MethodWriter.java
index bb362558796..cda8c23e3bf 100644
--- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/MethodWriter.java
+++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/MethodWriter.java
@@ -34,10 +34,6 @@ import java.util.ArrayList;
import java.util.Deque;
import java.util.List;
-import static org.elasticsearch.painless.WriterConstants.ADDEXACT_INT;
-import static org.elasticsearch.painless.WriterConstants.ADDEXACT_LONG;
-import static org.elasticsearch.painless.WriterConstants.ADDWOOVERLOW_DOUBLE;
-import static org.elasticsearch.painless.WriterConstants.ADDWOOVERLOW_FLOAT;
import static org.elasticsearch.painless.WriterConstants.DEF_ADD_CALL;
import static org.elasticsearch.painless.WriterConstants.DEF_AND_CALL;
import static org.elasticsearch.painless.WriterConstants.DEF_DIV_CALL;
@@ -49,19 +45,9 @@ import static org.elasticsearch.painless.WriterConstants.DEF_RSH_CALL;
import static org.elasticsearch.painless.WriterConstants.DEF_SUB_CALL;
import static org.elasticsearch.painless.WriterConstants.DEF_USH_CALL;
import static org.elasticsearch.painless.WriterConstants.DEF_XOR_CALL;
-import static org.elasticsearch.painless.WriterConstants.DIVWOOVERLOW_DOUBLE;
-import static org.elasticsearch.painless.WriterConstants.DIVWOOVERLOW_FLOAT;
-import static org.elasticsearch.painless.WriterConstants.DIVWOOVERLOW_INT;
-import static org.elasticsearch.painless.WriterConstants.DIVWOOVERLOW_LONG;
import static org.elasticsearch.painless.WriterConstants.INDY_STRING_CONCAT_BOOTSTRAP_HANDLE;
import static org.elasticsearch.painless.WriterConstants.MAX_INDY_STRING_CONCAT_ARGS;
-import static org.elasticsearch.painless.WriterConstants.MULEXACT_INT;
-import static org.elasticsearch.painless.WriterConstants.MULEXACT_LONG;
-import static org.elasticsearch.painless.WriterConstants.MULWOOVERLOW_DOUBLE;
-import static org.elasticsearch.painless.WriterConstants.MULWOOVERLOW_FLOAT;
import static org.elasticsearch.painless.WriterConstants.PAINLESS_ERROR_TYPE;
-import static org.elasticsearch.painless.WriterConstants.REMWOOVERLOW_DOUBLE;
-import static org.elasticsearch.painless.WriterConstants.REMWOOVERLOW_FLOAT;
import static org.elasticsearch.painless.WriterConstants.STRINGBUILDER_APPEND_BOOLEAN;
import static org.elasticsearch.painless.WriterConstants.STRINGBUILDER_APPEND_CHAR;
import static org.elasticsearch.painless.WriterConstants.STRINGBUILDER_APPEND_DOUBLE;
@@ -74,28 +60,6 @@ import static org.elasticsearch.painless.WriterConstants.STRINGBUILDER_CONSTRUCT
import static org.elasticsearch.painless.WriterConstants.STRINGBUILDER_TOSTRING;
import static org.elasticsearch.painless.WriterConstants.STRINGBUILDER_TYPE;
import static org.elasticsearch.painless.WriterConstants.STRING_TYPE;
-import static org.elasticsearch.painless.WriterConstants.SUBEXACT_INT;
-import static org.elasticsearch.painless.WriterConstants.SUBEXACT_LONG;
-import static org.elasticsearch.painless.WriterConstants.SUBWOOVERLOW_DOUBLE;
-import static org.elasticsearch.painless.WriterConstants.SUBWOOVERLOW_FLOAT;
-import static org.elasticsearch.painless.WriterConstants.TOBYTEEXACT_INT;
-import static org.elasticsearch.painless.WriterConstants.TOBYTEEXACT_LONG;
-import static org.elasticsearch.painless.WriterConstants.TOBYTEWOOVERFLOW_DOUBLE;
-import static org.elasticsearch.painless.WriterConstants.TOBYTEWOOVERFLOW_FLOAT;
-import static org.elasticsearch.painless.WriterConstants.TOCHAREXACT_INT;
-import static org.elasticsearch.painless.WriterConstants.TOCHAREXACT_LONG;
-import static org.elasticsearch.painless.WriterConstants.TOCHARWOOVERFLOW_DOUBLE;
-import static org.elasticsearch.painless.WriterConstants.TOCHARWOOVERFLOW_FLOAT;
-import static org.elasticsearch.painless.WriterConstants.TOFLOATWOOVERFLOW_DOUBLE;
-import static org.elasticsearch.painless.WriterConstants.TOINTEXACT_LONG;
-import static org.elasticsearch.painless.WriterConstants.TOINTWOOVERFLOW_DOUBLE;
-import static org.elasticsearch.painless.WriterConstants.TOINTWOOVERFLOW_FLOAT;
-import static org.elasticsearch.painless.WriterConstants.TOLONGWOOVERFLOW_DOUBLE;
-import static org.elasticsearch.painless.WriterConstants.TOLONGWOOVERFLOW_FLOAT;
-import static org.elasticsearch.painless.WriterConstants.TOSHORTEXACT_INT;
-import static org.elasticsearch.painless.WriterConstants.TOSHORTEXACT_LONG;
-import static org.elasticsearch.painless.WriterConstants.TOSHORTWOOVERFLOW_DOUBLE;
-import static org.elasticsearch.painless.WriterConstants.TOSHORTWOOVERFLOW_FLOAT;
/**
* Extension of {@link GeneratorAdapter} with some utility methods.
@@ -236,231 +200,53 @@ public final class MethodWriter extends GeneratorAdapter {
}
}
- public void writeBinaryInstruction(final CompilerSettings settings, final Definition definition,
+ public void writeBinaryInstruction(final Definition definition,
final String location,
final Type type, final Operation operation) {
final Sort sort = type.sort;
- boolean exact = !settings.getNumericOverflow() &&
- ((sort == Sort.INT || sort == Sort.LONG) &&
- (operation == Operation.MUL || operation == Operation.DIV ||
- operation == Operation.ADD || operation == Operation.SUB) ||
- (sort == Sort.FLOAT || sort == Sort.DOUBLE) &&
- (operation == Operation.MUL || operation == Operation.DIV || operation == Operation.REM ||
- operation == Operation.ADD || operation == Operation.SUB));
-
- if (exact) {
- switch (sort) {
- case INT:
- switch (operation) {
- case MUL: invokeStatic(definition.getType("Math").type, MULEXACT_INT); break;
- case DIV: invokeStatic(definition.getType("Utility").type, DIVWOOVERLOW_INT); break;
- case ADD: invokeStatic(definition.getType("Math").type, ADDEXACT_INT); break;
- case SUB: invokeStatic(definition.getType("Math").type, SUBEXACT_INT); break;
- }
-
- break;
- case LONG:
- switch (operation) {
- case MUL: invokeStatic(definition.getType("Math").type, MULEXACT_LONG); break;
- case DIV: invokeStatic(definition.getType("Utility").type, DIVWOOVERLOW_LONG); break;
- case ADD: invokeStatic(definition.getType("Math").type, ADDEXACT_LONG); break;
- case SUB: invokeStatic(definition.getType("Math").type, SUBEXACT_LONG); break;
- }
-
- break;
- case FLOAT:
- switch (operation) {
- case MUL: invokeStatic(definition.getType("Utility").type, MULWOOVERLOW_FLOAT); break;
- case DIV: invokeStatic(definition.getType("Utility").type, DIVWOOVERLOW_FLOAT); break;
- case REM: invokeStatic(definition.getType("Utility").type, REMWOOVERLOW_FLOAT); break;
- case ADD: invokeStatic(definition.getType("Utility").type, ADDWOOVERLOW_FLOAT); break;
- case SUB: invokeStatic(definition.getType("Utility").type, SUBWOOVERLOW_FLOAT); break;
- default:
- throw new IllegalStateException("Error " + location + ": Illegal tree structure.");
- }
-
- break;
- case DOUBLE:
- switch (operation) {
- case MUL: invokeStatic(definition.getType("Utility").type, MULWOOVERLOW_DOUBLE); break;
- case DIV: invokeStatic(definition.getType("Utility").type, DIVWOOVERLOW_DOUBLE); break;
- case REM: invokeStatic(definition.getType("Utility").type, REMWOOVERLOW_DOUBLE); break;
- case ADD: invokeStatic(definition.getType("Utility").type, ADDWOOVERLOW_DOUBLE); break;
- case SUB: invokeStatic(definition.getType("Utility").type, SUBWOOVERLOW_DOUBLE); break;
- default:
- throw new IllegalStateException("Error " + location + ": Illegal tree structure.");
- }
-
- break;
+
+ if ((sort == Sort.FLOAT || sort == Sort.DOUBLE) &&
+ (operation == Operation.LSH || operation == Operation.USH ||
+ operation == Operation.RSH || operation == Operation.BWAND ||
+ operation == Operation.XOR || operation == Operation.BWOR)) {
+ throw new IllegalStateException("Error " + location + ": Illegal tree structure.");
+ }
+
+ if (sort == Sort.DEF) {
+ switch (operation) {
+ case MUL: invokeStatic(definition.getType("Def").type, DEF_MUL_CALL); break;
+ case DIV: invokeStatic(definition.getType("Def").type, DEF_DIV_CALL); break;
+ case REM: invokeStatic(definition.getType("Def").type, DEF_REM_CALL); break;
+ case ADD: invokeStatic(definition.getType("Def").type, DEF_ADD_CALL); break;
+ case SUB: invokeStatic(definition.getType("Def").type, DEF_SUB_CALL); break;
+ case LSH: invokeStatic(definition.getType("Def").type, DEF_LSH_CALL); break;
+ case USH: invokeStatic(definition.getType("Def").type, DEF_RSH_CALL); break;
+ case RSH: invokeStatic(definition.getType("Def").type, DEF_USH_CALL); break;
+ case BWAND: invokeStatic(definition.getType("Def").type, DEF_AND_CALL); break;
+ case XOR: invokeStatic(definition.getType("Def").type, DEF_XOR_CALL); break;
+ case BWOR: invokeStatic(definition.getType("Def").type, DEF_OR_CALL); break;
default:
throw new IllegalStateException("Error " + location + ": Illegal tree structure.");
}
} else {
- if ((sort == Sort.FLOAT || sort == Sort.DOUBLE) &&
- (operation == Operation.LSH || operation == Operation.USH ||
- operation == Operation.RSH || operation == Operation.BWAND ||
- operation == Operation.XOR || operation == Operation.BWOR)) {
- throw new IllegalStateException("Error " + location + ": Illegal tree structure.");
- }
-
- if (sort == Sort.DEF) {
- switch (operation) {
- case MUL: invokeStatic(definition.getType("Def").type, DEF_MUL_CALL); break;
- case DIV: invokeStatic(definition.getType("Def").type, DEF_DIV_CALL); break;
- case REM: invokeStatic(definition.getType("Def").type, DEF_REM_CALL); break;
- case ADD: invokeStatic(definition.getType("Def").type, DEF_ADD_CALL); break;
- case SUB: invokeStatic(definition.getType("Def").type, DEF_SUB_CALL); break;
- case LSH: invokeStatic(definition.getType("Def").type, DEF_LSH_CALL); break;
- case USH: invokeStatic(definition.getType("Def").type, DEF_RSH_CALL); break;
- case RSH: invokeStatic(definition.getType("Def").type, DEF_USH_CALL); break;
- case BWAND: invokeStatic(definition.getType("Def").type, DEF_AND_CALL); break;
- case XOR: invokeStatic(definition.getType("Def").type, DEF_XOR_CALL); break;
- case BWOR: invokeStatic(definition.getType("Def").type, DEF_OR_CALL); break;
- default:
- throw new IllegalStateException("Error " + location + ": Illegal tree structure.");
- }
- } else {
- switch (operation) {
- case MUL: math(GeneratorAdapter.MUL, type.type); break;
- case DIV: math(GeneratorAdapter.DIV, type.type); break;
- case REM: math(GeneratorAdapter.REM, type.type); break;
- case ADD: math(GeneratorAdapter.ADD, type.type); break;
- case SUB: math(GeneratorAdapter.SUB, type.type); break;
- case LSH: math(GeneratorAdapter.SHL, type.type); break;
- case USH: math(GeneratorAdapter.USHR, type.type); break;
- case RSH: math(GeneratorAdapter.SHR, type.type); break;
- case BWAND: math(GeneratorAdapter.AND, type.type); break;
- case XOR: math(GeneratorAdapter.XOR, type.type); break;
- case BWOR: math(GeneratorAdapter.OR, type.type); break;
- default:
- throw new IllegalStateException("Error " + location + ": Illegal tree structure.");
- }
+ switch (operation) {
+ case MUL: math(GeneratorAdapter.MUL, type.type); break;
+ case DIV: math(GeneratorAdapter.DIV, type.type); break;
+ case REM: math(GeneratorAdapter.REM, type.type); break;
+ case ADD: math(GeneratorAdapter.ADD, type.type); break;
+ case SUB: math(GeneratorAdapter.SUB, type.type); break;
+ case LSH: math(GeneratorAdapter.SHL, type.type); break;
+ case USH: math(GeneratorAdapter.USHR, type.type); break;
+ case RSH: math(GeneratorAdapter.SHR, type.type); break;
+ case BWAND: math(GeneratorAdapter.AND, type.type); break;
+ case XOR: math(GeneratorAdapter.XOR, type.type); break;
+ case BWOR: math(GeneratorAdapter.OR, type.type); break;
+ default:
+ throw new IllegalStateException("Error " + location + ": Illegal tree structure.");
}
}
}
- /**
- * Called for any compound assignment (including increment/decrement instructions).
- * We have to be stricter than writeBinary and do overflow checks against the original type's size
- * instead of the promoted type's size, since the result will be implicitly cast back.
- *
- * @return This will be true if an instruction is written, false otherwise.
- */
- public boolean writeExactInstruction(
- final Definition definition, final Sort fsort, final Sort tsort) {
- if (fsort == Sort.DOUBLE) {
- if (tsort == Sort.FLOAT) {
- invokeStatic(definition.getType("Utility").type, TOFLOATWOOVERFLOW_DOUBLE);
- } else if (tsort == Sort.FLOAT_OBJ) {
- invokeStatic(definition.getType("Utility").type, TOFLOATWOOVERFLOW_DOUBLE);
- checkCast(definition.getType("Float").type);
- } else if (tsort == Sort.LONG) {
- invokeStatic(definition.getType("Utility").type, TOLONGWOOVERFLOW_DOUBLE);
- } else if (tsort == Sort.LONG_OBJ) {
- invokeStatic(definition.getType("Utility").type, TOLONGWOOVERFLOW_DOUBLE);
- checkCast(definition.getType("Long").type);
- } else if (tsort == Sort.INT) {
- invokeStatic(definition.getType("Utility").type, TOINTWOOVERFLOW_DOUBLE);
- } else if (tsort == Sort.INT_OBJ) {
- invokeStatic(definition.getType("Utility").type, TOINTWOOVERFLOW_DOUBLE);
- checkCast(definition.getType("Integer").type);
- } else if (tsort == Sort.CHAR) {
- invokeStatic(definition.getType("Utility").type, TOCHARWOOVERFLOW_DOUBLE);
- } else if (tsort == Sort.CHAR_OBJ) {
- invokeStatic(definition.getType("Utility").type, TOCHARWOOVERFLOW_DOUBLE);
- checkCast(definition.getType("Character").type);
- } else if (tsort == Sort.SHORT) {
- invokeStatic(definition.getType("Utility").type, TOSHORTWOOVERFLOW_DOUBLE);
- } else if (tsort == Sort.SHORT_OBJ) {
- invokeStatic(definition.getType("Utility").type, TOSHORTWOOVERFLOW_DOUBLE);
- checkCast(definition.getType("Short").type);
- } else if (tsort == Sort.BYTE) {
- invokeStatic(definition.getType("Utility").type, TOBYTEWOOVERFLOW_DOUBLE);
- } else if (tsort == Sort.BYTE_OBJ) {
- invokeStatic(definition.getType("Utility").type, TOBYTEWOOVERFLOW_DOUBLE);
- checkCast(definition.getType("Byte").type);
- } else {
- return false;
- }
- } else if (fsort == Sort.FLOAT) {
- if (tsort == Sort.LONG) {
- invokeStatic(definition.getType("Utility").type, TOLONGWOOVERFLOW_FLOAT);
- } else if (tsort == Sort.LONG_OBJ) {
- invokeStatic(definition.getType("Utility").type, TOLONGWOOVERFLOW_FLOAT);
- checkCast(definition.getType("Long").type);
- } else if (tsort == Sort.INT) {
- invokeStatic(definition.getType("Utility").type, TOINTWOOVERFLOW_FLOAT);
- } else if (tsort == Sort.INT_OBJ) {
- invokeStatic(definition.getType("Utility").type, TOINTWOOVERFLOW_FLOAT);
- checkCast(definition.getType("Integer").type);
- } else if (tsort == Sort.CHAR) {
- invokeStatic(definition.getType("Utility").type, TOCHARWOOVERFLOW_FLOAT);
- } else if (tsort == Sort.CHAR_OBJ) {
- invokeStatic(definition.getType("Utility").type, TOCHARWOOVERFLOW_FLOAT);
- checkCast(definition.getType("Character").type);
- } else if (tsort == Sort.SHORT) {
- invokeStatic(definition.getType("Utility").type, TOSHORTWOOVERFLOW_FLOAT);
- } else if (tsort == Sort.SHORT_OBJ) {
- invokeStatic(definition.getType("Utility").type, TOSHORTWOOVERFLOW_FLOAT);
- checkCast(definition.getType("Short").type);
- } else if (tsort == Sort.BYTE) {
- invokeStatic(definition.getType("Utility").type, TOBYTEWOOVERFLOW_FLOAT);
- } else if (tsort == Sort.BYTE_OBJ) {
- invokeStatic(definition.getType("Utility").type, TOBYTEWOOVERFLOW_FLOAT);
- checkCast(definition.getType("Byte").type);
- } else {
- return false;
- }
- } else if (fsort == Sort.LONG) {
- if (tsort == Sort.INT) {
- invokeStatic(definition.getType("Math").type, TOINTEXACT_LONG);
- } else if (tsort == Sort.INT_OBJ) {
- invokeStatic(definition.getType("Math").type, TOINTEXACT_LONG);
- checkCast(definition.getType("Integer").type);
- } else if (tsort == Sort.CHAR) {
- invokeStatic(definition.getType("Utility").type, TOCHAREXACT_LONG);
- } else if (tsort == Sort.CHAR_OBJ) {
- invokeStatic(definition.getType("Utility").type, TOCHAREXACT_LONG);
- checkCast(definition.getType("Character").type);
- } else if (tsort == Sort.SHORT) {
- invokeStatic(definition.getType("Utility").type, TOSHORTEXACT_LONG);
- } else if (tsort == Sort.SHORT_OBJ) {
- invokeStatic(definition.getType("Utility").type, TOSHORTEXACT_LONG);
- checkCast(definition.getType("Short").type);
- } else if (tsort == Sort.BYTE) {
- invokeStatic(definition.getType("Utility").type, TOBYTEEXACT_LONG);
- } else if (tsort == Sort.BYTE_OBJ) {
- invokeStatic(definition.getType("Utility").type, TOBYTEEXACT_LONG);
- checkCast(definition.getType("Byte").type);
- } else {
- return false;
- }
- } else if (fsort == Sort.INT) {
- if (tsort == Sort.CHAR) {
- invokeStatic(definition.getType("Utility").type, TOCHAREXACT_INT);
- } else if (tsort == Sort.CHAR_OBJ) {
- invokeStatic(definition.getType("Utility").type, TOCHAREXACT_INT);
- checkCast(definition.getType("Character").type);
- } else if (tsort == Sort.SHORT) {
- invokeStatic(definition.getType("Utility").type, TOSHORTEXACT_INT);
- } else if (tsort == Sort.SHORT_OBJ) {
- invokeStatic(definition.getType("Utility").type, TOSHORTEXACT_INT);
- checkCast(definition.getType("Short").type);
- } else if (tsort == Sort.BYTE) {
- invokeStatic(definition.getType("Utility").type, TOBYTEEXACT_INT);
- } else if (tsort == Sort.BYTE_OBJ) {
- invokeStatic(definition.getType("Utility").type, TOBYTEEXACT_INT);
- checkCast(definition.getType("Byte").type);
- } else {
- return false;
- }
- } else {
- return false;
- }
-
- return true;
- }
-
public void writeDup(final int size, final int xsize) {
if (size == 1) {
if (xsize == 2) {
diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/PainlessScriptEngineService.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/PainlessScriptEngineService.java
index 1d11dae720f..4c627d08eca 100644
--- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/PainlessScriptEngineService.java
+++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/PainlessScriptEngineService.java
@@ -115,13 +115,7 @@ public final class PainlessScriptEngineService extends AbstractComponent impleme
// Use custom settings specified by params.
compilerSettings = new CompilerSettings();
Map copy = new HashMap<>(params);
- String value = copy.remove(CompilerSettings.NUMERIC_OVERFLOW);
-
- if (value != null) {
- compilerSettings.setNumericOverflow(Boolean.parseBoolean(value));
- }
-
- value = copy.remove(CompilerSettings.MAX_LOOP_COUNTER);
+ String value = copy.remove(CompilerSettings.MAX_LOOP_COUNTER);
if (value != null) {
compilerSettings.setMaxLoopCounter(Integer.parseInt(value));
diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/Utility.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/Utility.java
index 32641649827..559e909ed77 100644
--- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/Utility.java
+++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/Utility.java
@@ -481,347 +481,6 @@ public class Utility {
return value.charAt(0);
}
- // although divide by zero is guaranteed, the special overflow case is not caught.
- // its not needed for remainder because it is not possible there.
- // see https://docs.oracle.com/javase/specs/jls/se8/html/jls-15.html#jls-15.17.2
-
- /**
- * Integer divide without overflow
- * @throws ArithmeticException on overflow or divide-by-zero
- */
- public static int divideWithoutOverflow(int x, int y) {
- if (x == Integer.MIN_VALUE && y == -1) {
- throw new ArithmeticException("integer overflow");
- }
- return x / y;
- }
-
- /**
- * Long divide without overflow
- * @throws ArithmeticException on overflow or divide-by-zero
- */
- public static long divideWithoutOverflow(long x, long y) {
- if (x == Long.MIN_VALUE && y == -1L) {
- throw new ArithmeticException("long overflow");
- }
- return x / y;
- }
-
- // byte, short, and char are promoted to int for normal operations,
- // so the JDK exact methods are typically used, and the result has a wider range.
- // but compound assignments and increment/decrement operators (e.g. byte b = Byte.MAX_VALUE; b++;)
- // implicitly cast back to the original type: so these need to be checked against the original range.
-
- /**
- * Like {@link Math#toIntExact(long)} but for byte range.
- */
- public static byte toByteExact(int value) {
- byte s = (byte) value;
- if (s != value) {
- throw new ArithmeticException("byte overflow");
- }
- return s;
- }
-
- /**
- * Like {@link Math#toIntExact(long)} but for byte range.
- */
- public static byte toByteExact(long value) {
- byte s = (byte) value;
- if (s != value) {
- throw new ArithmeticException("byte overflow");
- }
- return s;
- }
-
- /**
- * Like {@link Math#toIntExact(long)} but for byte range.
- */
- public static byte toByteWithoutOverflow(float value) {
- if (value < Byte.MIN_VALUE || value > Byte.MAX_VALUE) {
- throw new ArithmeticException("byte overflow");
- }
- return (byte)value;
- }
-
- /**
- * Like {@link Math#toIntExact(long)} but for byte range.
- */
- public static byte toByteWithoutOverflow(double value) {
- if (value < Byte.MIN_VALUE || value > Byte.MAX_VALUE) {
- throw new ArithmeticException("byte overflow");
- }
- return (byte)value;
- }
-
- /**
- * Like {@link Math#toIntExact(long)} but for short range.
- */
- public static short toShortExact(int value) {
- short s = (short) value;
- if (s != value) {
- throw new ArithmeticException("short overflow");
- }
- return s;
- }
-
- /**
- * Like {@link Math#toIntExact(long)} but for short range.
- */
- public static short toShortExact(long value) {
- short s = (short) value;
- if (s != value) {
- throw new ArithmeticException("short overflow");
- }
- return s;
- }
-
- /**
- * Like {@link Math#toIntExact(long)} but for short range.
- */
- public static short toShortWithoutOverflow(float value) {
- if (value < Short.MIN_VALUE || value > Short.MAX_VALUE) {
- throw new ArithmeticException("short overflow");
- }
- return (short)value;
- }
-
- /**
- * Like {@link Math#toIntExact(long)} but for short range.
- */
- public static short toShortExact(double value) {
- if (value < Short.MIN_VALUE || value > Short.MAX_VALUE) {
- throw new ArithmeticException("short overflow");
- }
- return (short)value;
- }
-
- /**
- * Like {@link Math#toIntExact(long)} but for char range.
- */
- public static char toCharExact(int value) {
- char s = (char) value;
- if (s != value) {
- throw new ArithmeticException("char overflow");
- }
- return s;
- }
-
- /**
- * Like {@link Math#toIntExact(long)} but for char range.
- */
- public static char toCharExact(long value) {
- char s = (char) value;
- if (s != value) {
- throw new ArithmeticException("char overflow");
- }
- return s;
- }
-
- /**
- * Like {@link Math#toIntExact(long)} but for char range.
- */
- public static char toCharWithoutOverflow(float value) {
- if (value < Character.MIN_VALUE || value > Character.MAX_VALUE) {
- throw new ArithmeticException("char overflow");
- }
- return (char)value;
- }
-
- /**
- * Like {@link Math#toIntExact(long)} but for char range.
- */
- public static char toCharWithoutOverflow(double value) {
- if (value < Character.MIN_VALUE || value > Character.MAX_VALUE) {
- throw new ArithmeticException("char overflow");
- }
- return (char)value;
- }
-
- /**
- * Like {@link Math#toIntExact(long)} but for int range.
- */
- public static int toIntWithoutOverflow(float value) {
- if (value < Integer.MIN_VALUE || value > Integer.MAX_VALUE) {
- throw new ArithmeticException("int overflow");
- }
- return (int)value;
- }
-
- /**
- * Like {@link Math#toIntExact(long)} but for int range.
- */
- public static int toIntWithoutOverflow(double value) {
- if (value < Integer.MIN_VALUE || value > Integer.MAX_VALUE) {
- throw new ArithmeticException("int overflow");
- }
- return (int)value;
- }
-
- /**
- * Like {@link Math#toIntExact(long)} but for long range.
- */
- public static long toLongWithoutOverflow(float value) {
- if (value < Long.MIN_VALUE || value > Long.MAX_VALUE) {
- throw new ArithmeticException("long overflow");
- }
- return (long)value;
- }
-
- /**
- * Like {@link Math#toIntExact(long)} but for long range.
- */
- public static float toLongWithoutOverflow(double value) {
- if (value < Long.MIN_VALUE || value > Long.MAX_VALUE) {
- throw new ArithmeticException("long overflow");
- }
- return (long)value;
- }
-
- /**
- * Like {@link Math#toIntExact(long)} but for float range.
- */
- public static float toFloatWithoutOverflow(double value) {
- if (value < Float.MIN_VALUE || value > Float.MAX_VALUE) {
- throw new ArithmeticException("float overflow");
- }
- return (float)value;
- }
-
- /**
- * Checks for overflow, result is infinite but operands are finite
- * @throws ArithmeticException if overflow occurred
- */
- private static float checkInfFloat(float x, float y, float z) {
- if (Float.isInfinite(z)) {
- if (Float.isFinite(x) && Float.isFinite(y)) {
- throw new ArithmeticException("float overflow");
- }
- }
- return z;
- }
-
- /**
- * Checks for NaN, result is NaN but operands are finite
- * @throws ArithmeticException if overflow occurred
- */
- private static float checkNaNFloat(float x, float y, float z) {
- if (Float.isNaN(z)) {
- if (Float.isFinite(x) && Float.isFinite(y)) {
- throw new ArithmeticException("NaN");
- }
- }
- return z;
- }
-
- /**
- * Checks for NaN, result is infinite but operands are finite
- * @throws ArithmeticException if overflow occurred
- */
- private static double checkInfDouble(double x, double y, double z) {
- if (Double.isInfinite(z)) {
- if (Double.isFinite(x) && Double.isFinite(y)) {
- throw new ArithmeticException("double overflow");
- }
- }
- return z;
- }
-
- /**
- * Checks for NaN, result is NaN but operands are finite
- * @throws ArithmeticException if overflow occurred
- */
- private static double checkNaNDouble(double x, double y, double z) {
- if (Double.isNaN(z)) {
- if (Double.isFinite(x) && Double.isFinite(y)) {
- throw new ArithmeticException("NaN");
- }
- }
- return z;
- }
-
- /**
- * Adds two floats but throws {@code ArithmeticException}
- * if the result overflows.
- */
- public static float addWithoutOverflow(float x, float y) {
- return checkInfFloat(x, y, x + y);
- }
-
- /**
- * Adds two doubles but throws {@code ArithmeticException}
- * if the result overflows.
- */
- public static double addWithoutOverflow(double x, double y) {
- return checkInfDouble(x, y, x + y);
- }
-
- /**
- * Subtracts two floats but throws {@code ArithmeticException}
- * if the result overflows.
- */
- public static float subtractWithoutOverflow(float x, float y) {
- return checkInfFloat(x, y, x - y);
- }
-
- /**
- * Subtracts two doubles but throws {@code ArithmeticException}
- * if the result overflows.
- */
- public static double subtractWithoutOverflow(double x, double y) {
- return checkInfDouble(x, y , x - y);
- }
-
- /**
- * Multiplies two floats but throws {@code ArithmeticException}
- * if the result overflows.
- */
- public static float multiplyWithoutOverflow(float x, float y) {
- return checkInfFloat(x, y, x * y);
- }
-
- /**
- * Multiplies two doubles but throws {@code ArithmeticException}
- * if the result overflows.
- */
- public static double multiplyWithoutOverflow(double x, double y) {
- return checkInfDouble(x, y, x * y);
- }
-
- /**
- * Divides two floats but throws {@code ArithmeticException}
- * if the result overflows, or would create NaN from finite
- * inputs ({@code x == 0, y == 0})
- */
- public static float divideWithoutOverflow(float x, float y) {
- return checkNaNFloat(x, y, checkInfFloat(x, y, x / y));
- }
-
- /**
- * Divides two doubles but throws {@code ArithmeticException}
- * if the result overflows, or would create NaN from finite
- * inputs ({@code x == 0, y == 0})
- */
- public static double divideWithoutOverflow(double x, double y) {
- return checkNaNDouble(x, y, checkInfDouble(x, y, x / y));
- }
-
- /**
- * Takes remainder two floats but throws {@code ArithmeticException}
- * if the result would create NaN from finite inputs ({@code y == 0})
- */
- public static float remainderWithoutOverflow(float x, float y) {
- return checkNaNFloat(x, y, x % y);
- }
-
- /**
- * Divides two doubles but throws {@code ArithmeticException}
- * if the result would create NaN from finite inputs ({@code y == 0})
- */
- public static double remainderWithoutOverflow(double x, double y) {
- return checkNaNDouble(x, y, x % y);
- }
-
public static boolean checkEquals(final Object left, final Object right) {
if (left != null) {
return left.equals(right);
diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/WriterConstants.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/WriterConstants.java
index 6bdb9856114..d167646e9dd 100644
--- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/WriterConstants.java
+++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/WriterConstants.java
@@ -27,7 +27,6 @@ import org.objectweb.asm.Type;
import org.objectweb.asm.commons.Method;
import java.lang.invoke.CallSite;
-import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodType;
import java.util.Map;
@@ -116,59 +115,8 @@ public final class WriterConstants {
public final static Method STRINGBUILDER_APPEND_OBJECT = getAsmMethod(StringBuilder.class, "append", Object.class);
public final static Method STRINGBUILDER_TOSTRING = getAsmMethod(String.class, "toString");
- public final static Method TOINTEXACT_LONG = getAsmMethod(int.class, "toIntExact", long.class);
- public final static Method NEGATEEXACT_INT = getAsmMethod(int.class, "negateExact", int.class);
- public final static Method NEGATEEXACT_LONG = getAsmMethod(long.class, "negateExact", long.class);
- public final static Method MULEXACT_INT = getAsmMethod(int.class, "multiplyExact", int.class, int.class);
- public final static Method MULEXACT_LONG = getAsmMethod(long.class, "multiplyExact", long.class, long.class);
- public final static Method ADDEXACT_INT = getAsmMethod(int.class, "addExact", int.class, int.class);
- public final static Method ADDEXACT_LONG = getAsmMethod(long.class, "addExact", long.class, long.class);
- public final static Method SUBEXACT_INT = getAsmMethod(int.class, "subtractExact", int.class, int.class);
- public final static Method SUBEXACT_LONG = getAsmMethod(long.class, "subtractExact", long.class, long.class);
-
public final static Method CHECKEQUALS =
getAsmMethod(boolean.class, "checkEquals", Object.class, Object.class);
- public final static Method TOBYTEEXACT_INT = getAsmMethod(byte.class, "toByteExact", int.class);
- public final static Method TOBYTEEXACT_LONG = getAsmMethod(byte.class, "toByteExact", long.class);
- public final static Method TOBYTEWOOVERFLOW_FLOAT = getAsmMethod(byte.class, "toByteWithoutOverflow", float.class);
- public final static Method TOBYTEWOOVERFLOW_DOUBLE = getAsmMethod(byte.class, "toByteWithoutOverflow", double.class);
- public final static Method TOSHORTEXACT_INT = getAsmMethod(short.class, "toShortExact", int.class);
- public final static Method TOSHORTEXACT_LONG = getAsmMethod(short.class, "toShortExact", long.class);
- public final static Method TOSHORTWOOVERFLOW_FLOAT = getAsmMethod(short.class, "toShortWithoutOverflow", float.class);
- public final static Method TOSHORTWOOVERFLOW_DOUBLE = getAsmMethod(short.class, "toShortWihtoutOverflow", double.class);
- public final static Method TOCHAREXACT_INT = getAsmMethod(char.class, "toCharExact", int.class);
- public final static Method TOCHAREXACT_LONG = getAsmMethod(char.class, "toCharExact", long.class);
- public final static Method TOCHARWOOVERFLOW_FLOAT = getAsmMethod(char.class, "toCharWithoutOverflow", float.class);
- public final static Method TOCHARWOOVERFLOW_DOUBLE = getAsmMethod(char.class, "toCharWithoutOverflow", double.class);
- public final static Method TOINTWOOVERFLOW_FLOAT = getAsmMethod(int.class, "toIntWithoutOverflow", float.class);
- public final static Method TOINTWOOVERFLOW_DOUBLE = getAsmMethod(int.class, "toIntWithoutOverflow", double.class);
- public final static Method TOLONGWOOVERFLOW_FLOAT = getAsmMethod(long.class, "toLongWithoutOverflow", float.class);
- public final static Method TOLONGWOOVERFLOW_DOUBLE = getAsmMethod(long.class, "toLongWithoutOverflow", double.class);
- public final static Method TOFLOATWOOVERFLOW_DOUBLE = getAsmMethod(float.class , "toFloatWihtoutOverflow", double.class);
- public final static Method MULWOOVERLOW_FLOAT =
- getAsmMethod(float.class, "multiplyWithoutOverflow", float.class, float.class);
- public final static Method MULWOOVERLOW_DOUBLE =
- getAsmMethod(double.class, "multiplyWithoutOverflow", double.class, double.class);
- public final static Method DIVWOOVERLOW_INT =
- getAsmMethod(int.class, "divideWithoutOverflow", int.class, int.class);
- public final static Method DIVWOOVERLOW_LONG =
- getAsmMethod(long.class, "divideWithoutOverflow", long.class, long.class);
- public final static Method DIVWOOVERLOW_FLOAT =
- getAsmMethod(float.class, "divideWithoutOverflow", float.class, float.class);
- public final static Method DIVWOOVERLOW_DOUBLE =
- getAsmMethod(double.class, "divideWithoutOverflow", double.class, double.class);
- public final static Method REMWOOVERLOW_FLOAT =
- getAsmMethod(float.class, "remainderWithoutOverflow", float.class, float.class);
- public final static Method REMWOOVERLOW_DOUBLE =
- getAsmMethod(double.class, "remainderWithoutOverflow", double.class, double.class);
- public final static Method ADDWOOVERLOW_FLOAT =
- getAsmMethod(float.class, "addWithoutOverflow", float.class, float.class);
- public final static Method ADDWOOVERLOW_DOUBLE =
- getAsmMethod(double.class, "addWithoutOverflow", double.class, double.class);
- public final static Method SUBWOOVERLOW_FLOAT =
- getAsmMethod(float.class, "subtractWithoutOverflow", float.class, float.class);
- public final static Method SUBWOOVERLOW_DOUBLE =
- getAsmMethod(double.class, "subtractWithoutOverflow", double.class, double.class);
private static Method getAsmMethod(final Class> rtype, final String name, final Class>... ptypes) {
return new Method(name, MethodType.methodType(rtype, ptypes).toMethodDescriptorString());
diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EBinary.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EBinary.java
index 18b9de80fb6..f22b7394ca0 100644
--- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EBinary.java
+++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EBinary.java
@@ -94,21 +94,16 @@ public final class EBinary extends AExpression {
right = right.cast(settings, definition, variables);
if (left.constant != null && right.constant != null) {
- final boolean overflow = settings.getNumericOverflow();
final Sort sort = promote.sort;
if (sort == Sort.INT) {
- constant = overflow ? (int)left.constant * (int)right.constant :
- Math.multiplyExact((int)left.constant, (int)right.constant);
+ constant = (int)left.constant * (int)right.constant;
} else if (sort == Sort.LONG) {
- constant = overflow ? (long)left.constant * (long)right.constant :
- Math.multiplyExact((long)left.constant, (long)right.constant);
+ constant = (long)left.constant * (long)right.constant;
} else if (sort == Sort.FLOAT) {
- constant = overflow ? (float)left.constant * (float)right.constant :
- org.elasticsearch.painless.Utility.multiplyWithoutOverflow((float)left.constant, (float)right.constant);
+ constant = (float)left.constant * (float)right.constant;
} else if (sort == Sort.DOUBLE) {
- constant = overflow ? (double)left.constant * (double)right.constant :
- org.elasticsearch.painless.Utility.multiplyWithoutOverflow((double)left.constant, (double)right.constant);
+ constant = (double)left.constant * (double)right.constant;
} else {
throw new IllegalStateException(error("Illegal tree structure."));
}
@@ -135,21 +130,16 @@ public final class EBinary extends AExpression {
right = right.cast(settings, definition, variables);
if (left.constant != null && right.constant != null) {
- final boolean overflow = settings.getNumericOverflow();
final Sort sort = promote.sort;
if (sort == Sort.INT) {
- constant = overflow ? (int)left.constant / (int)right.constant :
- org.elasticsearch.painless.Utility.divideWithoutOverflow((int)left.constant, (int)right.constant);
+ constant = (int)left.constant / (int)right.constant;
} else if (sort == Sort.LONG) {
- constant = overflow ? (long)left.constant / (long)right.constant :
- org.elasticsearch.painless.Utility.divideWithoutOverflow((long)left.constant, (long)right.constant);
+ constant = (long)left.constant / (long)right.constant;
} else if (sort == Sort.FLOAT) {
- constant = overflow ? (float)left.constant / (float)right.constant :
- org.elasticsearch.painless.Utility.divideWithoutOverflow((float)left.constant, (float)right.constant);
+ constant = (float)left.constant / (float)right.constant;
} else if (sort == Sort.DOUBLE) {
- constant = overflow ? (double)left.constant / (double)right.constant :
- org.elasticsearch.painless.Utility.divideWithoutOverflow((double)left.constant, (double)right.constant);
+ constant = (double)left.constant / (double)right.constant;
} else {
throw new IllegalStateException(error("Illegal tree structure."));
}
@@ -176,7 +166,6 @@ public final class EBinary extends AExpression {
right = right.cast(settings, definition, variables);
if (left.constant != null && right.constant != null) {
- final boolean overflow = settings.getNumericOverflow();
final Sort sort = promote.sort;
if (sort == Sort.INT) {
@@ -184,11 +173,9 @@ public final class EBinary extends AExpression {
} else if (sort == Sort.LONG) {
constant = (long)left.constant % (long)right.constant;
} else if (sort == Sort.FLOAT) {
- constant = overflow ? (float)left.constant % (float)right.constant :
- org.elasticsearch.painless.Utility.remainderWithoutOverflow((float)left.constant, (float)right.constant);
+ constant = (float)left.constant % (float)right.constant;
} else if (sort == Sort.DOUBLE) {
- constant = overflow ? (double)left.constant % (double)right.constant :
- org.elasticsearch.painless.Utility.remainderWithoutOverflow((double)left.constant, (double)right.constant);
+ constant = (double)left.constant % (double)right.constant;
} else {
throw new IllegalStateException(error("Illegal tree structure."));
}
@@ -231,20 +218,14 @@ public final class EBinary extends AExpression {
right = right.cast(settings, definition, variables);
if (left.constant != null && right.constant != null) {
- final boolean overflow = settings.getNumericOverflow();
-
if (sort == Sort.INT) {
- constant = overflow ? (int)left.constant + (int)right.constant :
- Math.addExact((int)left.constant, (int)right.constant);
+ constant = (int)left.constant + (int)right.constant;
} else if (sort == Sort.LONG) {
- constant = overflow ? (long)left.constant + (long)right.constant :
- Math.addExact((long)left.constant, (long)right.constant);
+ constant = (long)left.constant + (long)right.constant;
} else if (sort == Sort.FLOAT) {
- constant = overflow ? (float)left.constant + (float)right.constant :
- org.elasticsearch.painless.Utility.addWithoutOverflow((float)left.constant, (float)right.constant);
+ constant = (float)left.constant + (float)right.constant;
} else if (sort == Sort.DOUBLE) {
- constant = overflow ? (double)left.constant + (double)right.constant :
- org.elasticsearch.painless.Utility.addWithoutOverflow((double)left.constant, (double)right.constant);
+ constant = (double)left.constant + (double)right.constant;
} else if (sort == Sort.STRING) {
constant = "" + left.constant + right.constant;
} else {
@@ -273,21 +254,16 @@ public final class EBinary extends AExpression {
right = right.cast(settings, definition, variables);
if (left.constant != null && right.constant != null) {
- final boolean overflow = settings.getNumericOverflow();
final Sort sort = promote.sort;
if (sort == Sort.INT) {
- constant = overflow ? (int)left.constant - (int)right.constant :
- Math.subtractExact((int)left.constant, (int)right.constant);
+ constant = (int)left.constant - (int)right.constant;
} else if (sort == Sort.LONG) {
- constant = overflow ? (long)left.constant - (long)right.constant :
- Math.subtractExact((long)left.constant, (long)right.constant);
+ constant = (long)left.constant - (long)right.constant;
} else if (sort == Sort.FLOAT) {
- constant = overflow ? (float)left.constant - (float)right.constant :
- org.elasticsearch.painless.Utility.subtractWithoutOverflow((float)left.constant, (float)right.constant);
+ constant = (float)left.constant - (float)right.constant;
} else if (sort == Sort.DOUBLE) {
- constant = overflow ? (double)left.constant - (double)right.constant :
- org.elasticsearch.painless.Utility.subtractWithoutOverflow((double)left.constant, (double)right.constant);
+ constant = (double)left.constant - (double)right.constant;
} else {
throw new IllegalStateException(error("Illegal tree structure."));
}
@@ -519,7 +495,7 @@ public final class EBinary extends AExpression {
left.write(settings, definition, adapter);
right.write(settings, definition, adapter);
- adapter.writeBinaryInstruction(settings, definition, location, actual, operation);
+ adapter.writeBinaryInstruction(definition, location, actual, operation);
}
adapter.writeBranch(tru, fals);
diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EChain.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EChain.java
index 763005d17ba..933295f9beb 100644
--- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EChain.java
+++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EChain.java
@@ -44,7 +44,6 @@ public final class EChain extends AExpression {
boolean cat = false;
Type promote = null;
- boolean exact = false;
Cast there = null;
Cast back = null;
@@ -208,9 +207,6 @@ public final class EChain extends AExpression {
expression = expression.cast(settings, definition, variables);
- exact = !settings.getNumericOverflow() &&
- (operation == Operation.MUL || operation == Operation.DIV || operation == Operation.REM ||
- operation == Operation.ADD || operation == Operation.SUB);
there = AnalyzerCaster.getLegalCast(definition, location, last.after, promote, false);
back = AnalyzerCaster.getLegalCast(definition, location, promote, last.after, true);
@@ -293,11 +289,9 @@ public final class EChain extends AExpression {
adapter.writeCast(there);
expression.write(settings, definition, adapter);
- adapter.writeBinaryInstruction(settings, definition, location, promote, operation);
+ adapter.writeBinaryInstruction(definition, location, promote, operation);
- if (!exact || !adapter.writeExactInstruction(definition, promote.sort, link.after.sort)) {
- adapter.writeCast(back);
- }
+ adapter.writeCast(back);
if (link.load && !post) {
adapter.writeDup(link.after.sort.size, link.size);
diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EUnary.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EUnary.java
index cbf76373136..409d1081ae9 100644
--- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EUnary.java
+++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EUnary.java
@@ -31,8 +31,6 @@ import org.elasticsearch.painless.MethodWriter;
import static org.elasticsearch.painless.WriterConstants.DEF_NEG_CALL;
import static org.elasticsearch.painless.WriterConstants.DEF_NOT_CALL;
-import static org.elasticsearch.painless.WriterConstants.NEGATEEXACT_INT;
-import static org.elasticsearch.painless.WriterConstants.NEGATEEXACT_LONG;
/**
* Represents a unary math expression.
@@ -147,14 +145,13 @@ public final class EUnary extends AExpression {
child = child.cast(settings, definition, variables);
if (child.constant != null) {
- final boolean overflow = settings.getNumericOverflow();
final Sort sort = promote.sort;
if (sort == Sort.INT) {
- constant = overflow ? -(int)child.constant : Math.negateExact((int)child.constant);
+ constant = -(int)child.constant;
} else if (sort == Sort.LONG) {
- constant = overflow ? -(long)child.constant : Math.negateExact((long)child.constant);
+ constant = -(long)child.constant;
} else if (sort == Sort.FLOAT) {
constant = -(float)child.constant;
} else if (sort == Sort.DOUBLE) {
@@ -211,17 +208,7 @@ public final class EUnary extends AExpression {
if (sort == Sort.DEF) {
adapter.invokeStatic(definition.getType("Def").type, DEF_NEG_CALL);
} else {
- if (settings.getNumericOverflow()) {
- adapter.math(MethodWriter.NEG, type);
- } else {
- if (sort == Sort.INT) {
- adapter.invokeStatic(definition.getType("Math").type, NEGATEEXACT_INT);
- } else if (sort == Sort.LONG) {
- adapter.invokeStatic(definition.getType("Math").type, NEGATEEXACT_LONG);
- } else {
- throw new IllegalStateException(error("Illegal tree structure."));
- }
- }
+ adapter.math(MethodWriter.NEG, type);
}
} else if (operation != Operation.ADD) {
throw new IllegalStateException(error("Illegal tree structure."));
diff --git a/modules/lang-painless/src/test/java/org/elasticsearch/painless/FloatOverflowDisabledTests.java b/modules/lang-painless/src/test/java/org/elasticsearch/painless/FloatOverflowDisabledTests.java
deleted file mode 100644
index 7bec0b110df..00000000000
--- a/modules/lang-painless/src/test/java/org/elasticsearch/painless/FloatOverflowDisabledTests.java
+++ /dev/null
@@ -1,293 +0,0 @@
-/*
- * Licensed to Elasticsearch under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package org.elasticsearch.painless;
-
-import java.util.Collections;
-import java.util.Map;
-
-/** Tests floating point overflow with numeric overflow disabled */
-public class FloatOverflowDisabledTests extends ScriptTestCase {
-
- /** wire overflow to false for all tests */
- @Override
- public Object exec(String script, Map vars) {
- return exec(script, vars, Collections.singletonMap(CompilerSettings.NUMERIC_OVERFLOW, "false"));
- }
-
- public void testAssignmentAdditionOverflow() {
- // float
- try {
- exec("float x = 3.4028234663852886E38f; x += 3.4028234663852886E38f; return x;");
- fail("didn't hit expected exception");
- } catch (ArithmeticException expected) {}
- try {
- exec("float x = -3.4028234663852886E38f; x += -3.4028234663852886E38f; return x;");
- fail("didn't hit expected exception");
- } catch (ArithmeticException expected) {}
-
- // double
- try {
- exec("double x = 1.7976931348623157E308; x += 1.7976931348623157E308; return x;");
- fail("didn't hit expected exception");
- } catch (ArithmeticException expected) {}
- try {
- exec("double x = -1.7976931348623157E308; x += -1.7976931348623157E308; return x;");
- fail("didn't hit expected exception");
- } catch (ArithmeticException expected) {}
- }
-
- public void testAssignmentSubtractionOverflow() {
- // float
- try {
- exec("float x = 3.4028234663852886E38f; x -= -3.4028234663852886E38f; return x;");
- fail("didn't hit expected exception");
- } catch (ArithmeticException expected) {}
- try {
- exec("float x = -3.4028234663852886E38f; x -= 3.4028234663852886E38f; return x;");
- fail("didn't hit expected exception");
- } catch (ArithmeticException expected) {}
-
- // double
- try {
- exec("double x = 1.7976931348623157E308; x -= -1.7976931348623157E308; return x;");
- fail("didn't hit expected exception");
- } catch (ArithmeticException expected) {}
- try {
- exec("double x = -1.7976931348623157E308; x -= 1.7976931348623157E308; return x;");
- fail("didn't hit expected exception");
- } catch (ArithmeticException expected) {}
- }
-
- public void testAssignmentMultiplicationOverflow() {
- // float
- try {
- exec("float x = 3.4028234663852886E38f; x *= 3.4028234663852886E38f; return x;");
- fail("didn't hit expected exception");
- } catch (ArithmeticException expected) {}
- try {
- exec("float x = 3.4028234663852886E38f; x *= -3.4028234663852886E38f; return x;");
- fail("didn't hit expected exception");
- } catch (ArithmeticException expected) {}
-
- // double
- try {
- exec("double x = 1.7976931348623157E308; x *= 1.7976931348623157E308; return x;");
- fail("didn't hit expected exception");
- } catch (ArithmeticException expected) {}
- try {
- exec("double x = 1.7976931348623157E308; x *= -1.7976931348623157E308; return x;");
- fail("didn't hit expected exception");
- } catch (ArithmeticException expected) {}
- }
-
- public void testAssignmentDivisionOverflow() {
- // float
- try {
- exec("float x = 3.4028234663852886E38f; x /= 1.401298464324817E-45f; return x;");
- fail("didn't hit expected exception");
- } catch (ArithmeticException expected) {}
- try {
- exec("float x = 3.4028234663852886E38f; x /= -1.401298464324817E-45f; return x;");
- fail("didn't hit expected exception");
- } catch (ArithmeticException expected) {}
- try {
- exec("float x = 1.0f; x /= 0.0f; return x;");
- fail("didn't hit expected exception");
- } catch (ArithmeticException expected) {}
-
- // double
- try {
- exec("double x = 1.7976931348623157E308; x /= 4.9E-324; return x;");
- fail("didn't hit expected exception");
- } catch (ArithmeticException expected) {}
- try {
- exec("double x = 1.7976931348623157E308; x /= -4.9E-324; return x;");
- fail("didn't hit expected exception");
- } catch (ArithmeticException expected) {}
- try {
- exec("double x = 1.0f; x /= 0.0; return x;");
- fail("didn't hit expected exception");
- } catch (ArithmeticException expected) {}
- }
-
- public void testAddition() throws Exception {
- try {
- exec("float x = 3.4028234663852886E38f; float y = 3.4028234663852886E38f; return x + y;");
- fail("didn't hit expected exception");
- } catch (ArithmeticException expected) {}
- try {
- exec("double x = 1.7976931348623157E308; double y = 1.7976931348623157E308; return x + y;");
- fail("didn't hit expected exception");
- } catch (ArithmeticException expected) {}
- }
-
- public void testAdditionConst() throws Exception {
- try {
- exec("return 3.4028234663852886E38f + 3.4028234663852886E38f;");
- fail("didn't hit expected exception");
- } catch (ArithmeticException expected) {}
- try {
- exec("return 1.7976931348623157E308 + 1.7976931348623157E308;");
- fail("didn't hit expected exception");
- } catch (ArithmeticException expected) {}
- }
-
- public void testSubtraction() throws Exception {
- try {
- exec("float x = -3.4028234663852886E38f; float y = 3.4028234663852886E38f; return x - y;");
- fail("didn't hit expected exception");
- } catch (ArithmeticException expected) {}
- try {
- exec("double x = -1.7976931348623157E308; double y = 1.7976931348623157E308; return x - y;");
- fail("didn't hit expected exception");
- } catch (ArithmeticException expected) {}
- }
-
- public void testSubtractionConst() throws Exception {
- try {
- exec("return -3.4028234663852886E38f - 3.4028234663852886E38f;");
- fail("didn't hit expected exception");
- } catch (ArithmeticException expected) {}
- try {
- exec("return -1.7976931348623157E308 - 1.7976931348623157E308;");
- fail("didn't hit expected exception");
- } catch (ArithmeticException expected) {}
- }
-
- public void testMultiplication() throws Exception {
- try {
- exec("float x = 3.4028234663852886E38f; float y = 3.4028234663852886E38f; return x * y;");
- fail("didn't hit expected exception");
- } catch (ArithmeticException expected) {}
- try {
- exec("double x = 1.7976931348623157E308; double y = 1.7976931348623157E308; return x * y;");
- fail("didn't hit expected exception");
- } catch (ArithmeticException expected) {}
- }
-
- public void testMultiplicationConst() throws Exception {
- try {
- exec("return 3.4028234663852886E38f * 3.4028234663852886E38f;");
- fail("didn't hit expected exception");
- } catch (ArithmeticException expected) {}
- try {
- exec("return 1.7976931348623157E308 * 1.7976931348623157E308;");
- fail("didn't hit expected exception");
- } catch (ArithmeticException expected) {}
- }
-
- public void testDivision() throws Exception {
- try {
- exec("float x = 3.4028234663852886E38f; float y = 1.401298464324817E-45f; return x / y;");
- fail("didn't hit expected exception");
- } catch (ArithmeticException expected) {}
- try {
- exec("float x = 1.0f; float y = 0.0f; return x / y;");
- fail("didn't hit expected exception");
- } catch (ArithmeticException expected) {}
- try {
- exec("double x = 1.7976931348623157E308; double y = 4.9E-324; return x / y;");
- fail("didn't hit expected exception");
- } catch (ArithmeticException expected) {}
- try {
- exec("double x = 1.0; double y = 0.0; return x / y;");
- fail("didn't hit expected exception");
- } catch (ArithmeticException expected) {}
- }
-
- public void testDivisionConst() throws Exception {
- try {
- exec("return 3.4028234663852886E38f / 1.401298464324817E-45f;");
- fail("didn't hit expected exception");
- } catch (ArithmeticException expected) {}
- try {
- exec("return 1.0f / 0.0f;");
- fail("didn't hit expected exception");
- } catch (ArithmeticException expected) {}
- try {
- exec("return 1.7976931348623157E308 / 4.9E-324;");
- fail("didn't hit expected exception");
- } catch (ArithmeticException expected) {}
- try {
- exec("return 1.0 / 0.0;");
- fail("didn't hit expected exception");
- } catch (ArithmeticException expected) {}
- }
-
- public void testDivisionNaN() throws Exception {
- // float division, constant division, and assignment
- try {
- exec("float x = 0f; float y = 0f; return x / y;");
- fail("didn't hit expected exception");
- } catch (ArithmeticException expected) {}
- try {
- exec("return 0f / 0f;");
- fail("didn't hit expected exception");
- } catch (ArithmeticException expected) {}
- try {
- exec("float x = 0f; x /= 0f; return x;");
- fail("didn't hit expected exception");
- } catch (ArithmeticException expected) {}
-
- // double division, constant division, and assignment
- try {
- exec("double x = 0.0; double y = 0.0; return x / y;");
- fail("didn't hit expected exception");
- } catch (ArithmeticException expected) {}
- try {
- exec("return 0.0 / 0.0;");
- fail("didn't hit expected exception");
- } catch (ArithmeticException expected) {}
- try {
- exec("double x = 0.0; x /= 0.0; return x;");
- fail("didn't hit expected exception");
- } catch (ArithmeticException expected) {}
- }
-
- public void testRemainderNaN() throws Exception {
- // float division, constant division, and assignment
- try {
- exec("float x = 1f; float y = 0f; return x % y;");
- fail("didn't hit expected exception");
- } catch (ArithmeticException expected) {}
- try {
- exec("return 1f % 0f;");
- fail("didn't hit expected exception");
- } catch (ArithmeticException expected) {}
- try {
- exec("float x = 1f; x %= 0f; return x;");
- fail("didn't hit expected exception");
- } catch (ArithmeticException expected) {}
-
- // double division, constant division, and assignment
- try {
- exec("double x = 1.0; double y = 0.0; return x % y;");
- fail("didn't hit expected exception");
- } catch (ArithmeticException expected) {}
- try {
- exec("return 1.0 % 0.0;");
- fail("didn't hit expected exception");
- } catch (ArithmeticException expected) {}
- try {
- exec("double x = 1.0; x %= 0.0; return x;");
- fail("didn't hit expected exception");
- } catch (ArithmeticException expected) {}
- }
-}
diff --git a/modules/lang-painless/src/test/java/org/elasticsearch/painless/FloatOverflowEnabledTests.java b/modules/lang-painless/src/test/java/org/elasticsearch/painless/FloatOverflowTests.java
similarity index 94%
rename from modules/lang-painless/src/test/java/org/elasticsearch/painless/FloatOverflowEnabledTests.java
rename to modules/lang-painless/src/test/java/org/elasticsearch/painless/FloatOverflowTests.java
index ccfd2232e88..4b3eb8f0e7f 100644
--- a/modules/lang-painless/src/test/java/org/elasticsearch/painless/FloatOverflowEnabledTests.java
+++ b/modules/lang-painless/src/test/java/org/elasticsearch/painless/FloatOverflowTests.java
@@ -19,17 +19,8 @@
package org.elasticsearch.painless;
-import java.util.Collections;
-import java.util.Map;
-
-/** Tests floating point overflow with numeric overflow enabled */
-public class FloatOverflowEnabledTests extends ScriptTestCase {
-
- /** wire overflow to true for all tests */
- @Override
- public Object exec(String script, Map vars) {
- return exec(script, vars, Collections.singletonMap(CompilerSettings.NUMERIC_OVERFLOW, "true"));
- }
+/** Tests floating point overflow cases */
+public class FloatOverflowTests extends ScriptTestCase {
public void testAssignmentAdditionOverflow() {
// float
diff --git a/modules/lang-painless/src/test/java/org/elasticsearch/painless/IntegerOverflowDisabledTests.java b/modules/lang-painless/src/test/java/org/elasticsearch/painless/IntegerOverflowDisabledTests.java
deleted file mode 100644
index f4adcfce878..00000000000
--- a/modules/lang-painless/src/test/java/org/elasticsearch/painless/IntegerOverflowDisabledTests.java
+++ /dev/null
@@ -1,444 +0,0 @@
-/*
- * Licensed to Elasticsearch under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package org.elasticsearch.painless;
-
-import java.util.Collections;
-import java.util.Map;
-
-/** Tests integer overflow with numeric overflow disabled */
-public class IntegerOverflowDisabledTests extends ScriptTestCase {
-
- /** wire overflow to true for all tests */
- @Override
- public Object exec(String script, Map vars) {
- return exec(script, vars, Collections.singletonMap(CompilerSettings.NUMERIC_OVERFLOW, "false"));
- }
-
- public void testAssignmentAdditionOverflow() {
- // byte
- try {
- exec("byte x = 0; x += 128; return x;");
- fail("did not get expected exception");
- } catch (ArithmeticException expected) {}
-
- try {
- exec("byte x = 0; x += -129; return x;");
- fail("did not get expected exception");
- } catch (ArithmeticException expected) {}
-
- // short
- try {
- exec("short x = 0; x += 32768; return x;");
- fail("did not get expected exception");
- } catch (ArithmeticException expected) {}
-
- try {
- exec("byte x = 0; x += -32769; return x;");
- fail("did not get expected exception");
- } catch (ArithmeticException expected) {}
-
- // char
- try {
- exec("char x = 0; x += 65536; return x;");
- fail("did not get expected exception");
- } catch (ArithmeticException expected) {}
-
- try {
- exec("char x = 0; x += -65536; return x;");
- fail("did not get expected exception");
- } catch (ArithmeticException expected) {}
-
- // int
- try {
- exec("int x = 1; x += 2147483647; return x;");
- fail("did not get expected exception");
- } catch (ArithmeticException expected) {}
-
- try {
- exec("int x = -2; x += -2147483647; return x;");
- fail("did not get expected exception");
- } catch (ArithmeticException expected) {}
-
- // long
- try {
- exec("long x = 1; x += 9223372036854775807L; return x;");
- fail("did not get expected exception");
- } catch (ArithmeticException expected) {}
-
- try {
- exec("long x = -2; x += -9223372036854775807L; return x;");
- fail("did not get expected exception");
- } catch (ArithmeticException expected) {}
- }
-
- public void testAssignmentSubtractionOverflow() {
- // byte
- try {
- exec("byte x = 0; x -= -128; return x;");
- fail("did not get expected exception");
- } catch (ArithmeticException expected) {}
-
- try {
- exec("byte x = 0; x -= 129; return x;");
- fail("did not get expected exception");
- } catch (ArithmeticException expected) {}
-
- // short
- try {
- exec("short x = 0; x -= -32768; return x;");
- fail("did not get expected exception");
- } catch (ArithmeticException expected) {}
-
- try {
- exec("byte x = 0; x -= 32769; return x;");
- fail("did not get expected exception");
- } catch (ArithmeticException expected) {}
-
- // char
- try {
- exec("char x = 0; x -= -65536; return x;");
- fail("did not get expected exception");
- } catch (ArithmeticException expected) {}
-
- try {
- exec("char x = 0; x -= 65536; return x;");
- fail("did not get expected exception");
- } catch (ArithmeticException expected) {}
-
- // int
- try {
- exec("int x = 1; x -= -2147483647; return x;");
- fail("did not get expected exception");
- } catch (ArithmeticException expected) {}
-
- try {
- exec("int x = -2; x -= 2147483647; return x;");
- fail("did not get expected exception");
- } catch (ArithmeticException expected) {}
-
- // long
- try {
- exec("long x = 1; x -= -9223372036854775807L; return x;");
- fail("did not get expected exception");
- } catch (ArithmeticException expected) {}
-
- try {
- exec("long x = -2; x -= 9223372036854775807L; return x;");
- fail("did not get expected exception");
- } catch (ArithmeticException expected) {}
- }
-
- public void testAssignmentMultiplicationOverflow() {
- // byte
- try {
- exec("byte x = 2; x *= 128; return x;");
- fail("did not get expected exception");
- } catch (ArithmeticException expected) {}
-
- try {
- exec("byte x = 2; x *= -128; return x;");
- fail("did not get expected exception");
- } catch (ArithmeticException expected) {}
-
- // char
- try {
- exec("char x = 2; x *= 65536; return x;");
- fail("did not get expected exception");
- } catch (ArithmeticException expected) {}
-
- try {
- exec("char x = 2; x *= -65536; return x;");
- fail("did not get expected exception");
- } catch (ArithmeticException expected) {}
-
- // int
- try {
- exec("int x = 2; x *= 2147483647; return x;");
- fail("did not get expected exception");
- } catch (ArithmeticException expected) {}
-
- try {
- exec("int x = 2; x *= -2147483647; return x;");
- fail("did not get expected exception");
- } catch (ArithmeticException expected) {}
-
- // long
- try {
- exec("long x = 2; x *= 9223372036854775807L; return x;");
- fail("did not get expected exception");
- } catch (ArithmeticException expected) {}
-
- try {
- exec("long x = 2; x *= -9223372036854775807L; return x;");
- fail("did not get expected exception");
- } catch (ArithmeticException expected) {}
- }
-
- public void testAssignmentDivisionOverflow() {
- // byte
- try {
- exec("byte x = (byte) -128; x /= -1; return x;");
- fail("should have hit exception");
- } catch (ArithmeticException expected) {}
-
- // short
- try {
- exec("short x = (short) -32768; x /= -1; return x;");
- fail("should have hit exception");
- } catch (ArithmeticException expected) {}
-
- // cannot happen for char: unsigned
-
- // int
- try {
- exec("int x = -2147483647 - 1; x /= -1; return x;");
- fail("should have hit exception");
- } catch (ArithmeticException expected) {}
-
- // long
- try {
- exec("long x = -9223372036854775807L - 1L; x /=-1L; return x;");
- fail("should have hit exception");
- } catch (ArithmeticException expected) {}
- }
-
- public void testIncrementOverFlow() throws Exception {
- // byte
- try {
- exec("byte x = 127; ++x; return x;");
- fail("did not get expected exception");
- } catch (ArithmeticException expected) {}
-
- try {
- exec("byte x = 127; x++; return x;");
- fail("did not get expected exception");
- } catch (ArithmeticException expected) {}
-
- try {
- exec("byte x = (byte) -128; --x; return x;");
- fail("did not get expected exception");
- } catch (ArithmeticException expected) {}
-
- try {
- exec("byte x = (byte) -128; x--; return x;");
- fail("did not get expected exception");
- } catch (ArithmeticException expected) {}
-
- // short
- try {
- exec("short x = 32767; ++x; return x;");
- fail("did not get expected exception");
- } catch (ArithmeticException expected) {}
-
- try {
- exec("short x = 32767; x++; return x;");
- fail("did not get expected exception");
- } catch (ArithmeticException expected) {}
-
- try {
- exec("short x = (short) -32768; --x; return x;");
- fail("did not get expected exception");
- } catch (ArithmeticException expected) {}
-
- try {
- exec("short x = (short) -32768; x--; return x;");
- } catch (ArithmeticException expected) {}
-
- // char
- try {
- exec("char x = 65535; ++x; return x;");
- } catch (ArithmeticException expected) {}
-
- try {
- exec("char x = 65535; x++; return x;");
- } catch (ArithmeticException expected) {}
-
- try {
- exec("char x = (char) 0; --x; return x;");
- } catch (ArithmeticException expected) {}
-
- try {
- exec("char x = (char) 0; x--; return x;");
- } catch (ArithmeticException expected) {}
-
- // int
- try {
- exec("int x = 2147483647; ++x; return x;");
- fail("did not get expected exception");
- } catch (ArithmeticException expected) {}
-
- try {
- exec("int x = 2147483647; x++; return x;");
- fail("did not get expected exception");
- } catch (ArithmeticException expected) {}
-
- try {
- exec("int x = (int) -2147483648L; --x; return x;");
- fail("did not get expected exception");
- } catch (ArithmeticException expected) {}
-
- try {
- exec("int x = (int) -2147483648L; x--; return x;");
- fail("did not get expected exception");
- } catch (ArithmeticException expected) {}
-
- // long
- try {
- exec("long x = 9223372036854775807L; ++x; return x;");
- fail("did not get expected exception");
- } catch (ArithmeticException expected) {}
-
- try {
- exec("long x = 9223372036854775807L; x++; return x;");
- fail("did not get expected exception");
- } catch (ArithmeticException expected) {}
-
- try {
- exec("long x = -9223372036854775807L - 1L; --x; return x;");
- fail("did not get expected exception");
- } catch (ArithmeticException expected) {}
-
- try {
- exec("long x = -9223372036854775807L - 1L; x--; return x;");
- fail("did not get expected exception");
- } catch (ArithmeticException expected) {}
- }
-
- public void testAddition() throws Exception {
- try {
- exec("int x = 2147483647; int y = 2147483647; return x + y;");
- fail("should have hit exception");
- } catch (ArithmeticException expected) {}
-
- try {
- exec("long x = 9223372036854775807L; long y = 9223372036854775807L; return x + y;");
- fail("should have hit exception");
- } catch (ArithmeticException expected) {}
- }
-
- public void testAdditionConst() throws Exception {
- try {
- exec("return 2147483647 + 2147483647;");
- fail("should have hit exception");
- } catch (ArithmeticException expected) {}
-
- try {
- exec("return 9223372036854775807L + 9223372036854775807L;");
- fail("should have hit exception");
- } catch (ArithmeticException expected) {}
- }
-
-
- public void testSubtraction() throws Exception {
- try {
- exec("int x = -10; int y = 2147483647; return x - y;");
- fail("should have hit exception");
- } catch (ArithmeticException expected) {}
-
- try {
- exec("long x = -10L; long y = 9223372036854775807L; return x - y;");
- fail("should have hit exception");
- } catch (ArithmeticException expected) {}
- }
-
- public void testSubtractionConst() throws Exception {
- try {
- exec("return -10 - 2147483647;");
- fail("should have hit exception");
- } catch (ArithmeticException expected) {}
-
- try {
- exec("return -10L - 9223372036854775807L;");
- fail("should have hit exception");
- } catch (ArithmeticException expected) {}
- }
-
- public void testMultiplication() throws Exception {
- try {
- exec("int x = 2147483647; int y = 2147483647; return x * y;");
- fail("should have hit exception");
- } catch (ArithmeticException expected) {}
-
- try {
- exec("long x = 9223372036854775807L; long y = 9223372036854775807L; return x * y;");
- fail("should have hit exception");
- } catch (ArithmeticException expected) {}
- }
-
- public void testMultiplicationConst() throws Exception {
- try {
- exec("return 2147483647 * 2147483647;");
- fail("should have hit exception");
- } catch (ArithmeticException expected) {}
-
- try {
- exec("return 9223372036854775807L * 9223372036854775807L;");
- fail("should have hit exception");
- } catch (ArithmeticException expected) {}
- }
-
- public void testDivision() throws Exception {
- try {
- exec("int x = -2147483647 - 1; int y = -1; return x / y;");
- fail("should have hit exception");
- } catch (ArithmeticException expected) {}
-
- try {
- exec("long x = -9223372036854775808L; long y = -1L; return x / y;");
- fail("should have hit exception");
- } catch (ArithmeticException expected) {}
- }
-
- public void testDivisionConst() throws Exception {
- try {
- exec("return (-2147483648) / -1;");
- fail("should have hit exception");
- } catch (ArithmeticException expected) {}
-
- try {
- exec("return (-9223372036854775808L) / -1L;");
- fail("should have hit exception");
- } catch (ArithmeticException expected) {}
- }
-
- public void testNegationOverflow() throws Exception {
- try {
- exec("int x = -2147483648; x = -x; return x;");
- fail("did not get expected exception");
- } catch (ArithmeticException expected) {}
-
- try {
- exec("long x = -9223372036854775808L; x = -x; return x;");
- fail("did not get expected exception");
- } catch (ArithmeticException expected) {}
- }
-
- public void testNegationOverflowConst() throws Exception {
- try {
- exec("int x = -(-2147483648); return x;");
- fail("did not get expected exception");
- } catch (ArithmeticException expected) {}
-
- try {
- exec("long x = -(-9223372036854775808L); return x;");
- fail("did not get expected exception");
- } catch (ArithmeticException expected) {}
- }
-}
diff --git a/modules/lang-painless/src/test/java/org/elasticsearch/painless/IntegerOverflowEnabledTests.java b/modules/lang-painless/src/test/java/org/elasticsearch/painless/IntegerOverflowTests.java
similarity index 95%
rename from modules/lang-painless/src/test/java/org/elasticsearch/painless/IntegerOverflowEnabledTests.java
rename to modules/lang-painless/src/test/java/org/elasticsearch/painless/IntegerOverflowTests.java
index 41b3f857c0a..1165547bf5a 100644
--- a/modules/lang-painless/src/test/java/org/elasticsearch/painless/IntegerOverflowEnabledTests.java
+++ b/modules/lang-painless/src/test/java/org/elasticsearch/painless/IntegerOverflowTests.java
@@ -19,17 +19,8 @@
package org.elasticsearch.painless;
-import java.util.Collections;
-import java.util.Map;
-
-/** Tests integer overflow with numeric overflow enabled */
-public class IntegerOverflowEnabledTests extends ScriptTestCase {
-
- /** wire overflow to true for all tests */
- @Override
- public Object exec(String script, Map vars) {
- return exec(script, vars, Collections.singletonMap(CompilerSettings.NUMERIC_OVERFLOW, "true"));
- }
+/** Tests integer overflow cases */
+public class IntegerOverflowTests extends ScriptTestCase {
public void testAssignmentAdditionOverflow() {
// byte
diff --git a/modules/lang-painless/src/test/java/org/elasticsearch/painless/ScriptTestCase.java b/modules/lang-painless/src/test/java/org/elasticsearch/painless/ScriptTestCase.java
index 2ccd2f1460a..c3ce127034e 100644
--- a/modules/lang-painless/src/test/java/org/elasticsearch/painless/ScriptTestCase.java
+++ b/modules/lang-painless/src/test/java/org/elasticsearch/painless/ScriptTestCase.java
@@ -48,7 +48,7 @@ public abstract class ScriptTestCase extends ESTestCase {
/** Compiles and returns the result of {@code script} with access to {@code vars} */
public Object exec(String script, Map vars) {
- return exec(script, vars, Collections.singletonMap(CompilerSettings.NUMERIC_OVERFLOW, Boolean.toString(random().nextBoolean())));
+ return exec(script, vars, Collections.emptyMap());
}
/** Compiles and returns the result of {@code script} with access to {@code vars} and compile-time parameters */
diff --git a/modules/lang-painless/src/test/java/org/elasticsearch/painless/UtilityTests.java b/modules/lang-painless/src/test/java/org/elasticsearch/painless/UtilityTests.java
deleted file mode 100644
index ba476fac7f2..00000000000
--- a/modules/lang-painless/src/test/java/org/elasticsearch/painless/UtilityTests.java
+++ /dev/null
@@ -1,250 +0,0 @@
-/*
- * Licensed to Elasticsearch under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package org.elasticsearch.painless;
-
-import org.elasticsearch.test.ESTestCase;
-
-/**
- * Tests utility methods (typically built-ins)
- */
-public class UtilityTests extends ESTestCase {
-
- public void testDivideWithoutOverflowInt() {
- assertEquals(5 / 2, Utility.divideWithoutOverflow(5, 2));
-
- try {
- Utility.divideWithoutOverflow(Integer.MIN_VALUE, -1);
- fail("did not get expected exception");
- } catch (ArithmeticException expected) {}
-
- try {
- Utility.divideWithoutOverflow(5, 0);
- fail("did not get expected exception");
- } catch (ArithmeticException expected) {}
- }
-
- public void testDivideWithoutOverflowLong() {
- assertEquals(5L / 2L, Utility.divideWithoutOverflow(5L, 2L));
-
- try {
- Utility.divideWithoutOverflow(Long.MIN_VALUE, -1L);
- fail("did not get expected exception");
- } catch (ArithmeticException expected) {}
-
- try {
- Utility.divideWithoutOverflow(5L, 0L);
- fail("did not get expected exception");
- } catch (ArithmeticException expected) {}
- }
-
- public void testToByteExact() {
- for (int b = Byte.MIN_VALUE; b < Byte.MAX_VALUE; b++) {
- assertEquals((byte)b, Utility.toByteExact(b));
- }
-
- try {
- Utility.toByteExact(Byte.MIN_VALUE - 1);
- fail("did not get expected exception");
- } catch (ArithmeticException expected) {}
-
- try {
- Utility.toByteExact(Byte.MAX_VALUE + 1);
- fail("did not get expected exception");
- } catch (ArithmeticException expected) {}
- }
-
- public void testToShortExact() {
- for (int s = Short.MIN_VALUE; s < Short.MAX_VALUE; s++) {
- assertEquals((short)s, Utility.toShortExact(s));
- }
-
- try {
- Utility.toShortExact(Short.MIN_VALUE - 1);
- fail("did not get expected exception");
- } catch (ArithmeticException expected) {}
-
- try {
- Utility.toShortExact(Short.MAX_VALUE + 1);
- fail("did not get expected exception");
- } catch (ArithmeticException expected) {}
- }
-
- public void testToCharExact() {
- for (int c = Character.MIN_VALUE; c < Character.MAX_VALUE; c++) {
- assertEquals((char)c, Utility.toCharExact(c));
- }
-
- try {
- Utility.toCharExact(Character.MIN_VALUE - 1);
- fail("did not get expected exception");
- } catch (ArithmeticException expected) {}
-
- try {
- Utility.toCharExact(Character.MAX_VALUE + 1);
- fail("did not get expected exception");
- } catch (ArithmeticException expected) {}
- }
-
- public void testAddWithoutOverflowFloat() {
- assertEquals(10F, Utility.addWithoutOverflow(5F, 5F), 0F);
- assertTrue(Float.isNaN(Utility.addWithoutOverflow(5F, Float.NaN)));
- assertTrue(Float.isNaN(Utility.addWithoutOverflow(Float.POSITIVE_INFINITY, Float.NEGATIVE_INFINITY)));
-
- try {
- Utility.addWithoutOverflow(Float.MAX_VALUE, Float.MAX_VALUE);
- fail("did not get expected exception");
- } catch (ArithmeticException expected) {}
-
- try {
- Utility.addWithoutOverflow(-Float.MAX_VALUE, -Float.MAX_VALUE);
- fail("did not get expected exception");
- } catch (ArithmeticException expected) {}
- }
-
- public void testAddWithoutOverflowDouble() {
- assertEquals(10D, Utility.addWithoutOverflow(5D, 5D), 0D);
- assertTrue(Double.isNaN(Utility.addWithoutOverflow(5D, Double.NaN)));
- assertTrue(Double.isNaN(Utility.addWithoutOverflow(Double.POSITIVE_INFINITY, Double.NEGATIVE_INFINITY)));
-
- try {
- Utility.addWithoutOverflow(Double.MAX_VALUE, Double.MAX_VALUE);
- fail("did not get expected exception");
- } catch (ArithmeticException expected) {}
-
- try {
- Utility.addWithoutOverflow(-Double.MAX_VALUE, -Double.MAX_VALUE);
- fail("did not get expected exception");
- } catch (ArithmeticException expected) {}
- }
-
- public void testSubtractWithoutOverflowFloat() {
- assertEquals(5F, Utility.subtractWithoutOverflow(10F, 5F), 0F);
- assertTrue(Float.isNaN(Utility.subtractWithoutOverflow(5F, Float.NaN)));
- assertTrue(Float.isNaN(Utility.subtractWithoutOverflow(Float.POSITIVE_INFINITY, Float.POSITIVE_INFINITY)));
-
- try {
- Utility.subtractWithoutOverflow(Float.MAX_VALUE, -Float.MAX_VALUE);
- fail("did not get expected exception");
- } catch (ArithmeticException expected) {}
-
- try {
- Utility.subtractWithoutOverflow(-Float.MAX_VALUE, Float.MAX_VALUE);
- fail("did not get expected exception");
- } catch (ArithmeticException expected) {}
- }
-
- public void testSubtractWithoutOverflowDouble() {
- assertEquals(5D, Utility.subtractWithoutOverflow(10D, 5D), 0D);
- assertTrue(Double.isNaN(Utility.subtractWithoutOverflow(5D, Double.NaN)));
- assertTrue(Double.isNaN(Utility.subtractWithoutOverflow(Double.POSITIVE_INFINITY, Double.POSITIVE_INFINITY)));
-
- try {
- Utility.subtractWithoutOverflow(Double.MAX_VALUE, -Double.MAX_VALUE);
- fail("did not get expected exception");
- } catch (ArithmeticException expected) {}
-
- try {
- Utility.subtractWithoutOverflow(-Double.MAX_VALUE, Double.MAX_VALUE);
- fail("did not get expected exception");
- } catch (ArithmeticException expected) {}
- }
-
- public void testMultiplyWithoutOverflowFloat() {
- assertEquals(25F, Utility.multiplyWithoutOverflow(5F, 5F), 0F);
- assertTrue(Float.isNaN(Utility.multiplyWithoutOverflow(5F, Float.NaN)));
- assertEquals(Float.POSITIVE_INFINITY, Utility.multiplyWithoutOverflow(5F, Float.POSITIVE_INFINITY), 0F);
-
- try {
- Utility.multiplyWithoutOverflow(Float.MAX_VALUE, Float.MAX_VALUE);
- fail("did not get expected exception");
- } catch (ArithmeticException expected) {}
- }
-
- public void testMultiplyWithoutOverflowDouble() {
- assertEquals(25D, Utility.multiplyWithoutOverflow(5D, 5D), 0D);
- assertTrue(Double.isNaN(Utility.multiplyWithoutOverflow(5D, Double.NaN)));
- assertEquals(Double.POSITIVE_INFINITY, Utility.multiplyWithoutOverflow(5D, Double.POSITIVE_INFINITY), 0D);
-
- try {
- Utility.multiplyWithoutOverflow(Double.MAX_VALUE, Double.MAX_VALUE);
- fail("did not get expected exception");
- } catch (ArithmeticException expected) {}
- }
-
- public void testDivideWithoutOverflowFloat() {
- assertEquals(5F, Utility.divideWithoutOverflow(25F, 5F), 0F);
- assertTrue(Float.isNaN(Utility.divideWithoutOverflow(5F, Float.NaN)));
- assertEquals(Float.POSITIVE_INFINITY, Utility.divideWithoutOverflow(Float.POSITIVE_INFINITY, 5F), 0F);
-
- try {
- Utility.divideWithoutOverflow(Float.MAX_VALUE, Float.MIN_VALUE);
- fail("did not get expected exception");
- } catch (ArithmeticException expected) {}
-
- try {
- Utility.divideWithoutOverflow(0F, 0F);
- fail("did not get expected exception");
- } catch (ArithmeticException expected) {}
-
- try {
- Utility.divideWithoutOverflow(5F, 0F);
- fail("did not get expected exception");
- } catch (ArithmeticException expected) {}
- }
-
- public void testDivideWithoutOverflowDouble() {
- assertEquals(5D, Utility.divideWithoutOverflow(25D, 5D), 0D);
- assertTrue(Double.isNaN(Utility.divideWithoutOverflow(5D, Double.NaN)));
- assertEquals(Double.POSITIVE_INFINITY, Utility.divideWithoutOverflow(Double.POSITIVE_INFINITY, 5D), 0D);
-
- try {
- Utility.divideWithoutOverflow(Double.MAX_VALUE, Double.MIN_VALUE);
- fail("did not get expected exception");
- } catch (ArithmeticException expected) {}
-
- try {
- Utility.divideWithoutOverflow(0D, 0D);
- fail("did not get expected exception");
- } catch (ArithmeticException expected) {}
-
- try {
- Utility.divideWithoutOverflow(5D, 0D);
- fail("did not get expected exception");
- } catch (ArithmeticException expected) {}
- }
-
- public void testRemainderWithoutOverflowFloat() {
- assertEquals(1F, Utility.remainderWithoutOverflow(25F, 4F), 0F);
-
- try {
- Utility.remainderWithoutOverflow(5F, 0F);
- fail("did not get expected exception");
- } catch (ArithmeticException expected) {}
- }
-
- public void testRemainderWithoutOverflowDouble() {
- assertEquals(1D, Utility.remainderWithoutOverflow(25D, 4D), 0D);
-
- try {
- Utility.remainderWithoutOverflow(5D, 0D);
- fail("did not get expected exception");
- } catch (ArithmeticException expected) {}
- }
-}