aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorErik Verbruggen <erik.verbruggen@qt.io>2018-08-06 11:51:56 +0200
committerErik Verbruggen <erik.verbruggen@qt.io>2018-08-09 07:51:16 +0000
commit024cb75206c0be123729c1fd1ddd99b634e0350f (patch)
tree9947472dbdb8e6138b9e36b77d9fd37efc825b95
parentabba0b6e2c00df2df39ad16a20eba3870e68f252 (diff)
JS: Also have modulo return integer 0 when the lhs is 0
When both operands of a modulo are integers, and the right-hand side is bigger than zero, it is fine to have the left-hand side be 0, as the result is (positive) zero. This also handles the somewhat common case below, where lhs is 0, and where returning a double would result in the slow path to do the actual array access: array[lhs % array.length] Change-Id: I4ca268a08604c3c77a23a92eee193c807696d5ba Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
-rw-r--r--src/qml/jsruntime/qv4runtime.cpp11
1 files changed, 7 insertions, 4 deletions
diff --git a/src/qml/jsruntime/qv4runtime.cpp b/src/qml/jsruntime/qv4runtime.cpp
index 11f06d9ed1..82e1284289 100644
--- a/src/qml/jsruntime/qv4runtime.cpp
+++ b/src/qml/jsruntime/qv4runtime.cpp
@@ -1801,10 +1801,13 @@ ReturnedValue Runtime::method_mod(const Value &left, const Value &right)
{
TRACE2(left, right);
- if (Value::integerCompatible(left, right) && left.integerValue() > 0 && right.integerValue() > 0) {
- int intRes = left.integerValue() % right.integerValue();
- if (intRes != 0 || left.integerValue() >= 0)
- return Encode(intRes);
+ if (Value::integerCompatible(left, right) && left.integerValue() >= 0 && right.integerValue() > 0) {
+ // special cases are handled by fmod, among them:
+ // - arithmic execeptions for ints in c++, eg: INT_MIN % -1
+ // - undefined behavior in c++, e.g.: anything % 0
+ // - uncommon cases which would complicate the condition, e.g.: negative integers
+ // (this makes sure that -1 % 1 == -0 by passing it to fmod)
+ return Encode(left.integerValue() % right.integerValue());
}
double lval = RuntimeHelpers::toNumber(left);