summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/_http_outgoing.js6
-rw-r--r--lib/internal/async_hooks.js6
-rw-r--r--lib/internal/bootstrap/loaders.js7
-rw-r--r--lib/internal/bootstrap/primordials.js33
-rw-r--r--lib/internal/cli_table.js6
-rw-r--r--lib/internal/console/constructor.js6
-rw-r--r--lib/internal/error-serdes.js37
-rw-r--r--lib/internal/modules/esm/create_dynamic_module.js8
-rw-r--r--lib/internal/modules/esm/loader.js12
-rw-r--r--lib/internal/modules/esm/translators.js16
-rw-r--r--lib/internal/policy/manifest.js25
-rw-r--r--lib/internal/policy/sri.js17
-rw-r--r--lib/internal/process/per_thread.js24
-rw-r--r--lib/internal/process/task_queues.js6
-rw-r--r--lib/internal/util.js12
-rw-r--r--lib/internal/util/comparisons.js72
-rw-r--r--lib/internal/util/inspect.js71
-rw-r--r--lib/internal/util/types.js2
-rw-r--r--lib/util.js15
-rw-r--r--lib/vm.js14
20 files changed, 206 insertions, 189 deletions
diff --git a/lib/_http_outgoing.js b/lib/_http_outgoing.js
index 34b064a6a3..2c2346d211 100644
--- a/lib/_http_outgoing.js
+++ b/lib/_http_outgoing.js
@@ -21,6 +21,8 @@
'use strict';
+const { ObjectPrototype } = primordials;
+
const assert = require('internal/assert');
const Stream = require('stream');
const internalUtil = require('internal/util');
@@ -53,8 +55,6 @@ const { CRLF, debug } = common;
const kIsCorked = Symbol('isCorked');
-const hasOwnProperty = Function.call.bind(Object.prototype.hasOwnProperty);
-
const RE_CONN_CLOSE = /(?:^|\W)close(?:$|\W)/i;
const RE_TE_CHUNKED = common.chunkExpression;
@@ -310,7 +310,7 @@ function _storeHeader(firstLine, headers) {
}
} else {
for (const key in headers) {
- if (hasOwnProperty(headers, key)) {
+ if (ObjectPrototype.hasOwnProperty(headers, key)) {
processHeader(this, state, key, headers[key], true);
}
}
diff --git a/lib/internal/async_hooks.js b/lib/internal/async_hooks.js
index a1f3c07def..9d30ad133d 100644
--- a/lib/internal/async_hooks.js
+++ b/lib/internal/async_hooks.js
@@ -1,6 +1,6 @@
'use strict';
-const { Reflect } = primordials;
+const { FunctionPrototype, Reflect } = primordials;
const {
ERR_ASYNC_TYPE,
@@ -77,8 +77,6 @@ const { kInit, kBefore, kAfter, kDestroy, kTotals, kPromiseResolve,
kCheck, kExecutionAsyncId, kAsyncIdCounter, kTriggerAsyncId,
kDefaultTriggerAsyncId, kStackLength } = async_wrap.constants;
-const FunctionBind = Function.call.bind(Function.prototype.bind);
-
// Used in AsyncHook and AsyncResource.
const async_id_symbol = Symbol('asyncId');
const trigger_async_id_symbol = Symbol('triggerAsyncId');
@@ -181,7 +179,7 @@ function emitHook(symbol, asyncId) {
}
function emitHookFactory(symbol, name) {
- const fn = FunctionBind(emitHook, undefined, symbol);
+ const fn = FunctionPrototype.bind(emitHook, undefined, symbol);
// Set the name property of the function as it looks good in the stack trace.
Object.defineProperty(fn, 'name', {
diff --git a/lib/internal/bootstrap/loaders.js b/lib/internal/bootstrap/loaders.js
index ffcc931334..e4d1a09587 100644
--- a/lib/internal/bootstrap/loaders.js
+++ b/lib/internal/bootstrap/loaders.js
@@ -225,7 +225,7 @@ NativeModule.prototype.compileForPublicLoader = function(needToProxify) {
};
const getOwn = (target, property, receiver) => {
- return Reflect.apply(ObjectPrototype.hasOwnProperty, target, [property]) ?
+ return ObjectPrototype.hasOwnProperty(target, property) ?
Reflect.get(target, property, receiver) :
undefined;
};
@@ -239,8 +239,7 @@ NativeModule.prototype.proxifyExports = function() {
const update = (property, value) => {
if (this.reflect !== undefined &&
- Reflect.apply(ObjectPrototype.hasOwnProperty,
- this.reflect.exports, [property]))
+ ObjectPrototype.hasOwnProperty(this.reflect.exports, property))
this.reflect.exports[property].set(value);
};
@@ -254,7 +253,7 @@ NativeModule.prototype.proxifyExports = function() {
!Reflect.has(handler, 'get')) {
handler.get = (target, prop, receiver) => {
const value = Reflect.get(target, prop, receiver);
- if (Reflect.apply(ObjectPrototype.hasOwnProperty, target, [prop]))
+ if (ObjectPrototype.hasOwnProperty(target, prop))
update(prop, value);
return value;
};
diff --git a/lib/internal/bootstrap/primordials.js b/lib/internal/bootstrap/primordials.js
index e1fef7f886..8d2150b7b7 100644
--- a/lib/internal/bootstrap/primordials.js
+++ b/lib/internal/bootstrap/primordials.js
@@ -12,6 +12,19 @@
// `primordials.Object` where `primordials` is a lexical variable passed
// by the native module compiler.
+const ReflectApply = Reflect.apply;
+
+// This function is borrowed from the function with the same name on V8 Extras'
+// `utils` object. V8 implements Reflect.apply very efficiently in conjunction
+// with the spread syntax, such that no additional special case is needed for
+// function calls w/o arguments.
+// Refs: https://github.com/v8/v8/blob/d6ead37d265d7215cf9c5f768f279e21bd170212/src/js/prologue.js#L152-L156
+function uncurryThis(func) {
+ return (thisArg, ...args) => ReflectApply(func, thisArg, args);
+}
+
+primordials.uncurryThis = uncurryThis;
+
function copyProps(src, dest) {
for (const key of Reflect.ownKeys(src)) {
if (!Reflect.getOwnPropertyDescriptor(dest, key)) {
@@ -23,6 +36,18 @@ function copyProps(src, dest) {
}
}
+function copyPrototype(src, dest) {
+ for (const key of Reflect.ownKeys(src)) {
+ if (!Reflect.getOwnPropertyDescriptor(dest, key)) {
+ const desc = Reflect.getOwnPropertyDescriptor(src, key);
+ if (typeof desc.value === 'function') {
+ desc.value = uncurryThis(desc.value);
+ }
+ Reflect.defineProperty(dest, key, desc);
+ }
+ }
+}
+
function makeSafe(unsafe, safe) {
copyProps(unsafe.prototype, safe.prototype);
copyProps(unsafe, safe);
@@ -64,17 +89,23 @@ primordials.SafePromise = makeSafe(
// Create copies of intrinsic objects
[
'Array',
+ 'BigInt',
+ 'Boolean',
'Date',
+ 'Error',
'Function',
+ 'Map',
+ 'Number',
'Object',
'RegExp',
+ 'Set',
'String',
'Symbol',
].forEach((name) => {
const target = primordials[name] = Object.create(null);
copyProps(global[name], target);
const proto = primordials[name + 'Prototype'] = Object.create(null);
- copyProps(global[name].prototype, proto);
+ copyPrototype(global[name].prototype, proto);
});
Object.setPrototypeOf(primordials, null);
diff --git a/lib/internal/cli_table.js b/lib/internal/cli_table.js
index b2d2779e5f..6e9a6bdbc9 100644
--- a/lib/internal/cli_table.js
+++ b/lib/internal/cli_table.js
@@ -1,10 +1,9 @@
'use strict';
-const { Math } = primordials;
+const { Math, ObjectPrototype } = primordials;
const { Buffer } = require('buffer');
const { removeColors } = require('internal/util');
-const HasOwnProperty = Function.call.bind(Object.prototype.hasOwnProperty);
// The use of Unicode characters below is the only non-comment use of non-ASCII
// Unicode characters in Node.js built-in modules. If they are ever removed or
@@ -61,7 +60,8 @@ const table = (head, columns) => {
for (var j = 0; j < longestColumn; j++) {
if (rows[j] === undefined)
rows[j] = [];
- const value = rows[j][i] = HasOwnProperty(column, j) ? column[j] : '';
+ const value = rows[j][i] =
+ ObjectPrototype.hasOwnProperty(column, j) ? column[j] : '';
const width = columnWidths[i] || 0;
const counted = countSymbols(value);
columnWidths[i] = Math.max(width, counted);
diff --git a/lib/internal/console/constructor.js b/lib/internal/console/constructor.js
index 9e75dce3af..46fd1e9c62 100644
--- a/lib/internal/console/constructor.js
+++ b/lib/internal/console/constructor.js
@@ -3,7 +3,7 @@
// The Console constructor is not actually used to construct the global
// console. It's exported for backwards compatibility.
-const { Reflect } = primordials;
+const { ObjectPrototype, Reflect } = primordials;
const { trace } = internalBinding('trace_events');
const {
@@ -36,7 +36,6 @@ const {
keys: ObjectKeys,
values: ObjectValues,
} = Object;
-const hasOwnProperty = Function.call.bind(Object.prototype.hasOwnProperty);
const {
isArray: ArrayIsArray,
@@ -493,7 +492,8 @@ const consoleMethods = {
for (const key of keys) {
if (map[key] === undefined)
map[key] = [];
- if ((primitive && properties) || !hasOwnProperty(item, key))
+ if ((primitive && properties) ||
+ !ObjectPrototype.hasOwnProperty(item, key))
map[key][i] = '';
else
map[key][i] = _inspect(item[key]);
diff --git a/lib/internal/error-serdes.js b/lib/internal/error-serdes.js
index b907842c38..8647e3b78d 100644
--- a/lib/internal/error-serdes.js
+++ b/lib/internal/error-serdes.js
@@ -2,27 +2,17 @@
const Buffer = require('buffer').Buffer;
const {
- SafeSet,
+ ArrayPrototype,
+ FunctionPrototype,
Object,
ObjectPrototype,
- FunctionPrototype,
- ArrayPrototype
+ SafeSet,
} = primordials;
const kSerializedError = 0;
const kSerializedObject = 1;
const kInspectedError = 2;
-const GetPrototypeOf = Object.getPrototypeOf;
-const GetOwnPropertyDescriptor = Object.getOwnPropertyDescriptor;
-const GetOwnPropertyNames = Object.getOwnPropertyNames;
-const DefineProperty = Object.defineProperty;
-const Assign = Object.assign;
-const ObjectPrototypeToString =
- FunctionPrototype.call.bind(ObjectPrototype.toString);
-const ForEach = FunctionPrototype.call.bind(ArrayPrototype.forEach);
-const Call = FunctionPrototype.call.bind(FunctionPrototype.call);
-
const errors = {
Error, TypeError, RangeError, URIError, SyntaxError, ReferenceError, EvalError
};
@@ -32,17 +22,18 @@ function TryGetAllProperties(object, target = object) {
const all = Object.create(null);
if (object === null)
return all;
- Assign(all, TryGetAllProperties(GetPrototypeOf(object), target));
- const keys = GetOwnPropertyNames(object);
- ForEach(keys, (key) => {
+ Object.assign(all,
+ TryGetAllProperties(Object.getPrototypeOf(object), target));
+ const keys = Object.getOwnPropertyNames(object);
+ ArrayPrototype.forEach(keys, (key) => {
let descriptor;
try {
- descriptor = GetOwnPropertyDescriptor(object, key);
+ descriptor = Object.getOwnPropertyDescriptor(object, key);
} catch { return; }
const getter = descriptor.get;
if (getter && key !== '__proto__') {
try {
- descriptor.value = Call(getter, target);
+ descriptor.value = FunctionPrototype.call(getter, target);
} catch {}
}
if ('value' in descriptor && typeof descriptor.value !== 'function') {
@@ -59,10 +50,10 @@ function GetConstructors(object) {
for (var current = object;
current !== null;
- current = GetPrototypeOf(current)) {
- const desc = GetOwnPropertyDescriptor(current, 'constructor');
+ current = Object.getPrototypeOf(current)) {
+ const desc = Object.getOwnPropertyDescriptor(current, 'constructor');
if (desc && desc.value) {
- DefineProperty(constructors, constructors.length, {
+ Object.defineProperty(constructors, constructors.length, {
value: desc.value, enumerable: true
});
}
@@ -72,7 +63,7 @@ function GetConstructors(object) {
}
function GetName(object) {
- const desc = GetOwnPropertyDescriptor(object, 'name');
+ const desc = Object.getOwnPropertyDescriptor(object, 'name');
return desc && desc.value;
}
@@ -89,7 +80,7 @@ function serializeError(error) {
if (!serialize) serialize = require('v8').serialize;
try {
if (typeof error === 'object' &&
- ObjectPrototypeToString(error) === '[object Error]') {
+ ObjectPrototype.toString(error) === '[object Error]') {
const constructors = GetConstructors(error);
for (var i = 0; i < constructors.length; i++) {
const name = GetName(constructors[i]);
diff --git a/lib/internal/modules/esm/create_dynamic_module.js b/lib/internal/modules/esm/create_dynamic_module.js
index d4356b4b67..d3e74263c4 100644
--- a/lib/internal/modules/esm/create_dynamic_module.js
+++ b/lib/internal/modules/esm/create_dynamic_module.js
@@ -1,16 +1,16 @@
'use strict';
+const { ArrayPrototype } = primordials;
+
const { ModuleWrap, callbackMap } = internalBinding('module_wrap');
const debug = require('util').debuglog('esm');
-const ArrayJoin = Function.call.bind(Array.prototype.join);
-const ArrayMap = Function.call.bind(Array.prototype.map);
const createDynamicModule = (exports, url = '', evaluate) => {
debug('creating ESM facade for %s with exports: %j', url, exports);
- const names = ArrayMap(exports, (name) => `${name}`);
+ const names = ArrayPrototype.map(exports, (name) => `${name}`);
const source = `
-${ArrayJoin(ArrayMap(names, (name) =>
+${ArrayPrototype.join(ArrayPrototype.map(names, (name) =>
`let $${name};
export { $${name} as ${name} };
import.meta.exports.${name} = {
diff --git a/lib/internal/modules/esm/loader.js b/lib/internal/modules/esm/loader.js
index 88f03119fc..f752550d12 100644
--- a/lib/internal/modules/esm/loader.js
+++ b/lib/internal/modules/esm/loader.js
@@ -1,5 +1,7 @@
'use strict';
+const { FunctionPrototype } = primordials;
+
const {
ERR_INVALID_RETURN_PROPERTY,
ERR_INVALID_RETURN_PROPERTY_VALUE,
@@ -18,8 +20,6 @@ const createDynamicModule = require(
const { translators } = require('internal/modules/esm/translators');
const { ModuleWrap } = internalBinding('module_wrap');
-const FunctionBind = Function.call.bind(Function.prototype.bind);
-
const debug = require('internal/util/debuglog').debuglog('esm');
const {
@@ -132,9 +132,11 @@ class Loader {
hook({ resolve, dynamicInstantiate }) {
// Use .bind() to avoid giving access to the Loader instance when called.
if (resolve !== undefined)
- this._resolve = FunctionBind(resolve, null);
- if (dynamicInstantiate !== undefined)
- this._dynamicInstantiate = FunctionBind(dynamicInstantiate, null);
+ this._resolve = FunctionPrototype.bind(resolve, null);
+ if (dynamicInstantiate !== undefined) {
+ this._dynamicInstantiate =
+ FunctionPrototype.bind(dynamicInstantiate, null);
+ }
}
async getModuleJob(specifier, parentURL) {
diff --git a/lib/internal/modules/esm/translators.js b/lib/internal/modules/esm/translators.js
index 4b2db024c5..8494f5e307 100644
--- a/lib/internal/modules/esm/translators.js
+++ b/lib/internal/modules/esm/translators.js
@@ -1,5 +1,11 @@
'use strict';
+const {
+ SafeMap,
+ StringPrototype,
+ JSON
+} = primordials;
+
const { NativeModule } = require('internal/bootstrap/loaders');
const { ModuleWrap, callbackMap } = internalBinding('module_wrap');
const {
@@ -11,10 +17,6 @@ const internalURLModule = require('internal/url');
const createDynamicModule = require(
'internal/modules/esm/create_dynamic_module');
const fs = require('fs');
-const {
- SafeMap,
- JSON
-} = primordials;
const { fileURLToPath, URL } = require('url');
const { debuglog } = require('internal/util/debuglog');
const { promisify } = require('internal/util');
@@ -23,7 +25,6 @@ const {
ERR_UNKNOWN_BUILTIN_MODULE
} = require('internal/errors').codes;
const readFileAsync = promisify(fs.readFile);
-const StringReplace = Function.call.bind(String.prototype.replace);
const JsonParse = JSON.parse;
const debug = debuglog('esm');
@@ -67,7 +68,8 @@ translators.set('commonjs', async function commonjsStrategy(url, isMain) {
return cached;
}
const module = CJSModule._cache[
- isWindows ? StringReplace(pathname, winSepRegEx, '\\') : pathname];
+ isWindows ? StringPrototype.replace(pathname, winSepRegEx, '\\') : pathname
+ ];
if (module && module.loaded) {
const exports = module.exports;
return createDynamicModule(['default'], url, (reflect) => {
@@ -110,7 +112,7 @@ translators.set('json', async function jsonStrategy(url) {
debug(`Loading JSONModule ${url}`);
const pathname = fileURLToPath(url);
const modulePath = isWindows ?
- StringReplace(pathname, winSepRegEx, '\\') : pathname;
+ StringPrototype.replace(pathname, winSepRegEx, '\\') : pathname;
let module = CJSModule._cache[modulePath];
if (module && module.loaded) {
const exports = module.exports;
diff --git a/lib/internal/policy/manifest.js b/lib/internal/policy/manifest.js
index 1715bcba56..0714b2294b 100644
--- a/lib/internal/policy/manifest.js
+++ b/lib/internal/policy/manifest.js
@@ -1,4 +1,12 @@
'use strict';
+
+const {
+ SafeWeakMap,
+ Object,
+ RegExpPrototype,
+ uncurryThis
+} = primordials;
+
const {
ERR_MANIFEST_ASSERT_INTEGRITY,
ERR_MANIFEST_INTEGRITY_MISMATCH,
@@ -6,21 +14,14 @@ const {
} = require('internal/errors').codes;
const debug = require('internal/util/debuglog').debuglog('policy');
const SRI = require('internal/policy/sri');
-const {
- SafeWeakMap,
- FunctionPrototype,
- Object,
- RegExpPrototype
-} = primordials;
const crypto = require('crypto');
const { Buffer } = require('buffer');
const { URL } = require('url');
const { createHash, timingSafeEqual } = crypto;
-const HashUpdate = FunctionPrototype.call.bind(crypto.Hash.prototype.update);
-const HashDigest = FunctionPrototype.call.bind(crypto.Hash.prototype.digest);
-const BufferEquals = FunctionPrototype.call.bind(Buffer.prototype.equals);
-const BufferToString = FunctionPrototype.call.bind(Buffer.prototype.toString);
-const RegExpTest = FunctionPrototype.call.bind(RegExpPrototype.test);
+const HashUpdate = uncurryThis(crypto.Hash.prototype.update);
+const HashDigest = uncurryThis(crypto.Hash.prototype.digest);
+const BufferEquals = uncurryThis(Buffer.prototype.equals);
+const BufferToString = uncurryThis(Buffer.prototype.toString);
const { entries } = Object;
const kIntegrities = new SafeWeakMap();
const kReactions = new SafeWeakMap();
@@ -76,7 +77,7 @@ class Manifest {
const integrity = manifestEntries[i][1].integrity;
if (integrity != null) {
debug(`Manifest contains integrity for url ${url}`);
- if (RegExpTest(kRelativeURLStringPattern, url)) {
+ if (RegExpPrototype.test(kRelativeURLStringPattern, url)) {
url = new URL(url, manifestURL).href;
}
diff --git a/lib/internal/policy/sri.js b/lib/internal/policy/sri.js
index 1cdec8d739..55c3c0c507 100644
--- a/lib/internal/policy/sri.js
+++ b/lib/internal/policy/sri.js
@@ -1,6 +1,12 @@
'use strict';
// Value of https://w3c.github.io/webappsec-subresource-integrity/#the-integrity-attribute
+const {
+ Object,
+ RegExpPrototype,
+ StringPrototype
+} = primordials;
+
// Returns [{algorithm, value (in base64 string), options,}]
const {
ERR_SRI_PARSE
@@ -19,19 +25,14 @@ Object.seal(kSRIPattern);
const kAllWSP = new RegExp(`^${kWSP}*$`);
Object.seal(kAllWSP);
-const RegExpExec = Function.call.bind(RegExp.prototype.exec);
-const RegExpTest = Function.call.bind(RegExp.prototype.test);
-const StringSlice = Function.call.bind(String.prototype.slice);
-
const BufferFrom = require('buffer').Buffer.from;
-const { defineProperty } = Object;
const parse = (str) => {
kSRIPattern.lastIndex = 0;
let prevIndex = 0;
let match;
const entries = [];
- while (match = RegExpExec(kSRIPattern, str)) {
+ while (match = RegExpPrototype.exec(kSRIPattern, str)) {
if (match.index !== prevIndex) {
throw new ERR_SRI_PARSE(str, prevIndex);
}
@@ -40,7 +41,7 @@ const parse = (str) => {
}
// Avoid setters being fired
- defineProperty(entries, entries.length, {
+ Object.defineProperty(entries, entries.length, {
enumerable: true,
configurable: true,
value: freeze({
@@ -54,7 +55,7 @@ const parse = (str) => {
}
if (prevIndex !== str.length) {
- if (!RegExpTest(kAllWSP, StringSlice(str, prevIndex))) {
+ if (!RegExpPrototype.test(kAllWSP, StringPrototype.slice(str, prevIndex))) {
throw new ERR_SRI_PARSE(str, prevIndex);
}
}
diff --git a/lib/internal/process/per_thread.js b/lib/internal/process/per_thread.js
index aa2bcce16c..ef9012535f 100644
--- a/lib/internal/process/per_thread.js
+++ b/lib/internal/process/per_thread.js
@@ -5,6 +5,12 @@
// thread and the worker threads.
const {
+ RegExpPrototype,
+ SetPrototype,
+ StringPrototype
+} = primordials;
+
+const {
errnoException,
codes: {
ERR_ASSERTION,
@@ -199,11 +205,6 @@ const replaceUnderscoresRegex = /_/g;
const leadingDashesRegex = /^--?/;
const trailingValuesRegex = /=.*$/;
-// Save references so user code does not interfere
-const replace = Function.call.bind(String.prototype.replace);
-const has = Function.call.bind(Set.prototype.has);
-const test = Function.call.bind(RegExp.prototype.test);
-
// This builds the initial process.allowedNodeEnvironmentFlags
// from data in the config binding.
function buildAllowedFlags() {
@@ -243,7 +244,8 @@ function buildAllowedFlags() {
}
}
- const trimLeadingDashes = (flag) => replace(flag, leadingDashesRegex, '');
+ const trimLeadingDashes =
+ (flag) => StringPrototype.replace(flag, leadingDashesRegex, '');
// Save these for comparison against flags provided to
// process.allowedNodeEnvironmentFlags.has() which lack leading dashes.
@@ -281,12 +283,12 @@ function buildAllowedFlags() {
// on a dummy option set and see whether it rejects the argument or
// not.
if (typeof key === 'string') {
- key = replace(key, replaceUnderscoresRegex, '-');
- if (test(leadingDashesRegex, key)) {
- key = replace(key, trailingValuesRegex, '');
- return has(this, key);
+ key = StringPrototype.replace(key, replaceUnderscoresRegex, '-');
+ if (RegExpPrototype.test(leadingDashesRegex, key)) {
+ key = StringPrototype.replace(key, trailingValuesRegex, '');
+ return SetPrototype.has(this, key);
}
- return has(nodeFlags, key);
+ return SetPrototype.has(nodeFlags, key);
}
return false;
}
diff --git a/lib/internal/process/task_queues.js b/lib/internal/process/task_queues.js
index 5f5ca5a008..bc65d25307 100644
--- a/lib/internal/process/task_queues.js
+++ b/lib/internal/process/task_queues.js
@@ -1,6 +1,6 @@
'use strict';
-const { Reflect } = primordials;
+const { FunctionPrototype, Reflect } = primordials;
const {
// For easy access to the nextTick state in the C++ land,
@@ -37,8 +37,6 @@ const {
} = require('internal/errors').codes;
const FixedQueue = require('internal/fixed_queue');
-const FunctionBind = Function.call.bind(Function.prototype.bind);
-
// *Must* match Environment::TickInfo::Fields in src/env.h.
const kHasTickScheduled = 0;
@@ -176,7 +174,7 @@ function queueMicrotask(callback) {
const asyncResource = createMicrotaskResource();
asyncResource.callback = callback;
- enqueueMicrotask(FunctionBind(runMicrotask, asyncResource));
+ enqueueMicrotask(FunctionPrototype.bind(runMicrotask, asyncResource));
}
module.exports = {
diff --git a/lib/internal/util.js b/lib/internal/util.js
index ba332f7e85..e7dca9a23c 100644
--- a/lib/internal/util.js
+++ b/lib/internal/util.js
@@ -387,17 +387,6 @@ function once(callback) {
};
}
-const ReflectApply = Reflect.apply;
-
-// This function is borrowed from the function with the same name on V8 Extras'
-// `utils` object. V8 implements Reflect.apply very efficiently in conjunction
-// with the spread syntax, such that no additional special case is needed for
-// function calls w/o arguments.
-// Refs: https://github.com/v8/v8/blob/d6ead37d265d7215cf9c5f768f279e21bd170212/src/js/prologue.js#L152-L156
-function uncurryThis(func) {
- return (thisArg, ...args) => ReflectApply(func, thisArg, args);
-}
-
module.exports = {
assertCrypto,
cachedResult,
@@ -418,7 +407,6 @@ module.exports = {
promisify,
spliceOne,
removeColors,
- uncurryThis,
// Symbol used to customize promisify conversion
customPromisifyArgs: kCustomPromisifyArgsSymbol,
diff --git a/lib/internal/util/comparisons.js b/lib/internal/util/comparisons.js
index 18fb790507..2b0970a9ea 100644
--- a/lib/internal/util/comparisons.js
+++ b/lib/internal/util/comparisons.js
@@ -1,5 +1,21 @@
'use strict';
+const {
+ BigIntPrototype,
+ BooleanPrototype,
+ DatePrototype,
+ Number,
+ NumberPrototype,
+ Object,
+ ObjectPrototype: {
+ hasOwnProperty,
+ propertyIsEnumerable,
+ toString: objectToString
+ },
+ StringPrototype,
+ SymbolPrototype
+} = primordials;
+
const { compare } = internalBinding('buffer');
const {
isAnyArrayBuffer,
@@ -24,7 +40,6 @@ const {
ONLY_ENUMERABLE
}
} = internalBinding('util');
-const { uncurryThis } = require('internal/util');
const kStrict = true;
const kLoose = false;
@@ -34,23 +49,6 @@ const kIsArray = 1;
const kIsSet = 2;
const kIsMap = 3;
-const objectToString = uncurryThis(Object.prototype.toString);
-const hasOwnProperty = uncurryThis(Object.prototype.hasOwnProperty);
-const propertyIsEnumerable = uncurryThis(Object.prototype.propertyIsEnumerable);
-const dateGetTime = uncurryThis(Date.prototype.getTime);
-
-const bigIntValueOf = uncurryThis(BigInt.prototype.valueOf);
-const booleanValueOf = uncurryThis(Boolean.prototype.valueOf);
-const numberValueOf = uncurryThis(Number.prototype.valueOf);
-const symbolValueOf = uncurryThis(Symbol.prototype.valueOf);
-const stringValueOf = uncurryThis(String.prototype.valueOf);
-
-const objectKeys = Object.keys;
-const getPrototypeOf = Object.getPrototypeOf;
-const getOwnPropertySymbols = Object.getOwnPropertySymbols;
-const objectIs = Object.is;
-const numberIsNaN = Number.isNaN;
-
// Check if they have the same source and flags
function areSimilarRegExps(a, b) {
return a.source === b.source && a.flags === b.flags;
@@ -84,19 +82,23 @@ function areEqualArrayBuffers(buf1, buf2) {
function isEqualBoxedPrimitive(val1, val2) {
if (isNumberObject(val1)) {
return isNumberObject(val2) &&
- objectIs(numberValueOf(val1), numberValueOf(val2));
+ Object.is(NumberPrototype.valueOf(val1),
+ NumberPrototype.valueOf(val2));
}
if (isStringObject(val1)) {
- return isStringObject(val2) && stringValueOf(val1) === stringValueOf(val2);
+ return isStringObject(val2) &&
+ StringPrototype.valueOf(val1) === StringPrototype.valueOf(val2);
}
if (isBooleanObject(val1)) {
return isBooleanObject(val2) &&
- booleanValueOf(val1) === booleanValueOf(val2);
+ BooleanPrototype.valueOf(val1) === BooleanPrototype.valueOf(val2);
}
if (isBigIntObject(val1)) {
- return isBigIntObject(val2) && bigIntValueOf(val1) === bigIntValueOf(val2);
+ return isBigIntObject(val2) &&
+ BigIntPrototype.valueOf(val1) === BigIntPrototype.valueOf(val2);
}
- return isSymbolObject(val2) && symbolValueOf(val1) === symbolValueOf(val2);
+ return isSymbolObject(val2) &&
+ SymbolPrototype.valueOf(val1) === SymbolPrototype.valueOf(val2);
}
// Notes: Type tags are historical [[Class]] properties that can be set by
@@ -123,19 +125,19 @@ function innerDeepEqual(val1, val2, strict, memos) {
if (val1 === val2) {
if (val1 !== 0)
return true;
- return strict ? objectIs(val1, val2) : true;
+ return strict ? Object.is(val1, val2) : true;
}
// Check more closely if val1 and val2 are equal.
if (strict) {
if (typeof val1 !== 'object') {
- return typeof val1 === 'number' && numberIsNaN(val1) &&
- numberIsNaN(val2);
+ return typeof val1 === 'number' && Number.isNaN(val1) &&
+ Number.isNaN(val2);
}
if (typeof val2 !== 'object' || val1 === null || val2 === null) {
return false;
}
- if (getPrototypeOf(val1) !== getPrototypeOf(val2)) {
+ if (Object.getPrototypeOf(val1) !== Object.getPrototypeOf(val2)) {
return false;
}
} else {
@@ -172,7 +174,7 @@ function innerDeepEqual(val1, val2, strict, memos) {
return keyCheck(val1, val2, strict, memos, kNoIterator);
}
if (isDate(val1)) {
- if (dateGetTime(val1) !== dateGetTime(val2)) {
+ if (DatePrototype.getTime(val1) !== DatePrototype.getTime(val2)) {
return false;
}
} else if (isRegExp(val1)) {
@@ -235,8 +237,8 @@ function keyCheck(val1, val2, strict, memos, iterationType, aKeys) {
// d) For Sets and Maps, equal contents
// Note: this accounts for both named and indexed properties on Arrays.
if (arguments.length === 5) {
- aKeys = objectKeys(val1);
- const bKeys = objectKeys(val2);
+ aKeys = Object.keys(val1);
+ const bKeys = Object.keys(val2);
// The pair must have the same number of owned properties.
if (aKeys.length !== bKeys.length) {
@@ -253,7 +255,7 @@ function keyCheck(val1, val2, strict, memos, iterationType, aKeys) {
}
if (strict && arguments.length === 5) {
- const symbolKeysA = getOwnPropertySymbols(val1);
+ const symbolKeysA = Object.getOwnPropertySymbols(val1);
if (symbolKeysA.length !== 0) {
let count = 0;
for (i = 0; i < symbolKeysA.length; i++) {
@@ -268,13 +270,13 @@ function keyCheck(val1, val2, strict, memos, iterationType, aKeys) {
return false;
}
}
- const symbolKeysB = getOwnPropertySymbols(val2);
+ const symbolKeysB = Object.getOwnPropertySymbols(val2);
if (symbolKeysA.length !== symbolKeysB.length &&
getEnumerables(val2, symbolKeysB).length !== count) {
return false;
}
} else {
- const symbolKeysB = getOwnPropertySymbols(val2);
+ const symbolKeysB = Object.getOwnPropertySymbols(val2);
if (symbolKeysB.length !== 0 &&
getEnumerables(val2, symbolKeysB).length !== 0) {
return false;
@@ -518,7 +520,7 @@ function objEquiv(a, b, strict, keys, memos, iterationType) {
return false;
} else {
// Array is sparse.
- const keysA = objectKeys(a);
+ const keysA = Object.keys(a);
for (; i < keysA.length; i++) {
const key = keysA[i];
if (!hasOwnProperty(b, key) ||
@@ -526,7 +528,7 @@ function objEquiv(a, b, strict, keys, memos, iterationType) {
return false;
}
}
- if (keysA.length !== objectKeys(b).length) {
+ if (keysA.length !== Object.keys(b).length) {
return false;
}
return true;
diff --git a/lib/internal/util/inspect.js b/lib/internal/util/inspect.js
index 8131166417..e5a8b2ecb6 100644
--- a/lib/internal/util/inspect.js
+++ b/lib/internal/util/inspect.js
@@ -1,6 +1,25 @@
'use strict';
-const { JSON, Math } = primordials;
+const {
+ BigIntPrototype,
+ BooleanPrototype,
+ DatePrototype,
+ ErrorPrototype,
+ JSON,
+ MapPrototype,
+ Math,
+ NumberPrototype,
+ Object,
+ ObjectPrototype: {
+ hasOwnProperty,
+ propertyIsEnumerable
+ },
+ RegExpPrototype,
+ SetPrototype,
+ StringPrototype,
+ SymbolPrototype,
+ uncurryThis
+} = primordials;
const {
getOwnNonIndexProperties,
@@ -19,8 +38,7 @@ const {
customInspectSymbol,
isError,
join,
- removeColors,
- uncurryThis
+ removeColors
} = require('internal/util');
const {
@@ -68,25 +86,6 @@ const {
const assert = require('internal/assert');
-// Avoid monkey-patched built-ins.
-const { Object } = primordials;
-
-const propertyIsEnumerable = uncurryThis(Object.prototype.propertyIsEnumerable);
-const regExpToString = uncurryThis(RegExp.prototype.toString);
-const dateToISOString = uncurryThis(Date.prototype.toISOString);
-const dateToString = uncurryThis(Date.prototype.toString);
-const errorToString = uncurryThis(Error.prototype.toString);
-
-const bigIntValueOf = uncurryThis(BigInt.prototype.valueOf);
-const booleanValueOf = uncurryThis(Boolean.prototype.valueOf);
-const numberValueOf = uncurryThis(Number.prototype.valueOf);
-const symbolValueOf = uncurryThis(Symbol.prototype.valueOf);
-const stringValueOf = uncurryThis(String.prototype.valueOf);
-
-const setValues = uncurryThis(Set.prototype.values);
-const mapEntries = uncurryThis(Map.prototype.entries);
-const dateGetTime = uncurryThis(Date.prototype.getTime);
-const hasOwnProperty = uncurryThis(Object.prototype.hasOwnProperty);
let hexSlice;
const inspectDefaultOptions = Object.seal({
@@ -475,10 +474,10 @@ function noPrototypeIterator(ctx, value, recurseTimes) {
let newVal;
if (isSet(value)) {
const clazz = clazzWithNullPrototype(Set, 'Set');
- newVal = new clazz(setValues(value));
+ newVal = new clazz(SetPrototype.values(value));
} else if (isMap(value)) {
const clazz = clazzWithNullPrototype(Map, 'Map');
- newVal = new clazz(mapEntries(value));
+ newVal = new clazz(MapPrototype.entries(value));
} else if (Array.isArray(value)) {
const clazz = clazzWithNullPrototype(Array, 'Array');
newVal = new clazz(value.length);
@@ -650,7 +649,9 @@ function formatRaw(ctx, value, recurseTimes, typedArray) {
base = `[${name}]`;
} else if (isRegExp(value)) {
// Make RegExps say that they are RegExps
- base = regExpToString(constructor !== null ? value : new RegExp(value));
+ base = RegExpPrototype.toString(
+ constructor !== null ? value : new RegExp(value)
+ );
const prefix = getPrefix(constructor, tag, 'RegExp');
if (prefix !== 'RegExp ')
base = `${prefix}${base}`;
@@ -658,9 +659,9 @@ function formatRaw(ctx, value, recurseTimes, typedArray) {
return ctx.stylize(base, 'regexp');
} else if (isDate(value)) {
// Make dates with properties first say the date
- base = Number.isNaN(dateGetTime(value)) ?
- dateToString(value) :
- dateToISOString(value);
+ base = Number.isNaN(DatePrototype.getTime(value)) ?
+ DatePrototype.toString(value) :
+ DatePrototype.toISOString(value);
const prefix = getPrefix(constructor, tag, 'Date');
if (prefix !== 'Date ')
base = `${prefix}${base}`;
@@ -705,23 +706,25 @@ function formatRaw(ctx, value, recurseTimes, typedArray) {
} else if (isBoxedPrimitive(value)) {
let type;
if (isNumberObject(value)) {
- base = `[Number: ${getBoxedValue(numberValueOf(value))}]`;
+ base = `[Number: ${getBoxedValue(NumberPrototype.valueOf(value))}]`;
type = 'number';
} else if (isStringObject(value)) {
- base = `[String: ${getBoxedValue(stringValueOf(value), ctx)}]`;
+ base = `[String: ${
+ getBoxedValue(StringPrototype.valueOf(value), ctx)
+ }]`;
type = 'string';
// For boxed Strings, we have to remove the 0-n indexed entries,
// since they just noisy up the output and are redundant
// Make boxed primitive Strings look like such
keys = keys.slice(value.length);
} else if (isBooleanObject(value)) {
- base = `[Boolean: ${getBoxedValue(booleanValueOf(value))}]`;
+ base = `[Boolean: ${getBoxedValue(BooleanPrototype.valueOf(value))}]`;
type = 'boolean';
} else if (isBigIntObject(value)) {
- base = `[BigInt: ${getBoxedValue(bigIntValueOf(value))}]`;
+ base = `[BigInt: ${getBoxedValue(BigIntPrototype.valueOf(value))}]`;
type = 'bigint';
} else {
- base = `[Symbol: ${getBoxedValue(symbolValueOf(value))}]`;
+ base = `[Symbol: ${getBoxedValue(SymbolPrototype.valueOf(value))}]`;
type = 'symbol';
}
if (keys.length === 0) {
@@ -832,7 +835,7 @@ function formatRaw(ctx, value, recurseTimes, typedArray) {
function formatError(err, constructor, tag, ctx) {
// TODO(BridgeAR): Always show the error code if present.
- let stack = err.stack || errorToString(err);
+ let stack = err.stack || ErrorPrototype.toString(err);
// A stack trace may contain arbitrary data. Only manipulate the output
// for "regular errors" (errors that "look normal") for now.
diff --git a/lib/internal/util/types.js b/lib/internal/util/types.js
index f41d11443f..28ef7f27a6 100644
--- a/lib/internal/util/types.js
+++ b/lib/internal/util/types.js
@@ -1,6 +1,6 @@
'use strict';
-const { uncurryThis } = require('internal/util');
+const { uncurryThis } = primordials;
const TypedArrayPrototype = Object.getPrototypeOf(Uint8Array.prototype);
diff --git a/lib/util.js b/lib/util.js
index f6b3082760..4b35784dc4 100644
--- a/lib/util.js
+++ b/lib/util.js
@@ -21,7 +21,7 @@
'use strict';
-const { Reflect } = primordials;
+const { ObjectPrototype, Reflect } = primordials;
const {
codes: {
@@ -47,12 +47,9 @@ const types = require('internal/util/types');
const {
deprecate,
getSystemErrorName: internalErrorName,
- promisify,
- uncurryThis
+ promisify
} = require('internal/util');
-const objectToString = uncurryThis(Object.prototype.toString);
-
let internalDeepEqual;
function isBoolean(arg) {
@@ -87,6 +84,10 @@ function isObject(arg) {
return arg !== null && typeof arg === 'object';
}
+function isError(e) {
+ return ObjectPrototype.toString(e) === '[object Error]' || e instanceof Error;
+}
+
function isFunction(arg) {
return typeof arg === 'function';
}
@@ -249,9 +250,7 @@ module.exports = {
isRegExp: types.isRegExp,
isObject,
isDate: types.isDate,
- isError(e) {
- return objectToString(e) === '[object Error]' || e instanceof Error;
- },
+ isError,
isFunction,
isPrimitive,
log,
diff --git a/lib/vm.js b/lib/vm.js
index b2875d1e11..d06fc835fc 100644
--- a/lib/vm.js
+++ b/lib/vm.js
@@ -21,6 +21,8 @@
'use strict';
+const { Array, ArrayPrototype } = primordials;
+
const {
ContextifyScript,
makeContext,
@@ -41,9 +43,6 @@ const {
const { kVmBreakFirstLineSymbol } = require('internal/util');
const kParsingContext = Symbol('script parsing context');
-const ArrayForEach = Function.call.bind(Array.prototype.forEach);
-const ArrayIsArray = Array.isArray;
-
class Script extends ContextifyScript {
constructor(code, options = {}) {
code = `${code}`;
@@ -317,10 +316,11 @@ function runInThisContext(code, options) {
function compileFunction(code, params, options = {}) {
validateString(code, 'code');
if (params !== undefined) {
- if (!ArrayIsArray(params)) {
+ if (!Array.isArray(params)) {
throw new ERR_INVALID_ARG_TYPE('params', 'Array', params);
}
- ArrayForEach(params, (param, i) => validateString(param, `params[${i}]`));
+ ArrayPrototype.forEach(params,
+ (param, i) => validateString(param, `params[${i}]`));
}
const {
@@ -363,14 +363,14 @@ function compileFunction(code, params, options = {}) {
);
}
}
- if (!ArrayIsArray(contextExtensions)) {
+ if (!Array.isArray(contextExtensions)) {
throw new ERR_INVALID_ARG_TYPE(
'options.contextExtensions',
'Array',
contextExtensions
);
}
- ArrayForEach(contextExtensions, (extension, i) => {
+ ArrayPrototype.forEach(contextExtensions, (extension, i) => {
if (typeof extension !== 'object') {
throw new ERR_INVALID_ARG_TYPE(
`options.contextExtensions[${i}]`,