Skip to content

Commit 1bac086

Browse files
aduh95mcollina
andcommitted
stream: only pass the expected number of parameters to callbacks
Signed-off-by: Antoine du Hamel <[email protected]> Co-authored-by: Matteo Collina <[email protected]> PR-URL: #63909 Reviewed-By: Matteo Collina <[email protected]> Reviewed-By: Gürgün Dayıoğlu <[email protected]> Reviewed-By: Mattias Buelens <[email protected]> Reviewed-By: Filip Skokan <[email protected]>
1 parent 6f3e342 commit 1bac086

4 files changed

Lines changed: 38 additions & 17 deletions

File tree

lib/internal/webstreams/readablestream.js

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ const {
100100
canCopyArrayBuffer,
101101
cloneAsUint8Array,
102102
copyArrayBuffer,
103-
createPromiseCallback,
103+
createPromiseCallback1Param,
104104
customInspect,
105105
dequeueValue,
106106
enqueueValueWithSize,
@@ -2578,10 +2578,10 @@ function setupReadableStreamDefaultControllerFromSource(
25782578
FunctionPrototypeBind(start, source, controller) :
25792579
nonOpStart;
25802580
const pullAlgorithm = pull ?
2581-
createPromiseCallback('source.pull', pull, source) :
2581+
createPromiseCallback1Param('source.pull', pull, source) :
25822582
nonOpPull;
25832583
const cancelAlgorithm = cancel ?
2584-
createPromiseCallback('source.cancel', cancel, source) :
2584+
createPromiseCallback1Param('source.cancel', cancel, source) :
25852585
nonOpCancel;
25862586

25872587
setupReadableStreamDefaultController(
@@ -3401,10 +3401,10 @@ function setupReadableByteStreamControllerFromSource(
34013401
FunctionPrototypeBind(start, source, controller) :
34023402
nonOpStart;
34033403
const pullAlgorithm = pull ?
3404-
createPromiseCallback('source.pull', pull, source, controller) :
3404+
createPromiseCallback1Param('source.pull', pull, source) :
34053405
nonOpPull;
34063406
const cancelAlgorithm = cancel ?
3407-
createPromiseCallback('source.cancel', cancel, source) :
3407+
createPromiseCallback1Param('source.cancel', cancel, source) :
34083408
nonOpCancel;
34093409

34103410
if (autoAllocateChunkSize === 0) {

lib/internal/webstreams/transformstream.js

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,8 @@ const {
4343
} = require('internal/worker/js_transferable');
4444

4545
const {
46-
createPromiseCallback,
46+
createPromiseCallback1Param,
47+
createPromiseCallback2Params,
4748
customInspect,
4849
extractHighWaterMark,
4950
extractSizeAlgorithm,
@@ -462,13 +463,13 @@ function setupTransformStreamDefaultControllerFromTransformer(
462463
const flush = transformer?.flush;
463464
const cancel = transformer?.cancel;
464465
const transformAlgorithm = transform ?
465-
createPromiseCallback('transformer.transform', transform, transformer) :
466+
createPromiseCallback2Params('transformer.transform', transform, transformer) :
466467
defaultTransformAlgorithm;
467468
const flushAlgorithm = flush ?
468-
createPromiseCallback('transformer.flush', flush, transformer) :
469+
createPromiseCallback1Param('transformer.flush', flush, transformer) :
469470
nonOpFlush;
470471
const cancelAlgorithm = cancel ?
471-
createPromiseCallback('transformer.cancel', cancel, transformer) :
472+
createPromiseCallback1Param('transformer.cancel', cancel, transformer) :
472473
nonOpCancel;
473474

474475
setupTransformStreamDefaultController(

lib/internal/webstreams/util.js

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,10 @@ const {
77
ArrayPrototypePush,
88
ArrayPrototypeShift,
99
AsyncIteratorPrototype,
10+
FunctionPrototypeCall,
1011
MathMax,
1112
NumberIsNaN,
1213
PromisePrototypeThen,
13-
ReflectApply,
1414
ReflectGet,
1515
Symbol,
1616
Uint8Array,
@@ -169,9 +169,25 @@ function enqueueValueWithSize(controller, value, size) {
169169
controller[kState].queueTotalSize += size;
170170
}
171171

172-
function createPromiseCallback(name, fn, thisArg) {
172+
// Arity-specialized variants of the promise-callback wrapper. The generic
173+
// rest-parameter + ReflectApply form allocated an arguments array on every
174+
// invocation; these run on per-chunk hot paths (pull/write/transform), so
175+
// each known call-site arity gets its own wrapper. The exact number of
176+
// arguments passed through to the user callback is observable and must be
177+
// preserved.
178+
function createPromiseCallbackNoParams(name, fn, thisArg) {
173179
validateFunction(fn, name);
174-
return async (...args) => ReflectApply(fn, thisArg, args);
180+
return async () => FunctionPrototypeCall(fn, thisArg);
181+
}
182+
183+
function createPromiseCallback1Param(name, fn, thisArg) {
184+
validateFunction(fn, name);
185+
return async (arg) => FunctionPrototypeCall(fn, thisArg, arg);
186+
}
187+
188+
function createPromiseCallback2Params(name, fn, thisArg) {
189+
validateFunction(fn, name);
190+
return async (arg1, arg2) => FunctionPrototypeCall(fn, thisArg, arg1, arg2);
175191
}
176192

177193
function isPromisePending(promise) {
@@ -213,7 +229,9 @@ module.exports = {
213229
canCopyArrayBuffer,
214230
cloneAsUint8Array,
215231
copyArrayBuffer,
216-
createPromiseCallback,
232+
createPromiseCallbackNoParams,
233+
createPromiseCallback1Param,
234+
createPromiseCallback2Params,
217235
customInspect,
218236
dequeueValue,
219237
enqueueValueWithSize,

lib/internal/webstreams/writablestream.js

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,9 @@ const {
5555
} = require('internal/worker/js_transferable');
5656

5757
const {
58-
createPromiseCallback,
58+
createPromiseCallbackNoParams,
59+
createPromiseCallback1Param,
60+
createPromiseCallback2Params,
5961
customInspect,
6062
dequeueValue,
6163
enqueueValueWithSize,
@@ -1272,13 +1274,13 @@ function setupWritableStreamDefaultControllerFromSink(
12721274
FunctionPrototypeBind(start, sink, controller) :
12731275
nonOpStart;
12741276
const writeAlgorithm = write ?
1275-
createPromiseCallback('sink.write', write, sink) :
1277+
createPromiseCallback2Params('sink.write', write, sink) :
12761278
nonOpWrite;
12771279
const closeAlgorithm = close ?
1278-
createPromiseCallback('sink.close', close, sink) :
1280+
createPromiseCallbackNoParams('sink.close', close, sink) :
12791281
nonOpCancel;
12801282
const abortAlgorithm = abort ?
1281-
createPromiseCallback('sink.abort', abort, sink) :
1283+
createPromiseCallback1Param('sink.abort', abort, sink) :
12821284
nonOpCancel;
12831285
setupWritableStreamDefaultController(
12841286
stream,

0 commit comments

Comments
 (0)