Skip to content

Commit

Permalink
Deoptimize return values of async functions
Browse files Browse the repository at this point in the history
  • Loading branch information
lukastaegert committed Jul 1, 2021
1 parent 9cb15d6 commit 2493164
Show file tree
Hide file tree
Showing 8 changed files with 83 additions and 3 deletions.
14 changes: 13 additions & 1 deletion src/ast/nodes/ArrowFunctionExpression.ts
Expand Up @@ -20,6 +20,7 @@ export default class ArrowFunctionExpression extends NodeBase {
preventChildBlockScope!: true;
scope!: ReturnValueScope;
type!: NodeType.tArrowFunctionExpression;
private deoptimizedReturn = false;

createScope(parentScope: Scope): void {
this.scope = new ReturnValueScope(parentScope, this.context);
Expand All @@ -37,7 +38,18 @@ export default class ArrowFunctionExpression extends NodeBase {
deoptimizeThisOnEventAtPath(): void {}

getReturnExpressionWhenCalledAtPath(path: ObjectPath): ExpressionEntity {
return !this.async && path.length === 0 ? this.scope.getReturnExpression() : UNKNOWN_EXPRESSION;
if (path.length !== 0) {
return UNKNOWN_EXPRESSION;
}
if (this.async) {
if (!this.deoptimizedReturn) {
this.deoptimizedReturn = true;
this.scope.getReturnExpression().deoptimizePath(UNKNOWN_PATH);
this.context.requestTreeshakingPass();
}
return UNKNOWN_EXPRESSION;
}
return this.scope.getReturnExpression();
}

hasEffects(): boolean {
Expand Down
1 change: 1 addition & 0 deletions src/ast/nodes/AwaitExpression.ts
Expand Up @@ -34,5 +34,6 @@ export default class AwaitExpression extends NodeBase {
protected applyDeoptimizations(): void {
this.deoptimized = true;
this.argument.deoptimizePath(UNKNOWN_PATH);
this.context.requestTreeshakingPass();
}
}
14 changes: 13 additions & 1 deletion src/ast/nodes/shared/FunctionNode.ts
Expand Up @@ -21,6 +21,7 @@ export default class FunctionNode extends NodeBase {
params!: PatternNode[];
preventChildBlockScope!: true;
scope!: FunctionScope;
private deoptimizedReturn = false;
private isPrototypeDeoptimized = false;

createScope(parentScope: FunctionScope): void {
Expand Down Expand Up @@ -57,7 +58,18 @@ export default class FunctionNode extends NodeBase {
}

getReturnExpressionWhenCalledAtPath(path: ObjectPath): ExpressionEntity {
return !this.async && path.length === 0 ? this.scope.getReturnExpression() : UNKNOWN_EXPRESSION;
if (path.length !== 0) {
return UNKNOWN_EXPRESSION;
}
if (this.async) {
if (!this.deoptimizedReturn) {
this.deoptimizedReturn = true;
this.scope.getReturnExpression().deoptimizePath(UNKNOWN_PATH);
this.context.requestTreeshakingPass();
}
return UNKNOWN_EXPRESSION;
}
return this.scope.getReturnExpression();
}

hasEffects(): boolean {
Expand Down
@@ -0,0 +1,10 @@
const assert = require('assert');

module.exports = {
description: 'tracks object mutations of async arrow function return values',
async exports(exports) {
assert.strictEqual(exports.toggled, false);
await exports.test();
assert.strictEqual(exports.toggled, true);
}
};
@@ -0,0 +1,18 @@
const fn = async () => {
const obj = {
test() {
if (typeof obj.testfn === 'function') {
obj.testfn();
}
}
};
return obj;
};

export let toggled = false;

export const test = async function () {
const obj = await fn();
obj.testfn = () => (toggled = true);
obj.test();
};
10 changes: 10 additions & 0 deletions test/function/samples/track-async-function-return-value/_config.js
@@ -0,0 +1,10 @@
const assert = require('assert');

module.exports = {
description: 'tracks object mutations of async function return values',
async exports(exports) {
assert.strictEqual(exports.toggled, false);
await exports.test();
assert.strictEqual(exports.toggled, true);
}
};
18 changes: 18 additions & 0 deletions test/function/samples/track-async-function-return-value/main.js
@@ -0,0 +1,18 @@
async function fn() {
const obj = {
test() {
if (typeof obj.testfn === 'function') {
obj.testfn();
}
}
};
return obj;
}

export let toggled = false;

export const test = async function () {
const obj = await fn();
obj.testfn = () => (toggled = true);
obj.test();
};
1 change: 0 additions & 1 deletion test/function/samples/track-awaited-object/main.js
Expand Up @@ -6,7 +6,6 @@ function fn() {
}
}
};

return obj;
}

Expand Down

0 comments on commit 2493164

Please sign in to comment.