Bug 209289 - [JSC][BigEndians] JSTests/stress/dataview-jit-set-nan.js subtest misbehaves
Summary: [JSC][BigEndians] JSTests/stress/dataview-jit-set-nan.js subtest misbehaves
Status: NEW
Alias: None
Product: WebKit
Classification: Unclassified
Component: JavaScriptCore (show other bugs)
Version: WebKit Nightly Build
Hardware: Unspecified Unspecified
: P2 Normal
Assignee: Nobody
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2020-03-19 09:59 PDT by Tomas Popela
Modified: 2020-03-19 12:02 PDT (History)
1 user (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Tomas Popela 2020-03-19 09:59:40 PDT
The whole background story could be found in bug 194007.

While working on patch I found one case where the suggested solution doesn't work:

"use strict";

function assert(b) {
    if (!b)
        throw new Error;
}

function getIsLittleEndian() {
    let ab = new ArrayBuffer(2);
    let ta = new Int16Array(ab);
    ta[0] = 0x0102;
    let dv = new DataView(ab);
    return dv.getInt16(0, true) === 0x0102;
}

let isLittleEndian = getIsLittleEndian();

function adjustForEndianessFloat32(value) {
    if (isLittleEndian)
        return value;

    let ab = new ArrayBuffer(4);
    let ta = new Float32Array(ab);
    ta[0] = value;
    let dv = new DataView(ab);
    return dv.getFloat32(0, true);
}

function test() {
    function storeLittleEndian(dv, index, value) {
        dv.setFloat32(index, value, true);
    }
    noInline(storeLittleEndian);

    function store(dv, index, value, littleEndian) {
        dv.setFloat32(index, value, littleEndian);
    }
    noInline(store);

    let buffer = new ArrayBuffer(4);
    let arr = new Float32Array(buffer);
    let bits = new Uint32Array(buffer);
    let dv = new DataView(buffer);

    for (let i = 0; i < 10000; ++i) {
        storeLittleEndian(dv, 0, adjustForEndianessFloat32(12912.124123215122));
        assert(arr[0] === 12912.1240234375);
        assert(bits[0] === 0x4649c07f);
    }
}
test();


On big endian machine the arr[0] contains 6.905458702346266e-41 and bits[0] 0xc07f.

If I replace the storeLittleEndian() call with:

store(dv, 0, 12912.124123215122, isLittleEndian);

then it does work, but it's strange that the storeLittleEndian() doesn't.

Is the 12912.124123215122 number somehow special? If I observe what's in arr[0], when I change that number then it's:

input to adjustForEndianessFloat32() : arr[0] value
12912 : 12912
12912.1 : 12912.099609375
12912.12 : 12912.1201171875
12912.124 : 6.905458702346266e-41

Does anyone have an idea?