mirror of
https://github.com/bendtherules/ask262.git
synced 2026-08-19 00:31:06 +00:00
89 lines
3.1 KiB
TypeScript
89 lines
3.1 KiB
TypeScript
import {
|
|
surroundingAgent,
|
|
} from '../host-defined/engine.mts';
|
|
import {
|
|
Descriptor,
|
|
UndefinedValue,
|
|
Value,
|
|
type Arguments,
|
|
type FunctionCallContext,
|
|
} from '../value.mts';
|
|
import { Q, X, type ValueEvaluator } from '../completion.mts';
|
|
import { captureStack, callSiteToErrorString } from '../helpers.mts';
|
|
import { bootstrapConstructor, bootstrapPrototype } from './bootstrap.mts';
|
|
import type { ErrorObject } from './Error.mts';
|
|
import {
|
|
DefinePropertyOrThrow,
|
|
OrdinaryCreateFromConstructor,
|
|
InstallErrorCause,
|
|
ToString,
|
|
Realm,
|
|
type FunctionObject,
|
|
} from '#self';
|
|
|
|
const nativeErrorNames = [
|
|
'EvalError',
|
|
'RangeError',
|
|
'ReferenceError',
|
|
'SyntaxError',
|
|
'TypeError',
|
|
'URIError',
|
|
] as const;
|
|
export type NativeErrorNames = typeof nativeErrorNames[number];
|
|
export function bootstrapNativeError(realmRec: Realm) {
|
|
for (const name of nativeErrorNames) {
|
|
const proto = bootstrapPrototype(realmRec, [
|
|
['name', Value(name)],
|
|
['message', Value('')],
|
|
], realmRec.Intrinsics['%Error.prototype%']);
|
|
|
|
/** https://tc39.es/ecma262/#sec-nativeerror */
|
|
const Constructor = function* Constructor([message = Value.undefined, options = Value.undefined]: Arguments, { NewTarget }: FunctionCallContext): ValueEvaluator {
|
|
// 1. If NewTarget is undefined, let newTarget be the active function object; else let newTarget be NewTarget.
|
|
let newTarget;
|
|
if (NewTarget instanceof UndefinedValue) {
|
|
newTarget = surroundingAgent.activeFunctionObject;
|
|
} else {
|
|
newTarget = NewTarget;
|
|
}
|
|
// 2. Let O be ? OrdinaryCreateFromConstructor(newTarget, "%NativeError.prototype%", « [[ErrorData]] »).
|
|
const O = Q(yield* OrdinaryCreateFromConstructor(newTarget as FunctionObject, `%${name}.prototype%`, [
|
|
'ErrorData',
|
|
'HostDefinedErrorStack',
|
|
])) as ErrorObject;
|
|
// 3. If message is not undefined, then
|
|
if (message !== Value.undefined) {
|
|
// a. Let msg be ? ToString(message).
|
|
const msg = Q(yield* ToString(message));
|
|
// b. Let msgDesc be the PropertyDescriptor { [[Value]]: msg, [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: true }.
|
|
const msgDesc = Descriptor({
|
|
Value: msg,
|
|
Writable: Value.true,
|
|
Enumerable: Value.false,
|
|
Configurable: Value.true,
|
|
});
|
|
// c. Perform ! DefinePropertyOrThrow(O, "message", msgDesc).
|
|
X(DefinePropertyOrThrow(O, Value('message'), msgDesc));
|
|
}
|
|
// 4. Perform ? InstallErrorCause(O, options).
|
|
Q(yield* InstallErrorCause(O, options));
|
|
// NON-SPEC
|
|
const S = captureStack();
|
|
O.HostDefinedErrorStack = S.stack;
|
|
O.ErrorData = X(callSiteToErrorString(O, S.stack, S.nativeStack));
|
|
// 5. Return O.
|
|
return O;
|
|
};
|
|
Object.defineProperty(Constructor, 'name', {
|
|
value: `${name}Constructor`,
|
|
configurable: true,
|
|
});
|
|
|
|
const cons = bootstrapConstructor(realmRec, Constructor, name, 1, proto, []);
|
|
cons.Prototype = realmRec.Intrinsics['%Error%'];
|
|
|
|
realmRec.Intrinsics[`%${name}.prototype%`] = proto;
|
|
realmRec.Intrinsics[`%${name}%`] = cons;
|
|
}
|
|
}
|