Moddable-OpenSource / moddable

Tools for developers to create truly open IoT products using standard JavaScript on low cost microcontrollers.
http://www.moddable.com
1.32k stars 236 forks source link

XS reports incorrect byteLength for some TypedArrays #1392

Closed gibson042 closed 2 weeks ago

gibson042 commented 1 month ago

Environment: XS 15.5.1, slot 32 bytes, ID 4 bytes

Description When a TypedArray has an element size that does not evenly divide its underlying buffer (because of e.g. resize), byteLength incorrectly includes the excess bytes.

Steps to Reproduce

const buf = new ArrayBuffer(8, { maxByteLength: 8 });
new Uint8Array(buf).set(Array.from({ length: buf.byteLength }, (_, i) => i));
const arr = new Uint32Array(buf);
const log = arr => {
  const bufSize = arr.buffer.byteLength;
  const { byteOffset: arrByteOffset, byteLength: arrByteLength, BYTES_PER_ELEMENT } = arr;
  const arrType = arr.constructor.name;
  const bufSliceDesc = `ArrayBuffer(${bufSize})[${arrByteOffset}:${arrByteOffset + arrByteLength}]`;
  const elRepr = n => "0x" + n.toString(16).padStart(BYTES_PER_ELEMENT * 2, "0");
  print(`${bufSliceDesc} holds ${arrType}(${arr.length}) [${[...arr].map(elRepr).join(" ")}]`);
};
log(arr);
buf.resize(7);
log(arr);

Actual behavior

ArrayBuffer(8)[0:8] holds Uint32Array(2) [0x03020100 0x07060504]
ArrayBuffer(7)[0:7] holds Uint32Array(1) [0x03020100]

(little-endian)

Expected behavior

ArrayBuffer(8)[0:8] holds Uint32Array(2) [0x03020100 0x07060504]
ArrayBuffer(7)[0:4] holds Uint32Array(1) [0x03020100]

byteLength is specified to depend upon TypedArrayByteLength, which for a resizable buffer returns elementLength × elementSize (where elementLength comes from TypedArrayLength as floor((byteLength - byteOffset) / elementSize), i.e. the integer number of complete TypedArray elements that can fit in the buffer).

test262 pull request: https://github.com/tc39/test262/pull/4199

phoddie commented 1 month ago

Thanks for the report and test case. I'm able to reproduce the behavior. This looks straightforward to resolve.

phoddie commented 2 weeks ago

Fixed.