ses
Version:
Hardened JavaScript for Fearless Cooperation
182 lines (148 loc) • 5.81 kB
JavaScript
import {
FERAL_FUNCTION,
Float32Array,
Map,
Set,
String,
getOwnPropertyDescriptor,
getPrototypeOf,
iterateArray,
iterateMap,
iterateSet,
iterateString,
matchAllRegExp,
matchAllSymbol,
regexpPrototype,
globalThis,
assign,
AsyncGeneratorFunctionInstance,
ArrayBuffer,
} from './commons.js';
import { InertCompartment } from './compartment.js';
/**
* Object.getConstructorOf()
* Helper function to improve readability, similar to Object.getPrototypeOf().
*
* @param {object} obj
*/
function getConstructorOf(obj) {
return getPrototypeOf(obj).constructor;
}
// getAnonymousIntrinsics uses a utility function to construct an arguments
// object, since it cannot have one of its own and also be a const export.
function makeArguments() {
// eslint-disable-next-line prefer-rest-params
return arguments;
}
/**
* getAnonymousIntrinsics()
* Get the intrinsics not otherwise reachable by named own property
* traversal from the global object.
*
* @returns {object}
*/
export const getAnonymousIntrinsics = () => {
const InertFunction = FERAL_FUNCTION.prototype.constructor;
// 9.2.4.1 %ThrowTypeError%
const argsCalleeDesc = getOwnPropertyDescriptor(makeArguments(), 'callee');
const ThrowTypeError = argsCalleeDesc && argsCalleeDesc.get;
// 21.1.5.2 The %StringIteratorPrototype% Object
// eslint-disable-next-line no-new-wrappers
const StringIteratorObject = iterateString(new String());
const StringIteratorPrototype = getPrototypeOf(StringIteratorObject);
// 21.2.7.1 The %RegExpStringIteratorPrototype% Object
const RegExpStringIterator =
regexpPrototype[matchAllSymbol] && matchAllRegExp(/./);
const RegExpStringIteratorPrototype =
RegExpStringIterator && getPrototypeOf(RegExpStringIterator);
// 22.1.5.2 The %ArrayIteratorPrototype% Object
// eslint-disable-next-line no-array-constructor
const ArrayIteratorObject = iterateArray([]);
const ArrayIteratorPrototype = getPrototypeOf(ArrayIteratorObject);
// 22.2.1 The %TypedArray% Intrinsic Object
const TypedArray = getPrototypeOf(Float32Array);
// 23.1.5.2 The %MapIteratorPrototype% Object
const MapIteratorObject = iterateMap(new Map());
const MapIteratorPrototype = getPrototypeOf(MapIteratorObject);
// 23.2.5.2 The %SetIteratorPrototype% Object
const SetIteratorObject = iterateSet(new Set());
const SetIteratorPrototype = getPrototypeOf(SetIteratorObject);
// 25.1.2 The %IteratorPrototype% Object
const IteratorPrototype = getPrototypeOf(ArrayIteratorPrototype);
// 25.2.1 The GeneratorFunction Constructor
// eslint-disable-next-line no-empty-function
function* GeneratorFunctionInstance() {}
const GeneratorFunction = getConstructorOf(GeneratorFunctionInstance);
// 25.2.3 Properties of the GeneratorFunction Prototype Object
const Generator = GeneratorFunction.prototype;
// 25.7.1 The AsyncFunction Constructor
// eslint-disable-next-line no-empty-function
async function AsyncFunctionInstance() {}
const AsyncFunction = getConstructorOf(AsyncFunctionInstance);
const intrinsics = {
'%InertFunction%': InertFunction,
'%ArrayIteratorPrototype%': ArrayIteratorPrototype,
'%InertAsyncFunction%': AsyncFunction,
'%Generator%': Generator,
'%InertGeneratorFunction%': GeneratorFunction,
'%IteratorPrototype%': IteratorPrototype,
'%MapIteratorPrototype%': MapIteratorPrototype,
'%RegExpStringIteratorPrototype%': RegExpStringIteratorPrototype,
'%SetIteratorPrototype%': SetIteratorPrototype,
'%StringIteratorPrototype%': StringIteratorPrototype,
'%ThrowTypeError%': ThrowTypeError,
'%TypedArray%': TypedArray,
'%InertCompartment%': InertCompartment,
};
if (AsyncGeneratorFunctionInstance !== undefined) {
// 25.3.1 The AsyncGeneratorFunction Constructor
const AsyncGeneratorFunction = getConstructorOf(
AsyncGeneratorFunctionInstance,
);
// 25.3.2.2 AsyncGeneratorFunction.prototype
const AsyncGenerator = AsyncGeneratorFunction.prototype;
// 25.5.1 Properties of the AsyncGenerator Prototype Object
const AsyncGeneratorPrototype = AsyncGenerator.prototype;
const AsyncIteratorPrototype = getPrototypeOf(AsyncGeneratorPrototype);
assign(intrinsics, {
'%AsyncGenerator%': AsyncGenerator,
'%InertAsyncGeneratorFunction%': AsyncGeneratorFunction,
'%AsyncGeneratorPrototype%': AsyncGeneratorPrototype,
'%AsyncIteratorPrototype%': AsyncIteratorPrototype,
});
}
if (globalThis.Iterator) {
intrinsics['%IteratorHelperPrototype%'] = getPrototypeOf(
// eslint-disable-next-line @endo/no-polymorphic-call
globalThis.Iterator.from([]).take(0),
);
intrinsics['%WrapForValidIteratorPrototype%'] = getPrototypeOf(
// eslint-disable-next-line @endo/no-polymorphic-call
globalThis.Iterator.from({
next() {
return { value: undefined };
},
}),
);
}
if (globalThis.AsyncIterator) {
intrinsics['%AsyncIteratorHelperPrototype%'] = getPrototypeOf(
// eslint-disable-next-line @endo/no-polymorphic-call
globalThis.AsyncIterator.from([]).take(0),
);
intrinsics['%WrapForValidAsyncIteratorPrototype%'] = getPrototypeOf(
// eslint-disable-next-line @endo/no-polymorphic-call
globalThis.AsyncIterator.from({ next() {} }),
);
}
const ab = new ArrayBuffer(0);
// @ts-expect-error TODO How do I add sliceToImmutable to ArrayBuffer type?
// eslint-disable-next-line @endo/no-polymorphic-call
const iab = ab.sliceToImmutable();
const iabProto = getPrototypeOf(iab);
if (iabProto !== ArrayBuffer.prototype) {
// In a native implementation, these will be the same prototype
intrinsics['%ImmutableArrayBufferPrototype%'] = iabProto;
}
return intrinsics;
};