checkpoint: M4.0 + M4.A complete; M4.B remaining

Snapshot of FFI progress mid-M4. Allocator-aware sx-defined-class
lifecycle is done end-to-end (state struct + +alloc + -dealloc).
Stdlib NSObject + autoreleasepool helper landed; defer-release
pattern works at user code. Property ARC ops (M4.B) is the next
slice.

185/185 example tests pass; chess on iOS-sim regression-verified
at every M4 sub-commit.
This commit is contained in:
agra
2026-05-26 22:39:52 +03:00
parent 29404afdee
commit afa9d4aa46

View File

@@ -221,10 +221,55 @@ plus 2 codegen fixes surfaced along the way.**
## Current state
- 169/169 example tests pass; `zig build test` green.
- Phase 3.0/3.1/3.2 + M1.0M1.3 + M2.1M2.3 + M3 (full
retire-`uikit_register_classes`) all landed.
- 185/185 example tests pass; `zig build test` green.
- Phase 3.0/3.1/3.2 + M1.0M1.3 + M2.1M2.3 + M3 + M4.0 + M4.A all landed.
- Chess on macOS / iOS-sim / Android all build and run.
**M4.0 — context.allocator threading** (4 commits this session):
- `__sx_allocator: Allocator` prepended at field index 0 of every
sx-defined class's state struct
([src/ir/lower.zig:`objcDefinedStateStructType`](../src/ir/lower.zig)).
- Sx-side `Cls.alloc()` intercepted in `lowerObjcStaticCall` for
sx-defined classes — emits the inline alloc-and-init sequence
using the caller's `current_ctx_ref`. `push Context.{ allocator =
arena }` now backs the next `SxFoo.alloc()`.
- Runtime-side `+alloc` IMP is now a shim that reads
`__sx_default_context.allocator` and forwards to the same shared
helper.
- Shared `emitObjcDefinedAllocAndInit(fcd, cls_ref, ctx_addr)` does
the work: class_createInstance → ctx.allocator.alloc(STATE_SIZE)
via the inline-protocol fn-ptr → memset 0 → store allocator at
state[0] → object_setIvar(__sx_state).
- `-dealloc` IMP loads `state->__sx_allocator` and dispatches
`allocator.dealloc(state)` instead of the old raw `free(state)`.
- TrackingAllocator now sees sx-defined class alloc/dealloc pairs.
**M4.A — stdlib NSObject + autoreleasepool** (1 commit):
- `NSObject :: #foreign #objc_class("NSObject")` declared in
std/objc.sx with the full inherited surface: retain/release/
autorelease/new/alloc/init/class/description/hash/isEqual_/
isKindOfClass_/respondsToSelector_.
- All previously-unrooted foreign classes in uikit.sx now
`#extends NSObject;` (NSValue, NSNumber, NSDictionary, etc.) so
M2.3's extends-chain dispatch finds retain/release on any UIKit
type.
- `autoreleasepool(body: Closure())` stdlib helper wraps the
push/defer-pop pair.
- Canonical idiom enabled: `view := UIView.alloc().init(); defer
view.release();`.
- Smoke test [examples/ffi-objc-arc-01-autoreleasepool.sx](../examples/ffi-objc-arc-01-autoreleasepool.sx)
exercises the retain/release + autoreleasepool round-trip.
**M4.B remaining** (compiler-internal property ARC ops; not yet
landed):
- `objcPropertyKind(field)` helper + `ensureArcRuntimeDecls`.
- Setter wiring strong/weak/copy ops.
- Getter via objc_loadWeakRetained for weak properties.
- Dealloc property-aware cleanup (release strong/copy, destroyWeak
weak) before freeing state struct.
**Previous-session wins still in this checkpoint:**
- M4.0 / M4.A built on top of these earlier commits this session:
- `library/modules/platform/uikit.sx` follow-up cleanup just
shipped: every `plat: *UIKitPlatform` helper and every
`(self: *void, _cmd: *void, ...)` trampoline is now a method