mirror of
https://github.com/morluto/rea.git
synced 2026-10-30 11:25:39 +00:00
fix(javascript): handle deep AST traversal and addition without stack overflow (#915)
* fix(javascript): avoid recursion and eager ancestry copies in deep ASTs * fix(javascript): traverse static analysis and bundler ASTs iteratively
This commit is contained in:
1 parent
f6a58f1062
commit
62b37111e7
9 files changed
+203
-40
No files matched your search
@@ -268,12 +268,38 @@ const evaluateAddition = (
|
||||
node: t.BinaryExpression,
|
||||
context: EvaluationContext,
|
||||
): JavaScriptSemanticValue => {
|
||||
const left = primitiveCandidates(
|
||||
evaluateExpression(node.left, nestedContext(context)),
|
||||
);
|
||||
const right = primitiveCandidates(
|
||||
evaluateExpression(node.right, nestedContext(context)),
|
||||
);
|
||||
const pending: {
|
||||
readonly node: t.BinaryExpression;
|
||||
left: JavaScriptSemanticValue | undefined;
|
||||
}[] = [];
|
||||
let current: t.Node = node;
|
||||
while (true) {
|
||||
if (t.isBinaryExpression(current, { operator: "+" })) {
|
||||
pending.push({ node: current, left: undefined });
|
||||
current = current.left;
|
||||
continue;
|
||||
}
|
||||
let value = evaluateExpression(current, nestedContext(context));
|
||||
while (true) {
|
||||
const parent = pending.at(-1);
|
||||
if (parent === undefined) return value;
|
||||
if (parent.left === undefined) {
|
||||
parent.left = value;
|
||||
current = parent.node.right;
|
||||
break;
|
||||
}
|
||||
value = addPrimitiveValues(parent.left, value);
|
||||
pending.pop();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const addPrimitiveValues = (
|
||||
leftValue: JavaScriptSemanticValue,
|
||||
rightValue: JavaScriptSemanticValue,
|
||||
): JavaScriptSemanticValue => {
|
||||
const left = primitiveCandidates(leftValue);
|
||||
const right = primitiveCandidates(rightValue);
|
||||
if (left === null || right === null)
|
||||
return { status: "unknown", reason: "Non-primitive addition." };
|
||||
const values = left.flatMap((leftValue) =>
|
||||
|
||||
Reference in new issue
Block a user