perf(tooling): preserve sparse arrays and avoid redundant copy in assert.deepStrictEqual shim - #9479
Conversation
… assert.deepStrictEqual shim
|
/gemini review |
There was a problem hiding this comment.
Code Review
This pull request updates bin/proxyquire-bun-shim.cjs to replace Array.from() with new Array(length) when creating copies of the actual and expected arrays. This changes how the array copies are initialized before their properties are defined. There are no review comments to evaluate, and I have no feedback to provide.
There was a problem hiding this comment.
Code Review
This pull request replaces the use of 'Array.from()' with 'new Array(length)' when copying arrays in 'bin/proxyquire-bun-shim.cjs'. The feedback recommends coercing the array lengths to unsigned 32-bit integers using '>>> 0' to avoid potential 'RangeError' exceptions or unexpected behavior if the length property is not a primitive number.
| ) { | ||
| try { | ||
| const copyA = Array.from(actual); | ||
| const copyA = new Array(actual.length); |
There was a problem hiding this comment.
Using new Array(actual.length) can lead to unexpected behavior or a RangeError if actual.length is not a primitive number (for example, if it is a string like "5", undefined, or a negative number). In JavaScript, new Array("5") creates an array containing the single element "5" (length 1) instead of an empty array of length 5, and new Array(undefined) creates [undefined] (length 1). To ensure robustness and guarantee that the argument is always treated as a numeric length, coerce the length to an unsigned 32-bit integer using the unsigned right shift operator (>>> 0). This is the standard ECMAScript behavior for array-like length coercion.
const copyA = new Array(actual.length >>> 0);
| } | ||
| } | ||
| const copyB = Array.from(expected); | ||
| const copyB = new Array(expected.length); |
b2fa115
into
bun-runtime/1-test-runner-handwritten-libraries-4-1
Summary
Stacked on top of #9460 (
bun-runtime/1-test-runner-handwritten-libraries-4-1).In
bin/proxyquire-bun-shim.cjs,assert.deepStrictEqualclonesactualandexpectedarrays when retrying comparisons for Array subclasses withconstructor === Arrayin Bun <= 1.4.Previously,
Array.from(actual)andArray.from(expected)were used before iterating overReflect.ownKeysand copying every own property descriptor viaObject.defineProperty. This had two drawbacks:Array.from()converts holes in sparse arrays into explicitundefinedelements (creating own properties for indices that were originally empty slots), altering sparse array semantics because the subsequentReflect.ownKeysloop only defines properties that exist on the source array and does not delete the filled holes.Array.from()iterates and populates all array indices upfront, only for the subsequent loop to immediately redefine every own property viaObject.defineProperty.Initializing
copyAandcopyBwithnew Array(actual.length)andnew Array(expected.length)allocates an empty array of the matching length, preserving sparse array holes and avoiding redundant element copying beforeObject.definePropertytransfers all own property descriptors.