Commit b1a97694 authored by Benedikt Meurer's avatar Benedikt Meurer Committed by Commit Bot

[async] Follow initial promise chains created via Promise#then().

For the --async-stack-traces we can also look through initial parts of
the promise chain that were created by regular Promise#then() calls to
walk up to the first async function frame. This addresses the missing
support for aforementioned example

```js
(async function() {
  await Promise.resolve().then(() =>
    console.log(new Error().stack));
})();
```

which now also works.

Bug: v8:7522
Change-Id: I574943c1fc6ee4a1bd56f208dce78eb7506c5c4f
Reviewed-on: https://chromium-review.googlesource.com/c/1278276Reviewed-by: 's avatarMaya Lekova <mslekova@chromium.org>
Commit-Queue: Benedikt Meurer <bmeurer@chromium.org>
Cr-Commit-Position: refs/heads/master@{#56613}
parent 75b56661
...@@ -784,6 +784,18 @@ Handle<Object> Isolate::CaptureSimpleStackTrace(Handle<JSReceiver> error_object, ...@@ -784,6 +784,18 @@ Handle<Object> Isolate::CaptureSimpleStackTrace(Handle<JSReceiver> error_object,
JSPromise::cast(async_generator_request->promise()), this); JSPromise::cast(async_generator_request->promise()), this);
CaptureAsyncStackTrace(this, promise, &builder); CaptureAsyncStackTrace(this, promise, &builder);
} }
} else {
// The {promise_reaction_job_task} doesn't belong to an await (or
// yield inside an async generator), but we might still be able to
// find an async frame if we follow along the chain of promises on
// the {promise_reaction_job_task}.
Handle<HeapObject> promise_or_capability(
promise_reaction_job_task->promise_or_capability(), this);
if (promise_or_capability->IsJSPromise()) {
Handle<JSPromise> promise =
Handle<JSPromise>::cast(promise_or_capability);
CaptureAsyncStackTrace(this, promise, &builder);
}
} }
} }
} }
......
...@@ -268,3 +268,34 @@ ...@@ -268,3 +268,34 @@
await test(one); await test(one);
})()); })());
})(); })();
// Basic test to check that we also follow initial
// promise chains created via Promise#then().
(function() {
async function one(p) {
return await p.then(two);
}
function two() {
throw new Error();
}
async function test(f) {
try {
await f(Promise.resolve());
assertUnreachable();
} catch (e) {
assertInstanceof(e, Error);
assertMatches(/Error.+at two.+at async one.+at async test/ms, e.stack);
}
}
assertPromiseResult((async () => {
await test(one);
await test(one);
%OptimizeFunctionOnNextCall(two);
await test(one);
%OptimizeFunctionOnNextCall(one);
await test(one);
})());
})();
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment