mirror of
https://github.com/nodejs/node.git
synced 2026-10-28 10:15:07 +08:00
Web IDL overload resolution treats functions as objects, accepts a null iterator as missing, and retrieves the iterator method only once. Reuse that method during sequence conversion in both postMessage entry points. Signed-off-by: Filip Skokan <panva.ip@gmail.com> Assisted-by: Codex PR-URL: https://github.com/nodejs/node/pull/66354 Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Aviv Keller <me@aviv.sh>
54 lines
1.9 KiB
JavaScript
54 lines
1.9 KiB
JavaScript
// Flags: --experimental-web-worker
|
|
'use strict';
|
|
|
|
const common = require('../common');
|
|
const assert = require('node:assert');
|
|
const { pathToFileURL } = require('node:url');
|
|
|
|
function checkPostMessage(post) {
|
|
// A null iterator selects the dictionary overload.
|
|
const dictionaryBuffer = new ArrayBuffer(8);
|
|
post(null, { [Symbol.iterator]: null, transfer: [dictionaryBuffer] });
|
|
assert.strictEqual(dictionaryBuffer.byteLength, 0);
|
|
|
|
// Callable objects can also be iterable transfer lists.
|
|
const functionBuffer = new ArrayBuffer(8);
|
|
function transfer() {}
|
|
transfer[Symbol.iterator] = function*() { yield functionBuffer; };
|
|
post(null, transfer);
|
|
assert.strictEqual(functionBuffer.byteLength, 0);
|
|
|
|
// Overload resolution must reuse the iterator method it retrieved.
|
|
const getterBuffer = new ArrayBuffer(8);
|
|
const iterable = {};
|
|
Object.defineProperty(iterable, Symbol.iterator, {
|
|
get: common.mustCall(() => common.mustCall(function*() {
|
|
assert.strictEqual(this, iterable);
|
|
yield getterBuffer;
|
|
})),
|
|
});
|
|
post(null, iterable);
|
|
assert.strictEqual(getterBuffer.byteLength, 0);
|
|
|
|
// A present, non-callable iterator must fail before reading the dictionary.
|
|
for (const value of [{}, function() {}]) {
|
|
value[Symbol.iterator] = 1;
|
|
Object.defineProperty(value, 'transfer', { get: common.mustNotCall() });
|
|
assert.throws(() => post(null, value), TypeError);
|
|
}
|
|
}
|
|
|
|
// The test runner can also execute this file in a regular Node worker.
|
|
if (typeof globalThis.DedicatedWorkerGlobalScope === 'undefined') {
|
|
const worker = new Worker(pathToFileURL(__filename));
|
|
worker.onerror = common.mustNotCall('worker failed');
|
|
const done = common.mustCall(() => worker.terminate());
|
|
worker.onmessage = ({ data }) => {
|
|
if (data === 'done') done();
|
|
};
|
|
checkPostMessage(worker.postMessage.bind(worker));
|
|
} else {
|
|
checkPostMessage(globalThis.postMessage);
|
|
globalThis.postMessage('done');
|
|
}
|