Skip to content

Commit 62c11b0

Browse files
committed
lib: refactor internal webidl converters
Rework lib/internal/webidl.js into a documented shared converter module that follows the Web IDL conversion algorithms more closely. Improvements: - Add documented converters and helper factories for dictionaries, enums, sequences, interfaces, required arguments, and integers. - Move WebCrypto to the shared converters, keeping compatibility wrappers for existing BufferSource and BigInteger behavior. - Use shared converters from Blob, Performance, Web Locks, and structured clone option handling. - Add focused tests for core converters, WebCrypto converters, integer conversion, and buffer source behavior. Fixes: - Make core BufferSource and Uint8Array reject resizable ArrayBuffer and growable SharedArrayBuffer backing stores unless allowed. This is non-breaking because the core behavior has no runtime consumers other than WebCrypto. WebCrypto keeps its legacy behavior until a semver-major follow-up opts in to the correct behavior. - Use Web IDL ToNumber and ToString behavior for BigInt, Symbol, and object primitive conversion. - Use exact BigInt modulo for 64-bit ConvertToInt wrapping and document the Number approximation behavior. - Normalize mathematical modulo results to +0 where Web IDL requires it. - Cover detached buffers, resizable-backed views, growable-backed views, cross-realm buffer sources, and mutation-after-call behavior. Signed-off-by: Filip Skokan <[email protected]>
1 parent 21436f0 commit 62c11b0

14 files changed

Lines changed: 1726 additions & 671 deletions
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
'use strict';
2+
3+
const assert = require('assert');
4+
const common = require('../common.js');
5+
6+
const bench = common.createBenchmark(main, {
7+
converter: [
8+
'octet',
9+
'unsigned short',
10+
'unsigned long',
11+
'long long',
12+
],
13+
input: [
14+
'integer',
15+
'fractional',
16+
'wrap',
17+
'clamp',
18+
'enforce-range',
19+
'object',
20+
],
21+
n: [1e6],
22+
}, { flags: ['--expose-internals'] });
23+
24+
function getInput(input) {
25+
switch (input) {
26+
case 'integer':
27+
return { value: 7 };
28+
case 'fractional':
29+
return { value: 7.9 };
30+
case 'wrap':
31+
return { value: 2 ** 63 + 2 ** 11 };
32+
case 'clamp':
33+
return { value: 300.8, options: { clamp: true } };
34+
case 'enforce-range':
35+
return { value: 7.9, options: { enforceRange: true } };
36+
case 'object':
37+
return {
38+
value: {
39+
valueOf() { return 7; },
40+
},
41+
};
42+
default:
43+
throw new Error(`Unsupported input: ${input}`);
44+
}
45+
}
46+
47+
function main({ n, converter, input }) {
48+
const { converters } = require('internal/webidl');
49+
const convert = converters[converter];
50+
const { value, options } = getInput(input);
51+
52+
let noDead;
53+
bench.start();
54+
if (options === undefined) {
55+
for (let i = 0; i < n; i++)
56+
noDead = convert(value);
57+
} else {
58+
for (let i = 0; i < n; i++)
59+
noDead = convert(value, options);
60+
}
61+
bench.end(n);
62+
63+
assert.strictEqual(typeof noDead, 'number');
64+
}

lib/internal/blob.js

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,6 @@ const {
5454
const { inspect } = require('internal/util/inspect');
5555
const {
5656
converters,
57-
convertToInt,
5857
createSequenceConverter,
5958
} = require('internal/webidl');
6059

@@ -245,10 +244,14 @@ class Blob {
245244
if (!isBlob(this))
246245
throw new ERR_INVALID_THIS('Blob');
247246

248-
// Coerce values to int
249-
const opts = { __proto__: null, signed: true };
250-
start = convertToInt('start', start, 64, opts);
251-
end = convertToInt('end', end, 64, opts);
247+
start = converters['long long'](
248+
start,
249+
{ __proto__: null, context: 'start' },
250+
);
251+
end = converters['long long'](
252+
end,
253+
{ __proto__: null, context: 'end' },
254+
);
252255

253256
if (start < 0) {
254257
start = MathMax(this[kLength] + start, 0);

0 commit comments

Comments
 (0)