blob: 44ea58aa346d6bb7a578e3dab4f15d2b2572b758 [file] [log] [blame]
"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 readHex(dv, bytes) {
let str = "";
function readByte(i) {
let b = dv.getUint8(i).toString(16);
if (b.length === 1)
b = "0" + b;
else
assert(b.length === 2)
return b;
}
if (isLittleEndian) {
for (let i = bytes; i--;)
str = str + readByte(i);
} else {
for (let i = 0; i < bytes; ++i)
str = str + readByte(i);
}
return "0x" + str;
}
{
let b = new ArrayBuffer(4);
let dv = new DataView(b);
dv.setInt32(0, 0x00112233, isLittleEndian);
assert(readHex(dv, 4) === "0x00112233");
}
function adjustForEndianessUint16(value) {
if (isLittleEndian)
return value;
let ab = new ArrayBuffer(4);
let ta = new Uint16Array(ab);
ta[0] = value;
let dv = new DataView(ab);
return dv.getUint16(0, true);
}
function test() {
function storeLittleEndian(dv, index, value) {
dv.setInt16(index, value, true);
}
noInline(storeLittleEndian);
function storeBigEndian(dv, index, value) {
dv.setInt16(index, value, false);
}
noInline(storeBigEndian);
function store(dv, index, value, littleEndian) {
dv.setInt16(index, value, littleEndian);
}
noInline(store);
let buffer = new ArrayBuffer(2);
let arr = new Uint16Array(buffer);
let dv = new DataView(buffer);
for (let i = 0; i < 10000; ++i) {
storeLittleEndian(dv, 0, adjustForEndianessUint16(0xfaba));
assert(arr[0] === 0xfaba);
store(dv, 0, adjustForEndianessUint16(0xabcd), true);
assert(arr[0] === 0xabcd);
store(dv, 0, adjustForEndianessUint16(0xbadbeef), true);
assert(arr[0] === 0xbeef);
storeLittleEndian(dv, 0, adjustForEndianessUint16(0xbb4db33f), true);
assert(arr[0] === 0xb33f);
storeBigEndian(dv, 0, adjustForEndianessUint16(0xfada));
assert(arr[0] === 0xdafa);
storeBigEndian(dv, 0, adjustForEndianessUint16(0x12ab));
assert(arr[0] === 0xab12);
store(dv, 0, adjustForEndianessUint16(0x1234), false);
assert(arr[0] === 0x3412);
store(dv, 0, adjustForEndianessUint16(0x0102), false);
assert(arr[0] === 0x0201);
store(dv, 0, adjustForEndianessUint16(-1), false);
assert(arr[0] === 0xffff);
store(dv, 0, adjustForEndianessUint16(-2), false);
assert(arr[0] === 0xfeff);
storeBigEndian(dv, 0, adjustForEndianessUint16(-1));
assert(arr[0] === 0xffff);
storeBigEndian(dv, 0, adjustForEndianessUint16(-2));
assert(arr[0] === 0xfeff);
storeBigEndian(dv, 0, adjustForEndianessUint16(-2147483648));
assert(arr[0] === 0x0000);
storeLittleEndian(dv, 0, adjustForEndianessUint16(-2147483648));
assert(arr[0] === 0x0000);
storeLittleEndian(dv, 0, adjustForEndianessUint16(-2147478988));
assert(arr[0] === 0x1234);
storeBigEndian(dv, 0, adjustForEndianessUint16(-2147478988));
assert(arr[0] === 0x3412);
}
}
test();
function test2() {
function storeLittleEndian(dv, index, value) {
dv.setUint16(index, value, true);
}
noInline(storeLittleEndian);
function storeBigEndian(dv, index, value) {
dv.setUint16(index, value, false);
}
noInline(storeBigEndian);
function store(dv, index, value, littleEndian) {
dv.setUint16(index, value, littleEndian);
}
noInline(store);
let buffer = new ArrayBuffer(2);
let arr = new Uint16Array(buffer);
let dv = new DataView(buffer);
for (let i = 0; i < 10000; ++i) {
storeLittleEndian(dv, 0, adjustForEndianessUint16(0xfaba));
assert(arr[0] === 0xfaba);
store(dv, 0, adjustForEndianessUint16(0xabcd), true);
assert(arr[0] === 0xabcd);
store(dv, 0, adjustForEndianessUint16(0xbadbeef), true);
assert(arr[0] === 0xbeef);
storeLittleEndian(dv, 0, adjustForEndianessUint16(0xbb4db33f), true);
assert(arr[0] === 0xb33f);
storeBigEndian(dv, 0, adjustForEndianessUint16(0xfada));
assert(arr[0] === 0xdafa);
storeBigEndian(dv, 0, adjustForEndianessUint16(0x12ab));
assert(arr[0] === 0xab12);
store(dv, 0, adjustForEndianessUint16(0x1234), false);
assert(arr[0] === 0x3412);
store(dv, 0, adjustForEndianessUint16(0x0102), false);
assert(arr[0] === 0x0201);
store(dv, 0, adjustForEndianessUint16(-1), false);
assert(arr[0] === 0xffff);
store(dv, 0, adjustForEndianessUint16(-2), false);
assert(arr[0] === 0xfeff);
storeBigEndian(dv, 0, adjustForEndianessUint16(-1));
assert(arr[0] === 0xffff);
storeBigEndian(dv, 0, adjustForEndianessUint16(-2));
assert(arr[0] === 0xfeff);
storeBigEndian(dv, 0, adjustForEndianessUint16(-2147483648));
assert(arr[0] === 0x0000);
storeLittleEndian(dv, 0, adjustForEndianessUint16(-2147483648));
assert(arr[0] === 0x0000);
storeLittleEndian(dv, 0, adjustForEndianessUint16(-2147478988));
assert(arr[0] === 0x1234);
storeBigEndian(dv, 0, adjustForEndianessUint16(-2147478988));
assert(arr[0] === 0x3412);
}
}
test2();
function adjustForEndianessUint32(value) {
if (isLittleEndian)
return value;
let ab = new ArrayBuffer(4);
let ta = new Uint32Array(ab);
ta[0] = value;
let dv = new DataView(ab);
return dv.getUint32(0, true);
}
function test3() {
function storeLittleEndian(dv, index, value) {
dv.setUint32(index, value, true);
}
noInline(storeLittleEndian);
function storeBigEndian(dv, index, value) {
dv.setUint32(index, value, false);
}
noInline(storeBigEndian);
function store(dv, index, value, littleEndian) {
dv.setUint32(index, value, littleEndian);
}
noInline(store);
let buffer = new ArrayBuffer(4);
let arr = new Uint32Array(buffer);
let arr2 = new Int32Array(buffer);
let dv = new DataView(buffer);
for (let i = 0; i < 10000; ++i) {
storeLittleEndian(dv, 0, adjustForEndianessUint32(0xffffffff));
assert(arr[0] === 0xffffffff);
assert(arr2[0] === -1);
storeLittleEndian(dv, 0, adjustForEndianessUint32(0xffaabbcc));
assert(arr[0] === 0xffaabbcc);
storeBigEndian(dv, 0, adjustForEndianessUint32(0x12345678));
assert(arr[0] === 0x78563412);
storeBigEndian(dv, 0, adjustForEndianessUint32(0xffaabbcc));
assert(arr[0] === 0xccbbaaff);
store(dv, 0, adjustForEndianessUint32(0xfaeadaca), false);
assert(arr[0] === 0xcadaeafa);
store(dv, 0, adjustForEndianessUint32(0xcadaeafa), false);
assert(arr2[0] === -85271862);
store(dv, 0, adjustForEndianessUint32(0x12345678), false);
assert(arr[0] === 0x78563412);
storeBigEndian(dv, 0, adjustForEndianessUint32(0xbeeffeeb));
assert(arr2[0] === -335614018);
}
}
test3();
function test4() {
function storeLittleEndian(dv, index, value) {
dv.setInt32(index, value, true);
}
noInline(storeLittleEndian);
function storeBigEndian(dv, index, value) {
dv.setInt32(index, value, false);
}
noInline(storeBigEndian);
function store(dv, index, value, littleEndian) {
dv.setInt32(index, value, littleEndian);
}
noInline(store);
let buffer = new ArrayBuffer(4);
let arr = new Uint32Array(buffer);
let arr2 = new Int32Array(buffer);
let dv = new DataView(buffer);
for (let i = 0; i < 10000; ++i) {
storeLittleEndian(dv, 0, adjustForEndianessUint32(0xffffffff));
assert(arr[0] === 0xffffffff);
assert(arr2[0] === -1);
storeLittleEndian(dv, 0, adjustForEndianessUint32(0xffaabbcc));
assert(arr[0] === 0xffaabbcc);
storeBigEndian(dv, 0, adjustForEndianessUint32(0x12345678));
assert(arr[0] === 0x78563412);
storeBigEndian(dv, 0, adjustForEndianessUint32(0xffaabbcc));
assert(arr[0] === 0xccbbaaff);
store(dv, 0, adjustForEndianessUint32(0xfaeadaca), false);
assert(arr[0] === 0xcadaeafa);
store(dv, 0, adjustForEndianessUint32(0xcadaeafa), false);
assert(arr2[0] === -85271862);
store(dv, 0, adjustForEndianessUint32(0x12345678), false);
assert(arr[0] === 0x78563412);
storeBigEndian(dv, 0, adjustForEndianessUint32(0xbeeffeeb));
assert(arr2[0] === -335614018);
}
}
test4();
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 test5() {
function storeLittleEndian(dv, index, value) {
dv.setFloat32(index, value, true);
}
noInline(storeLittleEndian);
function storeBigEndian(dv, index, value) {
dv.setFloat32(index, value, false);
}
noInline(storeBigEndian);
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);
let f32_exponent_bits = 0x7F800000;
let f32_fraction_bits = 0x007FFFFF;
for (let i = 0; i < 10000; ++i) {
storeLittleEndian(dv, 0, adjustForEndianessFloat32(1.5));
assert(arr[0] === 1.5);
// The right way how to process this test is to uncomment the line below
// and comment out the line below it. But strangely it doesn't work. I
// opened https://bugs.webkit.org/show_bug.cgi?id=209289 for it.
//storeLittleEndian(dv, 0, adjustForEndianessFloat32(12912.124123215122));
store(dv, 0, 12912.124123215122, isLittleEndian);
assert(bits[0] === 0x4649c07f);
assert(arr[0] === 12912.1240234375);
storeLittleEndian(dv, 0, adjustForEndianessFloat32(NaN));
assert(isNaN(arr[0]));
// The conversion of our initial 64-bit pure NaN (0x7ff8000000000000)
// should yield a Float32 NaN, but we can't check for a specific binary
// value since different CPUs might convert to different 32-bit NaNs,
// so we just check that the bits represent a NaN.
// The binary representation of a NaN has all its exponent bits set to
// 1 and at least one fraction bit set to 1.
assert(((bits[0] & f32_exponent_bits) === f32_exponent_bits) && !!(bits[0] & f32_fraction_bits))
storeLittleEndian(dv, 0, adjustForEndianessFloat32(2.3879393e-38));
assert(arr[0] === 2.387939260590663e-38);
assert(bits[0] === 0x01020304);
storeBigEndian(dv, 0, adjustForEndianessFloat32(2.3879393e-38));
assert(arr[0] === 1.539989614439558e-36);
assert(bits[0] === 0x04030201);
}
}
test5();
function adjustForEndianessFloat64(value) {
if (isLittleEndian)
return value;
let ab = new ArrayBuffer(8);
let ta = new Float64Array(ab);
ta[0] = value;
let dv = new DataView(ab);
return dv.getFloat64(0, true);
}
function test6() {
function storeLittleEndian(dv, index, value) {
dv.setFloat64(index, value, true);
}
noInline(storeLittleEndian);
function storeBigEndian(dv, index, value) {
dv.setFloat64(index, value, false);
}
noInline(storeBigEndian);
function store(dv, index, value, littleEndian) {
dv.setFloat64(index, value, littleEndian);
}
noInline(store);
let buffer = new ArrayBuffer(8);
let arr = new Float64Array(buffer);
let dv = new DataView(buffer);
for (let i = 0; i < 10000; ++i) {
storeLittleEndian(dv, 0, adjustForEndianessFloat64(NaN));
assert(isNaN(arr[0]));
// The NaN we stored should be a pure NaN, so that's what we should get
assert(readHex(dv, 8) == "0x7ff8000000000000");
storeLittleEndian(dv, 0, adjustForEndianessFloat64(-2.5075187084135162e+284));
assert(arr[0] === -2.5075187084135162e+284);
assert(readHex(dv, 8) === "0xfafafafafafafafa");
store(dv, 0, adjustForEndianessFloat64(124.553), true);
assert(readHex(dv, 8) === "0x405f23645a1cac08");
store(dv, 0, adjustForEndianessFloat64(Infinity), true);
assert(readHex(dv, 8) === "0x7ff0000000000000");
store(dv, 0, adjustForEndianessFloat64(Infinity), false);
assert(readHex(dv, 8) === "0x000000000000f07f");
store(dv, 0, adjustForEndianessFloat64(-Infinity), true);
assert(readHex(dv, 8) === "0xfff0000000000000");
storeBigEndian(dv, 0, adjustForEndianessFloat64(-2.5075187084135162e+284));
assert(arr[0] === -2.5075187084135162e+284);
assert(readHex(dv, 8) === "0xfafafafafafafafa");
storeBigEndian(dv, 0, adjustForEndianessFloat64(124.553));
assert(readHex(dv, 8) === "0x08ac1c5a64235f40");
}
}
test6();
function test7() {
function store(dv, index, value) {
dv.setInt8(index, value);
}
noInline(store);
let buffer = new ArrayBuffer(1);
let arr = new Uint8Array(buffer);
let arr2 = new Int8Array(buffer);
let dv = new DataView(buffer);
for (let i = 0; i < 10000; ++i) {
store(dv, 0, 0xff);
assert(arr[0] === 0xff);
assert(arr2[0] === -1);
store(dv, 0, 0xff00);
assert(arr[0] === 0);
assert(arr2[0] === 0);
store(dv, 0, -1);
assert(arr[0] === 0xff);
assert(arr2[0] === -1);
store(dv, 0, 0x0badbeef);
assert(arr[0] === 0xef);
assert(arr2[0] === -17);
}
}
test7();
function test8() {
function store(dv, index, value) {
dv.setInt8(index, value);
}
noInline(store);
let buffer = new ArrayBuffer(1);
let arr = new Uint8Array(buffer);
let arr2 = new Int8Array(buffer);
let dv = new DataView(buffer);
for (let i = 0; i < 10000; ++i) {
store(dv, 0, 0xff);
assert(arr[0] === 0xff);
assert(arr2[0] === -1);
store(dv, 0, 0xff00);
assert(arr[0] === 0);
assert(arr2[0] === 0);
store(dv, 0, -1);
assert(arr[0] === 0xff);
assert(arr2[0] === -1);
store(dv, 0, 0x0badbeef);
assert(arr[0] === 0xef);
assert(arr2[0] === -17);
}
}
test8();