Skip to content

Commit

Permalink
Merge branch 'master' of https://github.com/rollup/rollup into sync-5…
Browse files Browse the repository at this point in the history
…d377780
  • Loading branch information
docschina-bot committed Dec 21, 2024
2 parents 5ea4fed + 5d37778 commit 2bd82ba
Show file tree
Hide file tree
Showing 8 changed files with 51 additions and 17 deletions.
13 changes: 13 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,18 @@
# rollup changelog

## 4.29.1

_2024-12-21_

### Bug Fixes

- Fix crash from deoptimized logical expressions (#5771)

### Pull Requests

- [#5769](https://github.com/rollup/rollup/pull/5769): Remove unnecessary lifetimes (@lukastaegert)
- [#5771](https://github.com/rollup/rollup/pull/5771): fix: do not optimize the literal value if the cache is deoptimized (@TrickyPi)

## 4.29.0

_2024-12-20_
Expand Down
2 changes: 1 addition & 1 deletion browser/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@rollup/browser",
"version": "4.29.0",
"version": "4.29.1",
"description": "Next-generation ES module bundler browser build",
"main": "dist/rollup.browser.js",
"module": "dist/es/rollup.browser.js",
Expand Down
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "rollup",
"version": "4.29.0",
"version": "4.29.1",
"description": "Next-generation ES module bundler",
"main": "dist/rollup.js",
"module": "dist/es/rollup.js",
Expand Down
34 changes: 22 additions & 12 deletions src/ast/nodes/LogicalExpression.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,13 @@ export default class LogicalExpression extends NodeBase implements Deoptimizable
private expressionsToBeDeoptimized: DeoptimizableEntity[] = [];
private usedBranch: ExpressionNode | null = null;

private get hasDeoptimizedCache(): boolean {
return isFlagSet(this.flags, Flag.hasDeoptimizedCache);
}
private set hasDeoptimizedCache(value: boolean) {
this.flags = setFlag(this.flags, Flag.hasDeoptimizedCache, value);
}

deoptimizeArgumentsOnInteractionAtPath(
interaction: NodeInteraction,
path: ObjectPath,
Expand All @@ -61,22 +68,24 @@ export default class LogicalExpression extends NodeBase implements Deoptimizable
}

deoptimizeCache(): void {
if (this.hasDeoptimizedCache) return;
if (this.usedBranch) {
const unusedBranch = this.usedBranch === this.left ? this.right : this.left;
this.usedBranch = null;
unusedBranch.deoptimizePath(UNKNOWN_PATH);
const {
scope: { context },
expressionsToBeDeoptimized
} = this;
this.expressionsToBeDeoptimized = EMPTY_ARRAY as unknown as DeoptimizableEntity[];
for (const expression of expressionsToBeDeoptimized) {
expression.deoptimizeCache();
}
// Request another pass because we need to ensure "include" runs again if
// it is rendered
context.requestTreeshakingPass();
}
const {
scope: { context },
expressionsToBeDeoptimized
} = this;
this.expressionsToBeDeoptimized = EMPTY_ARRAY as unknown as DeoptimizableEntity[];
for (const expression of expressionsToBeDeoptimized) {
expression.deoptimizeCache();
}
// Request another pass because we need to ensure "include" runs again if
// it is rendered
context.requestTreeshakingPass();
this.hasDeoptimizedCache = true;
}

deoptimizePath(path: ObjectPath): void {
Expand All @@ -98,7 +107,7 @@ export default class LogicalExpression extends NodeBase implements Deoptimizable
if (usedBranch) {
this.expressionsToBeDeoptimized.push(origin);
return usedBranch.getLiteralValueAtPath(path, recursionTracker, origin);
} else {
} else if (!this.hasDeoptimizedCache) {
const rightValue = this.right.getLiteralValueAtPath(path, recursionTracker, origin);
const booleanOrUnknown = tryCastLiteralValueToBoolean(rightValue);
if (typeof booleanOrUnknown !== 'symbol') {
Expand All @@ -107,6 +116,7 @@ export default class LogicalExpression extends NodeBase implements Deoptimizable
return UnknownFalsyValue;
}
if (booleanOrUnknown && this.operator === '||') {
this.expressionsToBeDeoptimized.push(origin);
return UnknownTruthyValue;
}
}
Expand Down
3 changes: 2 additions & 1 deletion src/ast/nodes/shared/BitFlags.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@ export const enum Flag {
tail = 1 << 20,
prefix = 1 << 21,
generator = 1 << 22,
expression = 1 << 23
expression = 1 << 23,
hasDeoptimizedCache = 1 << 24
}

export function isFlagSet(flags: number, flag: Flag): boolean {
Expand Down
3 changes: 3 additions & 0 deletions test/function/samples/treeshake-logical-expression/_config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
module.exports = defineTest({
description: 'do not optimize the literal value of logical expression if the cache is deoptimized'
});
7 changes: 7 additions & 0 deletions test/function/samples/treeshake-logical-expression/main.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
let count = 0;
let foo = false;
let condition = foo && false;
if (!condition) count++;
foo = true;
if (!condition) count++;
assert.strictEqual(count, 2);

0 comments on commit 2bd82ba

Please sign in to comment.