fix: seed _generateCallWithError's local visited set from main traversal
- _emitBranch now sets _genVisited on blocks before calling generateOwnCode so that proc calls inside loop bodies can seed their error-handling visited set from the main traversal, preventing loop-decision re-walk - Add _noWalkNext flag on proc calls when error handling is active, so _emitBranch skips redundant nextFlow walking (the success path was already covered by the error-handling branch emission) - Known issue: shared blocks that are direct roots of emitBranch (from the shared set) may still be re-walked when they were already emitted by a downstream proc call's error-handling success path
This commit is contained in:
+13
-6
@@ -108,18 +108,23 @@
|
||||
return;
|
||||
}
|
||||
if (isDecision(el)) {
|
||||
// Decisions manage their own visited tracking inside generateCode.
|
||||
parts.push(el.generateCode(visited, loopTargets));
|
||||
} else {
|
||||
visited.add(el);
|
||||
if (loopTargets.has(el)) {
|
||||
parts.push("\n" + (el.id || "block") + ":");
|
||||
}
|
||||
el._genVisited = visited;
|
||||
parts.push(el.generateOwnCode());
|
||||
var flow = el.wcNextFlow || el.nextFlow || [];
|
||||
for (var j = 0; j < flow.length; j++) {
|
||||
walk(flow[j].toElement);
|
||||
// If the block's generateOwnCode already walked the success path
|
||||
// (e.g. error-handling proc call), don't re-walk its nextFlow.
|
||||
if (!el._noWalkNext) {
|
||||
var flow = el.wcNextFlow || el.nextFlow || [];
|
||||
for (var j = 0; j < flow.length; j++) {
|
||||
walk(flow[j].toElement);
|
||||
}
|
||||
}
|
||||
el._noWalkNext = false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -137,7 +142,7 @@
|
||||
* then success-exclusive and shared code after it (no else).
|
||||
*/
|
||||
CodeGen.generateCallWithError = function (
|
||||
ifHeader, errTargets, okTargets, isDecision, loopTargets
|
||||
ifHeader, errTargets, okTargets, isDecision, loopTargets, mainVisited
|
||||
) {
|
||||
loopTargets = loopTargets || new Set();
|
||||
var errAll = CodeGen.branchDescendants(errTargets, isDecision);
|
||||
@@ -147,7 +152,9 @@
|
||||
if (okAll.has(b)) shared.add(b);
|
||||
});
|
||||
|
||||
var visited = new Set();
|
||||
// Create a local visited seeded from the main set so blocks walked by
|
||||
// the error/success branches don't pollute the main traversal's set.
|
||||
var visited = new Set(mainVisited || []);
|
||||
var errCode = CodeGen.emitBranch(errTargets, shared, visited, isDecision, loopTargets);
|
||||
var okCode = CodeGen.emitBranch(okTargets, shared, visited, isDecision, loopTargets);
|
||||
var sharedCode = CodeGen.emitBranch(
|
||||
|
||||
Reference in New Issue
Block a user