mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-04-20 11:36:10 +00:00
LibJS: Do not generate implicit await for async functions
Despite the comment in our source, as far as I can tell from my testing, other engines do not appear to do this. For example, the result of the following test now matches node and LibJS by logging `0` calls. ``` async function myFunction() { let calls = 0; function makeConstructorObservable(promise) { Object.defineProperty(promise, "constructor", { get() { calls++; return Promise; }, }); return promise; } async function test() { try { return makeConstructorObservable(Promise.reject(1)); } catch { return 2; } } test().catch(() => { }); console.log(calls); }; myFunction() ``` We regress in one test262 Array.fromAsync test, but as far as I can tell this is due to some unrelated issue in the engine. Fixes #3251
This commit is contained in:
parent
cba9c099c8
commit
b34a8a38c6
2 changed files with 11 additions and 16 deletions
|
@ -1852,12 +1852,7 @@ Bytecode::CodeGenerationErrorOr<Optional<ScopedOperand>> ReturnStatement::genera
|
|||
return_value = TRY(m_argument->generate_bytecode(generator)).value();
|
||||
|
||||
// 3. If GetGeneratorKind() is async, set exprValue to ? Await(exprValue).
|
||||
// Spec Issue?: The spec doesn't seem to do implicit await on explicit return for async functions, but does for
|
||||
// async generators. However, the major engines do so, and this is observable via constructor lookups
|
||||
// on Promise objects and custom thenables.
|
||||
// See: https://tc39.es/ecma262/#sec-asyncblockstart
|
||||
// c. Assert: If we return here, the async function either threw an exception or performed an implicit or explicit return; all awaiting is done.
|
||||
if (generator.is_in_async_function()) {
|
||||
if (generator.is_in_async_generator_function()) {
|
||||
auto received_completion = generator.allocate_register();
|
||||
auto received_completion_type = generator.allocate_register();
|
||||
auto received_completion_value = generator.allocate_register();
|
||||
|
|
|
@ -202,7 +202,7 @@ describe("await cannot be used in class static init blocks", () => {
|
|||
});
|
||||
|
||||
describe("await thenables", () => {
|
||||
test("async returning a thanable variable without fulfilling", () => {
|
||||
test("async returning a thenable variable without fulfilling", () => {
|
||||
let isCalled = false;
|
||||
const obj = {
|
||||
then() {
|
||||
|
@ -216,7 +216,7 @@ describe("await thenables", () => {
|
|||
expect(isCalled).toBe(true);
|
||||
});
|
||||
|
||||
test("async returning a thanable variable that fulfills", () => {
|
||||
test("async returning a thenable variable that fulfills", () => {
|
||||
let isCalled = false;
|
||||
const obj = {
|
||||
then(fulfill) {
|
||||
|
@ -240,7 +240,7 @@ describe("await thenables", () => {
|
|||
});
|
||||
f();
|
||||
runQueuedPromiseJobs();
|
||||
expect(isCalled).toBe(true);
|
||||
expect(isCalled).toBe(false);
|
||||
});
|
||||
|
||||
test("async returning a thenable directly that fulfills", () => {
|
||||
|
@ -253,7 +253,7 @@ describe("await thenables", () => {
|
|||
});
|
||||
f();
|
||||
runQueuedPromiseJobs();
|
||||
expect(isCalled).toBe(true);
|
||||
expect(isCalled).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -279,15 +279,10 @@ describe("await observably looks up constructor of Promise objects increasing ca
|
|||
try {
|
||||
await makeConstructorObservable(Promise.reject(3));
|
||||
} catch {}
|
||||
try {
|
||||
return makeConstructorObservable(Promise.reject(1));
|
||||
} catch {
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
test();
|
||||
runQueuedPromiseJobs();
|
||||
expect(calls).toBe(4);
|
||||
expect(calls).toBe(3);
|
||||
});
|
||||
|
||||
describe("await observably looks up constructor of Promise objects not increasing call count", () => {
|
||||
|
@ -306,6 +301,11 @@ describe("await observably looks up constructor of Promise objects not increasin
|
|||
await makeConstructorObservable(new Boolean(true));
|
||||
await makeConstructorObservable({});
|
||||
await makeConstructorObservable(new Number(2));
|
||||
try {
|
||||
return makeConstructorObservable(Promise.reject(1));
|
||||
} catch {
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
test();
|
||||
runQueuedPromiseJobs();
|
||||
|
|
Loading…
Add table
Reference in a new issue