prepack
Version:
Execute a JS bundle, serialize global state and side effects to a snapshot that can be quickly restored.
168 lines (127 loc) • 5.63 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = _default;
exports.describeLocation = describeLocation;
exports.build = build;
var _index = require("../../values/index.js");
var _index2 = require("../../methods/index.js");
var _singletons = require("../../singletons.js");
var _invariant = _interopRequireDefault(require("../../invariant.js"));
var _descriptors = require("../../descriptors.js");
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
/**
* Copyright (c) 2017-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
/* strict-local */
function _default(realm) {
return build("Error", realm, false);
}
function describeLocation(realm, callerFn, env, loc) {
let locString = "";
let displayName = "";
let key = loc || callerFn; // check if we've already encountered the callFn and if so
// re-use that described location. plus we may get stuck trying
// to get the location by recursively checking the same fun
// so this also prevents a stack overflow
if (key) {
if (realm.alreadyDescribedLocations.has(key)) {
return realm.alreadyDescribedLocations.get(key);
}
realm.alreadyDescribedLocations.set(key, undefined);
}
if (callerFn) {
if (callerFn instanceof _index.NativeFunctionValue) {
locString = "native";
}
let name = callerFn._SafeGetDataPropertyValue("name");
if (!name.mightBeUndefined()) displayName = _singletons.To.ToStringPartial(realm, name);else name.throwIfNotConcrete();
if (env && env.environmentRecord.$NewTarget) displayName = `new ${displayName}`;
}
if (!locString) {
if (loc) {
locString = `${loc.start.line}:${loc.start.column + 1}`;
if (loc.source !== null) locString = `${loc.source}:${locString}`;
} else {
locString = (loc ? loc.source : undefined) || "unknown";
if (!displayName) return undefined;
}
}
let location;
if (displayName) {
location = `at ${displayName} (${locString})`;
} else {
location = `at ${locString}`;
}
if (key) {
realm.alreadyDescribedLocations.set(key, location);
}
return location;
}
const buildStackTemplateSrc = 'A + (B ? ": " + B : "") + C';
function buildStack(realm, context) {
(0, _invariant.default)(context.$ErrorData);
let stack = context.$ErrorData.contextStack;
if (!stack) return realm.intrinsics.undefined;
let lines = [];
let header = _singletons.To.ToStringPartial(realm, (0, _index2.Get)(realm, context, "name"));
let message = (0, _index2.Get)(realm, context, "message");
if (!message.mightBeUndefined()) {
message = _singletons.To.ToStringValue(realm, message);
} else {
message.throwIfNotConcrete();
}
for (let executionContext of stack.reverse()) {
let caller = executionContext.caller;
if (!executionContext.loc) continue; // compiler generated helper for destructuring arguments
let locString = describeLocation(realm, caller ? caller.function : undefined, caller ? caller.lexicalEnvironment : undefined, executionContext.loc);
if (locString !== undefined) lines.push(locString);
}
let footer = `\n ${lines.join("\n ")}`;
return message instanceof _index.StringValue ? new _index.StringValue(realm, `${header}${message.value ? `: ${message.value}` : ""}${footer}`) : _index.AbstractValue.createFromTemplate(realm, buildStackTemplateSrc, _index.StringValue, [new _index.StringValue(realm, header), message, new _index.StringValue(realm, footer)]);
}
function build(name, realm, inheritError = true) {
let func = new _index.NativeFunctionValue(realm, name, name, 1, (context, [message], argLength, NewTarget) => {
// 1. If NewTarget is undefined, let newTarget be the active function object, else let newTarget be NewTarget.
let newTarget = NewTarget || func; // 2. Let O be ? OrdinaryCreateFromConstructor(newTarget, "%ErrorPrototype%", « [[ErrorData]] »).
let O = _singletons.Create.OrdinaryCreateFromConstructor(realm, newTarget, `${name}Prototype`, {
$ErrorData: undefined
});
O.$ErrorData = {
contextStack: realm.contextStack.slice(1),
locationData: undefined
}; // 3. If message is not undefined, then
if (!message.mightBeUndefined()) {
// a. Let msg be ? ToString(message).
let msg = message.getType() === _index.StringValue ? message : _singletons.To.ToStringValue(realm, message); // b. Let msgDesc be the PropertyDescriptor{[[Value]]: msg, [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: true}.
let msgDesc = new _descriptors.PropertyDescriptor({
value: msg,
writable: true,
enumerable: false,
configurable: true
}); // c. Perform ! DefinePropertyOrThrow(O, "message", msgDesc).
_singletons.Properties.DefinePropertyOrThrow(realm, O, "message", msgDesc);
} else {
message.throwIfNotConcrete();
} // Build a text description of the stack.
let stackDesc = new _descriptors.PropertyDescriptor({
value: buildStack(realm, O),
enumerable: false,
configurable: true,
writable: true
});
_singletons.Properties.DefinePropertyOrThrow(realm, O, "stack", stackDesc); // 4. Return O.
return O;
});
if (inheritError) {
func.$Prototype = realm.intrinsics.Error;
}
return func;
}
//# sourceMappingURL=Error.js.map