(cfg, branchBlock, bodyBlock, phiNode)
| 339 | } |
| 340 | |
| 341 | executeBodyCallback(cfg, branchBlock, bodyBlock, phiNode) { |
| 342 | CFG.pushBlock(cfg, bodyBlock); |
| 343 | |
| 344 | // Create phi node references to pass to the body callback |
| 345 | const phiVars = {}; |
| 346 | const phiNodesForBody = {}; |
| 347 | CFG.pushBlockForModification(cfg, branchBlock); |
| 348 | for (const [varName, initialValueNode] of Object.entries(this.initialVars)) { |
| 349 | if (varName !== 'loopVar') { |
| 350 | // Create phi node that will be used for the final result |
| 351 | const varPhiNode = createPhiNode(this.strandsContext, [ |
| 352 | { value: initialValueNode, blockId: branchBlock }, // Initial value |
| 353 | { value: initialValueNode, blockId: bodyBlock } // Placeholder - will update after body execution |
| 354 | ], varName); |
| 355 | phiNodesForBody[varName] = varPhiNode; |
| 356 | phiVars[varName] = createStrandsNode(varPhiNode.id, varPhiNode.dimension, this.strandsContext); |
| 357 | } |
| 358 | } |
| 359 | CFG.popBlock(cfg); |
| 360 | |
| 361 | const loopVarNode = createStrandsNode(phiNode.id, phiNode.dimension, this.strandsContext); |
| 362 | this.bodyResults = this.bodyCb(loopVarNode, phiVars) || {}; |
| 363 | for (const key in this.bodyResults) { |
| 364 | this.bodyResults[key] = this.strandsContext.p5.strandsNode(this.bodyResults[key]); |
| 365 | } |
| 366 | this.phiNodesForBody = phiNodesForBody; |
| 367 | // Capture the final block after body execution before popping |
| 368 | this.finalBodyBlock = cfg.currentBlock; |
| 369 | CFG.popBlock(cfg); |
| 370 | } |
| 371 | |
| 372 | loopIsBounded(initialVar, conditionNode, updateVar) { |
| 373 | // A loop is considered "bounded" if we can determine at compile time that it will |
no test coverage detected