Skip to content

Commit 48f5856

Browse files
committed
fixup! lib: refactor internal webidl converters
Signed-off-by: Filip Skokan <panva.ip@gmail.com>
1 parent 53894c9 commit 48f5856

1 file changed

Lines changed: 25 additions & 3 deletions

File tree

lib/internal/webidl.js

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -328,6 +328,18 @@ function convertToInt(
328328
upperBound = pow2(bitLength - 1) - 1;
329329
}
330330

331+
// Common case: primitive Number values that already fit the Web IDL
332+
// range and have no fractional part are returned unchanged by every
333+
// ConvertToInt path, except that -0 must become +0. This skips the
334+
// generic ToNumber and option handling without skipping observable
335+
// object coercion.
336+
if (typeof V === 'number' &&
337+
V >= lowerBound &&
338+
V <= upperBound &&
339+
MathTrunc(V) === V) {
340+
return V === 0 ? 0 : V;
341+
}
342+
331343
// Step 4: convert V with ECMA-262 ToNumber.
332344
let x = toNumber(V, options);
333345
// Step 5: normalize -0 to +0.
@@ -373,6 +385,14 @@ function convertToInt(
373385
// Step 9: truncate to IntegerPart(x).
374386
x = integerPart(x);
375387

388+
// Steps 10-12 are an identity for values already in the step 1-3
389+
// bounds. For 64-bit conversions this only skips the safe-integer
390+
// subset; values outside it still need exact BigInt modulo and the
391+
// final Number approximation.
392+
if (x >= lowerBound && x <= upperBound) {
393+
return x;
394+
}
395+
376396
if (bitLength === 64) {
377397
// Steps 10-12 still wrap over the full 2^64 IDL integer range.
378398
// BigInt keeps x modulo 2^64 and the signed high-bit adjustment exact
@@ -396,11 +416,13 @@ function convertToInt(
396416
}
397417

398418
// Step 10: reduce modulo 2^bitLength.
399-
x = modulo(x, pow2(bitLength));
419+
const twoToTheBitLength = pow2(bitLength);
420+
const twoToOneLessThanTheBitLength = pow2(bitLength - 1);
421+
x = modulo(x, twoToTheBitLength);
400422

401423
// Step 11: wrap into the signed range when the high bit is set.
402-
if (signed && x >= pow2(bitLength - 1)) {
403-
return x - pow2(bitLength);
424+
if (signed && x >= twoToOneLessThanTheBitLength) {
425+
return x - twoToTheBitLength;
404426
}
405427

406428
// Step 12: return the unsigned value.

0 commit comments

Comments
 (0)