Skip to content
Merged
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ Releases are listed newest first.
- Fixed `--web --max-requests` crash-loop accounting (issue #516): workers that exit after a planned request-quota recycle now use a dedicated status that the master excludes from startup-death streaks, so sustained traffic with a low quota keeps respawning workers instead of shutting down the server; genuine setup failures, other exit codes, and signal deaths still feed the guard.
- Fixed nullable chained array reads (issue #525): consuming a value from a `?array` receiver now releases the one-shot hidden owned Mixed temporary created by nullable access, on both null and non-null paths, without invalidating the extracted result or double-releasing repeated reads.
- Fixed owned boxed Mixed temporaries leaking after string conversion (issue #527): explicit `(string)` casts plus implicit concatenation and interpolation now release detached Mixed sources, including by-value `foreach` element reads and non-null unions represented as Mixed; borrowed, persistent, moved, and non-heap values remain release no-ops.
- Fixed boxed Mixed values leaking when nested loops reinitialize a local whose storage widens after lowering (issue #534): EIR now records a deferred `ReleaseLocalSlot` before the overwrite, prunes it for final scalar or ref-bound slots, and lowers it using the final slot representation. Cleanup is flow-sensitive across conditional ref-cell promotion, aliases, by-reference `foreach` and pointer paths, and widened parameters, preventing both missed releases and double frees with the EIR optimizer enabled or disabled.

## [0.26.1]
- Expanded flow-sensitive type narrowing for PHP's common guard patterns: `int|false` and other false-sentinel unions now preserve the literal `false` subtype and narrow to their success type after a divergent `=== false` guard, without incorrectly removing a full `bool` member; `=== null` and `is_null()` guards narrow nullable values; and stable object properties can be narrowed through `instanceof`, ternaries, and throw guards. Property facts are invalidated after writes or receiver rebindings and are not retained across property hooks or `__get`, whose repeated reads may differ.
Expand Down
2 changes: 1 addition & 1 deletion docs/internals/builtins/pointer/ptr_get.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ sidebar:
## Where it lives

- **Signature**: [`src/builtins/pointers/ptr_get.rs`](https://github.com/illegalstudio/elephc/blob/main/src/builtins/pointers/ptr_get.rs)
- **Lowering**: [`src/codegen/lower_inst/builtins/pointers.rs`:109](https://github.com/illegalstudio/elephc/blob/main/src/codegen/lower_inst/builtins/pointers.rs#L109) (`lower_ptr_get`)
- **Lowering**: [`src/codegen/lower_inst/builtins/pointers.rs`:104](https://github.com/illegalstudio/elephc/blob/main/src/codegen/lower_inst/builtins/pointers.rs#L104) (`lower_ptr_get`)
- **Function symbol**: `lower_ptr_get()`


Expand Down
2 changes: 1 addition & 1 deletion docs/internals/builtins/pointer/ptr_is_null.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ sidebar:
## Where it lives

- **Signature**: [`src/builtins/pointers/ptr_is_null.rs`](https://github.com/illegalstudio/elephc/blob/main/src/builtins/pointers/ptr_is_null.rs)
- **Lowering**: [`src/codegen/lower_inst/builtins/pointers.rs`:56](https://github.com/illegalstudio/elephc/blob/main/src/codegen/lower_inst/builtins/pointers.rs#L56) (`lower_ptr_is_null`)
- **Lowering**: [`src/codegen/lower_inst/builtins/pointers.rs`:51](https://github.com/illegalstudio/elephc/blob/main/src/codegen/lower_inst/builtins/pointers.rs#L51) (`lower_ptr_is_null`)
- **Function symbol**: `lower_ptr_is_null()`


Expand Down
2 changes: 1 addition & 1 deletion docs/internals/builtins/pointer/ptr_null.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ sidebar:
## Where it lives

- **Signature**: [`src/builtins/pointers/ptr_null.rs`](https://github.com/illegalstudio/elephc/blob/main/src/builtins/pointers/ptr_null.rs)
- **Lowering**: [`src/codegen/lower_inst/builtins/pointers.rs`:49](https://github.com/illegalstudio/elephc/blob/main/src/codegen/lower_inst/builtins/pointers.rs#L49) (`lower_ptr_null`)
- **Lowering**: [`src/codegen/lower_inst/builtins/pointers.rs`:44](https://github.com/illegalstudio/elephc/blob/main/src/codegen/lower_inst/builtins/pointers.rs#L44) (`lower_ptr_null`)
- **Function symbol**: `lower_ptr_null()`


Expand Down
2 changes: 1 addition & 1 deletion docs/internals/builtins/pointer/ptr_offset.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ sidebar:
## Where it lives

- **Signature**: [`src/builtins/pointers/ptr_offset.rs`](https://github.com/illegalstudio/elephc/blob/main/src/builtins/pointers/ptr_offset.rs)
- **Lowering**: [`src/codegen/lower_inst/builtins/pointers.rs`:86](https://github.com/illegalstudio/elephc/blob/main/src/codegen/lower_inst/builtins/pointers.rs#L86) (`lower_ptr_offset`)
- **Lowering**: [`src/codegen/lower_inst/builtins/pointers.rs`:81](https://github.com/illegalstudio/elephc/blob/main/src/codegen/lower_inst/builtins/pointers.rs#L81) (`lower_ptr_offset`)
- **Function symbol**: `lower_ptr_offset()`


Expand Down
2 changes: 1 addition & 1 deletion docs/internals/builtins/pointer/ptr_read16.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ sidebar:
## Where it lives

- **Signature**: [`src/builtins/pointers/ptr_read16.rs`](https://github.com/illegalstudio/elephc/blob/main/src/builtins/pointers/ptr_read16.rs)
- **Lowering**: [`src/codegen/lower_inst/builtins/pointers.rs`:124](https://github.com/illegalstudio/elephc/blob/main/src/codegen/lower_inst/builtins/pointers.rs#L124) (`lower_ptr_read16`)
- **Lowering**: [`src/codegen/lower_inst/builtins/pointers.rs`:119](https://github.com/illegalstudio/elephc/blob/main/src/codegen/lower_inst/builtins/pointers.rs#L119) (`lower_ptr_read16`)
- **Function symbol**: `lower_ptr_read16()`


Expand Down
2 changes: 1 addition & 1 deletion docs/internals/builtins/pointer/ptr_read32.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ sidebar:
## Where it lives

- **Signature**: [`src/builtins/pointers/ptr_read32.rs`](https://github.com/illegalstudio/elephc/blob/main/src/builtins/pointers/ptr_read32.rs)
- **Lowering**: [`src/codegen/lower_inst/builtins/pointers.rs`:129](https://github.com/illegalstudio/elephc/blob/main/src/codegen/lower_inst/builtins/pointers.rs#L129) (`lower_ptr_read32`)
- **Lowering**: [`src/codegen/lower_inst/builtins/pointers.rs`:124](https://github.com/illegalstudio/elephc/blob/main/src/codegen/lower_inst/builtins/pointers.rs#L124) (`lower_ptr_read32`)
- **Function symbol**: `lower_ptr_read32()`


Expand Down
2 changes: 1 addition & 1 deletion docs/internals/builtins/pointer/ptr_read8.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ sidebar:
## Where it lives

- **Signature**: [`src/builtins/pointers/ptr_read8.rs`](https://github.com/illegalstudio/elephc/blob/main/src/builtins/pointers/ptr_read8.rs)
- **Lowering**: [`src/codegen/lower_inst/builtins/pointers.rs`:119](https://github.com/illegalstudio/elephc/blob/main/src/codegen/lower_inst/builtins/pointers.rs#L119) (`lower_ptr_read8`)
- **Lowering**: [`src/codegen/lower_inst/builtins/pointers.rs`:114](https://github.com/illegalstudio/elephc/blob/main/src/codegen/lower_inst/builtins/pointers.rs#L114) (`lower_ptr_read8`)
- **Function symbol**: `lower_ptr_read8()`


Expand Down
2 changes: 1 addition & 1 deletion docs/internals/builtins/pointer/ptr_read_string.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ sidebar:
## Where it lives

- **Signature**: [`src/builtins/pointers/ptr_read_string.rs`](https://github.com/illegalstudio/elephc/blob/main/src/builtins/pointers/ptr_read_string.rs)
- **Lowering**: [`src/codegen/lower_inst/builtins/pointers.rs`:134](https://github.com/illegalstudio/elephc/blob/main/src/codegen/lower_inst/builtins/pointers.rs#L134) (`lower_ptr_read_string`)
- **Lowering**: [`src/codegen/lower_inst/builtins/pointers.rs`:129](https://github.com/illegalstudio/elephc/blob/main/src/codegen/lower_inst/builtins/pointers.rs#L129) (`lower_ptr_read_string`)
- **Function symbol**: `lower_ptr_read_string()`


Expand Down
2 changes: 1 addition & 1 deletion docs/internals/builtins/pointer/ptr_set.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ sidebar:
## Where it lives

- **Signature**: [`src/builtins/pointers/ptr_set.rs`](https://github.com/illegalstudio/elephc/blob/main/src/builtins/pointers/ptr_set.rs)
- **Lowering**: [`src/codegen/lower_inst/builtins/pointers.rs`:114](https://github.com/illegalstudio/elephc/blob/main/src/codegen/lower_inst/builtins/pointers.rs#L114) (`lower_ptr_set`)
- **Lowering**: [`src/codegen/lower_inst/builtins/pointers.rs`:109](https://github.com/illegalstudio/elephc/blob/main/src/codegen/lower_inst/builtins/pointers.rs#L109) (`lower_ptr_set`)
- **Function symbol**: `lower_ptr_set()`


Expand Down
2 changes: 1 addition & 1 deletion docs/internals/builtins/pointer/ptr_sizeof.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ sidebar:
## Where it lives

- **Signature**: [`src/builtins/pointers/ptr_sizeof.rs`](https://github.com/illegalstudio/elephc/blob/main/src/builtins/pointers/ptr_sizeof.rs)
- **Lowering**: [`src/codegen/lower_inst/builtins/pointers.rs`:75](https://github.com/illegalstudio/elephc/blob/main/src/codegen/lower_inst/builtins/pointers.rs#L75) (`lower_ptr_sizeof`)
- **Lowering**: [`src/codegen/lower_inst/builtins/pointers.rs`:70](https://github.com/illegalstudio/elephc/blob/main/src/codegen/lower_inst/builtins/pointers.rs#L70) (`lower_ptr_sizeof`)
- **Function symbol**: `lower_ptr_sizeof()`


Expand Down
2 changes: 1 addition & 1 deletion docs/internals/builtins/pointer/ptr_write16.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ sidebar:
## Where it lives

- **Signature**: [`src/builtins/pointers/ptr_write16.rs`](https://github.com/illegalstudio/elephc/blob/main/src/builtins/pointers/ptr_write16.rs)
- **Lowering**: [`src/codegen/lower_inst/builtins/pointers.rs`:161](https://github.com/illegalstudio/elephc/blob/main/src/codegen/lower_inst/builtins/pointers.rs#L161) (`lower_ptr_write16`)
- **Lowering**: [`src/codegen/lower_inst/builtins/pointers.rs`:156](https://github.com/illegalstudio/elephc/blob/main/src/codegen/lower_inst/builtins/pointers.rs#L156) (`lower_ptr_write16`)
- **Function symbol**: `lower_ptr_write16()`


Expand Down
2 changes: 1 addition & 1 deletion docs/internals/builtins/pointer/ptr_write32.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ sidebar:
## Where it lives

- **Signature**: [`src/builtins/pointers/ptr_write32.rs`](https://github.com/illegalstudio/elephc/blob/main/src/builtins/pointers/ptr_write32.rs)
- **Lowering**: [`src/codegen/lower_inst/builtins/pointers.rs`:166](https://github.com/illegalstudio/elephc/blob/main/src/codegen/lower_inst/builtins/pointers.rs#L166) (`lower_ptr_write32`)
- **Lowering**: [`src/codegen/lower_inst/builtins/pointers.rs`:161](https://github.com/illegalstudio/elephc/blob/main/src/codegen/lower_inst/builtins/pointers.rs#L161) (`lower_ptr_write32`)
- **Function symbol**: `lower_ptr_write32()`


Expand Down
2 changes: 1 addition & 1 deletion docs/internals/builtins/pointer/ptr_write8.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ sidebar:
## Where it lives

- **Signature**: [`src/builtins/pointers/ptr_write8.rs`](https://github.com/illegalstudio/elephc/blob/main/src/builtins/pointers/ptr_write8.rs)
- **Lowering**: [`src/codegen/lower_inst/builtins/pointers.rs`:156](https://github.com/illegalstudio/elephc/blob/main/src/codegen/lower_inst/builtins/pointers.rs#L156) (`lower_ptr_write8`)
- **Lowering**: [`src/codegen/lower_inst/builtins/pointers.rs`:151](https://github.com/illegalstudio/elephc/blob/main/src/codegen/lower_inst/builtins/pointers.rs#L151) (`lower_ptr_write8`)
- **Function symbol**: `lower_ptr_write8()`


Expand Down
2 changes: 1 addition & 1 deletion docs/internals/builtins/pointer/ptr_write_string.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ sidebar:
## Where it lives

- **Signature**: [`src/builtins/pointers/ptr_write_string.rs`](https://github.com/illegalstudio/elephc/blob/main/src/builtins/pointers/ptr_write_string.rs)
- **Lowering**: [`src/codegen/lower_inst/builtins/pointers.rs`:171](https://github.com/illegalstudio/elephc/blob/main/src/codegen/lower_inst/builtins/pointers.rs#L171) (`lower_ptr_write_string`)
- **Lowering**: [`src/codegen/lower_inst/builtins/pointers.rs`:166](https://github.com/illegalstudio/elephc/blob/main/src/codegen/lower_inst/builtins/pointers.rs#L166) (`lower_ptr_write_string`)
- **Function symbol**: `lower_ptr_write_string()`


Expand Down
2 changes: 1 addition & 1 deletion docs/internals/builtins/pointer/zval_free.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ sidebar:
## Where it lives

- **Signature**: [`src/builtins/pointers/zval_free.rs`](https://github.com/illegalstudio/elephc/blob/main/src/builtins/pointers/zval_free.rs)
- **Lowering**: [`src/codegen/lower_inst/builtins/pointers.rs`:606](https://github.com/illegalstudio/elephc/blob/main/src/codegen/lower_inst/builtins/pointers.rs#L606) (`lower_zval_free`)
- **Lowering**: [`src/codegen/lower_inst/builtins/pointers.rs`:598](https://github.com/illegalstudio/elephc/blob/main/src/codegen/lower_inst/builtins/pointers.rs#L598) (`lower_zval_free`)
- **Function symbol**: `lower_zval_free()`


Expand Down
2 changes: 1 addition & 1 deletion docs/internals/builtins/pointer/zval_pack.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ sidebar:
## Where it lives

- **Signature**: [`src/builtins/pointers/zval_pack.rs`](https://github.com/illegalstudio/elephc/blob/main/src/builtins/pointers/zval_pack.rs)
- **Lowering**: [`src/codegen/lower_inst/builtins/pointers.rs`:541](https://github.com/illegalstudio/elephc/blob/main/src/codegen/lower_inst/builtins/pointers.rs#L541) (`lower_zval_pack`)
- **Lowering**: [`src/codegen/lower_inst/builtins/pointers.rs`:533](https://github.com/illegalstudio/elephc/blob/main/src/codegen/lower_inst/builtins/pointers.rs#L533) (`lower_zval_pack`)
- **Function symbol**: `lower_zval_pack()`


Expand Down
2 changes: 1 addition & 1 deletion docs/internals/builtins/pointer/zval_type.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ sidebar:
## Where it lives

- **Signature**: [`src/builtins/pointers/zval_type.rs`](https://github.com/illegalstudio/elephc/blob/main/src/builtins/pointers/zval_type.rs)
- **Lowering**: [`src/codegen/lower_inst/builtins/pointers.rs`:597](https://github.com/illegalstudio/elephc/blob/main/src/codegen/lower_inst/builtins/pointers.rs#L597) (`lower_zval_type`)
- **Lowering**: [`src/codegen/lower_inst/builtins/pointers.rs`:589](https://github.com/illegalstudio/elephc/blob/main/src/codegen/lower_inst/builtins/pointers.rs#L589) (`lower_zval_type`)
- **Function symbol**: `lower_zval_type()`


Expand Down
2 changes: 1 addition & 1 deletion docs/internals/builtins/pointer/zval_unpack.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ sidebar:
## Where it lives

- **Signature**: [`src/builtins/pointers/zval_unpack.rs`](https://github.com/illegalstudio/elephc/blob/main/src/builtins/pointers/zval_unpack.rs)
- **Lowering**: [`src/codegen/lower_inst/builtins/pointers.rs`:588](https://github.com/illegalstudio/elephc/blob/main/src/codegen/lower_inst/builtins/pointers.rs#L588) (`lower_zval_unpack`)
- **Lowering**: [`src/codegen/lower_inst/builtins/pointers.rs`:580](https://github.com/illegalstudio/elephc/blob/main/src/codegen/lower_inst/builtins/pointers.rs#L580) (`lower_zval_unpack`)
- **Function symbol**: `lower_zval_unpack()`


Expand Down
2 changes: 1 addition & 1 deletion docs/internals/memory-model.md
Original file line number Diff line number Diff line change
Expand Up @@ -278,7 +278,7 @@ When one of these checks trips, the program exits with a fatal heap-debug error

### When memory is freed

- **Variable reassignment**: when a heap-backed local/global/static slot is overwritten, codegen releases the previous owner through the appropriate runtime path (`__rt_heap_free_safe` for persisted strings, `__rt_decref_*` for refcounted arrays / hashes / objects)
- **Variable reassignment**: when a heap-backed local/global/static slot is overwritten, codegen releases the previous owner through the appropriate runtime path (`__rt_heap_free_safe` for persisted strings, `__rt_decref_*` for refcounted arrays / hashes / objects). When a store inside a loop is lowered before a later store has widened the slot to boxed storage (e.g. an inner `for` counter re-initialized by the outer body but widened Int→Mixed by its `++` update), lowering emits a deferred `release_local_slot` and the backend decides against the slot's final widened storage type, so the previous iteration's box is still released
- **`unset()`**: releases the current heap-backed value before nulling the slot
- **Targeted cycle collection**: when decref reaches a container/object graph that may only be keeping itself alive, `__rt_gc_collect_cycles` counts heap-only incoming edges, marks externally reachable blocks, and deep-frees the remaining unreachable array/hash/object island
- **Generator frame release**: Generator frames are object-kind heap blocks, but their custom Mixed slots and active `yield from` delegate are released by a Generator-specific branch in object deep-free
Expand Down
Loading
Loading