Jacek Caban : jscript: Import to_int32 implementation from WebKit.

Alexandre Julliard julliard at winehq.org
Thu Dec 5 17:14:11 CST 2019


Module: wine
Branch: master
Commit: cac0fedd339e79e16d8890bbc5e5a4fb0eb7d94f
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=cac0fedd339e79e16d8890bbc5e5a4fb0eb7d94f

Author: Jacek Caban <jacek at codeweavers.com>
Date:   Thu Dec  5 15:40:48 2019 +0100

jscript: Import to_int32 implementation from WebKit.

Signed-off-by: Jacek Caban <jacek at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/jscript/jsutils.c | 63 +++++++++++++++++++++++++++++++++++++++-----------
 1 file changed, 50 insertions(+), 13 deletions(-)

diff --git a/dlls/jscript/jsutils.c b/dlls/jscript/jsutils.c
index 0702c4e0be..a36c9c1e5b 100644
--- a/dlls/jscript/jsutils.c
+++ b/dlls/jscript/jsutils.c
@@ -657,37 +657,74 @@ HRESULT to_integer(script_ctx_t *ctx, jsval_t v, double *ret)
     return S_OK;
 }
 
+static INT32 double_to_int32(double number)
+{
+    INT32 exp, result;
+    union {
+        double d;
+        INT64 n;
+    } bits;
+
+    bits.d = number;
+    exp = ((INT32)(bits.n >> 52) & 0x7ff) - 0x3ff;
+
+    /* If exponent < 0 there will be no bits to the left of the decimal point
+     * after rounding; if the exponent is > 83 then no bits of precision can be
+     * left in the low 32-bit range of the result (IEEE-754 doubles have 52 bits
+     * of fractional precision).
+     * Note this case handles 0, -0, and all infinte, NaN, & denormal value. */
+    if(exp < 0 || exp > 83)
+        return 0;
+
+    /* Select the appropriate 32-bits from the floating point mantissa.  If the
+     * exponent is 52 then the bits we need to select are already aligned to the
+     * lowest bits of the 64-bit integer representation of tghe number, no need
+     * to shift.  If the exponent is greater than 52 we need to shift the value
+     * left by (exp - 52), if the value is less than 52 we need to shift right
+     * accordingly. */
+    result = (exp > 52) ? bits.n << (exp - 52) : bits.n >> (52 - exp);
+
+    /* IEEE-754 double precision values are stored omitting an implicit 1 before
+     * the decimal point; we need to reinsert this now.  We may also the shifted
+     * invalid bits into the result that are not a part of the mantissa (the sign
+     * and exponent bits from the floatingpoint representation); mask these out. */
+    if(exp < 32) {
+        INT32 missing_one = 1 << exp;
+        result &= missing_one - 1;
+        result += missing_one;
+    }
+
+    /* If the input value was negative (we could test either 'number' or 'bits',
+     * but testing 'bits' is likely faster) invert the result appropriately. */
+    return bits.n < 0 ? -result : result;
+}
+
 /* ECMA-262 3rd Edition    9.5 */
 HRESULT to_int32(script_ctx_t *ctx, jsval_t v, INT *ret)
 {
     double n;
     HRESULT hres;
 
-    const double p32 = (double)0xffffffff + 1;
-
     hres = to_number(ctx, v, &n);
     if(FAILED(hres))
         return hres;
 
-    if(is_finite(n))
-        n = n > 0 ? fmod(n, p32) : -fmod(-n, p32);
-    else
-        n = 0;
-
-    *ret = (UINT32)n;
+    *ret = double_to_int32(n);
     return S_OK;
 }
 
 /* ECMA-262 3rd Edition    9.6 */
 HRESULT to_uint32(script_ctx_t *ctx, jsval_t val, UINT32 *ret)
 {
-    INT32 n;
+    double n;
     HRESULT hres;
 
-    hres = to_int32(ctx, val, &n);
-    if(SUCCEEDED(hres))
-        *ret = n;
-    return hres;
+    hres = to_number(ctx, val, &n);
+    if(FAILED(hres))
+        return hres;
+
+    *ret = double_to_int32(n);
+    return S_OK;
 }
 
 HRESULT double_to_string(double n, jsstr_t **str)




More information about the wine-cvs mailing list