diff --git a/javascript/test.js b/javascript/test.js index 22f23be8708..5b8e17d08cc 100644 --- a/javascript/test.js +++ b/javascript/test.js @@ -103,3 +103,8 @@ test("integer (3 nodes)", () => { const result = parse("18446744073709552000"); assert(result.value.statements.body[0].value == 18446744073709552000n); }); + +test("double", () => { + const result = parse("1.0"); + assert(result.value.statements.body[0].value == 1.0); +}); diff --git a/templates/javascript/src/deserialize.js.erb b/templates/javascript/src/deserialize.js.erb index 060a1a804bf..71105ea6efe 100644 --- a/templates/javascript/src/deserialize.js.erb +++ b/templates/javascript/src/deserialize.js.erb @@ -4,6 +4,23 @@ const MAJOR_VERSION = 0; const MINOR_VERSION = 24; const PATCH_VERSION = 0; +// The DataView getFloat64 function takes an optional second argument that +// specifies whether the number is little-endian or big-endian. It does not +// appear to have a native endian mode, so we need to determine the endianness +// of the system at runtime. +const LITTLE_ENDIAN = (() => { + let uint32 = new Uint32Array([0x11223344]); + let uint8 = new Uint8Array(uint32.buffer); + + if (uint8[0] === 0x44) { + return true; + } else if (uInt8[0] === 0x11) { + return false; + } else { + throw new Error("Mixed endianness"); + } +})(); + class SerializationBuffer { constructor(source, array) { this.source = source; @@ -103,7 +120,7 @@ class SerializationBuffer { view.setUint8(index, this.readByte()); } - return view.getFloat64(0); + return view.getFloat64(0, LITTLE_ENDIAN); } }