lib: use safe methods from primordials
This changes the primordials to expose built-in prototypes with their methods already uncurried. The uncurryThis function is therefore moved to the primordials. All uses of uncurryThis on built-ins are changed to import the relevant prototypes from primordials. All uses of Function.call.bind are also changed to use primordials. PR-URL: https://github.com/nodejs/node/pull/27096 Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Joyee Cheung <joyeec9h3@gmail.com>
This commit is contained in:
parent
969bd1eb7b
commit
112cc7c275
@ -21,6 +21,8 @@
|
|||||||
|
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
|
const { ObjectPrototype } = primordials;
|
||||||
|
|
||||||
const assert = require('internal/assert');
|
const assert = require('internal/assert');
|
||||||
const Stream = require('stream');
|
const Stream = require('stream');
|
||||||
const internalUtil = require('internal/util');
|
const internalUtil = require('internal/util');
|
||||||
@ -53,8 +55,6 @@ const { CRLF, debug } = common;
|
|||||||
|
|
||||||
const kIsCorked = Symbol('isCorked');
|
const kIsCorked = Symbol('isCorked');
|
||||||
|
|
||||||
const hasOwnProperty = Function.call.bind(Object.prototype.hasOwnProperty);
|
|
||||||
|
|
||||||
const RE_CONN_CLOSE = /(?:^|\W)close(?:$|\W)/i;
|
const RE_CONN_CLOSE = /(?:^|\W)close(?:$|\W)/i;
|
||||||
const RE_TE_CHUNKED = common.chunkExpression;
|
const RE_TE_CHUNKED = common.chunkExpression;
|
||||||
|
|
||||||
@ -310,7 +310,7 @@ function _storeHeader(firstLine, headers) {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for (const key in headers) {
|
for (const key in headers) {
|
||||||
if (hasOwnProperty(headers, key)) {
|
if (ObjectPrototype.hasOwnProperty(headers, key)) {
|
||||||
processHeader(this, state, key, headers[key], true);
|
processHeader(this, state, key, headers[key], true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
const { Reflect } = primordials;
|
const { FunctionPrototype, Reflect } = primordials;
|
||||||
|
|
||||||
const {
|
const {
|
||||||
ERR_ASYNC_TYPE,
|
ERR_ASYNC_TYPE,
|
||||||
@ -77,8 +77,6 @@ const { kInit, kBefore, kAfter, kDestroy, kTotals, kPromiseResolve,
|
|||||||
kCheck, kExecutionAsyncId, kAsyncIdCounter, kTriggerAsyncId,
|
kCheck, kExecutionAsyncId, kAsyncIdCounter, kTriggerAsyncId,
|
||||||
kDefaultTriggerAsyncId, kStackLength } = async_wrap.constants;
|
kDefaultTriggerAsyncId, kStackLength } = async_wrap.constants;
|
||||||
|
|
||||||
const FunctionBind = Function.call.bind(Function.prototype.bind);
|
|
||||||
|
|
||||||
// Used in AsyncHook and AsyncResource.
|
// Used in AsyncHook and AsyncResource.
|
||||||
const async_id_symbol = Symbol('asyncId');
|
const async_id_symbol = Symbol('asyncId');
|
||||||
const trigger_async_id_symbol = Symbol('triggerAsyncId');
|
const trigger_async_id_symbol = Symbol('triggerAsyncId');
|
||||||
@ -181,7 +179,7 @@ function emitHook(symbol, asyncId) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function emitHookFactory(symbol, name) {
|
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.
|
// Set the name property of the function as it looks good in the stack trace.
|
||||||
Object.defineProperty(fn, 'name', {
|
Object.defineProperty(fn, 'name', {
|
||||||
|
@ -225,7 +225,7 @@ NativeModule.prototype.compileForPublicLoader = function(needToProxify) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const getOwn = (target, property, receiver) => {
|
const getOwn = (target, property, receiver) => {
|
||||||
return Reflect.apply(ObjectPrototype.hasOwnProperty, target, [property]) ?
|
return ObjectPrototype.hasOwnProperty(target, property) ?
|
||||||
Reflect.get(target, property, receiver) :
|
Reflect.get(target, property, receiver) :
|
||||||
undefined;
|
undefined;
|
||||||
};
|
};
|
||||||
@ -239,8 +239,7 @@ NativeModule.prototype.proxifyExports = function() {
|
|||||||
|
|
||||||
const update = (property, value) => {
|
const update = (property, value) => {
|
||||||
if (this.reflect !== undefined &&
|
if (this.reflect !== undefined &&
|
||||||
Reflect.apply(ObjectPrototype.hasOwnProperty,
|
ObjectPrototype.hasOwnProperty(this.reflect.exports, property))
|
||||||
this.reflect.exports, [property]))
|
|
||||||
this.reflect.exports[property].set(value);
|
this.reflect.exports[property].set(value);
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -254,7 +253,7 @@ NativeModule.prototype.proxifyExports = function() {
|
|||||||
!Reflect.has(handler, 'get')) {
|
!Reflect.has(handler, 'get')) {
|
||||||
handler.get = (target, prop, receiver) => {
|
handler.get = (target, prop, receiver) => {
|
||||||
const value = Reflect.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);
|
update(prop, value);
|
||||||
return value;
|
return value;
|
||||||
};
|
};
|
||||||
|
@ -12,6 +12,19 @@
|
|||||||
// `primordials.Object` where `primordials` is a lexical variable passed
|
// `primordials.Object` where `primordials` is a lexical variable passed
|
||||||
// by the native module compiler.
|
// 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) {
|
function copyProps(src, dest) {
|
||||||
for (const key of Reflect.ownKeys(src)) {
|
for (const key of Reflect.ownKeys(src)) {
|
||||||
if (!Reflect.getOwnPropertyDescriptor(dest, key)) {
|
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) {
|
function makeSafe(unsafe, safe) {
|
||||||
copyProps(unsafe.prototype, safe.prototype);
|
copyProps(unsafe.prototype, safe.prototype);
|
||||||
copyProps(unsafe, safe);
|
copyProps(unsafe, safe);
|
||||||
@ -64,17 +89,23 @@ primordials.SafePromise = makeSafe(
|
|||||||
// Create copies of intrinsic objects
|
// Create copies of intrinsic objects
|
||||||
[
|
[
|
||||||
'Array',
|
'Array',
|
||||||
|
'BigInt',
|
||||||
|
'Boolean',
|
||||||
'Date',
|
'Date',
|
||||||
|
'Error',
|
||||||
'Function',
|
'Function',
|
||||||
|
'Map',
|
||||||
|
'Number',
|
||||||
'Object',
|
'Object',
|
||||||
'RegExp',
|
'RegExp',
|
||||||
|
'Set',
|
||||||
'String',
|
'String',
|
||||||
'Symbol',
|
'Symbol',
|
||||||
].forEach((name) => {
|
].forEach((name) => {
|
||||||
const target = primordials[name] = Object.create(null);
|
const target = primordials[name] = Object.create(null);
|
||||||
copyProps(global[name], target);
|
copyProps(global[name], target);
|
||||||
const proto = primordials[name + 'Prototype'] = Object.create(null);
|
const proto = primordials[name + 'Prototype'] = Object.create(null);
|
||||||
copyProps(global[name].prototype, proto);
|
copyPrototype(global[name].prototype, proto);
|
||||||
});
|
});
|
||||||
|
|
||||||
Object.setPrototypeOf(primordials, null);
|
Object.setPrototypeOf(primordials, null);
|
||||||
|
@ -1,10 +1,9 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
const { Math } = primordials;
|
const { Math, ObjectPrototype } = primordials;
|
||||||
|
|
||||||
const { Buffer } = require('buffer');
|
const { Buffer } = require('buffer');
|
||||||
const { removeColors } = require('internal/util');
|
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
|
// 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
|
// 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++) {
|
for (var j = 0; j < longestColumn; j++) {
|
||||||
if (rows[j] === undefined)
|
if (rows[j] === undefined)
|
||||||
rows[j] = [];
|
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 width = columnWidths[i] || 0;
|
||||||
const counted = countSymbols(value);
|
const counted = countSymbols(value);
|
||||||
columnWidths[i] = Math.max(width, counted);
|
columnWidths[i] = Math.max(width, counted);
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
// The Console constructor is not actually used to construct the global
|
// The Console constructor is not actually used to construct the global
|
||||||
// console. It's exported for backwards compatibility.
|
// console. It's exported for backwards compatibility.
|
||||||
|
|
||||||
const { Reflect } = primordials;
|
const { ObjectPrototype, Reflect } = primordials;
|
||||||
|
|
||||||
const { trace } = internalBinding('trace_events');
|
const { trace } = internalBinding('trace_events');
|
||||||
const {
|
const {
|
||||||
@ -36,7 +36,6 @@ const {
|
|||||||
keys: ObjectKeys,
|
keys: ObjectKeys,
|
||||||
values: ObjectValues,
|
values: ObjectValues,
|
||||||
} = Object;
|
} = Object;
|
||||||
const hasOwnProperty = Function.call.bind(Object.prototype.hasOwnProperty);
|
|
||||||
|
|
||||||
const {
|
const {
|
||||||
isArray: ArrayIsArray,
|
isArray: ArrayIsArray,
|
||||||
@ -493,7 +492,8 @@ const consoleMethods = {
|
|||||||
for (const key of keys) {
|
for (const key of keys) {
|
||||||
if (map[key] === undefined)
|
if (map[key] === undefined)
|
||||||
map[key] = [];
|
map[key] = [];
|
||||||
if ((primitive && properties) || !hasOwnProperty(item, key))
|
if ((primitive && properties) ||
|
||||||
|
!ObjectPrototype.hasOwnProperty(item, key))
|
||||||
map[key][i] = '';
|
map[key][i] = '';
|
||||||
else
|
else
|
||||||
map[key][i] = _inspect(item[key]);
|
map[key][i] = _inspect(item[key]);
|
||||||
|
@ -2,27 +2,17 @@
|
|||||||
|
|
||||||
const Buffer = require('buffer').Buffer;
|
const Buffer = require('buffer').Buffer;
|
||||||
const {
|
const {
|
||||||
SafeSet,
|
ArrayPrototype,
|
||||||
|
FunctionPrototype,
|
||||||
Object,
|
Object,
|
||||||
ObjectPrototype,
|
ObjectPrototype,
|
||||||
FunctionPrototype,
|
SafeSet,
|
||||||
ArrayPrototype
|
|
||||||
} = primordials;
|
} = primordials;
|
||||||
|
|
||||||
const kSerializedError = 0;
|
const kSerializedError = 0;
|
||||||
const kSerializedObject = 1;
|
const kSerializedObject = 1;
|
||||||
const kInspectedError = 2;
|
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 = {
|
const errors = {
|
||||||
Error, TypeError, RangeError, URIError, SyntaxError, ReferenceError, EvalError
|
Error, TypeError, RangeError, URIError, SyntaxError, ReferenceError, EvalError
|
||||||
};
|
};
|
||||||
@ -32,17 +22,18 @@ function TryGetAllProperties(object, target = object) {
|
|||||||
const all = Object.create(null);
|
const all = Object.create(null);
|
||||||
if (object === null)
|
if (object === null)
|
||||||
return all;
|
return all;
|
||||||
Assign(all, TryGetAllProperties(GetPrototypeOf(object), target));
|
Object.assign(all,
|
||||||
const keys = GetOwnPropertyNames(object);
|
TryGetAllProperties(Object.getPrototypeOf(object), target));
|
||||||
ForEach(keys, (key) => {
|
const keys = Object.getOwnPropertyNames(object);
|
||||||
|
ArrayPrototype.forEach(keys, (key) => {
|
||||||
let descriptor;
|
let descriptor;
|
||||||
try {
|
try {
|
||||||
descriptor = GetOwnPropertyDescriptor(object, key);
|
descriptor = Object.getOwnPropertyDescriptor(object, key);
|
||||||
} catch { return; }
|
} catch { return; }
|
||||||
const getter = descriptor.get;
|
const getter = descriptor.get;
|
||||||
if (getter && key !== '__proto__') {
|
if (getter && key !== '__proto__') {
|
||||||
try {
|
try {
|
||||||
descriptor.value = Call(getter, target);
|
descriptor.value = FunctionPrototype.call(getter, target);
|
||||||
} catch {}
|
} catch {}
|
||||||
}
|
}
|
||||||
if ('value' in descriptor && typeof descriptor.value !== 'function') {
|
if ('value' in descriptor && typeof descriptor.value !== 'function') {
|
||||||
@ -59,10 +50,10 @@ function GetConstructors(object) {
|
|||||||
|
|
||||||
for (var current = object;
|
for (var current = object;
|
||||||
current !== null;
|
current !== null;
|
||||||
current = GetPrototypeOf(current)) {
|
current = Object.getPrototypeOf(current)) {
|
||||||
const desc = GetOwnPropertyDescriptor(current, 'constructor');
|
const desc = Object.getOwnPropertyDescriptor(current, 'constructor');
|
||||||
if (desc && desc.value) {
|
if (desc && desc.value) {
|
||||||
DefineProperty(constructors, constructors.length, {
|
Object.defineProperty(constructors, constructors.length, {
|
||||||
value: desc.value, enumerable: true
|
value: desc.value, enumerable: true
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -72,7 +63,7 @@ function GetConstructors(object) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function GetName(object) {
|
function GetName(object) {
|
||||||
const desc = GetOwnPropertyDescriptor(object, 'name');
|
const desc = Object.getOwnPropertyDescriptor(object, 'name');
|
||||||
return desc && desc.value;
|
return desc && desc.value;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -89,7 +80,7 @@ function serializeError(error) {
|
|||||||
if (!serialize) serialize = require('v8').serialize;
|
if (!serialize) serialize = require('v8').serialize;
|
||||||
try {
|
try {
|
||||||
if (typeof error === 'object' &&
|
if (typeof error === 'object' &&
|
||||||
ObjectPrototypeToString(error) === '[object Error]') {
|
ObjectPrototype.toString(error) === '[object Error]') {
|
||||||
const constructors = GetConstructors(error);
|
const constructors = GetConstructors(error);
|
||||||
for (var i = 0; i < constructors.length; i++) {
|
for (var i = 0; i < constructors.length; i++) {
|
||||||
const name = GetName(constructors[i]);
|
const name = GetName(constructors[i]);
|
||||||
|
@ -1,16 +1,16 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
|
const { ArrayPrototype } = primordials;
|
||||||
|
|
||||||
const { ModuleWrap, callbackMap } = internalBinding('module_wrap');
|
const { ModuleWrap, callbackMap } = internalBinding('module_wrap');
|
||||||
const debug = require('util').debuglog('esm');
|
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) => {
|
const createDynamicModule = (exports, url = '', evaluate) => {
|
||||||
debug('creating ESM facade for %s with exports: %j', url, exports);
|
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 = `
|
const source = `
|
||||||
${ArrayJoin(ArrayMap(names, (name) =>
|
${ArrayPrototype.join(ArrayPrototype.map(names, (name) =>
|
||||||
`let $${name};
|
`let $${name};
|
||||||
export { $${name} as ${name} };
|
export { $${name} as ${name} };
|
||||||
import.meta.exports.${name} = {
|
import.meta.exports.${name} = {
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
|
const { FunctionPrototype } = primordials;
|
||||||
|
|
||||||
const {
|
const {
|
||||||
ERR_INVALID_RETURN_PROPERTY,
|
ERR_INVALID_RETURN_PROPERTY,
|
||||||
ERR_INVALID_RETURN_PROPERTY_VALUE,
|
ERR_INVALID_RETURN_PROPERTY_VALUE,
|
||||||
@ -18,8 +20,6 @@ const createDynamicModule = require(
|
|||||||
const { translators } = require('internal/modules/esm/translators');
|
const { translators } = require('internal/modules/esm/translators');
|
||||||
const { ModuleWrap } = internalBinding('module_wrap');
|
const { ModuleWrap } = internalBinding('module_wrap');
|
||||||
|
|
||||||
const FunctionBind = Function.call.bind(Function.prototype.bind);
|
|
||||||
|
|
||||||
const debug = require('internal/util/debuglog').debuglog('esm');
|
const debug = require('internal/util/debuglog').debuglog('esm');
|
||||||
|
|
||||||
const {
|
const {
|
||||||
@ -132,9 +132,11 @@ class Loader {
|
|||||||
hook({ resolve, dynamicInstantiate }) {
|
hook({ resolve, dynamicInstantiate }) {
|
||||||
// Use .bind() to avoid giving access to the Loader instance when called.
|
// Use .bind() to avoid giving access to the Loader instance when called.
|
||||||
if (resolve !== undefined)
|
if (resolve !== undefined)
|
||||||
this._resolve = FunctionBind(resolve, null);
|
this._resolve = FunctionPrototype.bind(resolve, null);
|
||||||
if (dynamicInstantiate !== undefined)
|
if (dynamicInstantiate !== undefined) {
|
||||||
this._dynamicInstantiate = FunctionBind(dynamicInstantiate, null);
|
this._dynamicInstantiate =
|
||||||
|
FunctionPrototype.bind(dynamicInstantiate, null);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async getModuleJob(specifier, parentURL) {
|
async getModuleJob(specifier, parentURL) {
|
||||||
|
@ -1,5 +1,11 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
|
const {
|
||||||
|
SafeMap,
|
||||||
|
StringPrototype,
|
||||||
|
JSON
|
||||||
|
} = primordials;
|
||||||
|
|
||||||
const { NativeModule } = require('internal/bootstrap/loaders');
|
const { NativeModule } = require('internal/bootstrap/loaders');
|
||||||
const { ModuleWrap, callbackMap } = internalBinding('module_wrap');
|
const { ModuleWrap, callbackMap } = internalBinding('module_wrap');
|
||||||
const {
|
const {
|
||||||
@ -11,10 +17,6 @@ const internalURLModule = require('internal/url');
|
|||||||
const createDynamicModule = require(
|
const createDynamicModule = require(
|
||||||
'internal/modules/esm/create_dynamic_module');
|
'internal/modules/esm/create_dynamic_module');
|
||||||
const fs = require('fs');
|
const fs = require('fs');
|
||||||
const {
|
|
||||||
SafeMap,
|
|
||||||
JSON
|
|
||||||
} = primordials;
|
|
||||||
const { fileURLToPath, URL } = require('url');
|
const { fileURLToPath, URL } = require('url');
|
||||||
const { debuglog } = require('internal/util/debuglog');
|
const { debuglog } = require('internal/util/debuglog');
|
||||||
const { promisify } = require('internal/util');
|
const { promisify } = require('internal/util');
|
||||||
@ -23,7 +25,6 @@ const {
|
|||||||
ERR_UNKNOWN_BUILTIN_MODULE
|
ERR_UNKNOWN_BUILTIN_MODULE
|
||||||
} = require('internal/errors').codes;
|
} = require('internal/errors').codes;
|
||||||
const readFileAsync = promisify(fs.readFile);
|
const readFileAsync = promisify(fs.readFile);
|
||||||
const StringReplace = Function.call.bind(String.prototype.replace);
|
|
||||||
const JsonParse = JSON.parse;
|
const JsonParse = JSON.parse;
|
||||||
|
|
||||||
const debug = debuglog('esm');
|
const debug = debuglog('esm');
|
||||||
@ -67,7 +68,8 @@ translators.set('commonjs', async function commonjsStrategy(url, isMain) {
|
|||||||
return cached;
|
return cached;
|
||||||
}
|
}
|
||||||
const module = CJSModule._cache[
|
const module = CJSModule._cache[
|
||||||
isWindows ? StringReplace(pathname, winSepRegEx, '\\') : pathname];
|
isWindows ? StringPrototype.replace(pathname, winSepRegEx, '\\') : pathname
|
||||||
|
];
|
||||||
if (module && module.loaded) {
|
if (module && module.loaded) {
|
||||||
const exports = module.exports;
|
const exports = module.exports;
|
||||||
return createDynamicModule(['default'], url, (reflect) => {
|
return createDynamicModule(['default'], url, (reflect) => {
|
||||||
@ -110,7 +112,7 @@ translators.set('json', async function jsonStrategy(url) {
|
|||||||
debug(`Loading JSONModule ${url}`);
|
debug(`Loading JSONModule ${url}`);
|
||||||
const pathname = fileURLToPath(url);
|
const pathname = fileURLToPath(url);
|
||||||
const modulePath = isWindows ?
|
const modulePath = isWindows ?
|
||||||
StringReplace(pathname, winSepRegEx, '\\') : pathname;
|
StringPrototype.replace(pathname, winSepRegEx, '\\') : pathname;
|
||||||
let module = CJSModule._cache[modulePath];
|
let module = CJSModule._cache[modulePath];
|
||||||
if (module && module.loaded) {
|
if (module && module.loaded) {
|
||||||
const exports = module.exports;
|
const exports = module.exports;
|
||||||
|
@ -1,4 +1,12 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
|
const {
|
||||||
|
SafeWeakMap,
|
||||||
|
Object,
|
||||||
|
RegExpPrototype,
|
||||||
|
uncurryThis
|
||||||
|
} = primordials;
|
||||||
|
|
||||||
const {
|
const {
|
||||||
ERR_MANIFEST_ASSERT_INTEGRITY,
|
ERR_MANIFEST_ASSERT_INTEGRITY,
|
||||||
ERR_MANIFEST_INTEGRITY_MISMATCH,
|
ERR_MANIFEST_INTEGRITY_MISMATCH,
|
||||||
@ -6,21 +14,14 @@ const {
|
|||||||
} = require('internal/errors').codes;
|
} = require('internal/errors').codes;
|
||||||
const debug = require('internal/util/debuglog').debuglog('policy');
|
const debug = require('internal/util/debuglog').debuglog('policy');
|
||||||
const SRI = require('internal/policy/sri');
|
const SRI = require('internal/policy/sri');
|
||||||
const {
|
|
||||||
SafeWeakMap,
|
|
||||||
FunctionPrototype,
|
|
||||||
Object,
|
|
||||||
RegExpPrototype
|
|
||||||
} = primordials;
|
|
||||||
const crypto = require('crypto');
|
const crypto = require('crypto');
|
||||||
const { Buffer } = require('buffer');
|
const { Buffer } = require('buffer');
|
||||||
const { URL } = require('url');
|
const { URL } = require('url');
|
||||||
const { createHash, timingSafeEqual } = crypto;
|
const { createHash, timingSafeEqual } = crypto;
|
||||||
const HashUpdate = FunctionPrototype.call.bind(crypto.Hash.prototype.update);
|
const HashUpdate = uncurryThis(crypto.Hash.prototype.update);
|
||||||
const HashDigest = FunctionPrototype.call.bind(crypto.Hash.prototype.digest);
|
const HashDigest = uncurryThis(crypto.Hash.prototype.digest);
|
||||||
const BufferEquals = FunctionPrototype.call.bind(Buffer.prototype.equals);
|
const BufferEquals = uncurryThis(Buffer.prototype.equals);
|
||||||
const BufferToString = FunctionPrototype.call.bind(Buffer.prototype.toString);
|
const BufferToString = uncurryThis(Buffer.prototype.toString);
|
||||||
const RegExpTest = FunctionPrototype.call.bind(RegExpPrototype.test);
|
|
||||||
const { entries } = Object;
|
const { entries } = Object;
|
||||||
const kIntegrities = new SafeWeakMap();
|
const kIntegrities = new SafeWeakMap();
|
||||||
const kReactions = new SafeWeakMap();
|
const kReactions = new SafeWeakMap();
|
||||||
@ -76,7 +77,7 @@ class Manifest {
|
|||||||
const integrity = manifestEntries[i][1].integrity;
|
const integrity = manifestEntries[i][1].integrity;
|
||||||
if (integrity != null) {
|
if (integrity != null) {
|
||||||
debug(`Manifest contains integrity for url ${url}`);
|
debug(`Manifest contains integrity for url ${url}`);
|
||||||
if (RegExpTest(kRelativeURLStringPattern, url)) {
|
if (RegExpPrototype.test(kRelativeURLStringPattern, url)) {
|
||||||
url = new URL(url, manifestURL).href;
|
url = new URL(url, manifestURL).href;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,6 +1,12 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
// Value of https://w3c.github.io/webappsec-subresource-integrity/#the-integrity-attribute
|
// Value of https://w3c.github.io/webappsec-subresource-integrity/#the-integrity-attribute
|
||||||
|
|
||||||
|
const {
|
||||||
|
Object,
|
||||||
|
RegExpPrototype,
|
||||||
|
StringPrototype
|
||||||
|
} = primordials;
|
||||||
|
|
||||||
// Returns [{algorithm, value (in base64 string), options,}]
|
// Returns [{algorithm, value (in base64 string), options,}]
|
||||||
const {
|
const {
|
||||||
ERR_SRI_PARSE
|
ERR_SRI_PARSE
|
||||||
@ -19,19 +25,14 @@ Object.seal(kSRIPattern);
|
|||||||
const kAllWSP = new RegExp(`^${kWSP}*$`);
|
const kAllWSP = new RegExp(`^${kWSP}*$`);
|
||||||
Object.seal(kAllWSP);
|
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 BufferFrom = require('buffer').Buffer.from;
|
||||||
const { defineProperty } = Object;
|
|
||||||
|
|
||||||
const parse = (str) => {
|
const parse = (str) => {
|
||||||
kSRIPattern.lastIndex = 0;
|
kSRIPattern.lastIndex = 0;
|
||||||
let prevIndex = 0;
|
let prevIndex = 0;
|
||||||
let match;
|
let match;
|
||||||
const entries = [];
|
const entries = [];
|
||||||
while (match = RegExpExec(kSRIPattern, str)) {
|
while (match = RegExpPrototype.exec(kSRIPattern, str)) {
|
||||||
if (match.index !== prevIndex) {
|
if (match.index !== prevIndex) {
|
||||||
throw new ERR_SRI_PARSE(str, prevIndex);
|
throw new ERR_SRI_PARSE(str, prevIndex);
|
||||||
}
|
}
|
||||||
@ -40,7 +41,7 @@ const parse = (str) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Avoid setters being fired
|
// Avoid setters being fired
|
||||||
defineProperty(entries, entries.length, {
|
Object.defineProperty(entries, entries.length, {
|
||||||
enumerable: true,
|
enumerable: true,
|
||||||
configurable: true,
|
configurable: true,
|
||||||
value: freeze({
|
value: freeze({
|
||||||
@ -54,7 +55,7 @@ const parse = (str) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (prevIndex !== str.length) {
|
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);
|
throw new ERR_SRI_PARSE(str, prevIndex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,6 +4,12 @@
|
|||||||
// run when setting up each thread, including the main
|
// run when setting up each thread, including the main
|
||||||
// thread and the worker threads.
|
// thread and the worker threads.
|
||||||
|
|
||||||
|
const {
|
||||||
|
RegExpPrototype,
|
||||||
|
SetPrototype,
|
||||||
|
StringPrototype
|
||||||
|
} = primordials;
|
||||||
|
|
||||||
const {
|
const {
|
||||||
errnoException,
|
errnoException,
|
||||||
codes: {
|
codes: {
|
||||||
@ -199,11 +205,6 @@ const replaceUnderscoresRegex = /_/g;
|
|||||||
const leadingDashesRegex = /^--?/;
|
const leadingDashesRegex = /^--?/;
|
||||||
const trailingValuesRegex = /=.*$/;
|
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
|
// This builds the initial process.allowedNodeEnvironmentFlags
|
||||||
// from data in the config binding.
|
// from data in the config binding.
|
||||||
function buildAllowedFlags() {
|
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
|
// Save these for comparison against flags provided to
|
||||||
// process.allowedNodeEnvironmentFlags.has() which lack leading dashes.
|
// 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
|
// on a dummy option set and see whether it rejects the argument or
|
||||||
// not.
|
// not.
|
||||||
if (typeof key === 'string') {
|
if (typeof key === 'string') {
|
||||||
key = replace(key, replaceUnderscoresRegex, '-');
|
key = StringPrototype.replace(key, replaceUnderscoresRegex, '-');
|
||||||
if (test(leadingDashesRegex, key)) {
|
if (RegExpPrototype.test(leadingDashesRegex, key)) {
|
||||||
key = replace(key, trailingValuesRegex, '');
|
key = StringPrototype.replace(key, trailingValuesRegex, '');
|
||||||
return has(this, key);
|
return SetPrototype.has(this, key);
|
||||||
}
|
}
|
||||||
return has(nodeFlags, key);
|
return SetPrototype.has(nodeFlags, key);
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
const { Reflect } = primordials;
|
const { FunctionPrototype, Reflect } = primordials;
|
||||||
|
|
||||||
const {
|
const {
|
||||||
// For easy access to the nextTick state in the C++ land,
|
// For easy access to the nextTick state in the C++ land,
|
||||||
@ -37,8 +37,6 @@ const {
|
|||||||
} = require('internal/errors').codes;
|
} = require('internal/errors').codes;
|
||||||
const FixedQueue = require('internal/fixed_queue');
|
const FixedQueue = require('internal/fixed_queue');
|
||||||
|
|
||||||
const FunctionBind = Function.call.bind(Function.prototype.bind);
|
|
||||||
|
|
||||||
// *Must* match Environment::TickInfo::Fields in src/env.h.
|
// *Must* match Environment::TickInfo::Fields in src/env.h.
|
||||||
const kHasTickScheduled = 0;
|
const kHasTickScheduled = 0;
|
||||||
|
|
||||||
@ -176,7 +174,7 @@ function queueMicrotask(callback) {
|
|||||||
const asyncResource = createMicrotaskResource();
|
const asyncResource = createMicrotaskResource();
|
||||||
asyncResource.callback = callback;
|
asyncResource.callback = callback;
|
||||||
|
|
||||||
enqueueMicrotask(FunctionBind(runMicrotask, asyncResource));
|
enqueueMicrotask(FunctionPrototype.bind(runMicrotask, asyncResource));
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
|
@ -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 = {
|
module.exports = {
|
||||||
assertCrypto,
|
assertCrypto,
|
||||||
cachedResult,
|
cachedResult,
|
||||||
@ -418,7 +407,6 @@ module.exports = {
|
|||||||
promisify,
|
promisify,
|
||||||
spliceOne,
|
spliceOne,
|
||||||
removeColors,
|
removeColors,
|
||||||
uncurryThis,
|
|
||||||
|
|
||||||
// Symbol used to customize promisify conversion
|
// Symbol used to customize promisify conversion
|
||||||
customPromisifyArgs: kCustomPromisifyArgsSymbol,
|
customPromisifyArgs: kCustomPromisifyArgsSymbol,
|
||||||
|
@ -1,5 +1,21 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
|
const {
|
||||||
|
BigIntPrototype,
|
||||||
|
BooleanPrototype,
|
||||||
|
DatePrototype,
|
||||||
|
Number,
|
||||||
|
NumberPrototype,
|
||||||
|
Object,
|
||||||
|
ObjectPrototype: {
|
||||||
|
hasOwnProperty,
|
||||||
|
propertyIsEnumerable,
|
||||||
|
toString: objectToString
|
||||||
|
},
|
||||||
|
StringPrototype,
|
||||||
|
SymbolPrototype
|
||||||
|
} = primordials;
|
||||||
|
|
||||||
const { compare } = internalBinding('buffer');
|
const { compare } = internalBinding('buffer');
|
||||||
const {
|
const {
|
||||||
isAnyArrayBuffer,
|
isAnyArrayBuffer,
|
||||||
@ -24,7 +40,6 @@ const {
|
|||||||
ONLY_ENUMERABLE
|
ONLY_ENUMERABLE
|
||||||
}
|
}
|
||||||
} = internalBinding('util');
|
} = internalBinding('util');
|
||||||
const { uncurryThis } = require('internal/util');
|
|
||||||
|
|
||||||
const kStrict = true;
|
const kStrict = true;
|
||||||
const kLoose = false;
|
const kLoose = false;
|
||||||
@ -34,23 +49,6 @@ const kIsArray = 1;
|
|||||||
const kIsSet = 2;
|
const kIsSet = 2;
|
||||||
const kIsMap = 3;
|
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
|
// Check if they have the same source and flags
|
||||||
function areSimilarRegExps(a, b) {
|
function areSimilarRegExps(a, b) {
|
||||||
return a.source === b.source && a.flags === b.flags;
|
return a.source === b.source && a.flags === b.flags;
|
||||||
@ -84,19 +82,23 @@ function areEqualArrayBuffers(buf1, buf2) {
|
|||||||
function isEqualBoxedPrimitive(val1, val2) {
|
function isEqualBoxedPrimitive(val1, val2) {
|
||||||
if (isNumberObject(val1)) {
|
if (isNumberObject(val1)) {
|
||||||
return isNumberObject(val2) &&
|
return isNumberObject(val2) &&
|
||||||
objectIs(numberValueOf(val1), numberValueOf(val2));
|
Object.is(NumberPrototype.valueOf(val1),
|
||||||
|
NumberPrototype.valueOf(val2));
|
||||||
}
|
}
|
||||||
if (isStringObject(val1)) {
|
if (isStringObject(val1)) {
|
||||||
return isStringObject(val2) && stringValueOf(val1) === stringValueOf(val2);
|
return isStringObject(val2) &&
|
||||||
|
StringPrototype.valueOf(val1) === StringPrototype.valueOf(val2);
|
||||||
}
|
}
|
||||||
if (isBooleanObject(val1)) {
|
if (isBooleanObject(val1)) {
|
||||||
return isBooleanObject(val2) &&
|
return isBooleanObject(val2) &&
|
||||||
booleanValueOf(val1) === booleanValueOf(val2);
|
BooleanPrototype.valueOf(val1) === BooleanPrototype.valueOf(val2);
|
||||||
}
|
}
|
||||||
if (isBigIntObject(val1)) {
|
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
|
// 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 === val2) {
|
||||||
if (val1 !== 0)
|
if (val1 !== 0)
|
||||||
return true;
|
return true;
|
||||||
return strict ? objectIs(val1, val2) : true;
|
return strict ? Object.is(val1, val2) : true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check more closely if val1 and val2 are equal.
|
// Check more closely if val1 and val2 are equal.
|
||||||
if (strict) {
|
if (strict) {
|
||||||
if (typeof val1 !== 'object') {
|
if (typeof val1 !== 'object') {
|
||||||
return typeof val1 === 'number' && numberIsNaN(val1) &&
|
return typeof val1 === 'number' && Number.isNaN(val1) &&
|
||||||
numberIsNaN(val2);
|
Number.isNaN(val2);
|
||||||
}
|
}
|
||||||
if (typeof val2 !== 'object' || val1 === null || val2 === null) {
|
if (typeof val2 !== 'object' || val1 === null || val2 === null) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (getPrototypeOf(val1) !== getPrototypeOf(val2)) {
|
if (Object.getPrototypeOf(val1) !== Object.getPrototypeOf(val2)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -172,7 +174,7 @@ function innerDeepEqual(val1, val2, strict, memos) {
|
|||||||
return keyCheck(val1, val2, strict, memos, kNoIterator);
|
return keyCheck(val1, val2, strict, memos, kNoIterator);
|
||||||
}
|
}
|
||||||
if (isDate(val1)) {
|
if (isDate(val1)) {
|
||||||
if (dateGetTime(val1) !== dateGetTime(val2)) {
|
if (DatePrototype.getTime(val1) !== DatePrototype.getTime(val2)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} else if (isRegExp(val1)) {
|
} else if (isRegExp(val1)) {
|
||||||
@ -235,8 +237,8 @@ function keyCheck(val1, val2, strict, memos, iterationType, aKeys) {
|
|||||||
// d) For Sets and Maps, equal contents
|
// d) For Sets and Maps, equal contents
|
||||||
// Note: this accounts for both named and indexed properties on Arrays.
|
// Note: this accounts for both named and indexed properties on Arrays.
|
||||||
if (arguments.length === 5) {
|
if (arguments.length === 5) {
|
||||||
aKeys = objectKeys(val1);
|
aKeys = Object.keys(val1);
|
||||||
const bKeys = objectKeys(val2);
|
const bKeys = Object.keys(val2);
|
||||||
|
|
||||||
// The pair must have the same number of owned properties.
|
// The pair must have the same number of owned properties.
|
||||||
if (aKeys.length !== bKeys.length) {
|
if (aKeys.length !== bKeys.length) {
|
||||||
@ -253,7 +255,7 @@ function keyCheck(val1, val2, strict, memos, iterationType, aKeys) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (strict && arguments.length === 5) {
|
if (strict && arguments.length === 5) {
|
||||||
const symbolKeysA = getOwnPropertySymbols(val1);
|
const symbolKeysA = Object.getOwnPropertySymbols(val1);
|
||||||
if (symbolKeysA.length !== 0) {
|
if (symbolKeysA.length !== 0) {
|
||||||
let count = 0;
|
let count = 0;
|
||||||
for (i = 0; i < symbolKeysA.length; i++) {
|
for (i = 0; i < symbolKeysA.length; i++) {
|
||||||
@ -268,13 +270,13 @@ function keyCheck(val1, val2, strict, memos, iterationType, aKeys) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const symbolKeysB = getOwnPropertySymbols(val2);
|
const symbolKeysB = Object.getOwnPropertySymbols(val2);
|
||||||
if (symbolKeysA.length !== symbolKeysB.length &&
|
if (symbolKeysA.length !== symbolKeysB.length &&
|
||||||
getEnumerables(val2, symbolKeysB).length !== count) {
|
getEnumerables(val2, symbolKeysB).length !== count) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
const symbolKeysB = getOwnPropertySymbols(val2);
|
const symbolKeysB = Object.getOwnPropertySymbols(val2);
|
||||||
if (symbolKeysB.length !== 0 &&
|
if (symbolKeysB.length !== 0 &&
|
||||||
getEnumerables(val2, symbolKeysB).length !== 0) {
|
getEnumerables(val2, symbolKeysB).length !== 0) {
|
||||||
return false;
|
return false;
|
||||||
@ -518,7 +520,7 @@ function objEquiv(a, b, strict, keys, memos, iterationType) {
|
|||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
// Array is sparse.
|
// Array is sparse.
|
||||||
const keysA = objectKeys(a);
|
const keysA = Object.keys(a);
|
||||||
for (; i < keysA.length; i++) {
|
for (; i < keysA.length; i++) {
|
||||||
const key = keysA[i];
|
const key = keysA[i];
|
||||||
if (!hasOwnProperty(b, key) ||
|
if (!hasOwnProperty(b, key) ||
|
||||||
@ -526,7 +528,7 @@ function objEquiv(a, b, strict, keys, memos, iterationType) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (keysA.length !== objectKeys(b).length) {
|
if (keysA.length !== Object.keys(b).length) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
@ -1,6 +1,25 @@
|
|||||||
'use strict';
|
'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 {
|
const {
|
||||||
getOwnNonIndexProperties,
|
getOwnNonIndexProperties,
|
||||||
@ -19,8 +38,7 @@ const {
|
|||||||
customInspectSymbol,
|
customInspectSymbol,
|
||||||
isError,
|
isError,
|
||||||
join,
|
join,
|
||||||
removeColors,
|
removeColors
|
||||||
uncurryThis
|
|
||||||
} = require('internal/util');
|
} = require('internal/util');
|
||||||
|
|
||||||
const {
|
const {
|
||||||
@ -68,25 +86,6 @@ const {
|
|||||||
|
|
||||||
const assert = require('internal/assert');
|
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;
|
let hexSlice;
|
||||||
|
|
||||||
const inspectDefaultOptions = Object.seal({
|
const inspectDefaultOptions = Object.seal({
|
||||||
@ -475,10 +474,10 @@ function noPrototypeIterator(ctx, value, recurseTimes) {
|
|||||||
let newVal;
|
let newVal;
|
||||||
if (isSet(value)) {
|
if (isSet(value)) {
|
||||||
const clazz = clazzWithNullPrototype(Set, 'Set');
|
const clazz = clazzWithNullPrototype(Set, 'Set');
|
||||||
newVal = new clazz(setValues(value));
|
newVal = new clazz(SetPrototype.values(value));
|
||||||
} else if (isMap(value)) {
|
} else if (isMap(value)) {
|
||||||
const clazz = clazzWithNullPrototype(Map, 'Map');
|
const clazz = clazzWithNullPrototype(Map, 'Map');
|
||||||
newVal = new clazz(mapEntries(value));
|
newVal = new clazz(MapPrototype.entries(value));
|
||||||
} else if (Array.isArray(value)) {
|
} else if (Array.isArray(value)) {
|
||||||
const clazz = clazzWithNullPrototype(Array, 'Array');
|
const clazz = clazzWithNullPrototype(Array, 'Array');
|
||||||
newVal = new clazz(value.length);
|
newVal = new clazz(value.length);
|
||||||
@ -650,7 +649,9 @@ function formatRaw(ctx, value, recurseTimes, typedArray) {
|
|||||||
base = `[${name}]`;
|
base = `[${name}]`;
|
||||||
} else if (isRegExp(value)) {
|
} else if (isRegExp(value)) {
|
||||||
// Make RegExps say that they are RegExps
|
// 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');
|
const prefix = getPrefix(constructor, tag, 'RegExp');
|
||||||
if (prefix !== 'RegExp ')
|
if (prefix !== 'RegExp ')
|
||||||
base = `${prefix}${base}`;
|
base = `${prefix}${base}`;
|
||||||
@ -658,9 +659,9 @@ function formatRaw(ctx, value, recurseTimes, typedArray) {
|
|||||||
return ctx.stylize(base, 'regexp');
|
return ctx.stylize(base, 'regexp');
|
||||||
} else if (isDate(value)) {
|
} else if (isDate(value)) {
|
||||||
// Make dates with properties first say the date
|
// Make dates with properties first say the date
|
||||||
base = Number.isNaN(dateGetTime(value)) ?
|
base = Number.isNaN(DatePrototype.getTime(value)) ?
|
||||||
dateToString(value) :
|
DatePrototype.toString(value) :
|
||||||
dateToISOString(value);
|
DatePrototype.toISOString(value);
|
||||||
const prefix = getPrefix(constructor, tag, 'Date');
|
const prefix = getPrefix(constructor, tag, 'Date');
|
||||||
if (prefix !== 'Date ')
|
if (prefix !== 'Date ')
|
||||||
base = `${prefix}${base}`;
|
base = `${prefix}${base}`;
|
||||||
@ -705,23 +706,25 @@ function formatRaw(ctx, value, recurseTimes, typedArray) {
|
|||||||
} else if (isBoxedPrimitive(value)) {
|
} else if (isBoxedPrimitive(value)) {
|
||||||
let type;
|
let type;
|
||||||
if (isNumberObject(value)) {
|
if (isNumberObject(value)) {
|
||||||
base = `[Number: ${getBoxedValue(numberValueOf(value))}]`;
|
base = `[Number: ${getBoxedValue(NumberPrototype.valueOf(value))}]`;
|
||||||
type = 'number';
|
type = 'number';
|
||||||
} else if (isStringObject(value)) {
|
} else if (isStringObject(value)) {
|
||||||
base = `[String: ${getBoxedValue(stringValueOf(value), ctx)}]`;
|
base = `[String: ${
|
||||||
|
getBoxedValue(StringPrototype.valueOf(value), ctx)
|
||||||
|
}]`;
|
||||||
type = 'string';
|
type = 'string';
|
||||||
// For boxed Strings, we have to remove the 0-n indexed entries,
|
// For boxed Strings, we have to remove the 0-n indexed entries,
|
||||||
// since they just noisy up the output and are redundant
|
// since they just noisy up the output and are redundant
|
||||||
// Make boxed primitive Strings look like such
|
// Make boxed primitive Strings look like such
|
||||||
keys = keys.slice(value.length);
|
keys = keys.slice(value.length);
|
||||||
} else if (isBooleanObject(value)) {
|
} else if (isBooleanObject(value)) {
|
||||||
base = `[Boolean: ${getBoxedValue(booleanValueOf(value))}]`;
|
base = `[Boolean: ${getBoxedValue(BooleanPrototype.valueOf(value))}]`;
|
||||||
type = 'boolean';
|
type = 'boolean';
|
||||||
} else if (isBigIntObject(value)) {
|
} else if (isBigIntObject(value)) {
|
||||||
base = `[BigInt: ${getBoxedValue(bigIntValueOf(value))}]`;
|
base = `[BigInt: ${getBoxedValue(BigIntPrototype.valueOf(value))}]`;
|
||||||
type = 'bigint';
|
type = 'bigint';
|
||||||
} else {
|
} else {
|
||||||
base = `[Symbol: ${getBoxedValue(symbolValueOf(value))}]`;
|
base = `[Symbol: ${getBoxedValue(SymbolPrototype.valueOf(value))}]`;
|
||||||
type = 'symbol';
|
type = 'symbol';
|
||||||
}
|
}
|
||||||
if (keys.length === 0) {
|
if (keys.length === 0) {
|
||||||
@ -832,7 +835,7 @@ function formatRaw(ctx, value, recurseTimes, typedArray) {
|
|||||||
|
|
||||||
function formatError(err, constructor, tag, ctx) {
|
function formatError(err, constructor, tag, ctx) {
|
||||||
// TODO(BridgeAR): Always show the error code if present.
|
// 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
|
// A stack trace may contain arbitrary data. Only manipulate the output
|
||||||
// for "regular errors" (errors that "look normal") for now.
|
// for "regular errors" (errors that "look normal") for now.
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
const { uncurryThis } = require('internal/util');
|
const { uncurryThis } = primordials;
|
||||||
|
|
||||||
const TypedArrayPrototype = Object.getPrototypeOf(Uint8Array.prototype);
|
const TypedArrayPrototype = Object.getPrototypeOf(Uint8Array.prototype);
|
||||||
|
|
||||||
|
15
lib/util.js
15
lib/util.js
@ -21,7 +21,7 @@
|
|||||||
|
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
const { Reflect } = primordials;
|
const { ObjectPrototype, Reflect } = primordials;
|
||||||
|
|
||||||
const {
|
const {
|
||||||
codes: {
|
codes: {
|
||||||
@ -47,12 +47,9 @@ const types = require('internal/util/types');
|
|||||||
const {
|
const {
|
||||||
deprecate,
|
deprecate,
|
||||||
getSystemErrorName: internalErrorName,
|
getSystemErrorName: internalErrorName,
|
||||||
promisify,
|
promisify
|
||||||
uncurryThis
|
|
||||||
} = require('internal/util');
|
} = require('internal/util');
|
||||||
|
|
||||||
const objectToString = uncurryThis(Object.prototype.toString);
|
|
||||||
|
|
||||||
let internalDeepEqual;
|
let internalDeepEqual;
|
||||||
|
|
||||||
function isBoolean(arg) {
|
function isBoolean(arg) {
|
||||||
@ -87,6 +84,10 @@ function isObject(arg) {
|
|||||||
return arg !== null && typeof arg === 'object';
|
return arg !== null && typeof arg === 'object';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function isError(e) {
|
||||||
|
return ObjectPrototype.toString(e) === '[object Error]' || e instanceof Error;
|
||||||
|
}
|
||||||
|
|
||||||
function isFunction(arg) {
|
function isFunction(arg) {
|
||||||
return typeof arg === 'function';
|
return typeof arg === 'function';
|
||||||
}
|
}
|
||||||
@ -249,9 +250,7 @@ module.exports = {
|
|||||||
isRegExp: types.isRegExp,
|
isRegExp: types.isRegExp,
|
||||||
isObject,
|
isObject,
|
||||||
isDate: types.isDate,
|
isDate: types.isDate,
|
||||||
isError(e) {
|
isError,
|
||||||
return objectToString(e) === '[object Error]' || e instanceof Error;
|
|
||||||
},
|
|
||||||
isFunction,
|
isFunction,
|
||||||
isPrimitive,
|
isPrimitive,
|
||||||
log,
|
log,
|
||||||
|
14
lib/vm.js
14
lib/vm.js
@ -21,6 +21,8 @@
|
|||||||
|
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
|
const { Array, ArrayPrototype } = primordials;
|
||||||
|
|
||||||
const {
|
const {
|
||||||
ContextifyScript,
|
ContextifyScript,
|
||||||
makeContext,
|
makeContext,
|
||||||
@ -41,9 +43,6 @@ const {
|
|||||||
const { kVmBreakFirstLineSymbol } = require('internal/util');
|
const { kVmBreakFirstLineSymbol } = require('internal/util');
|
||||||
const kParsingContext = Symbol('script parsing context');
|
const kParsingContext = Symbol('script parsing context');
|
||||||
|
|
||||||
const ArrayForEach = Function.call.bind(Array.prototype.forEach);
|
|
||||||
const ArrayIsArray = Array.isArray;
|
|
||||||
|
|
||||||
class Script extends ContextifyScript {
|
class Script extends ContextifyScript {
|
||||||
constructor(code, options = {}) {
|
constructor(code, options = {}) {
|
||||||
code = `${code}`;
|
code = `${code}`;
|
||||||
@ -317,10 +316,11 @@ function runInThisContext(code, options) {
|
|||||||
function compileFunction(code, params, options = {}) {
|
function compileFunction(code, params, options = {}) {
|
||||||
validateString(code, 'code');
|
validateString(code, 'code');
|
||||||
if (params !== undefined) {
|
if (params !== undefined) {
|
||||||
if (!ArrayIsArray(params)) {
|
if (!Array.isArray(params)) {
|
||||||
throw new ERR_INVALID_ARG_TYPE('params', 'Array', 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 {
|
const {
|
||||||
@ -363,14 +363,14 @@ function compileFunction(code, params, options = {}) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!ArrayIsArray(contextExtensions)) {
|
if (!Array.isArray(contextExtensions)) {
|
||||||
throw new ERR_INVALID_ARG_TYPE(
|
throw new ERR_INVALID_ARG_TYPE(
|
||||||
'options.contextExtensions',
|
'options.contextExtensions',
|
||||||
'Array',
|
'Array',
|
||||||
contextExtensions
|
contextExtensions
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
ArrayForEach(contextExtensions, (extension, i) => {
|
ArrayPrototype.forEach(contextExtensions, (extension, i) => {
|
||||||
if (typeof extension !== 'object') {
|
if (typeof extension !== 'object') {
|
||||||
throw new ERR_INVALID_ARG_TYPE(
|
throw new ERR_INVALID_ARG_TYPE(
|
||||||
`options.contextExtensions[${i}]`,
|
`options.contextExtensions[${i}]`,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user