351 lines
13 KiB
JavaScript
351 lines
13 KiB
JavaScript
'use strict';
|
|
|
|
var undefined;
|
|
|
|
var $SyntaxError = SyntaxError;
|
|
var $Function = Function;
|
|
var $TypeError = TypeError;
|
|
|
|
// eslint-disable-next-line consistent-return
|
|
var getEvalledConstructor = function (expressionSyntax) {
|
|
try {
|
|
return $Function('"use strict"; return (' + expressionSyntax + ').constructor;')();
|
|
} catch (e) {}
|
|
};
|
|
|
|
var $gOPD = Object.getOwnPropertyDescriptor;
|
|
if ($gOPD) {
|
|
try {
|
|
$gOPD({}, '');
|
|
} catch (e) {
|
|
$gOPD = null; // this is IE 8, which has a broken gOPD
|
|
}
|
|
}
|
|
|
|
var throwTypeError = function () {
|
|
throw new $TypeError();
|
|
};
|
|
var ThrowTypeError = $gOPD
|
|
? (function () {
|
|
try {
|
|
// eslint-disable-next-line no-unused-expressions, no-caller, no-restricted-properties
|
|
arguments.callee; // IE 8 does not throw here
|
|
return throwTypeError;
|
|
} catch (calleeThrows) {
|
|
try {
|
|
// IE 8 throws on Object.getOwnPropertyDescriptor(arguments, '')
|
|
return $gOPD(arguments, 'callee').get;
|
|
} catch (gOPDthrows) {
|
|
return throwTypeError;
|
|
}
|
|
}
|
|
}())
|
|
: throwTypeError;
|
|
|
|
var hasSymbols = require('has-symbols')();
|
|
var hasProto = require('has-proto')();
|
|
|
|
var getProto = Object.getPrototypeOf || (
|
|
hasProto
|
|
? function (x) { return x.__proto__; } // eslint-disable-line no-proto
|
|
: null
|
|
);
|
|
|
|
var needsEval = {};
|
|
|
|
var TypedArray = typeof Uint8Array === 'undefined' || !getProto ? undefined : getProto(Uint8Array);
|
|
|
|
var INTRINSICS = {
|
|
'%AggregateError%': typeof AggregateError === 'undefined' ? undefined : AggregateError,
|
|
'%Array%': Array,
|
|
'%ArrayBuffer%': typeof ArrayBuffer === 'undefined' ? undefined : ArrayBuffer,
|
|
'%ArrayIteratorPrototype%': hasSymbols && getProto ? getProto([][Symbol.iterator]()) : undefined,
|
|
'%AsyncFromSyncIteratorPrototype%': undefined,
|
|
'%AsyncFunction%': needsEval,
|
|
'%AsyncGenerator%': needsEval,
|
|
'%AsyncGeneratorFunction%': needsEval,
|
|
'%AsyncIteratorPrototype%': needsEval,
|
|
'%Atomics%': typeof Atomics === 'undefined' ? undefined : Atomics,
|
|
'%BigInt%': typeof BigInt === 'undefined' ? undefined : BigInt,
|
|
'%BigInt64Array%': typeof BigInt64Array === 'undefined' ? undefined : BigInt64Array,
|
|
'%BigUint64Array%': typeof BigUint64Array === 'undefined' ? undefined : BigUint64Array,
|
|
'%Boolean%': Boolean,
|
|
'%DataView%': typeof DataView === 'undefined' ? undefined : DataView,
|
|
'%Date%': Date,
|
|
'%decodeURI%': decodeURI,
|
|
'%decodeURIComponent%': decodeURIComponent,
|
|
'%encodeURI%': encodeURI,
|
|
'%encodeURIComponent%': encodeURIComponent,
|
|
'%Error%': Error,
|
|
'%eval%': eval, // eslint-disable-line no-eval
|
|
'%EvalError%': EvalError,
|
|
'%Float32Array%': typeof Float32Array === 'undefined' ? undefined : Float32Array,
|
|
'%Float64Array%': typeof Float64Array === 'undefined' ? undefined : Float64Array,
|
|
'%FinalizationRegistry%': typeof FinalizationRegistry === 'undefined' ? undefined : FinalizationRegistry,
|
|
'%Function%': $Function,
|
|
'%GeneratorFunction%': needsEval,
|
|
'%Int8Array%': typeof Int8Array === 'undefined' ? undefined : Int8Array,
|
|
'%Int16Array%': typeof Int16Array === 'undefined' ? undefined : Int16Array,
|
|
'%Int32Array%': typeof Int32Array === 'undefined' ? undefined : Int32Array,
|
|
'%isFinite%': isFinite,
|
|
'%isNaN%': isNaN,
|
|
'%IteratorPrototype%': hasSymbols && getProto ? getProto(getProto([][Symbol.iterator]())) : undefined,
|
|
'%JSON%': typeof JSON === 'object' ? JSON : undefined,
|
|
'%Map%': typeof Map === 'undefined' ? undefined : Map,
|
|
'%MapIteratorPrototype%': typeof Map === 'undefined' || !hasSymbols || !getProto ? undefined : getProto(new Map()[Symbol.iterator]()),
|
|
'%Math%': Math,
|
|
'%Number%': Number,
|
|
'%Object%': Object,
|
|
'%parseFloat%': parseFloat,
|
|
'%parseInt%': parseInt,
|
|
'%Promise%': typeof Promise === 'undefined' ? undefined : Promise,
|
|
'%Proxy%': typeof Proxy === 'undefined' ? undefined : Proxy,
|
|
'%RangeError%': RangeError,
|
|
'%ReferenceError%': ReferenceError,
|
|
'%Reflect%': typeof Reflect === 'undefined' ? undefined : Reflect,
|
|
'%RegExp%': RegExp,
|
|
'%Set%': typeof Set === 'undefined' ? undefined : Set,
|
|
'%SetIteratorPrototype%': typeof Set === 'undefined' || !hasSymbols || !getProto ? undefined : getProto(new Set()[Symbol.iterator]()),
|
|
'%SharedArrayBuffer%': typeof SharedArrayBuffer === 'undefined' ? undefined : SharedArrayBuffer,
|
|
'%String%': String,
|
|
'%StringIteratorPrototype%': hasSymbols && getProto ? getProto(''[Symbol.iterator]()) : undefined,
|
|
'%Symbol%': hasSymbols ? Symbol : undefined,
|
|
'%SyntaxError%': $SyntaxError,
|
|
'%ThrowTypeError%': ThrowTypeError,
|
|
'%TypedArray%': TypedArray,
|
|
'%TypeError%': $TypeError,
|
|
'%Uint8Array%': typeof Uint8Array === 'undefined' ? undefined : Uint8Array,
|
|
'%Uint8ClampedArray%': typeof Uint8ClampedArray === 'undefined' ? undefined : Uint8ClampedArray,
|
|
'%Uint16Array%': typeof Uint16Array === 'undefined' ? undefined : Uint16Array,
|
|
'%Uint32Array%': typeof Uint32Array === 'undefined' ? undefined : Uint32Array,
|
|
'%URIError%': URIError,
|
|
'%WeakMap%': typeof WeakMap === 'undefined' ? undefined : WeakMap,
|
|
'%WeakRef%': typeof WeakRef === 'undefined' ? undefined : WeakRef,
|
|
'%WeakSet%': typeof WeakSet === 'undefined' ? undefined : WeakSet
|
|
};
|
|
|
|
if (getProto) {
|
|
try {
|
|
null.error; // eslint-disable-line no-unused-expressions
|
|
} catch (e) {
|
|
// https://github.com/tc39/proposal-shadowrealm/pull/384#issuecomment-1364264229
|
|
var errorProto = getProto(getProto(e));
|
|
INTRINSICS['%Error.prototype%'] = errorProto;
|
|
}
|
|
}
|
|
|
|
var doEval = function doEval(name) {
|
|
var value;
|
|
if (name === '%AsyncFunction%') {
|
|
value = getEvalledConstructor('async function () {}');
|
|
} else if (name === '%GeneratorFunction%') {
|
|
value = getEvalledConstructor('function* () {}');
|
|
} else if (name === '%AsyncGeneratorFunction%') {
|
|
value = getEvalledConstructor('async function* () {}');
|
|
} else if (name === '%AsyncGenerator%') {
|
|
var fn = doEval('%AsyncGeneratorFunction%');
|
|
if (fn) {
|
|
value = fn.prototype;
|
|
}
|
|
} else if (name === '%AsyncIteratorPrototype%') {
|
|
var gen = doEval('%AsyncGenerator%');
|
|
if (gen && getProto) {
|
|
value = getProto(gen.prototype);
|
|
}
|
|
}
|
|
|
|
INTRINSICS[name] = value;
|
|
|
|
return value;
|
|
};
|
|
|
|
var LEGACY_ALIASES = {
|
|
'%ArrayBufferPrototype%': ['ArrayBuffer', 'prototype'],
|
|
'%ArrayPrototype%': ['Array', 'prototype'],
|
|
'%ArrayProto_entries%': ['Array', 'prototype', 'entries'],
|
|
'%ArrayProto_forEach%': ['Array', 'prototype', 'forEach'],
|
|
'%ArrayProto_keys%': ['Array', 'prototype', 'keys'],
|
|
'%ArrayProto_values%': ['Array', 'prototype', 'values'],
|
|
'%AsyncFunctionPrototype%': ['AsyncFunction', 'prototype'],
|
|
'%AsyncGenerator%': ['AsyncGeneratorFunction', 'prototype'],
|
|
'%AsyncGeneratorPrototype%': ['AsyncGeneratorFunction', 'prototype', 'prototype'],
|
|
'%BooleanPrototype%': ['Boolean', 'prototype'],
|
|
'%DataViewPrototype%': ['DataView', 'prototype'],
|
|
'%DatePrototype%': ['Date', 'prototype'],
|
|
'%ErrorPrototype%': ['Error', 'prototype'],
|
|
'%EvalErrorPrototype%': ['EvalError', 'prototype'],
|
|
'%Float32ArrayPrototype%': ['Float32Array', 'prototype'],
|
|
'%Float64ArrayPrototype%': ['Float64Array', 'prototype'],
|
|
'%FunctionPrototype%': ['Function', 'prototype'],
|
|
'%Generator%': ['GeneratorFunction', 'prototype'],
|
|
'%GeneratorPrototype%': ['GeneratorFunction', 'prototype', 'prototype'],
|
|
'%Int8ArrayPrototype%': ['Int8Array', 'prototype'],
|
|
'%Int16ArrayPrototype%': ['Int16Array', 'prototype'],
|
|
'%Int32ArrayPrototype%': ['Int32Array', 'prototype'],
|
|
'%JSONParse%': ['JSON', 'parse'],
|
|
'%JSONStringify%': ['JSON', 'stringify'],
|
|
'%MapPrototype%': ['Map', 'prototype'],
|
|
'%NumberPrototype%': ['Number', 'prototype'],
|
|
'%ObjectPrototype%': ['Object', 'prototype'],
|
|
'%ObjProto_toString%': ['Object', 'prototype', 'toString'],
|
|
'%ObjProto_valueOf%': ['Object', 'prototype', 'valueOf'],
|
|
'%PromisePrototype%': ['Promise', 'prototype'],
|
|
'%PromiseProto_then%': ['Promise', 'prototype', 'then'],
|
|
'%Promise_all%': ['Promise', 'all'],
|
|
'%Promise_reject%': ['Promise', 'reject'],
|
|
'%Promise_resolve%': ['Promise', 'resolve'],
|
|
'%RangeErrorPrototype%': ['RangeError', 'prototype'],
|
|
'%ReferenceErrorPrototype%': ['ReferenceError', 'prototype'],
|
|
'%RegExpPrototype%': ['RegExp', 'prototype'],
|
|
'%SetPrototype%': ['Set', 'prototype'],
|
|
'%SharedArrayBufferPrototype%': ['SharedArrayBuffer', 'prototype'],
|
|
'%StringPrototype%': ['String', 'prototype'],
|
|
'%SymbolPrototype%': ['Symbol', 'prototype'],
|
|
'%SyntaxErrorPrototype%': ['SyntaxError', 'prototype'],
|
|
'%TypedArrayPrototype%': ['TypedArray', 'prototype'],
|
|
'%TypeErrorPrototype%': ['TypeError', 'prototype'],
|
|
'%Uint8ArrayPrototype%': ['Uint8Array', 'prototype'],
|
|
'%Uint8ClampedArrayPrototype%': ['Uint8ClampedArray', 'prototype'],
|
|
'%Uint16ArrayPrototype%': ['Uint16Array', 'prototype'],
|
|
'%Uint32ArrayPrototype%': ['Uint32Array', 'prototype'],
|
|
'%URIErrorPrototype%': ['URIError', 'prototype'],
|
|
'%WeakMapPrototype%': ['WeakMap', 'prototype'],
|
|
'%WeakSetPrototype%': ['WeakSet', 'prototype']
|
|
};
|
|
|
|
var bind = require('function-bind');
|
|
var hasOwn = require('hasown');
|
|
var $concat = bind.call(Function.call, Array.prototype.concat);
|
|
var $spliceApply = bind.call(Function.apply, Array.prototype.splice);
|
|
var $replace = bind.call(Function.call, String.prototype.replace);
|
|
var $strSlice = bind.call(Function.call, String.prototype.slice);
|
|
var $exec = bind.call(Function.call, RegExp.prototype.exec);
|
|
|
|
/* adapted from https://github.com/lodash/lodash/blob/4.17.15/dist/lodash.js#L6735-L6744 */
|
|
var rePropName = /[^%.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|%$))/g;
|
|
var reEscapeChar = /\\(\\)?/g; /** Used to match backslashes in property paths. */
|
|
var stringToPath = function stringToPath(string) {
|
|
var first = $strSlice(string, 0, 1);
|
|
var last = $strSlice(string, -1);
|
|
if (first === '%' && last !== '%') {
|
|
throw new $SyntaxError('invalid intrinsic syntax, expected closing `%`');
|
|
} else if (last === '%' && first !== '%') {
|
|
throw new $SyntaxError('invalid intrinsic syntax, expected opening `%`');
|
|
}
|
|
var result = [];
|
|
$replace(string, rePropName, function (match, number, quote, subString) {
|
|
result[result.length] = quote ? $replace(subString, reEscapeChar, '$1') : number || match;
|
|
});
|
|
return result;
|
|
};
|
|
/* end adaptation */
|
|
|
|
var getBaseIntrinsic = function getBaseIntrinsic(name, allowMissing) {
|
|
var intrinsicName = name;
|
|
var alias;
|
|
if (hasOwn(LEGACY_ALIASES, intrinsicName)) {
|
|
alias = LEGACY_ALIASES[intrinsicName];
|
|
intrinsicName = '%' + alias[0] + '%';
|
|
}
|
|
|
|
if (hasOwn(INTRINSICS, intrinsicName)) {
|
|
var value = INTRINSICS[intrinsicName];
|
|
if (value === needsEval) {
|
|
value = doEval(intrinsicName);
|
|
}
|
|
if (typeof value === 'undefined' && !allowMissing) {
|
|
throw new $TypeError('intrinsic ' + name + ' exists, but is not available. Please file an issue!');
|
|
}
|
|
|
|
return {
|
|
alias: alias,
|
|
name: intrinsicName,
|
|
value: value
|
|
};
|
|
}
|
|
|
|
throw new $SyntaxError('intrinsic ' + name + ' does not exist!');
|
|
};
|
|
|
|
module.exports = function GetIntrinsic(name, allowMissing) {
|
|
if (typeof name !== 'string' || name.length === 0) {
|
|
throw new $TypeError('intrinsic name must be a non-empty string');
|
|
}
|
|
if (arguments.length > 1 && typeof allowMissing !== 'boolean') {
|
|
throw new $TypeError('"allowMissing" argument must be a boolean');
|
|
}
|
|
|
|
if ($exec(/^%?[^%]*%?$/, name) === null) {
|
|
throw new $SyntaxError('`%` may not be present anywhere but at the beginning and end of the intrinsic name');
|
|
}
|
|
var parts = stringToPath(name);
|
|
var intrinsicBaseName = parts.length > 0 ? parts[0] : '';
|
|
|
|
var intrinsic = getBaseIntrinsic('%' + intrinsicBaseName + '%', allowMissing);
|
|
var intrinsicRealName = intrinsic.name;
|
|
var value = intrinsic.value;
|
|
var skipFurtherCaching = false;
|
|
|
|
var alias = intrinsic.alias;
|
|
if (alias) {
|
|
intrinsicBaseName = alias[0];
|
|
$spliceApply(parts, $concat([0, 1], alias));
|
|
}
|
|
|
|
for (var i = 1, isOwn = true; i < parts.length; i += 1) {
|
|
var part = parts[i];
|
|
var first = $strSlice(part, 0, 1);
|
|
var last = $strSlice(part, -1);
|
|
if (
|
|
(
|
|
(first === '"' || first === "'" || first === '`')
|
|
|| (last === '"' || last === "'" || last === '`')
|
|
)
|
|
&& first !== last
|
|
) {
|
|
throw new $SyntaxError('property names with quotes must have matching quotes');
|
|
}
|
|
if (part === 'constructor' || !isOwn) {
|
|
skipFurtherCaching = true;
|
|
}
|
|
|
|
intrinsicBaseName += '.' + part;
|
|
intrinsicRealName = '%' + intrinsicBaseName + '%';
|
|
|
|
if (hasOwn(INTRINSICS, intrinsicRealName)) {
|
|
value = INTRINSICS[intrinsicRealName];
|
|
} else if (value != null) {
|
|
if (!(part in value)) {
|
|
if (!allowMissing) {
|
|
throw new $TypeError('base intrinsic for ' + name + ' exists, but the property is not available.');
|
|
}
|
|
return void undefined;
|
|
}
|
|
if ($gOPD && (i + 1) >= parts.length) {
|
|
var desc = $gOPD(value, part);
|
|
isOwn = !!desc;
|
|
|
|
// By convention, when a data property is converted to an accessor
|
|
// property to emulate a data property that does not suffer from
|
|
// the override mistake, that accessor's getter is marked with
|
|
// an `originalValue` property. Here, when we detect this, we
|
|
// uphold the illusion by pretending to see that original data
|
|
// property, i.e., returning the value rather than the getter
|
|
// itself.
|
|
if (isOwn && 'get' in desc && !('originalValue' in desc.get)) {
|
|
value = desc.get;
|
|
} else {
|
|
value = value[part];
|
|
}
|
|
} else {
|
|
isOwn = hasOwn(value, part);
|
|
value = value[part];
|
|
}
|
|
|
|
if (isOwn && !skipFurtherCaching) {
|
|
INTRINSICS[intrinsicRealName] = value;
|
|
}
|
|
}
|
|
}
|
|
return value;
|
|
};
|