From 666a2e20e17097c403c867e308660f6aa9c02aac Mon Sep 17 00:00:00 2001 From: agra Date: Mon, 15 Jun 2026 04:45:55 +0300 Subject: [PATCH] =?UTF-8?q?refactor(ffi-linkage):=20Phase=206.4=20?= =?UTF-8?q?=E2=80=94=20migrate=20ffi/=20#foreign=E2=86=92extern?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Pure source rename across objc/objc_block/raylib/sdl3/wasm (~51 sites): fn-decl markers (bare / 'objc' LIB ref) → 'extern …', and objc.sx's 2 import runtime classes '#foreign #objc_class("X") {' → '#objc_class("X") extern {'. No bare defined classes. Behavior-preserving. objc + objc_block validated directly by the 50 marked 13xx corpus examples (incl. import classes 1300/1301 + defined classes 1339/1349); raylib/ffi-sdl3/wasm (no marked importers on host) verified by byte-identical 'sx ir' probes pre/post. Empty snapshot diff; suite green (647 corpus / 444 unit, 0 failed). --- library/modules/ffi/objc.sx | 36 ++++++++++++------------ library/modules/ffi/objc_block.sx | 2 +- library/modules/ffi/raylib.sx | 14 +++++----- library/modules/ffi/sdl3.sx | 46 +++++++++++++++---------------- library/modules/ffi/wasm.sx | 4 +-- 5 files changed, 51 insertions(+), 51 deletions(-) diff --git a/library/modules/ffi/objc.sx b/library/modules/ffi/objc.sx index 108204c..a141d51 100644 --- a/library/modules/ffi/objc.sx +++ b/library/modules/ffi/objc.sx @@ -35,16 +35,16 @@ BOOL :: i8; objc :: #library "objc"; #framework "Foundation"; -objc_getClass :: (name: [*]u8) -> *void #foreign objc; -objc_lookUpClass :: (name: [*]u8) -> *void #foreign objc; -sel_registerName :: (name: [*]u8) -> *void #foreign objc; -class_createInstance :: (cls: *void, extra: usize) -> *void #foreign objc; -object_getClass :: (obj: *void) -> *void #foreign objc; -object_getIvar :: (obj: *void, ivar: *void) -> *void #foreign objc; -object_setIvar :: (obj: *void, ivar: *void, val: *void) #foreign objc; +objc_getClass :: (name: [*]u8) -> *void extern objc; +objc_lookUpClass :: (name: [*]u8) -> *void extern objc; +sel_registerName :: (name: [*]u8) -> *void extern objc; +class_createInstance :: (cls: *void, extra: usize) -> *void extern objc; +object_getClass :: (obj: *void) -> *void extern objc; +object_getIvar :: (obj: *void, ivar: *void) -> *void extern objc; +object_setIvar :: (obj: *void, ivar: *void, val: *void) extern objc; // Declared with the simplest non-variadic shape. Cast per call site. -objc_msgSend :: (recv: *void, sel: *void) -> *void #foreign objc; +objc_msgSend :: (recv: *void, sel: *void) -> *void extern objc; // ─── Dynamic class registration ───────────────────────────────────────── // Define a new Obj-C class at runtime: allocate the pair, attach methods + @@ -64,15 +64,15 @@ objc_msgSend :: (recv: *void, sel: *void) -> *void #foreign objc; // "c@:" -> BOOL method(id, SEL) // "@@:@" -> id method(id, SEL, id) // "B@:@@" -> BOOL method(id, SEL, id, id) -objc_allocateClassPair :: (super: *void, name: [*]u8, extra: usize) -> *void #foreign objc; -class_addMethod :: (cls: *void, sel: *void, imp: *void, types: [*]u8) -> bool #foreign objc; -class_addProtocol :: (cls: *void, proto: *void) -> bool #foreign objc; -objc_getProtocol :: (name: [*]u8) -> *void #foreign objc; -objc_registerClassPair :: (cls: *void) -> void #foreign objc; +objc_allocateClassPair :: (super: *void, name: [*]u8, extra: usize) -> *void extern objc; +class_addMethod :: (cls: *void, sel: *void, imp: *void, types: [*]u8) -> bool extern objc; +class_addProtocol :: (cls: *void, proto: *void) -> bool extern objc; +objc_getProtocol :: (name: [*]u8) -> *void extern objc; +objc_registerClassPair :: (cls: *void) -> void extern objc; // Foundation C-API helpers (Foundation is already linked above via #framework). // NSLog takes an NSString format; the variadic tail is not exposed here. -NSLog :: (fmt: *NSString) #foreign; +NSLog :: (fmt: *NSString) extern; // ─── NSObject (Phase 4 / M4.A) ─────────────────────────────────────────── // Root of every Obj-C class hierarchy. Apple's runtime supplies the IMPs; @@ -88,7 +88,7 @@ NSLog :: (fmt: *NSString) #foreign; // sx isn't under clang ARC. Calling `view.release()` here is equivalent to // pre-ARC Obj-C source code: dispatches through the runtime, decrements the // refcount, fires `-dealloc` at zero. -NSObject :: #foreign #objc_class("NSObject") { +NSObject :: #objc_class("NSObject") extern { alloc :: () -> *NSObject; init :: (self: *Self) -> *NSObject; new :: () -> *NSObject; // shorthand for [[Cls alloc] init] @@ -108,7 +108,7 @@ NSObject :: #foreign #objc_class("NSObject") { // whose lifetime is tied to the NSString (don't free it). The `Into` impl // lets a string literal flow into any `*NSString` slot via `xx`, e.g. // `dict.objectForKey(xx "SomeKey")`. -NSString :: #foreign #objc_class("NSString") { +NSString :: #objc_class("NSString") extern { #extends NSObject; UTF8String :: (self: *Self) -> [*]u8; } @@ -134,8 +134,8 @@ impl Into(*NSString) for string { // Stdlib helper, not a language keyword. The closure call adds a frame — // for hot loops, inline the push/defer-pop pattern manually. -objc_autoreleasePoolPush :: () -> *void #foreign objc; -objc_autoreleasePoolPop :: (pool: *void) #foreign objc; +objc_autoreleasePoolPush :: () -> *void extern objc; +objc_autoreleasePoolPop :: (pool: *void) extern objc; autoreleasepool :: (body: Closure()) { pool := objc_autoreleasePoolPush(); diff --git a/library/modules/ffi/objc_block.sx b/library/modules/ffi/objc_block.sx index a56c8d7..99c1171 100644 --- a/library/modules/ffi/objc_block.sx +++ b/library/modules/ffi/objc_block.sx @@ -49,7 +49,7 @@ BlockDescriptor :: struct { // libSystem isa pointer for stack-allocated blocks. Resolved at link time // (auto-linked on every Apple target via libSystem). -_NSConcreteStackBlock : *void #foreign; +_NSConcreteStackBlock : *void extern; // Shared descriptor for the 48-byte sx-block layout. All Into impls below // point their `descriptor` field at this. diff --git a/library/modules/ffi/raylib.sx b/library/modules/ffi/raylib.sx index 1aa62ff..70ea87d 100644 --- a/library/modules/ffi/raylib.sx +++ b/library/modules/ffi/raylib.sx @@ -8,10 +8,10 @@ Vector2 :: struct { x, y: f32; } -InitWindow :: (width: i32, height: i32, title: [:0]u8) -> void #foreign raylib; -CloseWindow :: () -> void #foreign raylib; -WindowShouldClose :: () -> bool #foreign raylib; -BeginDrawing :: () -> void #foreign raylib; -EndDrawing :: () -> void #foreign raylib; -ClearBackground :: (color: Color) -> void #foreign raylib; -DrawTriangle :: (v1: Vector2, v2: Vector2, v3: Vector2, color: Color) -> void #foreign raylib; +InitWindow :: (width: i32, height: i32, title: [:0]u8) -> void extern raylib; +CloseWindow :: () -> void extern raylib; +WindowShouldClose :: () -> bool extern raylib; +BeginDrawing :: () -> void extern raylib; +EndDrawing :: () -> void extern raylib; +ClearBackground :: (color: Color) -> void extern raylib; +DrawTriangle :: (v1: Vector2, v2: Vector2, v3: Vector2, color: Color) -> void extern raylib; diff --git a/library/modules/ffi/sdl3.sx b/library/modules/ffi/sdl3.sx index 2af5886..7f80d4f 100644 --- a/library/modules/ffi/sdl3.sx +++ b/library/modules/ffi/sdl3.sx @@ -320,27 +320,27 @@ SDL_Event :: enum struct { tag: u32; _: u32; payload: [30]u32; } { } // Functions -SDL_Init :: (flags: u32) -> bool #foreign; -SDL_Quit :: () -> void #foreign; -SDL_CreateWindow :: (title: [:0]u8, w: i32, h: i32, flags: u64) -> *void #foreign; -SDL_DestroyWindow :: (window: *void) -> void #foreign; -SDL_GL_SetAttribute :: (attr: i32, value: i32) -> bool #foreign; -SDL_GL_CreateContext :: (window: *void) -> *void #foreign; -SDL_GL_DestroyContext :: (context: *void) -> bool #foreign; -SDL_GL_MakeCurrent :: (window: *void, context: *void) -> bool #foreign; -SDL_GL_SwapWindow :: (window: *void) -> bool #foreign; -SDL_GL_SetSwapInterval :: (interval: i32) -> bool #foreign; -SDL_GL_GetProcAddress :: (proc: [:0]u8) -> *void #foreign; -SDL_PollEvent :: (event: *SDL_Event) -> bool #foreign; -SDL_AddEventWatch :: (filter: *void, userdata: *void) -> bool #foreign; -SDL_GetTicks :: () -> u64 #foreign; -SDL_GetPerformanceCounter :: () -> u64 #foreign; -SDL_GetPerformanceFrequency :: () -> u64 #foreign; -SDL_Delay :: (ms: u32) -> void #foreign; -SDL_GetWindowDisplayScale :: (window: *void) -> f32 #foreign; -SDL_GetWindowSize :: (window: *void, w: *i32, h: *i32) -> bool #foreign; -SDL_SetWindowSize :: (window: *void, w: i32, h: i32) -> bool #foreign; -SDL_GetWindowSizeInPixels :: (window: *void, w: *i32, h: *i32) -> bool #foreign; +SDL_Init :: (flags: u32) -> bool extern; +SDL_Quit :: () -> void extern; +SDL_CreateWindow :: (title: [:0]u8, w: i32, h: i32, flags: u64) -> *void extern; +SDL_DestroyWindow :: (window: *void) -> void extern; +SDL_GL_SetAttribute :: (attr: i32, value: i32) -> bool extern; +SDL_GL_CreateContext :: (window: *void) -> *void extern; +SDL_GL_DestroyContext :: (context: *void) -> bool extern; +SDL_GL_MakeCurrent :: (window: *void, context: *void) -> bool extern; +SDL_GL_SwapWindow :: (window: *void) -> bool extern; +SDL_GL_SetSwapInterval :: (interval: i32) -> bool extern; +SDL_GL_GetProcAddress :: (proc: [:0]u8) -> *void extern; +SDL_PollEvent :: (event: *SDL_Event) -> bool extern; +SDL_AddEventWatch :: (filter: *void, userdata: *void) -> bool extern; +SDL_GetTicks :: () -> u64 extern; +SDL_GetPerformanceCounter :: () -> u64 extern; +SDL_GetPerformanceFrequency :: () -> u64 extern; +SDL_Delay :: (ms: u32) -> void extern; +SDL_GetWindowDisplayScale :: (window: *void) -> f32 extern; +SDL_GetWindowSize :: (window: *void, w: *i32, h: *i32) -> bool extern; +SDL_SetWindowSize :: (window: *void, w: i32, h: i32) -> bool extern; +SDL_GetWindowSizeInPixels :: (window: *void, w: *i32, h: *i32) -> bool extern; SDL_Rect :: struct { x: i32; @@ -349,5 +349,5 @@ SDL_Rect :: struct { h: i32; } -SDL_GetPrimaryDisplay :: () -> u32 #foreign; -SDL_GetDisplayUsableBounds :: (display_id: u32, rect: *SDL_Rect) -> bool #foreign; +SDL_GetPrimaryDisplay :: () -> u32 extern; +SDL_GetDisplayUsableBounds :: (display_id: u32, rect: *SDL_Rect) -> bool extern; diff --git a/library/modules/ffi/wasm.sx b/library/modules/ffi/wasm.sx index 5c06ade..a0733ae 100644 --- a/library/modules/ffi/wasm.sx +++ b/library/modules/ffi/wasm.sx @@ -1,4 +1,4 @@ libc :: #library "c"; -emscripten_set_main_loop :: (func: *void, fps: i32, sim_infinite: i32) #foreign libc; -emscripten_run_script_int :: (script: [:0]u8) -> i32 #foreign libc; +emscripten_set_main_loop :: (func: *void, fps: i32, sim_infinite: i32) extern libc; +emscripten_run_script_int :: (script: [:0]u8) -> i32 extern libc;