diff options
author | Erik Verbruggen <erik.verbruggen@qt.io> | 2018-08-06 11:51:56 +0200 |
---|---|---|
committer | Erik Verbruggen <erik.verbruggen@qt.io> | 2018-08-09 07:51:16 +0000 |
commit | 024cb75206c0be123729c1fd1ddd99b634e0350f (patch) | |
tree | 9947472dbdb8e6138b9e36b77d9fd37efc825b95 | |
parent | abba0b6e2c00df2df39ad16a20eba3870e68f252 (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.cpp | 11 |
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); |