Skip to content
Open
Changes from 1 commit
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
b0c3aed
Add ControlFlowType enum, ControlFlowMarker class, and RuntimeControl…
fglock Nov 6, 2025
e7b78e9
Modify EmitControlFlow to return marked RuntimeList for non-local con…
fglock Nov 6, 2025
48d5cd5
Add control flow check infrastructure (disabled) - WIP Phase 3
fglock Nov 6, 2025
10f631b
Phase 2 complete: Non-local control flow via tagged returns (99.8%)
fglock Nov 6, 2025
937c0b3
Fix plan: Skip Phase 3 (call-site checks), renumber to make straightf…
fglock Nov 6, 2025
86daaee
Phase 3 partial: Add TAILCALL trampoline at returnLabel (99.8% mainta…
fglock Nov 6, 2025
c03f76f
Phase 3: Tail call trampoline working, call-site checks deferred
fglock Nov 6, 2025
28f39a0
feat: Add feature flags and Phase 3 loop handler infrastructure
fglock Nov 6, 2025
0d1cccb
feat: Implement Phase 4 (Top-Level Safety)
fglock Nov 6, 2025
4a8a369
feat: Propagate isMainProgram flag to code generation
fglock Nov 6, 2025
1f5bc8b
feat: Add source location tracking to control flow markers
fglock Nov 6, 2025
5544bbc
feat: Pass source location to RuntimeControlFlowList
fglock Nov 6, 2025
065bc87
docs: Streamline design doc to action-oriented plan
fglock Nov 6, 2025
c4db263
feat: Dynamic slot allocation for control flow temp storage
fglock Nov 6, 2025
a183087
docs: Update plan with ASM frame computation findings
fglock Nov 6, 2025
e8c5a85
docs: Add critical decision document for control flow architecture
fglock Nov 6, 2025
e3bcbad
docs: Document existing SKIP workarounds to be removed
fglock Nov 6, 2025
b9ec4d0
fix: Remove top-level safety check - restored 99.8% pass rate
fglock Nov 6, 2025
0405780
docs: Update plan - Phases 5 & 6 complete (99.9% pass rate)
fglock Nov 6, 2025
c5c895d
test: Add comprehensive control flow unit tests
fglock Nov 6, 2025
fe226a3
Fix goto __SUB__ tail call by detecting it in handleGotoLabel
fglock Nov 6, 2025
326a856
Update MILESTONES.md: goto __SUB__ is now working
fglock Nov 6, 2025
bb0e5fe
Update design document: Phase 7 (Tail Call Trampoline) COMPLETE
fglock Nov 6, 2025
8c674dd
Add comprehensive comments explaining disabled features and next steps
fglock Nov 6, 2025
d5477dd
Update MILESTONES.md: Mark Phase 7 (Non-local control flow) as COMPLETE
fglock Nov 6, 2025
84084ac
Update FEATURE_MATRIX.md: Add tail call features, simplify control fl…
fglock Nov 6, 2025
055630b
docs
fglock Nov 6, 2025
cb28263
fix: Prevent RuntimeControlFlowList from being corrupted as data
fglock Nov 6, 2025
7cc0bf1
docs: Document RuntimeControlFlowList data corruption fix
fglock Nov 6, 2025
2d03783
docs: Comprehensive analysis of ASM frame computation blocker
fglock Nov 6, 2025
ee4cb82
feat: Implement runtime control flow registry for 'last SKIP' support
fglock Nov 6, 2025
b2e23ef
docs: Add comprehensive documentation for control flow registry solution
fglock Nov 6, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Fix plan: Skip Phase 3 (call-site checks), renumber to make straightf…
…orward

CORRECTED PLAN:
- Phase 1: Runtime classes ✅ DONE
- Phase 2: Control flow emission ✅ DONE (99.8% pass rate!)
- Phase 3: Loop handlers (NEXT - what we actually need!)
- Phase 4: Top-level safety
- Phase 5: Cleanup
- Phase 6: Testing
- Phase 7: Optional call-site optimization (deferred)
- Phase 8: Optional loop extraction (only if needed)

RATIONALE:
- Call-site checks are an optimization, not a requirement
- Control flow already propagates naturally through return values
- Loop handlers are what we need to make it actually work
- Better to implement in correct order: core functionality first, optimization later
- No surprises - straightforward sequential implementation!
  • Loading branch information
fglock committed Nov 6, 2025
commit 937c0b3cce3049f985ad5a53dc9e919ec0689576
59 changes: 43 additions & 16 deletions dev/design/TAGGED_RETURN_CONTROL_FLOW.md
Original file line number Diff line number Diff line change
Expand Up @@ -792,19 +792,31 @@ OUTER: for (@outer) {

---

### Phase 3: Call Site Checks - Detect and Handle Marked Returns
**Goal**: Add checks after subroutine calls to detect marked RuntimeList and handle control flow.
### Phase 3: SKIPPED - Not Needed Yet!

**⚠️ KEY OPTIMIZATION**: One trampoline per subroutine, not per call site!
- Call sites only check for control flow (~15 bytes each)
- TAILCALL jumps to `returnLabel` like other control flow
- Single trampoline loop at `returnLabel` handles all tail calls
- Much more efficient than inlining trampoline at every call site
**Original Goal**: Add call-site checks after subroutine calls to detect marked RuntimeList early.

**Why Skipped**:
- Control flow already propagates naturally through return values (Phase 2 works!)
- Call-site checks are an optimization, not a requirement
- Loop handlers (Phase 4) will catch the marked RuntimeList when it matters
- Adding call-site checks now creates complex stack management issues
- Better to implement loop handlers first, then optimize with call-site checks later

**Decision**: Move directly to Phase 4 (Loop Handlers) which is what we actually need.

---

### OLD Phase 3 (for future reference - may implement as Phase 7 optimization)

**Goal**: Add checks after subroutine calls to detect marked RuntimeList and handle control flow early.

**⚠️ TECHNICAL CHALLENGE**: Requires pre-allocated temp variable slots
- Dynamic `allocateLocalVariable()` during bytecode emission breaks ASM frame computation
- Need to pre-allocate slots at method creation time in `EmitterMethodCreator`
- Or use a static helper method to avoid inline frame issues

**⚠️ CONTINGENCY PLAN**: If "Method too large" errors occur during this phase:
1. **Immediate workaround**: Use a static flag `ENABLE_TAIL_CALLS = false` to disable tail call support
2. **Full fix**: Implement Phase 8 (loop extraction) early if needed
3. **Rationale**: This lets us continue development and test other phases
**⚠️ KEY OPTIMIZATION**: One trampoline per subroutine, not per call site!

**Files to modify**:
1. `src/main/java/org/perlonjava/codegen/EmitSubroutine.java`
Expand Down Expand Up @@ -905,9 +917,11 @@ returnLabel:

---

### Phase 4: Loop Handlers - Handle Control Flow in Loops
### Phase 3: Loop Handlers - Handle Control Flow in Loops
**Goal**: Generate control flow handlers for labeled loops to process marked RuntimeList.

**Why This Is Next**: This is what we actually need! Phase 2 returns marked RuntimeList, now we need loops to catch and handle them.

**Files to modify**:
1. `src/main/java/org/perlonjava/codegen/EmitForeach.java`
2. `src/main/java/org/perlonjava/codegen/EmitStatement.java`
Expand Down Expand Up @@ -983,7 +997,7 @@ propagate:

---

### Phase 5: Top-Level Safety - Catch Unhandled Control Flow
### Phase 4: Top-Level Safety - Catch Unhandled Control Flow
**Goal**: Add error handler to catch control flow that escapes to top level.

**File to modify**: `src/main/java/org/perlonjava/runtime/RuntimeCode.java`
Expand All @@ -1009,7 +1023,7 @@ propagate:

---

### Phase 6: Cleanup - Remove Old Exception-Based Code
### Phase 5: Cleanup - Remove Old Exception-Based Code
**Goal**: Remove exception classes and exception handlers that are no longer needed.

**Files to delete**:
Expand Down Expand Up @@ -1042,7 +1056,7 @@ propagate:

---

### Phase 7: Testing & Validation
### Phase 6: Testing & Validation
**Goal**: Comprehensive testing to ensure correctness and performance.

**Critical Regression Tests** (run before commit):
Expand Down Expand Up @@ -1079,7 +1093,20 @@ make test

---

### Phase 8: Optional Performance Optimization (if needed)
### Phase 7: Optional - Call-Site Checks (Future Optimization)

**Goal**: Add early detection of control flow at subroutine call sites (optional optimization).

**Status**: Deferred - not critical for correctness, only for early detection.

**Challenges**:
- Requires pre-allocated temp variable slots or helper methods
- ASM frame computation issues with dynamic allocation
- Better to validate correctness first, optimize later

---

### Phase 8: Optional - Loop Extraction (if "Method too large" errors occur)
**Goal**: Only if "Method too large" errors occur, add bytecode size management.

**When to do this**: Only if tests in Phase 7 reveal "Method too large" errors.
Expand Down