This commit is contained in:
agra
2026-03-04 09:18:24 +02:00
parent 0336f361c7
commit 67e02a20a5
6 changed files with 153 additions and 23 deletions

View File

@@ -370,6 +370,36 @@ Arena :: struct {
allocators : [2]Allocator = .[xx gpa, xx arena]; // protocol values in array
```
#### Ownership and Lifetime
Protocol values have two ownership modes depending on how they are created:
| Conversion | `ctx` points to | Lifetime | Who frees |
|------------|----------------|----------|-----------|
| `xx value` | Heap-allocated copy | Until `free(p)` | Caller |
| `xx @ptr` | Original pointee | Tied to pointee | Caller manages pointee |
**`xx value`** — the concrete data is heap-copied so the protocol value is self-contained.
It can be stored in containers, returned from functions, and outlives the scope where it was created.
Call `free(p)` to release the backing memory when done:
```sx
s : Sizable = xx Widget.{ value = 42 }; // heap-copies Widget
print("{}\n", s.size());
free(s); // frees the heap-allocated Widget copy
```
**`xx @ptr`** — the protocol borrows the pointer. The protocol value is only valid as long as
the pointee is alive. Mutations through the protocol are visible through the original pointer:
```sx
w := Widget.{ value = 0 };
s : Sizable = xx @w; // borrows &w
s.add(5); // modifies w through ctx
print("{}\n", w.value); // 5
// do NOT free(s) — w owns the data
```
**Vtables** are global constants — shared across all protocol values of the same `(Protocol, ConcreteType)` pair. They are never allocated or freed at runtime.
#### Default Methods
Protocol methods can have bodies. `self` dispatches through the vtable (dynamic dispatch):
```sx