Skip to content

Commit aba9c8e

Browse files
tniessendanielleadams
authored andcommitted
repl: fix overzealous top-level await
Fixes: #43777 PR-URL: #43827 Reviewed-By: Guy Bedford <guybedford@gmail.com> Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com> Reviewed-By: Benjamin Gruenbaum <benjamingr@gmail.com> Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de>
1 parent ec7e45e commit aba9c8e

4 files changed

Lines changed: 35 additions & 19 deletions

File tree

‎lib/internal/repl/await.js‎

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -237,8 +237,16 @@ function processTopLevelAwait(src) {
237237
// semicolon. Since there can only be more right parentheses between
238238
// node.expression.end and the semicolon, appending one more to
239239
// node.expression should be fine.
240-
state.prepend(node,'return (');
241-
state.append(node.expression,')');
240+
//
241+
// We also create a wrapper object around the result of the expression.
242+
// Consider an expression of the form `(await x).y`. If we just return
243+
// this expression from an async function, the caller will await `y`, too,
244+
// if it evaluates to a Promise. Instead, we return
245+
// `{ value: ((await x).y) }`, which allows the caller to retrieve the
246+
// awaited value correctly.
247+
state.prepend(node.expression,'{ value: (');
248+
state.prepend(node,'return ');
249+
state.append(node.expression,') }');
242250
}
243251
break;
244252
}

‎lib/repl.js‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -616,7 +616,7 @@ function REPLServer(prompt,
616616

617617
(async()=>{
618618
try{
619-
constresult=awaitpromise;
619+
constresult=(awaitpromise)?.value;
620620
finishExecution(null,result);
621621
}catch(err){
622622
if(err&&process.domain){

‎test/parallel/test-repl-preprocess-top-level-await.js‎

Lines changed: 20 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -17,25 +17,25 @@ const testCases = [
1717
['0',
1818
null],
1919
['await 0',
20-
'(async () => { return (await 0) })()'],
20+
'(async () => { return { value: (await 0) } })()'],
2121
[`await ${surrogate}`,
22-
`(async () => { return (await ${surrogate}) })()`],
22+
`(async () => { return { value: (await ${surrogate}) } })()`],
2323
['await 0;',
24-
'(async () => { return (await 0); })()'],
24+
'(async () => { return { value: (await 0) }; })()'],
2525
['await 0;;;',
26-
'(async () => { return (await 0);;; })()'],
26+
'(async () => { return { value: (await 0) };;; })()'],
2727
[`await ${surrogate};`,
28-
`(async () => { return (await ${surrogate}); })()`],
28+
`(async () => { return { value: (await ${surrogate}) }; })()`],
2929
[`await ${surrogate};`,
30-
`(async () => { return (await ${surrogate}); })()`],
30+
`(async () => { return { value: (await ${surrogate}) }; })()`],
3131
['(await 0)',
32-
'(async () => { return ((await 0)) })()'],
32+
'(async () => { return ({ value: (await 0) }) })()'],
3333
[`(await ${surrogate})`,
34-
`(async () => { return ((await ${surrogate})) })()`],
34+
`(async () => { return ({ value: (await ${surrogate}) }) })()`],
3535
['(await 0);',
36-
'(async () => { return ((await 0)); })()'],
36+
'(async () => { return ({ value: (await 0) }); })()'],
3737
[`(await ${surrogate});`,
38-
`(async () => { return ((await ${surrogate})); })()`],
38+
`(async () => { return ({ value: (await ${surrogate}) }); })()`],
3939
['async function foo() { await 0; }',
4040
null],
4141
['async () => await 0',
@@ -45,7 +45,7 @@ const testCases = [
4545
['await 0; return 0;',
4646
null],
4747
[`await ${surrogate}; await ${surrogate};`,
48-
`(async () => { await ${surrogate}; return (await ${surrogate}); })()`],
48+
`(async () => { await ${surrogate}; return { value: (await ${surrogate}) }; })()`],
4949
['var a = await 1',
5050
'var a; (async () => { void (a = await 1) })()'],
5151
[`var a = await ${surrogate}`,
@@ -71,7 +71,7 @@ const testCases = [
7171
' ([{d}] = [{d: 3}])) })()'],
7272
/* eslint-disable no-template-curly-in-string */
7373
['console.log(`${(await { a: 1 }).a}`)',
74-
'(async () => { return (console.log(`${(await { a: 1 }).a}`)) })()'],
74+
'(async () => { return { value: (console.log(`${(await { a: 1 }).a}`)) } })()'],
7575
/* eslint-enable no-template-curly-in-string */
7676
['await 0; function foo() {}',
7777
'var foo; (async () => { await 0; this.foo = foo; function foo() {} })()'],
@@ -92,15 +92,15 @@ const testCases = [
9292
['let o = await 1, p',
9393
'let o, p; (async () => { void ( (o = await 1), (p=undefined)) })()'],
9494
['await (async () => { let p = await 1; return p; })()',
95-
'(async () => { return (await (async () => '+
96-
'{ let p = await 1; return p; })()) })()'],
95+
'(async () => { return { value: (await (async () => '+
96+
'{ let p = await 1; return p; })()) } })()'],
9797
['{ let p = await 1; }',
9898
'(async () => { { let p = await 1; } })()'],
9999
['var p = await 1',
100100
'var p; (async () => { void (p = await 1) })()'],
101101
['await (async () => { var p = await 1; return p; })()',
102-
'(async () => { return (await (async () => '+
103-
'{ var p = await 1; return p; })()) })()'],
102+
'(async () => { return { value: (await (async () => '+
103+
'{ var p = await 1; return p; })()) } })()'],
104104
['{ var p = await 1; }',
105105
'var p; (async () => { { void (p = await 1); } })()'],
106106
['for await (var i of asyncIterable) { i; }',
@@ -140,6 +140,10 @@ const testCases = [
140140
['var x = await foo(); async function foo() { return Promise.resolve(1);}',
141141
'var x; var foo; (async () => { void (x = await foo()); this.foo = foo; '+
142142
'async function foo() { return Promise.resolve(1);} })()'],
143+
['(await x).y',
144+
'(async () => { return { value: ((await x).y) } })()'],
145+
['await (await x).y',
146+
'(async () => { return { value: (await (await x).y) } })()'],
143147
];
144148

145149
for(const[input,expected]oftestCases){

‎test/parallel/test-repl-top-level-await.js‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,10 @@ async function ordinaryTests() {
182182
'3',
183183
'undefined',
184184
]],
185+
// Regression test for https://github.com/nodejs/node/issues/43777.
186+
['await Promise.resolve(123), Promise.resolve(456)','Promise {',{line: 0}],
187+
['await Promise.resolve(123), await Promise.resolve(456)','456'],
188+
['await (Promise.resolve(123), Promise.resolve(456))','456'],
185189
];
186190

187191
for(const[input,expected=[`${input}\r`],options={}]oftestCases){

0 commit comments

Comments
 (0)