| … | … | @@ -4324,11 +4324,14 @@ injected per layer: |
| 4324 | 4324 | any promise they resolve directly, would be captured. The fix, as migration scaffold deleted at R4i together |
| 4325 | 4325 | with `Sync` (same lint), is a BOUNDARY MARKER: |
| 4326 | 4326 | - **rt:** a scope can be a FRONTIER scope (`scopePush(frontier)`). `scaffold::Foreign` is an RAII frame. While |
| 4327 | | it is the innermost frame, `queueMicrotask`, `complete` and `rejectedWithNoHandler` go to the context |
| 4328 | | outside the OUTERMOST open frontier: the root, or a non-frontier scope around it. That is today's position. |
| 4329 | | A core call that re-enters from foreign code opens its own scope on top, and is isolated again. With no |
| 4330 | | frontier open, `Foreign` pushes nothing. `scopeCheckpoint` / `scopeDeliver` / `scopePop` throw while a |
| 4331 | | `Foreign` frame is innermost; `handlerAdded` searches every level, as before. |
| 4327 | it is the innermost frame, `queueMicrotask`, `complete` and `rejectedWithNoHandler` go where they would go |
| 4328 | with NO frontier open: frontier frames are transparent, so the target is the innermost non-frontier scope, |
| 4329 | or the root. That is today's position by construction. "Outside the outermost frontier" was the first |
| 4330 | wording; it differs when foreign code opens its own `Sync` and calls core again, where it would have |
| 4331 | escaped that `Sync`. A core call that re-enters from foreign code opens its own scope on top, and is |
| 4332 | isolated again. With no frontier open, `Foreign` pushes nothing. `scopeCheckpoint` / `scopeDeliver` / |
| 4333 | `scopePop` and `rt::callback` throw while a `Foreign` frame is innermost (a native callback's checkpoint |
| 4334 | would drain the outer queue mid-frontier); `handlerAdded` searches every level, as before. |
| 4332 | 4335 | - **scaffold:** `Frontier` is a `Sync` (same `wait`, same drain to quiescence) that pushes a frontier scope. |
| 4333 | 4336 | E0's frontier sites use `Frontier`; core's internal storage scopes stay `Sync`. |
| 4334 | 4337 | - **core:** foreign functions are wrapped WHERE THEY ENTER core, not at each call site (`scaffold::foreign(fn)` |
| … | … | @@ -4336,9 +4339,9 @@ injected per layer: |
| 4336 | 4339 | hooks where repl assigns them, listeners at registration, option callbacks when stored. |
| 4337 | 4340 | - **Lint:** inside core, no `std::function` that came from outside core is invoked unwrapped. |
| 4338 | 4341 | - **Gate:** r4c_scaffold gains cases for this: foreign work queued inside a frontier runs after it, in FIFO |
| 4339 | | with the root's; re-entry from a `Foreign` frame is isolated; nested frontiers target the OUTERMOST |
| 4340 | | frontier's parent; a `Sync` inside a frontier captures as before; checkpoint / deliver / pop under a |
| 4341 | | `Foreign` frame throw. E0's gates (ctest, m4b / m4c / m4d / m3c / m5* / r3c) must be identical, which shows |
| 4342 | with the root's; re-entry from a `Foreign` frame is isolated; nested frontiers are transparent; a `Sync` |
| 4343 | opened by foreign code keeps what a nested `Foreign` queues; a `Sync` inside a frontier captures as before; |
| 4344 | checkpoint / deliver / pop / callback under a `Foreign` frame throw. E0's gates (ctest, m4b / m4c / m4d / m3c / m5* / r3c) must be identical, which shows |
| 4342 | 4345 | the frontier is atomic and no foreign work moved. A drill: removing any one wrapper must go red in a gate. |
| 4343 | 4346 | - **Rules carried from the hazards:** |
| 4344 | 4347 | - **Timer-resumed continuations open their own `Sync`.** `waitForRecovery`'s tail holds the state mutex, and |