ffi M4.A: stdlib NSObject + autoreleasepool helper + extends rooting
Declare `NSObject` in std/objc.sx as `#foreign #objc_class("NSObject")`
with the canonical instance + class-method surface every Obj-C class
inherits: `retain`/`release`/`autorelease`/`new`/`alloc`/`init`/
`description`/`hash`/`isEqual_`/`isKindOfClass_`/`respondsToSelector_`/
`class`. Root the foreign-class hierarchy in uikit.sx at NSObject by
adding `#extends NSObject;` to every previously-unrooted declaration
(NSValue, NSNumber, NSDictionary, NSSet, NSNotification, NSBundle,
NSNotificationCenter, NSRunLoop, CADisplayLink, CALayer, EAGLContext,
UIScreen, UIResponder) plus deeper chain fixes (NSMutableDictionary
extends NSDictionary; UIWindow extends UIView; UIViewController
extends UIResponder). After this, M2.3's extends-chain walk finds
`retain`/`release` on any UIKit-typed value:
view := UIView.alloc().init();
defer view.release(); // canonical sx idiom — no language magic
Plus `autoreleasepool(body: Closure())` stdlib helper that wraps
`body` in `objc_autoreleasePoolPush` / `defer objc_autoreleasePoolPop`.
Required for Foundation factory returns; closure-call frame is real
cost so hot loops should inline the push/defer-pop pattern manually.
Smoke test `ffi-objc-arc-01-autoreleasepool.sx` exercises both
patterns; refresh of two IR snapshots picks up the new stdlib decls
appearing in test outputs that include `modules/std/objc.sx`.
185/185 example tests pass; chess on iOS-sim green.
This commit is contained in:
@@ -59,11 +59,13 @@ CGRect :: struct {
|
||||
// (split on `_`; each piece becomes a keyword with `:`).
|
||||
|
||||
NSValue :: #foreign #objc_class("NSValue") {
|
||||
#extends NSObject;
|
||||
// CGRect unboxing — returns by value via the sret/HFA path.
|
||||
CGRectValue :: (self: *Self) -> CGRect;
|
||||
}
|
||||
|
||||
NSNumber :: #foreign #objc_class("NSNumber") {
|
||||
#extends NSObject;
|
||||
// Class method (no `self: *Self` first param → static dispatch).
|
||||
numberWithBool :: (b: s8) -> *NSNumber;
|
||||
// Instance value extractors.
|
||||
@@ -72,30 +74,36 @@ NSNumber :: #foreign #objc_class("NSNumber") {
|
||||
}
|
||||
|
||||
NSDictionary :: #foreign #objc_class("NSDictionary") {
|
||||
#extends NSObject;
|
||||
objectForKey :: (self: *Self, key: *void) -> *void;
|
||||
}
|
||||
|
||||
NSMutableDictionary :: #foreign #objc_class("NSMutableDictionary") {
|
||||
#extends NSDictionary;
|
||||
dictionary :: () -> *NSMutableDictionary;
|
||||
setObject_forKey :: (self: *Self, obj: *void, key: *void);
|
||||
}
|
||||
|
||||
NSSet :: #foreign #objc_class("NSSet") {
|
||||
#extends NSObject;
|
||||
anyObject :: (self: *Self) -> *void;
|
||||
}
|
||||
|
||||
// ── Notifications + Bundle (Phase 3.2 C2) ──────────────────────────────
|
||||
|
||||
NSNotification :: #foreign #objc_class("NSNotification") {
|
||||
#extends NSObject;
|
||||
userInfo :: (self: *Self) -> *NSDictionary;
|
||||
}
|
||||
|
||||
NSBundle :: #foreign #objc_class("NSBundle") {
|
||||
#extends NSObject;
|
||||
mainBundle :: () -> *NSBundle;
|
||||
resourcePath :: (self: *Self) -> *void;
|
||||
}
|
||||
|
||||
NSNotificationCenter :: #foreign #objc_class("NSNotificationCenter") {
|
||||
#extends NSObject;
|
||||
defaultCenter :: () -> *NSNotificationCenter;
|
||||
addObserver_selector_name_object :: (self: *Self, observer: *void, sel: *void, name: *void, obj: *void);
|
||||
}
|
||||
@@ -103,10 +111,12 @@ NSNotificationCenter :: #foreign #objc_class("NSNotificationCenter") {
|
||||
// ── RunLoop + display timing (Phase 3.2 C3) ────────────────────────────
|
||||
|
||||
NSRunLoop :: #foreign #objc_class("NSRunLoop") {
|
||||
#extends NSObject;
|
||||
currentRunLoop :: () -> *NSRunLoop;
|
||||
}
|
||||
|
||||
CADisplayLink :: #foreign #objc_class("CADisplayLink") {
|
||||
#extends NSObject;
|
||||
displayLinkWithTarget_selector :: (target: *void, sel: *void) -> *CADisplayLink;
|
||||
addToRunLoop_forMode :: (self: *Self, runloop: *NSRunLoop, mode: *void);
|
||||
targetTimestamp :: (self: *Self) -> f64;
|
||||
@@ -117,6 +127,7 @@ CADisplayLink :: #foreign #objc_class("CADisplayLink") {
|
||||
// (Declared before UIView so `layer :: (...) -> *CALayer` can reference it.)
|
||||
|
||||
CALayer :: #foreign #objc_class("CALayer") {
|
||||
#extends NSObject;
|
||||
setOpaque :: (self: *Self, opaque: s8);
|
||||
}
|
||||
|
||||
@@ -132,6 +143,7 @@ CAMetalLayer :: #foreign #objc_class("CAMetalLayer") {
|
||||
}
|
||||
|
||||
EAGLContext :: #foreign #objc_class("EAGLContext") {
|
||||
#extends NSObject;
|
||||
alloc :: () -> *EAGLContext;
|
||||
initWithAPI :: (self: *Self, api: s32) -> *EAGLContext;
|
||||
setCurrentContext :: (ctx: *EAGLContext);
|
||||
@@ -142,6 +154,7 @@ EAGLContext :: #foreign #objc_class("EAGLContext") {
|
||||
// ── UIKit chrome (Phase 3.2 C4) ────────────────────────────────────────
|
||||
|
||||
UIScreen :: #foreign #objc_class("UIScreen") {
|
||||
#extends NSObject;
|
||||
mainScreen :: () -> *UIScreen;
|
||||
nativeScale :: (self: *Self) -> f64;
|
||||
bounds :: (self: *Self) -> CGRect;
|
||||
@@ -152,6 +165,7 @@ UIScreen :: #foreign #objc_class("UIScreen") {
|
||||
// participate in lifecycle callbacks (delegates, scene delegates)
|
||||
// extend it so the runtime picks up the responder-chain behavior.
|
||||
UIResponder :: #foreign #objc_class("UIResponder") {
|
||||
#extends NSObject;
|
||||
becomeFirstResponder :: (self: *Self) -> s8;
|
||||
resignFirstResponder :: (self: *Self) -> s8;
|
||||
}
|
||||
@@ -165,6 +179,7 @@ UIView :: #foreign #objc_class("UIView") {
|
||||
}
|
||||
|
||||
UIWindow :: #foreign #objc_class("UIWindow") {
|
||||
#extends UIView;
|
||||
alloc :: () -> *UIWindow;
|
||||
initWithWindowScene :: (self: *Self, scene: *void) -> *UIWindow;
|
||||
setRootViewController :: (self: *Self, vc: *void);
|
||||
@@ -173,6 +188,7 @@ UIWindow :: #foreign #objc_class("UIWindow") {
|
||||
}
|
||||
|
||||
UIViewController :: #foreign #objc_class("UIViewController") {
|
||||
#extends UIResponder;
|
||||
alloc :: () -> *UIViewController;
|
||||
init :: (self: *Self) -> *UIViewController;
|
||||
setView :: (self: *Self, view: *void);
|
||||
|
||||
Reference in New Issue
Block a user