diff --git a/lib/internal/webidl.js b/lib/internal/webidl.js index 36bde94013d1a8..85bfb2c3db3180 100644 --- a/lib/internal/webidl.js +++ b/lib/internal/webidl.js @@ -108,11 +108,14 @@ function pow2(exponent) { // https://tc39.es/ecma262/#eqn-modulo // The notation “x modulo y” computes a value k of the same sign as y. +// As y is always positive in this file, we can do a simple r < 0 check for that. function modulo(x, y) { const r = x % y; // Convert -0 to +0. if (r === 0) { return 0; + } else if (r < 0) { + return r + y; } return r; } diff --git a/test/parallel/test-internal-webidl-converttoint.js b/test/parallel/test-internal-webidl-converttoint.js index 7e7c024387a0ec..8260d9d8d29914 100644 --- a/test/parallel/test-internal-webidl-converttoint.js +++ b/test/parallel/test-internal-webidl-converttoint.js @@ -56,3 +56,12 @@ assert.strictEqual(convertToInt('x', 0xFFFF_FFFF, 32), 0xFFFF_FFFF); // Out of range, step 11. assert.strictEqual(convertToInt('x', 0x8000_0000, 32, { signed: true }), -0x8000_0000); assert.strictEqual(convertToInt('x', 0xFFF_FFFF, 32, { signed: true }), 0xFFF_FFFF); + +// Negative values must wrap as two's-complement, matching typed-array behavior. +assert.strictEqual(convertToInt('x', -3, 8), 253); +assert.strictEqual(convertToInt('x', -3, 8), new Uint8Array([-3])[0]); +assert.strictEqual(convertToInt('x', -1, 32), 0xFFFF_FFFF); +assert.strictEqual(convertToInt('x', -1, 32), new Uint32Array([-1])[0]); +assert.strictEqual(convertToInt('x', -200, 8, { signed: true }), 56); +assert.strictEqual(convertToInt('x', -200, 8, { signed: true }), + new Int8Array([-200])[0]);