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 primitive values, dictionaries, enums, sequences, interfaces, required arguments, integers, `Uint8Array`, and `BufferSource`. - Move WebCrypto onto the shared converters, while keeping compatibility wrappers for its existing `BufferSource` and `BigInteger` behavior. - Use shared converters from Blob, Performance, Web Locks, and structured clone option handling. - Add benchmarks for `ConvertToInt` and WebCrypto Web IDL converter hot paths. - Add focused tests for core converters, WebCrypto converters, integer conversion, and buffer source behavior. Fixes: - Make the shared `BufferSource` and `Uint8Array` converters reject resizable `ArrayBuffer` and growable `SharedArrayBuffer` backing stores unless explicitly allowed. WebCrypto preserves its legacy resizable backing-store behavior through compatibility wrappers until a semver-major follow-up can opt in to the stricter 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 final Number approximation behavior. - Normalize mathematical modulo results to `+0` where Web IDL requires it. - Process inherited dictionaries in least-derived to most-derived order, sorting members only within each dictionary level. - Use `IteratorComplete` truthiness for sequence conversion. - Cover detached buffers, resizable-backed views, growable-backed views, cross-realm buffer sources, mutation-after-call behavior, inherited dictionary member order, and sequence iterator completion behavior. Signed-off-by: Filip Skokan <panva.ip@gmail.com> PR-URL: https://github.com/nodejs/node/pull/62979 Reviewed-By: Сковорода Никита Андреевич <chalkerx@gmail.com> Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
82 lines
1.9 KiB
JavaScript
82 lines
1.9 KiB
JavaScript
'use strict';
|
|
|
|
const assert = require('assert');
|
|
const common = require('../common.js');
|
|
|
|
const bench = common.createBenchmark(main, {
|
|
converter: [
|
|
'byte',
|
|
'octet',
|
|
'unsigned short',
|
|
'unsigned long',
|
|
'long long',
|
|
],
|
|
input: [
|
|
'integer',
|
|
'fractional',
|
|
'wrap',
|
|
'clamp',
|
|
'enforce-range',
|
|
'object',
|
|
],
|
|
n: [1e6],
|
|
}, { flags: ['--expose-internals'] });
|
|
|
|
function getConverter(converter) {
|
|
switch (converter) {
|
|
case 'byte':
|
|
return { bitLength: 8, signedness: 'signed' };
|
|
case 'octet':
|
|
return { bitLength: 8 };
|
|
case 'unsigned short':
|
|
return { bitLength: 16 };
|
|
case 'unsigned long':
|
|
return { bitLength: 32 };
|
|
case 'long long':
|
|
return { bitLength: 64, signedness: 'signed' };
|
|
default:
|
|
throw new Error(`Unsupported converter: ${converter}`);
|
|
}
|
|
}
|
|
|
|
function getInput(input) {
|
|
switch (input) {
|
|
case 'integer':
|
|
return { value: 7 };
|
|
case 'fractional':
|
|
return { value: 7.9 };
|
|
case 'wrap':
|
|
return { value: 2 ** 63 + 2 ** 11 };
|
|
case 'clamp':
|
|
return { value: 300.8, options: { clamp: true } };
|
|
case 'enforce-range':
|
|
return { value: 7.9, options: { enforceRange: true } };
|
|
case 'object':
|
|
return {
|
|
value: {
|
|
valueOf() { return 7; },
|
|
},
|
|
};
|
|
default:
|
|
throw new Error(`Unsupported input: ${input}`);
|
|
}
|
|
}
|
|
|
|
function main({ n, converter, input }) {
|
|
const { convertToInt } = require('internal/webidl');
|
|
const { bitLength, signedness } = getConverter(converter);
|
|
const { value, options } = getInput(input);
|
|
|
|
let noDead;
|
|
bench.start();
|
|
if (options === undefined) {
|
|
for (let i = 0; i < n; i++)
|
|
noDead = convertToInt(value, bitLength, signedness);
|
|
} else {
|
|
for (let i = 0; i < n; i++)
|
|
noDead = convertToInt(value, bitLength, signedness, options);
|
|
}
|
|
bench.end(n);
|
|
|
|
assert.strictEqual(typeof noDead, 'number');
|
|
}
|