diff --git a/core/01_core.js b/core/01_core.js index 21376b695b..0e823f54a8 100644 --- a/core/01_core.js +++ b/core/01_core.js @@ -17,6 +17,7 @@ Promise, ObjectFromEntries, MapPrototypeGet, + MapPrototypeHas, MapPrototypeDelete, MapPrototypeSet, PromisePrototypeThen, diff --git a/core/02_error.js b/core/02_error.js index 85c287102f..d061164e7e 100644 --- a/core/02_error.js +++ b/core/02_error.js @@ -15,156 +15,81 @@ ArrayPrototypeJoin, } = window.__bootstrap.primordials; - // Some of the code here is adapted directly from V8 and licensed under a BSD - // style license available here: https://github.com/v8/v8/blob/24886f2d1c565287d33d71e4109a53bf0b54b75c/LICENSE.v8 - function patchCallSite(callSite, location) { - return { - getThis() { - return callSite.getThis(); - }, - getTypeName() { - return callSite.getTypeName(); - }, - getFunction() { - return callSite.getFunction(); - }, - getFunctionName() { - return callSite.getFunctionName(); - }, - getMethodName() { - return callSite.getMethodName(); - }, - getFileName() { - return location.fileName; - }, - getLineNumber() { - return location.lineNumber; - }, - getColumnNumber() { - return location.columnNumber; - }, - getEvalOrigin() { - return callSite.getEvalOrigin(); - }, - isToplevel() { - return callSite.isToplevel(); - }, - isEval() { - return callSite.isEval(); - }, - isNative() { - return callSite.isNative(); - }, - isConstructor() { - return callSite.isConstructor(); - }, - isAsync() { - return callSite.isAsync(); - }, - isPromiseAll() { - return callSite.isPromiseAll(); - }, - getPromiseIndex() { - return callSite.getPromiseIndex(); - }, - }; - } - // Keep in sync with `cli/fmt_errors.rs`. - function formatLocation(callSite) { - if (callSite.isNative()) { + function formatLocation(cse) { + if (cse.isNative) { return "native"; } - let result = ""; - - const fileName = callSite.getFileName(); - - if (fileName) { - result += core.opSync("op_format_file_name", fileName); + if (cse.fileName) { + result += core.opSync("op_format_file_name", cse.fileName); } else { - if (callSite.isEval()) { - const evalOrigin = callSite.getEvalOrigin(); - if (evalOrigin == null) { + if (cse.isEval) { + if (cse.evalOrigin == null) { throw new Error("assert evalOrigin"); } - result += `${evalOrigin}, `; + result += `${cse.evalOrigin}, `; } result += ""; } - - const lineNumber = callSite.getLineNumber(); - if (lineNumber != null) { - result += `:${lineNumber}`; - - const columnNumber = callSite.getColumnNumber(); - if (columnNumber != null) { - result += `:${columnNumber}`; + if (cse.lineNumber != null) { + result += `:${cse.lineNumber}`; + if (cse.columnNumber != null) { + result += `:${cse.columnNumber}`; } } - return result; } // Keep in sync with `cli/fmt_errors.rs`. - function formatCallSite(callSite) { + function formatCallSiteEval(cse) { let result = ""; - const functionName = callSite.getFunctionName(); - - const isTopLevel = callSite.isToplevel(); - const isAsync = callSite.isAsync(); - const isPromiseAll = callSite.isPromiseAll(); - const isConstructor = callSite.isConstructor(); - const isMethodCall = !(isTopLevel || isConstructor); - - if (isAsync) { + if (cse.isAsync) { result += "async "; } - if (isPromiseAll) { - result += `Promise.all (index ${callSite.getPromiseIndex()})`; + if (cse.isPromiseAll) { + result += `Promise.all (index ${cse.promiseIndex})`; return result; } + const isMethodCall = !(cse.isToplevel || cse.isConstructor); if (isMethodCall) { - const typeName = callSite.getTypeName(); - const methodName = callSite.getMethodName(); - - if (functionName) { - if (typeName) { - if (!StringPrototypeStartsWith(functionName, typeName)) { - result += `${typeName}.`; + if (cse.functionName) { + if (cse.typeName) { + if (!StringPrototypeStartsWith(cse.functionName, cse.typeName)) { + result += `${cse.typeName}.`; } } - result += functionName; - if (methodName) { - if (!StringPrototypeEndsWith(functionName, methodName)) { - result += ` [as ${methodName}]`; + result += cse.functionName; + if (cse.methodName) { + if (!StringPrototypeEndsWith(cse.functionName, cse.methodName)) { + result += ` [as ${cse.methodName}]`; } } } else { - if (typeName) { - result += `${typeName}.`; + if (cse.typeName) { + result += `${cse.typeName}.`; } - if (methodName) { - result += methodName; + if (cse.methodName) { + result += cse.methodName; } else { result += ""; } } - } else if (isConstructor) { + } else if (cse.isConstructor) { result += "new "; - if (functionName) { - result += functionName; + if (cse.functionName) { + result += cse.functionName; } else { result += ""; } - } else if (functionName) { - result += functionName; + } else if (cse.functionName) { + result += cse.functionName; } else { - result += formatLocation(callSite); + result += formatLocation(cse); return result; } - result += ` (${formatLocation(callSite)})`; + result += ` (${formatLocation(cse)})`; return result; } @@ -189,37 +114,24 @@ }; } + function sourceMapCallSiteEval(cse) { + if (cse.fileName && cse.lineNumber != null && cse.columnNumber != null) { + return { ...cse, ...core.opSync("op_apply_source_map", cse) }; + } + return cse; + } + /** A function that can be used as `Error.prepareStackTrace`. */ - function prepareStackTrace( - error, - callSites, - ) { - const mappedCallSites = ArrayPrototypeMap(callSites, (callSite) => { - const fileName = callSite.getFileName(); - const lineNumber = callSite.getLineNumber(); - const columnNumber = callSite.getColumnNumber(); - if (fileName && lineNumber != null && columnNumber != null) { - return patchCallSite( - callSite, - core.opSync("op_apply_source_map", { - fileName, - lineNumber, - columnNumber, - }), - ); - } - return callSite; - }); + function prepareStackTrace(error, callSites) { + let callSiteEvals = ArrayPrototypeMap(callSites, evaluateCallSite); + callSiteEvals = ArrayPrototypeMap(callSiteEvals, sourceMapCallSiteEval); ObjectDefineProperties(error, { __callSiteEvals: { value: [], configurable: true }, }); const formattedCallSites = []; - for (const callSite of mappedCallSites) { - ArrayPrototypePush(error.__callSiteEvals, evaluateCallSite(callSite)); - ArrayPrototypePush( - formattedCallSites, - formatCallSite(callSite), - ); + for (const cse of callSiteEvals) { + ArrayPrototypePush(error.__callSiteEvals, cse); + ArrayPrototypePush(formattedCallSites, formatCallSiteEval(cse)); } const message = error.message !== undefined ? error.message : ""; const name = error.name !== undefined ? error.name : "Error";