From 0454bd9e289d30690879d32e1a92702f5923c444 Mon Sep 17 00:00:00 2001 From: Ilya Gorbunov Date: Thu, 14 Sep 2017 16:49:56 +0300 Subject: [PATCH] Detect endianness when reinterpreting Float64 as two Int32 #KT-18264 Use Int32Array instead of Uint32Array since ints are required to be singed. --- js/js.libraries/src/js/misc.js | 18 +++++++++++++----- libraries/stdlib/test/numbers/NumbersTest.kt | 1 + 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/js/js.libraries/src/js/misc.js b/js/js.libraries/src/js/misc.js index 67ff45d1a46..3491df9d43b 100644 --- a/js/js.libraries/src/js/misc.js +++ b/js/js.libraries/src/js/misc.js @@ -53,7 +53,15 @@ function imul(a, b) { var buf = new ArrayBuffer(8); var bufFloat64 = new Float64Array(buf); var bufFloat32 = new Float32Array(buf); - var bufInt32 = new Uint32Array(buf); + var bufInt32 = new Int32Array(buf); + var lowIndex = 0; + var highIndex = 1; + + bufFloat64[0] = -1; // bff00000_00000000 + if (bufInt32[lowIndex] !== 0) { + lowIndex = 1; + highIndex = 0; + } Kotlin.doubleToBits = function(value) { return Kotlin.doubleToRawBits(isNaN(value) ? NaN : value); @@ -61,12 +69,12 @@ function imul(a, b) { Kotlin.doubleToRawBits = function(value) { bufFloat64[0] = value; - return Kotlin.Long.fromBits(bufInt32[0], bufInt32[1]); + return Kotlin.Long.fromBits(bufInt32[lowIndex], bufInt32[highIndex]); }; Kotlin.doubleFromBits = function(value) { - bufInt32[0] = value.low_; - bufInt32[1] = value.high_; + bufInt32[lowIndex] = value.low_; + bufInt32[highIndex] = value.high_; return bufFloat64[0]; }; @@ -87,7 +95,7 @@ function imul(a, b) { // returns zero value for number with positive sign bit and non-zero value for number with negative sign bit. Kotlin.doubleSignBit = function(value) { bufFloat64[0] = value; - return bufInt32[1] & 0x80000000; + return bufInt32[highIndex] & 0x80000000; }; })(); diff --git a/libraries/stdlib/test/numbers/NumbersTest.kt b/libraries/stdlib/test/numbers/NumbersTest.kt index 6051a0f1aaf..ede491f8340 100644 --- a/libraries/stdlib/test/numbers/NumbersTest.kt +++ b/libraries/stdlib/test/numbers/NumbersTest.kt @@ -158,6 +158,7 @@ class NumbersTest { assertTrue(Float.NaN.toBits().let(Float.Companion::fromBits).isNaN()) assertTrue(Float.NaN.toRawBits().let { Float.fromBits(it) }.isNaN()) + assertEquals(0xbf800000.toInt(), (-1.0F).toBits()) assertEquals(0x7fc00000, Float.NaN.toBits()) assertEquals(0x7fc00000, Float.NaN.toRawBits())