Skip to content

Commit 5561595

Browse files
committed
lib: refactor prototype and Function.call.bind usage
1 parent e6b823d commit 5561595

File tree

10 files changed

+60
-27
lines changed

10 files changed

+60
-27
lines changed

lib/.eslintrc.yaml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,7 @@ rules:
55
node-core/no-let-in-for-declaration: error
66
node-core/lowercase-name-for-primitive: error
77
node-core/non-ascii-character: error
8+
9+
# Possible Errors
10+
# http://eslint.org/docs/rules/#possible-errors
11+
no-prototype-builtins: error

lib/assert.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ const { parseExpressionAt } = require('internal/deps/acorn/dist/acorn');
3131
const { inspect } = require('util');
3232
const { EOL } = require('os');
3333
const nativeModule = require('native_module');
34+
const { ObjectIsPrototypeOf } = require('primordials');
3435

3536
// Escape control characters but not \n and \t to keep the line breaks and
3637
// indentation intact.
@@ -400,7 +401,7 @@ function expectedException(actual, expected, msg) {
400401
if (expected.prototype !== undefined && actual instanceof expected) {
401402
return true;
402403
}
403-
if (Error.isPrototypeOf(expected)) {
404+
if (ObjectIsPrototypeOf(Error, expected)) {
404405
return false;
405406
}
406407
return expected.call({}, actual) === true;

lib/internal/async_hooks.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
'use strict';
22

3+
const { ObjectHasOwnProperty } = require('primordials');
34
const errors = require('internal/errors');
45
const async_wrap = process.binding('async_wrap');
6+
57
/* async_hook_fields is a Uint32Array wrapping the uint32_t array of
68
* Environment::AsyncHooks::fields_[]. Each index tracks the number of active
79
* hooks for each type.
@@ -252,7 +254,7 @@ function newAsyncId() {
252254
}
253255

254256
function getOrSetAsyncId(object) {
255-
if (object.hasOwnProperty(async_id_symbol)) {
257+
if (ObjectHasOwnProperty(object, async_id_symbol)) {
256258
return object[async_id_symbol];
257259
}
258260

lib/internal/bootstrap_node.js

Lines changed: 40 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
(function(process) {
1111
let internalBinding;
1212
const exceptionHandlerState = { captureFn: null };
13+
const primordials = makePrimordials();
1314

1415
function startup() {
1516
const EventEmitter = NativeModule.require('events');
@@ -411,7 +412,7 @@
411412
addCommandLineAPI('require', makeRequireFunction(consoleAPIModule));
412413
const config = {};
413414
for (const key of Object.keys(wrappedConsole)) {
414-
if (!originalConsole.hasOwnProperty(key))
415+
if (!primordials.ObjectHasOwnProperty(originalConsole, key))
415416
continue;
416417
// If global console has the same method as inspector console,
417418
// then wrap these two methods into one. Native wrapper will preserve
@@ -422,7 +423,7 @@
422423
config);
423424
}
424425
for (const key of Object.keys(originalConsole)) {
425-
if (wrappedConsole.hasOwnProperty(key))
426+
if (primordials.ObjectHasOwnProperty(wrappedConsole, key))
426427
continue;
427428
wrappedConsole[key] = originalConsole[key];
428429
}
@@ -601,6 +602,8 @@
601602
NativeModule.require = function(id) {
602603
if (id === 'native_module') {
603604
return NativeModule;
605+
} else if (id === 'primordials') {
606+
return primordials;
604607
}
605608

606609
const cached = NativeModule.getCached(id);
@@ -643,7 +646,7 @@
643646
};
644647

645648
NativeModule.exists = function(id) {
646-
return NativeModule._source.hasOwnProperty(id);
649+
return primordials.ObjectHasOwnProperty(NativeModule._source, id);
647650
};
648651

649652
if (config.exposeInternals) {
@@ -704,4 +707,38 @@
704707
};
705708

706709
startup();
710+
711+
function makePrimordials() {
712+
const ReflectApply = Reflect.apply;
713+
714+
// This function is borrowed from the function with the same name on V8
715+
// Extras' `utils` object. V8 implements Reflect.apply very efficiently in
716+
// conjunction with the spread syntax, such that no additional special case
717+
// is needed for function calls w/o arguments.
718+
// Refs: https://git.io/vAOyO
719+
function uncurryThis(func) {
720+
return (thisArg, ...args) => ReflectApply(func, thisArg, args);
721+
}
722+
723+
return {
724+
uncurryThis,
725+
726+
ArrayJoin: uncurryThis(Array.prototype.join),
727+
ArrayMap: uncurryThis(Array.prototype.map),
728+
729+
FunctionBind: uncurryThis(Function.prototype.bind),
730+
731+
JSONParse: JSON.parse,
732+
733+
ObjectIsPrototypeOf: uncurryThis(Object.prototype.isPrototypeOf),
734+
ObjectHasOwnProperty: uncurryThis(Object.prototype.hasOwnProperty),
735+
ObjectKeys: Object.keys,
736+
737+
ReflectApply,
738+
ReflectHas: Reflect.has,
739+
740+
StringReplace: uncurryThis(String.prototype.replace),
741+
StringStartsWith: uncurryThis(String.prototype.startsWith),
742+
};
743+
}
707744
});

lib/internal/crypto/sig.js

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ const {
1616
const { isArrayBufferView } = require('internal/util/types');
1717
const { Writable } = require('stream');
1818
const { inherits } = require('util');
19+
const { ObjectHasOwnProperty } = require('primordials');
1920

2021
function Sign(algorithm, options) {
2122
if (!(this instanceof Sign))
@@ -55,7 +56,7 @@ Sign.prototype.sign = function sign(options, encoding) {
5556

5657
// Options specific to RSA
5758
var rsaPadding = RSA_PKCS1_PADDING;
58-
if (options.hasOwnProperty('padding')) {
59+
if (ObjectHasOwnProperty(options, 'padding')) {
5960
if (options.padding === options.padding >> 0) {
6061
rsaPadding = options.padding;
6162
} else {
@@ -66,7 +67,7 @@ Sign.prototype.sign = function sign(options, encoding) {
6667
}
6768

6869
var pssSaltLength = RSA_PSS_SALTLEN_AUTO;
69-
if (options.hasOwnProperty('saltLength')) {
70+
if (ObjectHasOwnProperty(options, 'saltLength')) {
7071
if (options.saltLength === options.saltLength >> 0) {
7172
pssSaltLength = options.saltLength;
7273
} else {
@@ -114,7 +115,7 @@ Verify.prototype.verify = function verify(options, signature, sigEncoding) {
114115

115116
// Options specific to RSA
116117
var rsaPadding = RSA_PKCS1_PADDING;
117-
if (options.hasOwnProperty('padding')) {
118+
if (ObjectHasOwnProperty(options, 'padding')) {
118119
if (options.padding === options.padding >> 0) {
119120
rsaPadding = options.padding;
120121
} else {
@@ -125,7 +126,7 @@ Verify.prototype.verify = function verify(options, signature, sigEncoding) {
125126
}
126127

127128
var pssSaltLength = RSA_PSS_SALTLEN_AUTO;
128-
if (options.hasOwnProperty('saltLength')) {
129+
if (ObjectHasOwnProperty(options, 'saltLength')) {
129130
if (options.saltLength === options.saltLength >> 0) {
130131
pssSaltLength = options.saltLength;
131132
} else {

lib/internal/loader/CreateDynamicModule.js

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,7 @@
22

33
const { ModuleWrap } = internalBinding('module_wrap');
44
const debug = require('util').debuglog('esm');
5-
const ArrayJoin = Function.call.bind(Array.prototype.join);
6-
const ArrayMap = Function.call.bind(Array.prototype.map);
5+
const { ArrayJoin, ArrayMap } = require('primordials');
76

87
const createDynamicModule = (exports, url = '', evaluate) => {
98
debug(

lib/internal/loader/DefaultResolve.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ const { realpathSync } = require('fs');
99
const preserveSymlinks = !!process.binding('config').preserveSymlinks;
1010
const errors = require('internal/errors');
1111
const { resolve: moduleWrapResolve } = internalBinding('module_wrap');
12-
const StringStartsWith = Function.call.bind(String.prototype.startsWith);
12+
const { StringStartsWith } = require('primordials');
1313
const { getURLFromFilePath, getPathFromURL } = require('internal/url');
1414

1515
const realpathCache = new Map();

lib/internal/loader/Loader.js

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,7 @@ const ModuleJob = require('internal/loader/ModuleJob');
66
const defaultResolve = require('internal/loader/DefaultResolve');
77
const createDynamicModule = require('internal/loader/CreateDynamicModule');
88
const translators = require('internal/loader/Translators');
9-
10-
const FunctionBind = Function.call.bind(Function.prototype.bind);
9+
const { FunctionBind } = require('primordials');
1110

1211
const debug = require('util').debuglog('esm');
1312

lib/internal/loader/Translators.js

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,7 @@ const { URL } = require('url');
1313
const debug = require('util').debuglog('esm');
1414
const readFileAsync = require('util').promisify(fs.readFile);
1515
const readFileSync = fs.readFileSync;
16-
const StringReplace = Function.call.bind(String.prototype.replace);
17-
const JsonParse = JSON.parse;
16+
const { StringReplace, JSONParse } = require('primordials');
1817

1918
const translators = new SafeMap();
2019
module.exports = translators;
@@ -82,7 +81,7 @@ translators.set('json', async (url) => {
8281
const pathname = internalURLModule.getPathFromURL(new URL(url));
8382
const content = readFileSync(pathname, 'utf8');
8483
try {
85-
const exports = JsonParse(internalCJSModule.stripBOM(content));
84+
const exports = JSONParse(internalCJSModule.stripBOM(content));
8685
reflect.exports.default.set(exports);
8786
} catch (err) {
8887
err.message = pathname + ': ' + err.message;

lib/internal/util/types.js

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,6 @@
11
'use strict';
22

3-
const ReflectApply = Reflect.apply;
4-
5-
// This function is borrowed from the function with the same name on V8 Extras'
6-
// `utils` object. V8 implements Reflect.apply very efficiently in conjunction
7-
// with the spread syntax, such that no additional special case is needed for
8-
// function calls w/o arguments.
9-
// Refs: https://github.com/v8/v8/blob/d6ead37d265d7215cf9c5f768f279e21bd170212/src/js/prologue.js#L152-L156
10-
function uncurryThis(func) {
11-
return (thisArg, ...args) => ReflectApply(func, thisArg, args);
12-
}
3+
const { uncurryThis } = require('primordials');
134

145
const TypedArrayPrototype = Object.getPrototypeOf(Uint8Array.prototype);
156

0 commit comments

Comments
 (0)