Skip to content

Commit 882e66e

Browse files
committed
lib: use more primordials
This replaces all Function.prototype.apply, Function.prototype.bind, Function.prototype.call to their primordials alter ego.
1 parent 2a1273c commit 882e66e

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

69 files changed

+437
-276
lines changed

lib/_http_agent.js

+2-1
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
'use strict';
2323

2424
const {
25+
FunctionPrototypeCall,
2526
NumberIsNaN,
2627
ObjectKeys,
2728
ObjectSetPrototypeOf,
@@ -78,7 +79,7 @@ function Agent(options) {
7879
if (!(this instanceof Agent))
7980
return new Agent(options);
8081

81-
EventEmitter.call(this);
82+
FunctionPrototypeCall(EventEmitter, this);
8283

8384
this.defaultPort = 80;
8485
this.protocol = 'http:';

lib/_http_client.js

+5-3
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,12 @@ const {
2525
ArrayIsArray,
2626
Boolean,
2727
Error,
28+
FunctionPrototypeCall,
2829
NumberIsFinite,
2930
ObjectAssign,
3031
ObjectKeys,
3132
ObjectSetPrototypeOf,
33+
ReflectApply,
3234
String,
3335
Symbol
3436
} = primordials;
@@ -87,7 +89,7 @@ class HTTPClientAsyncResource {
8789

8890
let urlWarningEmitted = false;
8991
function ClientRequest(input, options, cb) {
90-
OutgoingMessage.call(this);
92+
FunctionPrototypeCall(OutgoingMessage, this);
9193

9294
if (typeof input === 'string') {
9395
const urlStr = input;
@@ -329,7 +331,7 @@ ObjectSetPrototypeOf(ClientRequest, OutgoingMessage);
329331

330332
ClientRequest.prototype._finish = function _finish() {
331333
DTRACE_HTTP_CLIENT_REQUEST(this, this.socket);
332-
OutgoingMessage.prototype._finish.call(this);
334+
FunctionPrototypeCall(OutgoingMessage.prototype._finish, this);
333335
};
334336

335337
ClientRequest.prototype._implicitHeader = function _implicitHeader() {
@@ -840,7 +842,7 @@ function _deferToConnect(method, arguments_, cb) {
840842

841843
const callSocketMethod = () => {
842844
if (method)
843-
this.socket[method].apply(this.socket, arguments_);
845+
ReflectApply(this.socket[method], this.socket, arguments_);
844846

845847
if (typeof cb === 'function')
846848
cb();

lib/_http_incoming.js

+3-1
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
'use strict';
2323

2424
const {
25+
FunctionPrototypeCall,
2526
ObjectDefineProperty,
2627
ObjectSetPrototypeOf,
2728
Symbol
@@ -54,7 +55,8 @@ function IncomingMessage(socket) {
5455
};
5556
}
5657

57-
Stream.Readable.call(this, { autoDestroy: false, ...streamOptions });
58+
FunctionPrototypeCall(Stream.Readable,
59+
this, { autoDestroy: false, ...streamOptions });
5860

5961
this._readableState.readingMore = true;
6062

lib/_http_outgoing.js

+4-2
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@
2323

2424
const {
2525
ArrayIsArray,
26+
FunctionPrototypeBind,
27+
FunctionPrototypeCall,
2628
ObjectCreate,
2729
ObjectDefineProperty,
2830
ObjectKeys,
@@ -87,7 +89,7 @@ function isCookieField(s) {
8789
function noopPendingOutput(amount) {}
8890

8991
function OutgoingMessage() {
90-
Stream.call(this);
92+
FunctionPrototypeCall(Stream, this);
9193

9294
// Queue that holds all currently pending data, until the response will be
9395
// assigned to the socket (until it will its turn in the HTTP pipeline).
@@ -827,7 +829,7 @@ OutgoingMessage.prototype.end = function end(chunk, encoding, callback) {
827829
if (typeof callback === 'function')
828830
this.once('finish', callback);
829831

830-
const finish = onFinish.bind(undefined, this);
832+
const finish = FunctionPrototypeBind(onFinish, undefined, this);
831833

832834
if (this._hasBody && this.chunkedEncoding) {
833835
this._send('0\r\n' + this._trailer + '\r\n', 'latin1', finish);

lib/_http_server.js

+37-19
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@
2424
const {
2525
ArrayIsArray,
2626
Error,
27+
FunctionPrototypeBind,
28+
FunctionPrototypeCall,
2729
ObjectKeys,
2830
ObjectSetPrototypeOf,
2931
Symbol,
@@ -169,7 +171,7 @@ class HTTPServerAsyncResource {
169171
}
170172

171173
function ServerResponse(req) {
172-
OutgoingMessage.call(this);
174+
FunctionPrototypeCall(OutgoingMessage, this);
173175

174176
if (req.method === 'HEAD') this._hasBody = false;
175177

@@ -197,7 +199,7 @@ ServerResponse.prototype._finish = function _finish() {
197199
if (this[kServerResponseStatistics] !== undefined) {
198200
emitStatistics(this[kServerResponseStatistics]);
199201
}
200-
OutgoingMessage.prototype._finish.call(this);
202+
FunctionPrototypeCall(OutgoingMessage.prototype._finish, this);
201203
};
202204

203205

@@ -371,7 +373,7 @@ function Server(options, requestListener) {
371373
validateBoolean(insecureHTTPParser, 'options.insecureHTTPParser');
372374
this.insecureHTTPParser = insecureHTTPParser;
373375

374-
net.Server.call(this, { allowHalfOpen: true });
376+
FunctionPrototypeCall(net.Server, this, { allowHalfOpen: true });
375377

376378
if (requestListener) {
377379
this.on('request', requestListener);
@@ -477,16 +479,21 @@ function connectionListenerInternal(server, socket) {
477479
outgoingData: 0,
478480
keepAliveTimeoutSet: false
479481
};
480-
state.onData = socketOnData.bind(undefined, server, socket, parser, state);
481-
state.onEnd = socketOnEnd.bind(undefined, server, socket, parser, state);
482-
state.onClose = socketOnClose.bind(undefined, socket, state);
483-
state.onDrain = socketOnDrain.bind(undefined, socket, state);
482+
state.onData = FunctionPrototypeBind(socketOnData, undefined, server,
483+
socket, parser, state);
484+
state.onEnd = FunctionPrototypeBind(socketOnEnd, undefined, server,
485+
socket, parser, state);
486+
state.onClose = FunctionPrototypeBind(socketOnClose, undefined,
487+
socket, state);
488+
state.onDrain = FunctionPrototypeBind(socketOnDrain, undefined,
489+
socket, state);
484490
socket.on('data', state.onData);
485491
socket.on('error', socketOnError);
486492
socket.on('end', state.onEnd);
487493
socket.on('close', state.onClose);
488494
socket.on('drain', state.onDrain);
489-
parser.onIncoming = parserOnIncoming.bind(undefined, server, socket, state);
495+
parser.onIncoming = FunctionPrototypeBind(parserOnIncoming, undefined, server,
496+
socket, state);
490497

491498
// We are consuming socket, so it won't get any actual data
492499
socket.on('resume', onSocketResume);
@@ -505,16 +512,22 @@ function connectionListenerInternal(server, socket) {
505512
socket._handle._consumed = true;
506513
parser.consume(socket._handle);
507514
}
508-
parser[kOnExecute] =
509-
onParserExecute.bind(undefined, server, socket, parser, state);
515+
parser[kOnExecute] = FunctionPrototypeBind(
516+
onParserExecute,
517+
undefined,
518+
server,
519+
socket,
520+
parser,
521+
state
522+
);
510523

511524
parser[kOnTimeout] =
512-
onParserTimeout.bind(undefined, server, socket);
525+
FunctionPrototypeBind(onParserTimeout, undefined, server, socket);
513526

514527
// When receiving new requests on the same socket (pipelining or keep alive)
515528
// make sure the requestTimeout is active.
516529
parser[kOnMessageBegin] =
517-
setRequestTimeout.bind(undefined, server, socket);
530+
FunctionPrototypeBind(setRequestTimeout, undefined, server, socket);
518531

519532
// This protects from DOS attack where an attacker establish the connection
520533
// without sending any data on applications where server.timeout is left to
@@ -592,7 +605,7 @@ function socketOnEnd(server, socket, parser, state) {
592605

593606
if (ret instanceof Error) {
594607
debug('parse error');
595-
socketOnError.call(socket, ret);
608+
FunctionPrototypeCall(socketOnError, socket, ret);
596609
return;
597610
}
598611

@@ -618,7 +631,7 @@ function socketOnData(server, socket, parser, state, d) {
618631

619632
function onRequestTimeout(socket) {
620633
socket[kRequestTimeout] = undefined;
621-
socketOnError.call(socket, new ERR_HTTP_REQUEST_TIMEOUT());
634+
FunctionPrototypeCall(socketOnError, socket, new ERR_HTTP_REQUEST_TIMEOUT());
622635
}
623636

624637
function onParserExecute(server, socket, parser, state, ret) {
@@ -685,7 +698,7 @@ function onParserExecuteCommon(server, socket, parser, state, ret, d) {
685698
prepareError(ret, parser, d);
686699
ret.rawPacket = d || parser.getCurrentBuffer();
687700
debug('parse error', ret);
688-
socketOnError.call(socket, ret);
701+
FunctionPrototypeCall(socketOnError, socket, ret);
689702
} else if (parser.incoming && parser.incoming.upgrade) {
690703
// Upgrade or CONNECT
691704
const req = parser.incoming;
@@ -724,7 +737,7 @@ function onParserExecuteCommon(server, socket, parser, state, ret, d) {
724737
// When receiving new requests on the same socket (pipelining or keep alive)
725738
// make sure the requestTimeout is active.
726739
parser[kOnMessageBegin] =
727-
setRequestTimeout.bind(undefined, server, socket);
740+
FunctionPrototypeBind(setRequestTimeout, undefined, server, socket);
728741
}
729742

730743
if (socket._paused && socket.parser) {
@@ -870,7 +883,8 @@ function parserOnIncoming(server, socket, state, req, keepAlive) {
870883

871884
const res = new server[kServerResponse](req);
872885
res._keepAliveTimeout = server.keepAliveTimeout;
873-
res._onPendingData = updateOutgoingData.bind(undefined, socket, state);
886+
res._onPendingData =
887+
FunctionPrototypeBind(updateOutgoingData, undefined, socket, state);
874888

875889
res.shouldKeepAlive = keepAlive;
876890
DTRACE_HTTP_SERVER_REQUEST(req, socket);
@@ -894,7 +908,8 @@ function parserOnIncoming(server, socket, state, req, keepAlive) {
894908
// When we're finished writing the response, check if this is the last
895909
// response, if so destroy the socket.
896910
res.on('finish',
897-
resOnFinish.bind(undefined, req, res, socket, state, server));
911+
FunctionPrototypeBind(resOnFinish, undefined, req, res,
912+
socket, state, server));
898913

899914
if (req.headers.expect !== undefined &&
900915
(req.httpVersionMajor === 1 && req.httpVersionMinor === 1)) {
@@ -966,7 +981,10 @@ function unconsume(parser, socket) {
966981

967982
function generateSocketListenerWrapper(originalFnName) {
968983
return function socketListenerWrap(ev, fn) {
969-
const res = net.Socket.prototype[originalFnName].call(this, ev, fn);
984+
const res = FunctionPrototypeCall(
985+
net.Socket.prototype[originalFnName],
986+
this, ev, fn
987+
);
970988
if (!this.parser) {
971989
this.on = net.Socket.prototype.on;
972990
this.addListener = net.Socket.prototype.addListener;

lib/_tls_wrap.js

+6-4
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,11 @@
2222
'use strict';
2323

2424
const {
25+
FunctionPrototypeCall,
2526
ObjectAssign,
2627
ObjectDefineProperty,
2728
ObjectSetPrototypeOf,
29+
ReflectApply,
2830
RegExp,
2931
Symbol,
3032
SymbolFor,
@@ -496,7 +498,7 @@ function TLSSocket(socket, opts) {
496498
// distinguishable from regular ones.
497499
this.encrypted = true;
498500

499-
net.Socket.call(this, {
501+
FunctionPrototypeCall(net.Socket, this, {
500502
handle: this._wrapHandle(wrap),
501503
allowHalfOpen: socket ? socket.allowHalfOpen : tlsOptions.allowHalfOpen,
502504
pauseOnCreate: tlsOptions.pauseOnConnect,
@@ -535,7 +537,7 @@ const proxiedMethods = [
535537
function makeMethodProxy(name) {
536538
return function methodProxy(...args) {
537539
if (this._parent[name])
538-
return this._parent[name].apply(this._parent, args);
540+
return ReflectApply(this._parent[name], this._parent, args);
539541
};
540542
}
541543
for (const proxiedMethod of proxiedMethods) {
@@ -993,7 +995,7 @@ TLSSocket.prototype.getCertificate = function() {
993995
function makeSocketMethodProxy(name) {
994996
return function socketMethodProxy(...args) {
995997
if (this._handle)
996-
return this._handle[name].apply(this._handle, args);
998+
return ReflectApply(this._handle[name], this._handle, args);
997999
return null;
9981000
};
9991001
}
@@ -1209,7 +1211,7 @@ function Server(options, listener) {
12091211
}
12101212

12111213
// constructor call
1212-
net.Server.call(this, options, tlsConnectionListener);
1214+
FunctionPrototypeCall(net.Server, this, options, tlsConnectionListener);
12131215

12141216
if (listener) {
12151217
this.on('secureConnection', listener);

lib/assert.js

+5-3
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@
2323
const {
2424
Error,
2525
ErrorCaptureStackTrace,
26+
FunctionPrototypeBind,
27+
FunctionPrototypeCall,
2628
ObjectAssign,
2729
ObjectIs,
2830
ObjectKeys,
@@ -234,7 +236,7 @@ function parseCode(code, offset) {
234236
classFields,
235237
staticClassFeatures
236238
);
237-
parseExpressionAt = Parser.parseExpressionAt.bind(Parser);
239+
parseExpressionAt = FunctionPrototypeBind(Parser.parseExpressionAt, Parser);
238240
}
239241
let node;
240242
let start = 0;
@@ -649,7 +651,7 @@ function expectedException(actual, expected, message, fn) {
649651
throwError = true;
650652
} else {
651653
// Check validation functions return value.
652-
const res = expected.call({}, actual);
654+
const res = FunctionPrototypeCall(expected, {}, actual);
653655
if (res !== true) {
654656
if (!message) {
655657
generatedMessage = true;
@@ -794,7 +796,7 @@ function hasMatchingError(actual, expected) {
794796
if (ObjectPrototypeIsPrototypeOf(Error, expected)) {
795797
return false;
796798
}
797-
return expected.call({}, actual) === true;
799+
return FunctionPrototypeCall(expected, {}, actual) === true;
798800
}
799801

800802
function expectsNoError(stackStartFn, actual, error, message) {

lib/async_hooks.js

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
'use strict';
22

33
const {
4+
FunctionPrototypeBind,
45
NumberIsSafeInteger,
56
ObjectDefineProperties,
67
ObjectIs,
@@ -218,7 +219,7 @@ class AsyncResource {
218219
bind(fn) {
219220
if (typeof fn !== 'function')
220221
throw new ERR_INVALID_ARG_TYPE('fn', 'Function', fn);
221-
const ret = this.runInAsyncScope.bind(this, fn);
222+
const ret = FunctionPrototypeBind(this.runInAsyncScope, this, fn);
222223
ObjectDefineProperties(ret, {
223224
'length': {
224225
configurable: true,

lib/buffer.js

+4-3
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ const {
2525
Array,
2626
ArrayIsArray,
2727
Error,
28+
FunctionPrototypeCall,
2829
MathFloor,
2930
MathMin,
3031
MathTrunc,
@@ -566,7 +567,7 @@ Buffer.concat = function concat(list, length) {
566567
// Zero-fill the remaining bytes if the specified `length` was more than
567568
// the actual total length, i.e. if we have some remaining allocated bytes
568569
// there were not initialized.
569-
TypedArrayFill.call(buffer, 0, pos, length);
570+
FunctionPrototypeCall(TypedArrayFill, buffer, 0, pos, length);
570571
}
571572

572573
return buffer;
@@ -1005,12 +1006,12 @@ function _fill(buf, value, offset, end, encoding) {
10051006

10061007
if (typeof value === 'number') {
10071008
// OOB check
1008-
const byteLen = TypedArrayProto_byteLength.call(buf);
1009+
const byteLen = FunctionPrototypeCall(TypedArrayProto_byteLength, buf);
10091010
const fillLength = end - offset;
10101011
if (offset > end || fillLength + offset > byteLen)
10111012
throw new ERR_BUFFER_OUT_OF_BOUNDS();
10121013

1013-
TypedArrayFill.call(buf, value, offset, end);
1014+
FunctionPrototypeCall(TypedArrayFill, buf, value, offset, end);
10141015
} else {
10151016
const res = bindingFill(buf, value, offset, end, encoding);
10161017
if (res < 0) {

0 commit comments

Comments
 (0)