diff options
Diffstat (limited to 'core/01_core.js')
-rw-r--r-- | core/01_core.js | 23 |
1 files changed, 22 insertions, 1 deletions
diff --git a/core/01_core.js b/core/01_core.js index d9a110eea..3a05a0cff 100644 --- a/core/01_core.js +++ b/core/01_core.js @@ -22,6 +22,8 @@ MapPrototypeDelete, MapPrototypeSet, PromisePrototypeThen, + PromisePrototypeFinally, + StringPrototypeSlice, ObjectAssign, SymbolFor, } = window.__bootstrap.primordials; @@ -48,6 +50,13 @@ // to users. Currently missing bindings. const promiseIdSymbol = SymbolFor("Deno.core.internalPromiseId"); + let opCallTracingEnabled = false; + const opCallTraces = new Map(); + + function enableOpCallTracing() { + opCallTracingEnabled = true; + } + function setPromise(promiseId) { const idx = promiseId % RING_SIZE; // Move old promise from ring to map @@ -139,7 +148,17 @@ const maybeError = opcallAsync(opsCache[opName], promiseId, arg1, arg2); // Handle sync error (e.g: error parsing args) if (maybeError) return unwrapOpResult(maybeError); - const p = PromisePrototypeThen(setPromise(promiseId), unwrapOpResult); + let p = PromisePrototypeThen(setPromise(promiseId), unwrapOpResult); + if (opCallTracingEnabled) { + // Capture a stack trace by creating a new `Error` object. We remove the + // first 6 characters (the `Error\n` prefix) to get just the stack trace. + const stack = StringPrototypeSlice(new Error().stack, 6); + MapPrototypeSet(opCallTraces, promiseId, { opName, stack }); + p = PromisePrototypeFinally( + p, + () => MapPrototypeDelete(opCallTraces, promiseId), + ); + } // Save the id on the promise so it can later be ref'ed or unref'ed p[promiseIdSymbol] = promiseId; return p; @@ -226,6 +245,8 @@ BadResourcePrototype, Interrupted, InterruptedPrototype, + enableOpCallTracing, + opCallTraces, }); ObjectAssign(globalThis.__bootstrap, { core }); |