| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| 'use strict'; |
|
|
| |
|
|
| |
| |
| |
|
|
| |
| |
| |
|
|
| const primordials = {}; |
|
|
| const { |
| defineProperty: ReflectDefineProperty, |
| getOwnPropertyDescriptor: ReflectGetOwnPropertyDescriptor, |
| ownKeys: ReflectOwnKeys, |
| } = Reflect; |
|
|
| |
| |
| |
| const { apply, bind, call } = Function.prototype; |
| const uncurryThis = bind.bind(call); |
| primordials.uncurryThis = uncurryThis; |
|
|
| |
| |
| |
| const applyBind = bind.bind(apply); |
| primordials.applyBind = applyBind; |
|
|
| |
| |
| |
| |
| const varargsMethods = [ |
| |
| |
| |
| 'ArrayOf', |
| 'ArrayPrototypePush', |
| 'ArrayPrototypeUnshift', |
| |
| |
| 'MathHypot', |
| 'MathMax', |
| 'MathMin', |
| 'StringPrototypeConcat', |
| 'TypedArrayOf', |
| ]; |
|
|
| function getNewKey(key) { |
| return typeof key === 'symbol' ? |
| `Symbol${key.description[7].toUpperCase()}${key.description.slice(8)}` : |
| `${key[0].toUpperCase()}${key.slice(1)}`; |
| } |
|
|
| function copyAccessor(dest, prefix, key, { enumerable, get, set }) { |
| ReflectDefineProperty(dest, `${prefix}Get${key}`, { |
| value: uncurryThis(get), |
| enumerable |
| }); |
| if (set !== undefined) { |
| ReflectDefineProperty(dest, `${prefix}Set${key}`, { |
| value: uncurryThis(set), |
| enumerable |
| }); |
| } |
| } |
|
|
| function copyPropsRenamed(src, dest, prefix) { |
| for (const key of ReflectOwnKeys(src)) { |
| const newKey = getNewKey(key); |
| const desc = ReflectGetOwnPropertyDescriptor(src, key); |
| if ('get' in desc) { |
| copyAccessor(dest, prefix, newKey, desc); |
| } else { |
| const name = `${prefix}${newKey}`; |
| ReflectDefineProperty(dest, name, desc); |
| if (varargsMethods.includes(name)) { |
| ReflectDefineProperty(dest, `${name}Apply`, { |
| |
| |
| |
| value: applyBind(desc.value, src), |
| }); |
| } |
| } |
| } |
| } |
|
|
| function copyPropsRenamedBound(src, dest, prefix) { |
| for (const key of ReflectOwnKeys(src)) { |
| const newKey = getNewKey(key); |
| const desc = ReflectGetOwnPropertyDescriptor(src, key); |
| if ('get' in desc) { |
| copyAccessor(dest, prefix, newKey, desc); |
| } else { |
| const { value } = desc; |
| if (typeof value === 'function') { |
| desc.value = value.bind(src); |
| } |
|
|
| const name = `${prefix}${newKey}`; |
| ReflectDefineProperty(dest, name, desc); |
| if (varargsMethods.includes(name)) { |
| ReflectDefineProperty(dest, `${name}Apply`, { |
| value: applyBind(value, src), |
| }); |
| } |
| } |
| } |
| } |
|
|
| function copyPrototype(src, dest, prefix) { |
| for (const key of ReflectOwnKeys(src)) { |
| const newKey = getNewKey(key); |
| const desc = ReflectGetOwnPropertyDescriptor(src, key); |
| if ('get' in desc) { |
| copyAccessor(dest, prefix, newKey, desc); |
| } else { |
| const { value } = desc; |
| if (typeof value === 'function') { |
| desc.value = uncurryThis(value); |
| } |
|
|
| const name = `${prefix}${newKey}`; |
| ReflectDefineProperty(dest, name, desc); |
| if (varargsMethods.includes(name)) { |
| ReflectDefineProperty(dest, `${name}Apply`, { |
| value: applyBind(value), |
| }); |
| } |
| } |
| } |
| } |
|
|
| |
| [ |
| 'Proxy', |
| 'globalThis', |
| ].forEach((name) => { |
| |
| primordials[name] = globalThis[name]; |
| }); |
|
|
| |
| [ |
| decodeURI, |
| decodeURIComponent, |
| encodeURI, |
| encodeURIComponent, |
| ].forEach((fn) => { |
| primordials[fn.name] = fn; |
| }); |
|
|
| |
| [ |
| 'JSON', |
| 'Math', |
| 'Proxy', |
| 'Reflect', |
| ].forEach((name) => { |
| |
| copyPropsRenamed(global[name], primordials, name); |
| }); |
|
|
| |
| [ |
| 'Array', |
| 'ArrayBuffer', |
| 'BigInt', |
| 'BigInt64Array', |
| 'BigUint64Array', |
| 'Boolean', |
| 'DataView', |
| 'Date', |
| 'Error', |
| 'EvalError', |
| 'Float32Array', |
| 'Float64Array', |
| 'Function', |
| 'Int16Array', |
| 'Int32Array', |
| 'Int8Array', |
| 'Map', |
| 'Number', |
| 'Object', |
| 'RangeError', |
| 'ReferenceError', |
| 'RegExp', |
| 'Set', |
| 'String', |
| 'Symbol', |
| 'SyntaxError', |
| 'TypeError', |
| 'URIError', |
| 'Uint16Array', |
| 'Uint32Array', |
| 'Uint8Array', |
| 'Uint8ClampedArray', |
| 'WeakMap', |
| 'WeakSet', |
| ].forEach((name) => { |
| |
| const original = global[name]; |
| primordials[name] = original; |
| copyPropsRenamed(original, primordials, name); |
| copyPrototype(original.prototype, primordials, `${name}Prototype`); |
| }); |
|
|
| |
| |
| |
| [ |
| 'Promise', |
| ].forEach((name) => { |
| |
| const original = global[name]; |
| primordials[name] = original; |
| copyPropsRenamedBound(original, primordials, name); |
| copyPrototype(original.prototype, primordials, `${name}Prototype`); |
| }); |
|
|
| |
| |
| |
| [ |
| { name: 'TypedArray', original: Reflect.getPrototypeOf(Uint8Array) }, |
| { name: 'ArrayIterator', original: { |
| prototype: Reflect.getPrototypeOf(Array.prototype[Symbol.iterator]()), |
| } }, |
| { name: 'StringIterator', original: { |
| prototype: Reflect.getPrototypeOf(String.prototype[Symbol.iterator]()), |
| } }, |
| ].forEach(({ name, original }) => { |
| primordials[name] = original; |
| |
| |
| copyPrototype(original, primordials, name); |
| copyPrototype(original.prototype, primordials, `${name}Prototype`); |
| }); |
|
|
| |
|
|
| const { |
| ArrayPrototypeForEach, |
| FunctionPrototypeCall, |
| Map, |
| ObjectFreeze, |
| ObjectSetPrototypeOf, |
| Set, |
| SymbolIterator, |
| WeakMap, |
| WeakSet, |
| } = primordials; |
|
|
| |
| |
| |
| const createSafeIterator = (factory, next) => { |
| class SafeIterator { |
| constructor(iterable) { |
| this._iterator = factory(iterable); |
| } |
| next() { |
| return next(this._iterator); |
| } |
| [SymbolIterator]() { |
| return this; |
| } |
| } |
| ObjectSetPrototypeOf(SafeIterator.prototype, null); |
| ObjectFreeze(SafeIterator.prototype); |
| ObjectFreeze(SafeIterator); |
| return SafeIterator; |
| }; |
|
|
| primordials.SafeArrayIterator = createSafeIterator( |
| primordials.ArrayPrototypeSymbolIterator, |
| primordials.ArrayIteratorPrototypeNext |
| ); |
| primordials.SafeStringIterator = createSafeIterator( |
| primordials.StringPrototypeSymbolIterator, |
| primordials.StringIteratorPrototypeNext |
| ); |
|
|
| const copyProps = (src, dest) => { |
| ArrayPrototypeForEach(ReflectOwnKeys(src), (key) => { |
| if (!ReflectGetOwnPropertyDescriptor(dest, key)) { |
| ReflectDefineProperty( |
| dest, |
| key, |
| ReflectGetOwnPropertyDescriptor(src, key)); |
| } |
| }); |
| }; |
|
|
| const makeSafe = (unsafe, safe) => { |
| if (SymbolIterator in unsafe.prototype) { |
| const dummy = new unsafe(); |
| let next; |
|
|
| ArrayPrototypeForEach(ReflectOwnKeys(unsafe.prototype), (key) => { |
| if (!ReflectGetOwnPropertyDescriptor(safe.prototype, key)) { |
| const desc = ReflectGetOwnPropertyDescriptor(unsafe.prototype, key); |
| if ( |
| typeof desc.value === 'function' && |
| desc.value.length === 0 && |
| SymbolIterator in (FunctionPrototypeCall(desc.value, dummy) ?? {}) |
| ) { |
| const createIterator = uncurryThis(desc.value); |
| next = next ?? uncurryThis(createIterator(dummy).next); |
| const SafeIterator = createSafeIterator(createIterator, next); |
| desc.value = function() { |
| return new SafeIterator(this); |
| }; |
| } |
| ReflectDefineProperty(safe.prototype, key, desc); |
| } |
| }); |
| } else { |
| copyProps(unsafe.prototype, safe.prototype); |
| } |
| copyProps(unsafe, safe); |
|
|
| ObjectSetPrototypeOf(safe.prototype, null); |
| ObjectFreeze(safe.prototype); |
| ObjectFreeze(safe); |
| return safe; |
| }; |
| primordials.makeSafe = makeSafe; |
|
|
| |
| |
| |
| |
| primordials.SafeMap = makeSafe( |
| Map, |
| class SafeMap extends Map { |
| constructor(i) { super(i); } |
| } |
| ); |
| primordials.SafeWeakMap = makeSafe( |
| WeakMap, |
| class SafeWeakMap extends WeakMap { |
| constructor(i) { super(i); } |
| } |
| ); |
| primordials.SafeSet = makeSafe( |
| Set, |
| class SafeSet extends Set { |
| constructor(i) { super(i); } |
| } |
| ); |
| primordials.SafeWeakSet = makeSafe( |
| WeakSet, |
| class SafeWeakSet extends WeakSet { |
| constructor(i) { super(i); } |
| } |
| ); |
|
|
| ObjectSetPrototypeOf(primordials, null); |
| ObjectFreeze(primordials); |
|
|
| module.exports = primordials; |
|
|