From 12920c34cfbb8bbd1610e0703c8a8cacd7eab73a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ionu=C8=9B=20Leonte?= Date: Fri, 3 May 2024 04:08:58 +0300 Subject: [PATCH] modules/Objective_C: update to versino 0.1.089 --- modules/Objective_C/AppKit.jai | 108 +- modules/Objective_C/Foundation.jai | 149 +- .../LightweightRenderingView/build.jai | 2 +- .../Objective_C/bindings/arm64/message.jai | 44 + .../Objective_C/bindings/arm64/runtime.jai | 1644 +++++++++++++++++ .../bindings/{ => x64}/message.jai | 2 +- .../bindings/{ => x64}/runtime.jai | 2 +- modules/Objective_C/generate.jai | 73 +- modules/Objective_C/module.jai | 72 +- 9 files changed, 1931 insertions(+), 165 deletions(-) create mode 100644 modules/Objective_C/bindings/arm64/message.jai create mode 100644 modules/Objective_C/bindings/arm64/runtime.jai rename modules/Objective_C/bindings/{ => x64}/message.jai (98%) rename modules/Objective_C/bindings/{ => x64}/runtime.jai (99%) diff --git a/modules/Objective_C/AppKit.jai b/modules/Objective_C/AppKit.jai index 9eba7e639..9e415fe58 100644 --- a/modules/Objective_C/AppKit.jai +++ b/modules/Objective_C/AppKit.jai @@ -49,10 +49,6 @@ NSApplication :: struct { objc_msgSend(self, _sel.sendEvent_, event); } - postEvent :: (self: *NSApplication, event: *NSEvent, atStart: BOOL) #no_context { - objc_msgSend(self, _sel.postEvent_atStart_, event, atStart); - } - updateWindows :: (self: *NSApplication) #no_context { objc_msgSend(self, _sel.updateWindows); } @@ -101,6 +97,11 @@ NSApplication :: struct { return xx objc_msgSend(self, _sel.requestUserAttention_, requestType); } + // Added for Focus + postEvent :: (self: *NSApplication, event: *NSEvent, atStart: BOOL) #no_context { + objc_msgSend(self, _sel.postEvent_atStart_, event, atStart); + } + replyToOpenOrPrint :: (self: *NSApplication, reply: NSUInteger) #no_context { objc_msgSend(self, _sel.replyToOpenOrPrint_, reply); } @@ -111,19 +112,6 @@ NSApplication :: struct { NSEvent :: struct { using #as super: NSObject; - otherEventWithType :: (type: NSEventType, location: NSPoint, modifierFlags: NSEventModifierFlags, timestamp: NSTimeInterval, windowNumber: u64, ctx: *void, subtype: u16, data1: u64, data2: u64) -> *NSEvent #c_call { - func: (*void, Selector, NSEventType, NSPoint, NSEventModifierFlags, NSTimeInterval, u64, *void, u16, u64, u64) -> *NSEvent #c_call; - func = xx objc_msgSend; - return xx func( - class(NSEvent), - _sel.otherEventWithType_location_modifierFlags_timestamp_windowNumber_context_subtype_data1_data2_, - type, location, modifierFlags, timestamp, windowNumber, ctx, subtype, data1, data2); - } - - window :: (self: *NSEvent) -> *NSWindow { - return xx objc_msgSend(self, _sel.window); - } - mouseLocation :: () -> NSPoint { func: (*void, Selector) -> NSPoint #c_call; func = xx objc_msgSend; @@ -200,6 +188,20 @@ NSEvent :: struct { return func(self, _sel.deltaZ); } + // Added for Focus + otherEventWithType :: (type: NSEventType, location: NSPoint, modifierFlags: NSEventModifierFlags, timestamp: NSTimeInterval, windowNumber: u64, ctx: *void, subtype: u16, data1: u64, data2: u64) -> *NSEvent #c_call { + func: (*void, Selector, NSEventType, NSPoint, NSEventModifierFlags, NSTimeInterval, u64, *void, u16, u64, u64) -> *NSEvent #c_call; + func = xx objc_msgSend; + return xx func( + class(NSEvent), + _sel.otherEventWithType_location_modifierFlags_timestamp_windowNumber_context_subtype_data1_data2_, + type, location, modifierFlags, timestamp, windowNumber, ctx, subtype, data1, data2); + } + + window :: (self: *NSEvent) -> *NSWindow { + return xx objc_msgSend(self, _sel.window); + } + scrollingDeltaX :: (self: *NSEvent) -> CGFloat { func: (self: *void, op: Selector) -> CGFloat #c_call; func = xx objc_msgSend; @@ -231,6 +233,7 @@ NSEvent :: struct { } } +// Added for Focus using NSEventPhase :: enum NSUInteger { NSEventPhaseNone :: 0; NSEventPhaseBegan :: 1; @@ -420,13 +423,13 @@ using NSBackingStoreType :: enum NSUInteger { NSResponder :: struct { using #as super: NSObject; - #insert #run,stallable create_objc_class_member_stub("NSResponder"); + #insert #run,stallable create_objc_class_member_stub("NSResponder", "AppKit"); } NSWindowController :: struct { using #as responder: NSResponder; - #insert #run,stallable create_objc_class_member_stub("NSWindowController"); + #insert #run,stallable create_objc_class_member_stub("NSWindowController", "AppKit"); } NSColor :: struct { @@ -529,9 +532,6 @@ NSWindow :: struct { setFrame :: (self: *NSWindow, frame: NSRect, display: BOOL) { objc_msgSend(self, _sel.setFrame_display_, frame, display); } - setFrame :: (self: *NSWindow, frame: NSRect, display: BOOL, animate: BOOL) { - objc_msgSend(self, _sel.setFrame_display_animate_, frame, display, animate); - } level :: (self: *NSWindow) -> NSWindowLevel { return xx objc_msgSend(self, _sel.level); @@ -643,6 +643,19 @@ NSWindow :: struct { objc_msgSend(self, _sel.toggleFullScreen_, sender); } + // helper functions + setTitle :: (self: *NSWindow, title: string) -> id { + nsstring := NSString.initWithString(objc_alloc(NSString), title); + defer release(nsstring); + + return setTitle(self, nsstring); + } + + // Added for Focus + setFrame :: (self: *NSWindow, frame: NSRect, display: BOOL, animate: BOOL) { + objc_msgSend(self, _sel.setFrame_display_animate_, frame, display, animate); + } + screen :: (self: *NSWindow) -> *NSScreen { return xx objc_msgSend(self, _sel.screen); } @@ -655,14 +668,6 @@ NSWindow :: struct { objc_msgSend(self, _sel.setAppearance_, appearance); } - // helper functions - setTitle :: (self: *NSWindow, title: string) -> id { - nsstring := NSString.initWithString(objc_alloc(NSString), title); - defer release(nsstring); - - return setTitle(self, nsstring); - } - maximize :: (self: *NSWindow) { visibleFrame := NSScreen.visibleFrame(screen(self)); setFrame(self, visibleFrame, display=YES); @@ -903,7 +908,7 @@ NSView :: struct { NSViewController :: struct { using #as responder: NSResponder; - #insert #run,stallable create_objc_class_member_stub("NSViewController"); + #insert #run,stallable create_objc_class_member_stub("NSViewController", "AppKit"); } NSOpenGLContext :: struct { @@ -1013,6 +1018,10 @@ NSOpenGLPixelFormat :: struct { initWithAttributes :: (self: id, attrs: *NSOpenGLPixelFormatAttribute) -> *NSOpenGLPixelFormat { return xx objc_msgSend(self, _sel.initWithAttributes_, attrs); } + + getValues :: (self: id, values: *s32 /*GLint*/, forAttribute: NSOpenGLPixelFormatAttribute, forVirtualScreen: s32 /*GLint*/) { + objc_msgSend(self, _sel.getValues_forAttribute_forVirtualScreen_, values, forAttribute, forVirtualScreen); + } } NSScreen :: struct { @@ -1244,11 +1253,6 @@ NSAppearance :: struct { #scope_module _sel: struct #type_info_no_size_complaint { - appearanceNamed_: Selector; - colorWithRed_green_blue_alpha_: Selector; - setTitlebarAppearsTransparent_: Selector; - setAppearance_: Selector; - replyToOpenOrPrint_: Selector; characters: Selector; run: Selector; keyCode: Selector; @@ -1257,7 +1261,6 @@ _sel: struct #type_info_no_size_complaint { sharedApplication: Selector; mainWindow: Selector; sendEvent_: Selector; - postEvent_atStart_: Selector; updateWindows: Selector; activateIgnoringOtherApps_: Selector; setActivationPolicy_: Selector; @@ -1286,7 +1289,6 @@ _sel: struct #type_info_no_size_complaint { initWithFormat_shareContext_: Selector; makeCurrentContext: Selector; initWithAttributes_: Selector; - window: Selector; type: Selector; mouseLocation: Selector; generalPasteboard: Selector; @@ -1300,12 +1302,6 @@ _sel: struct #type_info_no_size_complaint { deltaX: Selector; deltaY: Selector; deltaZ: Selector; - scrollingDeltaX: Selector; - scrollingDeltaY: Selector; - hasPreciseScrollingDeltas: Selector; - phase: Selector; - momentumPhase: Selector; - otherEventWithType_location_modifierFlags_timestamp_windowNumber_context_subtype_data1_data2_: Selector; associatedEventsMask: Selector; buttonNumber: Selector; clickCount: Selector; @@ -1315,14 +1311,12 @@ _sel: struct #type_info_no_size_complaint { frame: Selector; setFrame_: Selector; setFrame_display_: Selector; - setFrame_display_animate_: Selector; center: Selector; convertRectToBacking_: Selector; convertRectFromBacking_: Selector; convertPointToBacking_: Selector; convertPointFromBacking_: Selector; backingScaleFactor: Selector; - visibleFrame: Selector; setWantsBestResolutionOpenGLSurface_: Selector; mainScreen: Selector; hide: Selector; @@ -1342,13 +1336,13 @@ _sel: struct #type_info_no_size_complaint { enterFullScreenMode_withOptions_: Selector; exitFullScreenModeWithOptions_: Selector; toggleFullScreen_: Selector; - screen: Selector; setCollectionBehavior_: Selector; setContentSize_: Selector; setFrameOrigin_: Selector; level: Selector; setLevel_: Selector; setValues_forParameter_: Selector; + getValues_forAttribute_forVirtualScreen_: Selector; currentContext: Selector; view: Selector; URL: Selector; @@ -1416,10 +1410,28 @@ _sel: struct #type_info_no_size_complaint { registerForDraggedTypes_: Selector; draggingSourceOperationMask: Selector; draggingPasteboard: Selector; + + // Added for Focus + appearanceNamed_: Selector; + colorWithRed_green_blue_alpha_: Selector; + setTitlebarAppearsTransparent_: Selector; + setAppearance_: Selector; + replyToOpenOrPrint_: Selector; + window: Selector; + scrollingDeltaX: Selector; + scrollingDeltaY: Selector; + hasPreciseScrollingDeltas: Selector; + phase: Selector; + momentumPhase: Selector; + setFrame_display_animate_: Selector; + visibleFrame: Selector; + screen: Selector; + postEvent_atStart_: Selector; + otherEventWithType_location_modifierFlags_timestamp_windowNumber_context_subtype_data1_data2_: Selector; } #import "Objective_C"; -Cocoa :: #system_library "Cocoa"; +Cocoa :: #system_library "Cocoa"; AppKit :: #system_library "AppKit"; #load "CoreGraphics.jai"; diff --git a/modules/Objective_C/Foundation.jai b/modules/Objective_C/Foundation.jai index d0c18d5b7..97ac96ac9 100644 --- a/modules/Objective_C/Foundation.jai +++ b/modules/Objective_C/Foundation.jai @@ -18,11 +18,11 @@ NSAutoreleasePool :: struct { using #as super: NSObject; drain :: (self: *NSAutoreleasePool) { - objc_msgSend(self, _sel.drain); + objc_msgSend_typed(self, _sel.drain); } showPools :: () { - objc_msgSend(class(NSAutoreleasePool), _sel.showPools); + objc_msgSend_typed(class(NSAutoreleasePool), _sel.showPools); } } @@ -35,11 +35,11 @@ NSBundle :: struct { using #as super: NSObject; resourcePath :: (self: *NSBundle) -> *NSString { - return xx objc_msgSend(self, _sel.resourcePath); + return xx objc_msgSend_typed(self, _sel.resourcePath); } mainBundle :: () -> *NSBundle { - return xx objc_msgSend(class(NSBundle), _sel.mainBundle); + return xx objc_msgSend_typed(class(NSBundle), _sel.mainBundle); } } @@ -47,11 +47,11 @@ NSDate :: struct { using #as super: NSObject; distantPast :: () -> *NSDate { - return xx objc_msgSend(class(NSDate), _sel.distantPast); + return xx objc_msgSend_typed(class(NSDate), _sel.distantPast); } distantFuture :: () -> *NSDate { - return xx objc_msgSend(class(NSDate), _sel.distantFuture); + return xx objc_msgSend_typed(class(NSDate), _sel.distantFuture); } } @@ -107,25 +107,25 @@ NSString :: struct { using #as super: NSObject; initWithBytes :: (self: *NSString, bytes: *void, length: NSUInteger, encoding: NSStringEncoding) -> *NSString { - return xx objc_msgSend(self, _sel.initWithBytes_length_encoding_, bytes, length, encoding); + return xx objc_msgSend_typed(self, _sel.initWithBytes_length_encoding_, bytes, length, encoding); } UTF8String :: (self: *NSString) -> *u8 { - return xx objc_msgSend(self, _sel.UTF8String); + return xx objc_msgSend_typed(self, _sel.UTF8String); } dataUsingEncoding :: (self: *NSString, encoding: NSStringEncoding, allowLossyConversion := NO) -> *NSData { - return xx objc_msgSend(self, _sel.dataUsingEncoding_allowLossyConversion_, encoding, allowLossyConversion); + return xx objc_msgSend_typed(self, _sel.dataUsingEncoding_allowLossyConversion_, encoding, allowLossyConversion); } stringByExpandingTildeInPath :: (self: *NSString) -> *NSString { - return xx objc_msgSend(self, _sel.stringByExpandingTildeInPath); + return xx objc_msgSend_typed(self, _sel.stringByExpandingTildeInPath); } length :: (self: *NSString) -> NSUInteger { - return xx objc_msgSend(self, _sel.length); + return xx objc_msgSend_typed(self, _sel.length); } - + characterAtIndex :: (self: *NSString, at: int) -> u16 { return xx objc_msgSend(self, _sel.characterAtIndex_, at); } @@ -167,11 +167,11 @@ NSTimer :: struct { using #as super: NSObject; scheduledTimerWithTimeInterval :: (interval: NSTimeInterval, target: id, selector: Selector, userInfo: id, repeats: BOOL) -> *NSTimer { - return xx objc_msgSend(class(NSTimer), _sel.scheduledTimerWithTimeInterval_target_selector_userInfo_repeats_, interval, target, selector, userInfo, repeats); + return xx objc_msgSend_typed(class(NSTimer), _sel.scheduledTimerWithTimeInterval_target_selector_userInfo_repeats_, interval, target, selector, userInfo, repeats); } - + invalidate :: (self: *NSTimer) { - objc_msgSend(self, _sel.invalidate); + objc_msgSend_typed(self, _sel.invalidate); } } @@ -179,15 +179,16 @@ NSRunLoop :: struct { using #as super: NSObject; currentRunLoop :: () -> *NSRunLoop { - return xx objc_msgSend(objc_getClass("NSRunLoop"), _sel.currentRunLoop); + return xx objc_msgSend_typed(objc_getClass("NSRunLoop"), _sel.currentRunLoop); } run :: (self: *NSRunLoop) { - objc_msgSend(self, _sel.run); + objc_msgSend_typed(self, _sel.run); } - + + // Added for Focus addTimer :: (self: *NSRunLoop, timer: *NSTimer, run_mode: NSRunLoopMode) { - objc_msgSend(self, _sel.addTimer_forMode_, timer, run_mode); + objc_msgSend_typed(self, _sel.addTimer_forMode_, timer, run_mode); } } @@ -202,140 +203,134 @@ NSProcessInfo :: struct { automaticTerminationOptOutCounter: NSInteger; operatingSystem :: (self: *NSProcessInfo) -> NSUInteger { - _func: (obj: *void, selector: Selector) -> NSUInteger #c_call; - _func = xx objc_msgSend; - return _func(self, _sel.operatingSystem); + return xx objc_msgSend_typed(self, _sel.operatingSystem); } operatingSystemName :: (self: *NSProcessInfo) -> *NSString { - _func: (obj: *void, selector: Selector) -> *NSString #c_call; - _func = xx objc_msgSend; - return _func(self, _sel.operatingSystemName); + return xx objc_msgSend_typed(self, _sel.operatingSystemName); } isOperatingSystemAtLeastVersion :: (self: *NSProcessInfo, version: NSOperatingSystemVersion) -> BOOL { - _func: (obj: *void, selector: Selector, version: NSOperatingSystemVersion) -> BOOL #c_call; - _func = xx objc_msgSend; - return _func(self, _sel.isOperatingSystemAtLeastVersion_, version); + return xx objc_msgSend_typed(self, _sel.isOperatingSystemAtLeastVersion_, version); } disableSuddenTermination :: (self: *NSProcessInfo) -> () { _func: (obj: *void, selector: Selector) -> () #c_call; - _func = xx objc_msgSend; + _func = xx objc_msgSend_typed; _func(self, _sel.disableSuddenTermination); } enableSuddenTermination :: (self: *NSProcessInfo) -> () { _func: (obj: *void, selector: Selector) -> () #c_call; - _func = xx objc_msgSend; + _func = xx objc_msgSend_typed; _func(self, _sel.enableSuddenTermination); } disableAutomaticTermination :: (self: *NSProcessInfo, reason: *NSString) -> () { _func: (obj: *void, selector: Selector, reason: *NSString) -> () #c_call; - _func = xx objc_msgSend; + _func = xx objc_msgSend_typed; _func(self, _sel.disableAutomaticTermination_, reason); } enableAutomaticTermination :: (self: *NSProcessInfo, reason: *NSString) -> () { _func: (obj: *void, selector: Selector, reason: *NSString) -> () #c_call; - _func = xx objc_msgSend; + _func = xx objc_msgSend_typed; _func(self, _sel.enableAutomaticTermination_, reason); } processInfo :: () -> *NSProcessInfo { _func: (obj: *void, selector: Selector) -> *NSProcessInfo #c_call; - _func = xx objc_msgSend; + _func = xx objc_msgSend_typed; return _func(objc_getClass("NSProcessInfo"), _sel.processInfo); } environment :: (self: *NSProcessInfo) -> *NSDictionary { _func: (obj: *void, selector: Selector) -> *NSDictionary #c_call; - _func = xx objc_msgSend; + _func = xx objc_msgSend_typed; return _func(self, _sel.environment); } arguments :: (self: *NSProcessInfo) -> *NSArray(*NSString) { _func: (obj: *void, selector: Selector) -> *NSArray(*NSString) #c_call; - _func = xx objc_msgSend; + _func = xx objc_msgSend_typed; return _func(self, _sel.arguments); } hostName :: (self: *NSProcessInfo) -> *NSString { _func: (obj: *void, selector: Selector) -> *NSString #c_call; - _func = xx objc_msgSend; + _func = xx objc_msgSend_typed; return _func(self, _sel.hostName); } processName :: (self: *NSProcessInfo) -> *NSString { _func: (obj: *void, selector: Selector) -> *NSString #c_call; - _func = xx objc_msgSend; + _func = xx objc_msgSend_typed; return _func(self, _sel.processName); } setProcessName :: (self: *NSProcessInfo, processName: *NSString) -> () { _func: (obj: *void, selector: Selector, processName: *NSString) -> () #c_call; - _func = xx objc_msgSend; + _func = xx objc_msgSend_typed; _func(self, _sel.setProcessName_, processName); } processIdentifier :: (self: *NSProcessInfo) -> s32 { _func: (obj: *void, selector: Selector) -> s32 #c_call; - _func = xx objc_msgSend; + _func = xx objc_msgSend_typed; return _func(self, _sel.processIdentifier); } globallyUniqueString :: (self: *NSProcessInfo) -> *NSString { _func: (obj: *void, selector: Selector) -> *NSString #c_call; - _func = xx objc_msgSend; + _func = xx objc_msgSend_typed; return _func(self, _sel.globallyUniqueString); } operatingSystemVersionString :: (self: *NSProcessInfo) -> *NSString { _func: (obj: *void, selector: Selector) -> *NSString #c_call; - _func = xx objc_msgSend; + _func = xx objc_msgSend_typed; return _func(self, _sel.operatingSystemVersionString); } operatingSystemVersion :: (self: *NSProcessInfo) -> NSOperatingSystemVersion { _func: (obj: *void, selector: Selector) -> NSOperatingSystemVersion #c_call; - _func = xx objc_msgSend; + _func = xx objc_msgSend_typed; return _func(self, _sel.operatingSystemVersion); } processorCount :: (self: *NSProcessInfo) -> NSUInteger { _func: (obj: *void, selector: Selector) -> NSUInteger #c_call; - _func = xx objc_msgSend; + _func = xx objc_msgSend_typed; return _func(self, _sel.processorCount); } activeProcessorCount :: (self: *NSProcessInfo) -> NSUInteger { _func: (obj: *void, selector: Selector) -> NSUInteger #c_call; - _func = xx objc_msgSend; + _func = xx objc_msgSend_typed; return _func(self, _sel.activeProcessorCount); } physicalMemory :: (self: *NSProcessInfo) -> u64 { _func: (obj: *void, selector: Selector) -> u64 #c_call; - _func = xx objc_msgSend; + _func = xx objc_msgSend_typed; return _func(self, _sel.physicalMemory); } systemUptime :: (self: *NSProcessInfo) -> NSTimeInterval { _func: (obj: *void, selector: Selector) -> NSTimeInterval #c_call; - _func = xx objc_msgSend; + _func = xx objc_msgSend_typed; return _func(self, _sel.systemUptime); } automaticTerminationSupportEnabled :: (self: *NSProcessInfo) -> BOOL { _func: (obj: *void, selector: Selector) -> BOOL #c_call; - _func = xx objc_msgSend; + _func = xx objc_msgSend_typed; return _func(self, _sel.automaticTerminationSupportEnabled); } setAutomaticTerminationSupportEnabled :: (self: *NSProcessInfo, automaticTerminationSupportEnabled: BOOL) -> () { _func: (obj: *void, selector: Selector, automaticTerminationSupportEnabled: BOOL) -> () #c_call; - _func = xx objc_msgSend; + _func = xx objc_msgSend_typed; _func(self, _sel.setAutomaticTerminationSupportEnabled_, automaticTerminationSupportEnabled); } @@ -365,11 +360,11 @@ NSThread :: struct { _nsobject: NSObject; detachNewThreadSelectorToTargetWithObject :: (sel: Selector, toTarget: id, withObject: id) { - objc_msgSend(class(NSThread), _sel.detachNewThreadSelector_toTarget_withObject_, sel, toTarget, withObject); + objc_msgSend_typed(class(NSThread), _sel.detachNewThreadSelector_toTarget_withObject_, sel, toTarget, withObject); } isMultiThreaded :: () -> BOOL { - return xx objc_msgSend(class(NSThread), _sel.isMultiThreaded); + return xx objc_msgSend_typed(class(NSThread), _sel.isMultiThreaded); } } @@ -377,7 +372,7 @@ NSNotification :: struct { using #as super: NSObject; object :: (self: *NSNotification) -> *NSObject { - return xx objc_msgSend(self, _sel.object); + return xx objc_msgSend_typed(self, _sel.object); } } @@ -385,12 +380,12 @@ NSNotificationCenter :: struct { using #as super: NSObject; defaultCenter :: () -> *NSNotificationCenter { - return xx objc_msgSend(objc_getClass("NSNotificationCenter"), _sel.defaultCenter); + return xx objc_msgSend_typed(objc_getClass("NSNotificationCenter"), _sel.defaultCenter); } addObserver :: (self: *NSNotificationCenter, observer: id, selector: Selector, name: NSNotificationName, object: id) { - objc_msgSend(self, _sel.addObserver_selector_name_object_, observer, selector, name, object); + objc_msgSend_typed(self, _sel.addObserver_selector_name_object_, observer, selector, name, object); } } @@ -400,36 +395,36 @@ NSURL :: struct { using #as super: NSObject; URLWithString :: (str: *NSString) -> *NSURL { - return xx objc_msgSend(class(NSURL), _sel.URLWithString_, str); + return xx objc_msgSend_typed(class(NSURL), _sel.URLWithString_, str); } fileURLWithPath :: (path: *NSString) -> *NSURL { - return xx objc_msgSend(class(NSURL), _sel.fileURLWithPath_, path); + return xx objc_msgSend_typed(class(NSURL), _sel.fileURLWithPath_, path); } fileURLWithPath :: (path: *NSString, isDirectory: BOOL) -> *NSURL { - return xx objc_msgSend(class(NSURL), _sel.fileURLWithPath_isDirectory_, path, isDirectory); + return xx objc_msgSend_typed(class(NSURL), _sel.fileURLWithPath_isDirectory_, path, isDirectory); } // instance path :: (self: *NSURL) -> *NSString { - return xx objc_msgSend(self, _sel.path); + return xx objc_msgSend_typed(self, _sel.path); } URLByDeletingLastPathComponent :: (self: *NSURL) -> *NSURL { - return xx objc_msgSend(self, _sel.URLByDeletingLastPathComponent); + return xx objc_msgSend_typed(self, _sel.URLByDeletingLastPathComponent); } hasDirectoryPath :: (self: *NSURL) -> BOOL { - return xx objc_msgSend(self, _sel.hasDirectoryPath); + return xx objc_msgSend_typed(self, _sel.hasDirectoryPath); } URLByAppendingPathComponent :: (self: *NSURL, comp: *NSString) -> *NSURL { - return xx objc_msgSend(self, _sel.URLByAppendingPathComponent_, comp); + return xx objc_msgSend_typed(self, _sel.URLByAppendingPathComponent_, comp); } lastPathComponent :: (self: *NSURL) -> *NSString { - return xx objc_msgSend(self, _sel.lastPathComponent); + return xx objc_msgSend_typed(self, _sel.lastPathComponent); } } @@ -437,11 +432,11 @@ NSData :: struct { using #as super: NSObject; bytes :: (self: *NSData) -> *void { - return xx objc_msgSend(self, _sel.bytes); + return xx objc_msgSend_typed(self, _sel.bytes); } length :: (self: *NSData) -> NSUInteger { - return xx objc_msgSend(self, _sel.length); + return xx objc_msgSend_typed(self, _sel.length); } } @@ -454,10 +449,10 @@ NSArray :: struct (Object_Type: Type) { // static arrayWithObject :: (obj: Object_Type) -> *NSArray(Object_Type) { - return xx objc_msgSend(objc_getClass("NSArray"), _sel.arrayWithObject_, obj); + return xx objc_msgSend_typed(objc_getClass("NSArray"), _sel.arrayWithObject_, obj); } arrayWithObjects :: (objs: *Object_Type, count: NSUInteger) -> *NSArray(Object_Type) { - return xx objc_msgSend(objc_getClass("NSArray"), _sel.arrayWithObjects_count_, objs, count); + return xx objc_msgSend_typed(objc_getClass("NSArray"), _sel.arrayWithObjects_count_, objs, count); } // instance @@ -465,15 +460,15 @@ NSArray :: struct (Object_Type: Type) { // @Cleanup it would be nice if we had light generics so that only one version of these functions is generated // when NSArray is instantiated with several different types containsObject :: (self: *NSArray(Object_Type), anObject: Object_Type) -> BOOL { - return xx objc_msgSend(self, _sel.containsObject_, anObject); + return xx objc_msgSend_typed(self, _sel.containsObject_, anObject); } objectAtIndex :: (self: *NSArray(Object_Type), index: NSUInteger) -> Object_Type { - return xx objc_msgSend(self, _sel.objectAtIndex_, index); + return xx objc_msgSend_typed(self, _sel.objectAtIndex_, index); } count :: (self: *NSArray(Object_Type)) -> NSUInteger { - return xx objc_msgSend(self, _sel.count); + return xx objc_msgSend_typed(self, _sel.count); } } @@ -481,13 +476,13 @@ NSFileManager :: struct { using #as super: NSObject; defaultManager :: () -> *NSFileManager { - return xx objc_msgSend(class(NSFileManager), _sel.defaultManager); + return xx objc_msgSend_typed(class(NSFileManager), _sel.defaultManager); } // instance // MACOS 10.6+ URLForDirectory :: (self: *NSFileManager, dir: NSSearchPathDirectory, inDomain: NSSearchPathDomainMask, appropriateForURL: *NSURL, create: BOOL, error: **NSError) -> *NSURL { - return xx objc_msgSend(self, _sel.URLForDirectory_inDomain_appropriateForURL_create_error_, dir, inDomain, appropriateForURL, create, error); + return xx objc_msgSend_typed(self, _sel.URLForDirectory_inDomain_appropriateForURL_create_error_, dir, inDomain, appropriateForURL, create, error); } } @@ -533,7 +528,7 @@ NSError :: struct { using #as super: NSObject; localizedDescription :: (self: *NSError) -> *NSString { - return xx objc_msgSend(self, _sel.localizedDescription); + return xx objc_msgSend_typed(self, _sel.localizedDescription); } } @@ -541,11 +536,11 @@ NSHost :: struct { using #as super: NSObject; currentHost :: () -> *NSHost { - return xx objc_msgSend(objc_getClass("NSHost"), _sel.currentHost); + return xx objc_msgSend_typed(objc_getClass("NSHost"), _sel.currentHost); } localizedName :: (self: *NSHost) -> *NSString { - return xx objc_msgSend(self, _sel.localizedName); + return xx objc_msgSend_typed(self, _sel.localizedName); } } @@ -579,10 +574,8 @@ _sel: struct { dataUsingEncoding_allowLossyConversion_: Selector; stringByExpandingTildeInPath: Selector; scheduledTimerWithTimeInterval_target_selector_userInfo_repeats_: Selector; - invalidate: Selector; currentRunLoop: Selector; run: Selector; - addTimer_forMode_: Selector; operatingSystem: Selector; operatingSystemName: Selector; isOperatingSystemAtLeastVersion_: Selector; @@ -621,7 +614,6 @@ _sel: struct { lastPathComponent: Selector; bytes: Selector; length: Selector; - characterAtIndex_: Selector; arrayWithObject_: Selector; arrayWithObjects_count_: Selector; containsObject_: Selector; @@ -632,6 +624,11 @@ _sel: struct { currentHost: Selector; localizedName: Selector; localizedDescription: Selector; + + // Added for Focus + characterAtIndex_: Selector; + invalidate: Selector; + addTimer_forMode_: Selector; } diff --git a/modules/Objective_C/LightweightRenderingView/build.jai b/modules/Objective_C/LightweightRenderingView/build.jai index 49c8d9039..50bf28c64 100644 --- a/modules/Objective_C/LightweightRenderingView/build.jai +++ b/modules/Objective_C/LightweightRenderingView/build.jai @@ -4,7 +4,7 @@ MACOS_VERSION_ARG :: #run -> string { using options := get_build_options(); - return tprint("-mmacosx-version-min=%.%", minimum_os_version.major, minimum_os_version.minor); + return tprint("-mmacos-version-min=%.%", minimum_os_version.major, minimum_os_version.minor); } success := build_cpp_dynamic_lib("libLightweightRenderingView", "LightweightRenderingView.m", extra = .["-framework", "AppKit", "-framework", "QuartzCore", MACOS_VERSION_ARG]); diff --git a/modules/Objective_C/bindings/arm64/message.jai b/modules/Objective_C/bindings/arm64/message.jai new file mode 100644 index 000000000..2a4ce1501 --- /dev/null +++ b/modules/Objective_C/bindings/arm64/message.jai @@ -0,0 +1,44 @@ +// +// This file was auto-generated using the following command: +// +// jai modules/Objective_C/generate.jai - -arm64 +// + + + +marg_prearg_size :: 0; + +/// Specifies the superclass of an instance. +objc_super :: struct { + /// Specifies an instance of a class. + receiver: id; + + /* For compatibility with old objc-runtime.h header */ + class: Class; +} + +objc_msgSend :: () -> void #foreign libobjc; + +objc_msgSendSuper :: () -> void #foreign libobjc; + +method_invoke :: () -> void #foreign libobjc; + +_objc_msgForward :: () -> void #foreign libobjc; + +/* Variable-argument Messaging Primitives +* +* Use these functions to call methods with a list of arguments, such +* as the one passed to forward:: . +* +* The contents of the argument list are architecture-specific. +* Consult your local function call ABI documentation for details. +* +* These functions must be cast to an appropriate function pointer type +* before being called, except for objc_msgSendv_stret() which must not +* be cast to a struct-returning type. +*/ +marg_list :: *void; + +#scope_file + +libobjc :: #library,system "libobjc"; diff --git a/modules/Objective_C/bindings/arm64/runtime.jai b/modules/Objective_C/bindings/arm64/runtime.jai new file mode 100644 index 000000000..45ef2ce71 --- /dev/null +++ b/modules/Objective_C/bindings/arm64/runtime.jai @@ -0,0 +1,1644 @@ +// +// This file was auto-generated using the following command: +// +// jai modules/Objective_C/generate.jai - -arm64 +// + + + +OBJC_BOOL_IS_BOOL :: 1; + +ARITH_SHIFT :: 32; + +OBJC_GETCLASSHOOK_DEFINED :: 1; + +OBJC_ADDLOADIMAGEFUNC_DEFINED :: 1; + +OBJC_SETHOOK_LAZYCLASSNAMER_DEFINED :: 1; + +OBJC_REALIZECLASSFROMSWIFT_DEFINED :: 1; + +CLS_CLASS :: 0x1; + +CLS_META :: 0x2; + +CLS_INITIALIZED :: 0x4; + +CLS_POSING :: 0x8; + +CLS_MAPPED :: 0x10; + +CLS_FLUSH_CACHE :: 0x20; + +CLS_GROW_CACHE :: 0x40; + +CLS_NEED_BIND :: 0x80; + +CLS_METHOD_ARRAY :: 0x100; + +CLS_JAVA_HYBRID :: 0x200; +CLS_JAVA_CLASS :: 0x400; + +CLS_INITIALIZING :: 0x800; + +CLS_FROM_BUNDLE :: 0x1000; + +CLS_HAS_CXX_STRUCTORS :: 0x2000; + +CLS_NO_METHOD_ARRAY :: 0x4000; + +CLS_HAS_LOAD_METHOD :: 0x8000; + +CLS_CONSTRUCTING :: 0x10000; + +CLS_EXT :: 0x20000; + +OBSOLETE_OBJC_GETCLASSES :: 1; + +OBJC_NEXT_METHOD_LIST :: 1; + +/// An opaque type that represents an Objective-C class. +Class :: *objc_class; + +/// Represents an instance of a class. +NSObject :: struct { + isa: Class; +} + +/// A pointer to an instance of a class. +id :: *NSObject; + +objc_selector :: struct {} +/// An opaque type that represents a method selector. +SEL :: *objc_selector; + +IMP :: #type () -> void #c_call; + +/** +* Returns the name of the method specified by a given selector. +* +* @param sel A pointer of type \c SEL. Pass the selector whose name you wish to determine. +* +* @return A C string indicating the name of the selector. +*/ +sel_getName :: (sel: SEL) -> *u8 #foreign libobjc; + +/** +* Registers a method with the Objective-C runtime system, maps the method +* name to a selector, and returns the selector value. +* +* @param str A pointer to a C string. Pass the name of the method you wish to register. +* +* @return A pointer of type SEL specifying the selector for the named method. +* +* @note You must register a method name with the Objective-C runtime system to obtain the +* method’s selector before you can add the method to a class definition. If the method name +* has already been registered, this function simply returns the selector. +*/ +sel_registerName :: (str: *u8) -> SEL #foreign libobjc; + +/** +* Returns the class name of a given object. +* +* @param obj An Objective-C object. +* +* @return The name of the class of which \e obj is an instance. +*/ +object_getClassName :: (obj: id) -> *u8 #foreign libobjc; + +/** +* Returns a pointer to any extra bytes allocated with an instance given object. +* +* @param obj An Objective-C object. +* +* @return A pointer to any extra bytes allocated with \e obj. If \e obj was +* not allocated with any extra bytes, then dereferencing the returned pointer is undefined. +* +* @note This function returns a pointer to any extra bytes allocated with the instance +* (as specified by \c class_createInstance with extraBytes>0). This memory follows the +* object's ordinary ivars, but may not be adjacent to the last ivar. +* @note The returned pointer is guaranteed to be pointer-size aligned, even if the area following +* the object's last ivar is less aligned than that. Alignment greater than pointer-size is never +* guaranteed, even if the area following the object's last ivar is more aligned than that. +* @note In a garbage-collected environment, the memory is scanned conservatively. +*/ +object_getIndexedIvars :: (obj: id) -> *void #foreign libobjc; + +/** +* Identifies a selector as being valid or invalid. +* +* @param sel The selector you want to identify. +* +* @return YES if selector is valid and has a function implementation, NO otherwise. +* +* @warning On some platforms, an invalid reference (to invalid memory addresses) can cause +* a crash. +*/ +sel_isMapped :: (sel: SEL) -> BOOL #foreign libobjc; + +/** +* Registers a method name with the Objective-C runtime system. +* +* @param str A pointer to a C string. Pass the name of the method you wish to register. +* +* @return A pointer of type SEL specifying the selector for the named method. +* +* @note The implementation of this method is identical to the implementation of \c sel_registerName. +* @note Prior to OS X version 10.0, this method tried to find the selector mapped to the given name +* and returned \c NULL if the selector was not found. This was changed for safety, because it was +* observed that many of the callers of this function did not check the return value for \c NULL. +*/ +sel_getUid :: (str: *u8) -> SEL #foreign libobjc; + +objc_objectptr_t :: *void; + +// Obsolete ARC conversions. +objc_retainedObject :: (obj: objc_objectptr_t) -> id #foreign libobjc; + +objc_unretainedObject :: (obj: objc_objectptr_t) -> id #foreign libobjc; + +objc_unretainedPointer :: (obj: id) -> objc_objectptr_t #foreign libobjc; + +arith_t :: s64; +uarith_t :: u64; + +STR :: *u8; + +/// An opaque type that represents a method in a class definition. +Method :: *objc_method; + +/// An opaque type that represents an instance variable. +Ivar :: *objc_ivar; + +/// An opaque type that represents a category. +Category :: *objc_category; + +objc_property :: struct {} +/// An opaque type that represents an Objective-C declared property. +objc_property_t :: *objc_property; + +objc_class :: struct { + #as using super: NSObject; + super_class: Class; + name: *u8; + version: s64; + info: s64; + instance_size: s64; + ivars: *objc_ivar_list; + methodLists: **objc_method_list; + cache: *objc_cache; + protocols: *objc_protocol_list; +} + +Protocol :: NSObject; + +/// Defines a method +objc_method_description :: struct { + name: SEL; /**< The name of the method */ + types: *u8; /**< The types of the method arguments */ +} + +/// Defines a property attribute +objc_property_attribute_t :: struct { + name: *u8; /**< The name of the attribute */ + value: *u8; /**< The value of the attribute (usually empty) */ +} + +/** +* Returns a copy of a given object. +* +* @param obj An Objective-C object. +* @param size The size of the object \e obj. +* +* @return A copy of \e obj. +*/ +object_copy :: (obj: id, size: u64) -> id #foreign libobjc; + +/** +* Frees the memory occupied by a given object. +* +* @param obj An Objective-C object. +* +* @return nil +*/ +object_dispose :: (obj: id) -> id #foreign libobjc; + +/** +* Returns the class of an object. +* +* @param obj The object you want to inspect. +* +* @return The class object of which \e object is an instance, +* or \c Nil if \e object is \c nil. +*/ +object_getClass :: (obj: id) -> Class #foreign libobjc; + +/** +* Sets the class of an object. +* +* @param obj The object to modify. +* @param cls A class object. +* +* @return The previous value of \e object's class, or \c Nil if \e object is \c nil. +*/ +object_setClass :: (obj: id, cls: Class) -> Class #foreign libobjc; + +/** +* Returns whether an object is a class object. +* +* @param obj An Objective-C object. +* +* @return true if the object is a class or metaclass, false otherwise. +*/ +object_isClass :: (obj: id) -> BOOL #foreign libobjc; + +/** +* Reads the value of an instance variable in an object. +* +* @param obj The object containing the instance variable whose value you want to read. +* @param ivar The Ivar describing the instance variable whose value you want to read. +* +* @return The value of the instance variable specified by \e ivar, or \c nil if \e object is \c nil. +* +* @note \c object_getIvar is faster than \c object_getInstanceVariable if the Ivar +* for the instance variable is already known. +*/ +object_getIvar :: (obj: id, ivar: Ivar) -> id #foreign libobjc; + +/** +* Sets the value of an instance variable in an object. +* +* @param obj The object containing the instance variable whose value you want to set. +* @param ivar The Ivar describing the instance variable whose value you want to set. +* @param value The new value for the instance variable. +* +* @note Instance variables with known memory management (such as ARC strong and weak) +* use that memory management. Instance variables with unknown memory management +* are assigned as if they were unsafe_unretained. +* @note \c object_setIvar is faster than \c object_setInstanceVariable if the Ivar +* for the instance variable is already known. +*/ +object_setIvar :: (obj: id, ivar: Ivar, value: id) -> void #foreign libobjc; + +/** +* Sets the value of an instance variable in an object. +* +* @param obj The object containing the instance variable whose value you want to set. +* @param ivar The Ivar describing the instance variable whose value you want to set. +* @param value The new value for the instance variable. +* +* @note Instance variables with known memory management (such as ARC strong and weak) +* use that memory management. Instance variables with unknown memory management +* are assigned as if they were strong. +* @note \c object_setIvar is faster than \c object_setInstanceVariable if the Ivar +* for the instance variable is already known. +*/ +object_setIvarWithStrongDefault :: (obj: id, ivar: Ivar, value: id) -> void #foreign libobjc; + +/** +* Changes the value of an instance variable of a class instance. +* +* @param obj A pointer to an instance of a class. Pass the object containing +* the instance variable whose value you wish to modify. +* @param name A C string. Pass the name of the instance variable whose value you wish to modify. +* @param value The new value for the instance variable. +* +* @return A pointer to the \c Ivar data structure that defines the type and +* name of the instance variable specified by \e name. +* +* @note Instance variables with known memory management (such as ARC strong and weak) +* use that memory management. Instance variables with unknown memory management +* are assigned as if they were unsafe_unretained. +*/ +object_setInstanceVariable :: (obj: id, name: *u8, value: *void) -> Ivar #foreign libobjc; + +/** +* Changes the value of an instance variable of a class instance. +* +* @param obj A pointer to an instance of a class. Pass the object containing +* the instance variable whose value you wish to modify. +* @param name A C string. Pass the name of the instance variable whose value you wish to modify. +* @param value The new value for the instance variable. +* +* @return A pointer to the \c Ivar data structure that defines the type and +* name of the instance variable specified by \e name. +* +* @note Instance variables with known memory management (such as ARC strong and weak) +* use that memory management. Instance variables with unknown memory management +* are assigned as if they were strong. +*/ +object_setInstanceVariableWithStrongDefault :: (obj: id, name: *u8, value: *void) -> Ivar #foreign libobjc; + +/** +* Obtains the value of an instance variable of a class instance. +* +* @param obj A pointer to an instance of a class. Pass the object containing +* the instance variable whose value you wish to obtain. +* @param name A C string. Pass the name of the instance variable whose value you wish to obtain. +* @param outValue On return, contains a pointer to the value of the instance variable. +* +* @return A pointer to the \c Ivar data structure that defines the type and name of +* the instance variable specified by \e name. +*/ +object_getInstanceVariable :: (obj: id, name: *u8, outValue: **void) -> Ivar #foreign libobjc; + +/** +* Returns the class definition of a specified class. +* +* @param name The name of the class to look up. +* +* @return The Class object for the named class, or \c nil +* if the class is not registered with the Objective-C runtime. +* +* @note \c objc_getClass is different from \c objc_lookUpClass in that if the class +* is not registered, \c objc_getClass calls the class handler callback and then checks +* a second time to see whether the class is registered. \c objc_lookUpClass does +* not call the class handler callback. +* +* @warning Earlier implementations of this function (prior to OS X v10.0) +* terminate the program if the class does not exist. +*/ +objc_getClass :: (name: *u8) -> Class #foreign libobjc; + +/** +* Returns the metaclass definition of a specified class. +* +* @param name The name of the class to look up. +* +* @return The \c Class object for the metaclass of the named class, or \c nil if the class +* is not registered with the Objective-C runtime. +* +* @note If the definition for the named class is not registered, this function calls the class handler +* callback and then checks a second time to see if the class is registered. However, every class +* definition must have a valid metaclass definition, and so the metaclass definition is always returned, +* whether it’s valid or not. +*/ +objc_getMetaClass :: (name: *u8) -> Class #foreign libobjc; + +/** +* Returns the class definition of a specified class. +* +* @param name The name of the class to look up. +* +* @return The Class object for the named class, or \c nil if the class +* is not registered with the Objective-C runtime. +* +* @note \c objc_getClass is different from this function in that if the class is not +* registered, \c objc_getClass calls the class handler callback and then checks a second +* time to see whether the class is registered. This function does not call the class handler callback. +*/ +objc_lookUpClass :: (name: *u8) -> Class #foreign libobjc; + +/** +* Returns the class definition of a specified class. +* +* @param name The name of the class to look up. +* +* @return The Class object for the named class. +* +* @note This function is the same as \c objc_getClass, but kills the process if the class is not found. +* @note This function is used by ZeroLink, where failing to find a class would be a compile-time link error without ZeroLink. +*/ +objc_getRequiredClass :: (name: *u8) -> Class #foreign libobjc; + +/** +* Obtains the list of registered class definitions. +* +* @param buffer An array of \c Class values. On output, each \c Class value points to +* one class definition, up to either \e bufferCount or the total number of registered classes, +* whichever is less. You can pass \c NULL to obtain the total number of registered class +* definitions without actually retrieving any class definitions. +* @param bufferCount An integer value. Pass the number of pointers for which you have allocated space +* in \e buffer. On return, this function fills in only this number of elements. If this number is less +* than the number of registered classes, this function returns an arbitrary subset of the registered classes. +* +* @return An integer value indicating the total number of registered classes. +* +* @note The Objective-C runtime library automatically registers all the classes defined in your source code. +* You can create class definitions at runtime and register them with the \c objc_addClass function. +* +* @warning You cannot assume that class objects you get from this function are classes that inherit from \c NSObject, +* so you cannot safely call any methods on such classes without detecting that the method is implemented first. +*/ +objc_getClassList :: (buffer: *Class, bufferCount: s32) -> s32 #foreign libobjc; + +/** +* Creates and returns a list of pointers to all registered class definitions. +* +* @param outCount An integer pointer used to store the number of classes returned by +* this function in the list. It can be \c nil. +* +* @return A nil terminated array of classes. It must be freed with \c free(). +* +* @see objc_getClassList +*/ +objc_copyClassList :: (outCount: *u32) -> *Class #foreign libobjc; + +/** +* Returns the name of a class. +* +* @param cls A class object. +* +* @return The name of the class, or the empty string if \e cls is \c Nil. +*/ +class_getName :: (cls: Class) -> *u8 #foreign libobjc; + +/** +* Returns a Boolean value that indicates whether a class object is a metaclass. +* +* @param cls A class object. +* +* @return \c YES if \e cls is a metaclass, \c NO if \e cls is a non-meta class, +* \c NO if \e cls is \c Nil. +*/ +class_isMetaClass :: (cls: Class) -> BOOL #foreign libobjc; + +/** +* Returns the superclass of a class. +* +* @param cls A class object. +* +* @return The superclass of the class, or \c Nil if +* \e cls is a root class, or \c Nil if \e cls is \c Nil. +* +* @note You should usually use \c NSObject's \c superclass method instead of this function. +*/ +class_getSuperclass :: (cls: Class) -> Class #foreign libobjc; + +/** +* Sets the superclass of a given class. +* +* @param cls The class whose superclass you want to set. +* @param newSuper The new superclass for cls. +* +* @return The old superclass for cls. +* +* @warning You should not use this function. +*/ +class_setSuperclass :: (cls: Class, newSuper: Class) -> Class #foreign libobjc; + +/** +* Returns the version number of a class definition. +* +* @param cls A pointer to a \c Class data structure. Pass +* the class definition for which you wish to obtain the version. +* +* @return An integer indicating the version number of the class definition. +* +* @see class_setVersion +*/ +class_getVersion :: (cls: Class) -> s32 #foreign libobjc; + +/** +* Sets the version number of a class definition. +* +* @param cls A pointer to an Class data structure. +* Pass the class definition for which you wish to set the version. +* @param version An integer. Pass the new version number of the class definition. +* +* @note You can use the version number of the class definition to provide versioning of the +* interface that your class represents to other classes. This is especially useful for object +* serialization (that is, archiving of the object in a flattened form), where it is important to +* recognize changes to the layout of the instance variables in different class-definition versions. +* @note Classes derived from the Foundation framework \c NSObject class can set the class-definition +* version number using the \c setVersion: class method, which is implemented using the \c class_setVersion function. +*/ +class_setVersion :: (cls: Class, version: s32) -> void #foreign libobjc; + +/** +* Returns the size of instances of a class. +* +* @param cls A class object. +* +* @return The size in bytes of instances of the class \e cls, or \c 0 if \e cls is \c Nil. +*/ +class_getInstanceSize :: (cls: Class) -> u64 #foreign libobjc; + +/** +* Returns the \c Ivar for a specified instance variable of a given class. +* +* @param cls The class whose instance variable you wish to obtain. +* @param name The name of the instance variable definition to obtain. +* +* @return A pointer to an \c Ivar data structure containing information about +* the instance variable specified by \e name. +*/ +class_getInstanceVariable :: (cls: Class, name: *u8) -> Ivar #foreign libobjc; + +/** +* Returns the Ivar for a specified class variable of a given class. +* +* @param cls The class definition whose class variable you wish to obtain. +* @param name The name of the class variable definition to obtain. +* +* @return A pointer to an \c Ivar data structure containing information about the class variable specified by \e name. +*/ +class_getClassVariable :: (cls: Class, name: *u8) -> Ivar #foreign libobjc; + +/** +* Describes the instance variables declared by a class. +* +* @param cls The class to inspect. +* @param outCount On return, contains the length of the returned array. +* If outCount is NULL, the length is not returned. +* +* @return An array of pointers of type Ivar describing the instance variables declared by the class. +* Any instance variables declared by superclasses are not included. The array contains *outCount +* pointers followed by a NULL terminator. You must free the array with free(). +* +* If the class declares no instance variables, or cls is Nil, NULL is returned and *outCount is 0. +*/ +class_copyIvarList :: (cls: Class, outCount: *u32) -> *Ivar #foreign libobjc; + +/** +* Returns a specified instance method for a given class. +* +* @param cls The class you want to inspect. +* @param name The selector of the method you want to retrieve. +* +* @return The method that corresponds to the implementation of the selector specified by +* \e name for the class specified by \e cls, or \c NULL if the specified class or its +* superclasses do not contain an instance method with the specified selector. +* +* @note This function searches superclasses for implementations, whereas \c class_copyMethodList does not. +*/ +class_getInstanceMethod :: (cls: Class, name: SEL) -> Method #foreign libobjc; + +/** +* Returns a pointer to the data structure describing a given class method for a given class. +* +* @param cls A pointer to a class definition. Pass the class that contains the method you want to retrieve. +* @param name A pointer of type \c SEL. Pass the selector of the method you want to retrieve. +* +* @return A pointer to the \c Method data structure that corresponds to the implementation of the +* selector specified by aSelector for the class specified by aClass, or NULL if the specified +* class or its superclasses do not contain an instance method with the specified selector. +* +* @note Note that this function searches superclasses for implementations, +* whereas \c class_copyMethodList does not. +*/ +class_getClassMethod :: (cls: Class, name: SEL) -> Method #foreign libobjc; + +/** +* Returns the function pointer that would be called if a +* particular message were sent to an instance of a class. +* +* @param cls The class you want to inspect. +* @param name A selector. +* +* @return The function pointer that would be called if \c [object name] were called +* with an instance of the class, or \c NULL if \e cls is \c Nil. +* +* @note \c class_getMethodImplementation may be faster than \c method_getImplementation(class_getInstanceMethod(cls, name)). +* @note The function pointer returned may be a function internal to the runtime instead of +* an actual method implementation. For example, if instances of the class do not respond to +* the selector, the function pointer returned will be part of the runtime's message forwarding machinery. +*/ +class_getMethodImplementation :: (cls: Class, name: SEL) -> IMP #foreign libobjc; + +/** +* Returns a Boolean value that indicates whether instances of a class respond to a particular selector. +* +* @param cls The class you want to inspect. +* @param sel A selector. +* +* @return \c YES if instances of the class respond to the selector, otherwise \c NO. +* +* @note You should usually use \c NSObject's \c respondsToSelector: or \c instancesRespondToSelector: +* methods instead of this function. +*/ +class_respondsToSelector :: (cls: Class, sel: SEL) -> BOOL #foreign libobjc; + +/** +* Describes the instance methods implemented by a class. +* +* @param cls The class you want to inspect. +* @param outCount On return, contains the length of the returned array. +* If outCount is NULL, the length is not returned. +* +* @return An array of pointers of type Method describing the instance methods +* implemented by the class—any instance methods implemented by superclasses are not included. +* The array contains *outCount pointers followed by a NULL terminator. You must free the array with free(). +* +* If cls implements no instance methods, or cls is Nil, returns NULL and *outCount is 0. +* +* @note To get the class methods of a class, use \c class_copyMethodList(object_getClass(cls), &count). +* @note To get the implementations of methods that may be implemented by superclasses, +* use \c class_getInstanceMethod or \c class_getClassMethod. +*/ +class_copyMethodList :: (cls: Class, outCount: *u32) -> *Method #foreign libobjc; + +/** +* Returns a Boolean value that indicates whether a class conforms to a given protocol. +* +* @param cls The class you want to inspect. +* @param protocol A protocol. +* +* @return YES if cls conforms to protocol, otherwise NO. +* +* @note You should usually use NSObject's conformsToProtocol: method instead of this function. +*/ +class_conformsToProtocol :: (cls: Class, protocol: *Protocol) -> BOOL #foreign libobjc; + +/** +* Describes the protocols adopted by a class. +* +* @param cls The class you want to inspect. +* @param outCount On return, contains the length of the returned array. +* If outCount is NULL, the length is not returned. +* +* @return An array of pointers of type Protocol* describing the protocols adopted +* by the class. Any protocols adopted by superclasses or other protocols are not included. +* The array contains *outCount pointers followed by a NULL terminator. You must free the array with free(). +* +* If cls adopts no protocols, or cls is Nil, returns NULL and *outCount is 0. +*/ +class_copyProtocolList :: (cls: Class, outCount: *u32) -> **Protocol #foreign libobjc; + +/** +* Returns a property with a given name of a given class. +* +* @param cls The class you want to inspect. +* @param name The name of the property you want to inspect. +* +* @return A pointer of type \c objc_property_t describing the property, or +* \c NULL if the class does not declare a property with that name, +* or \c NULL if \e cls is \c Nil. +*/ +class_getProperty :: (cls: Class, name: *u8) -> objc_property_t #foreign libobjc; + +/** +* Describes the properties declared by a class. +* +* @param cls The class you want to inspect. +* @param outCount On return, contains the length of the returned array. +* If \e outCount is \c NULL, the length is not returned. +* +* @return An array of pointers of type \c objc_property_t describing the properties +* declared by the class. Any properties declared by superclasses are not included. +* The array contains \c *outCount pointers followed by a \c NULL terminator. You must free the array with \c free(). +* +* If \e cls declares no properties, or \e cls is \c Nil, returns \c NULL and \c *outCount is \c 0. +*/ +class_copyPropertyList :: (cls: Class, outCount: *u32) -> *objc_property_t #foreign libobjc; + +/** +* Returns a description of the \c Ivar layout for a given class. +* +* @param cls The class to inspect. +* +* @return A description of the \c Ivar layout for \e cls. +*/ +class_getIvarLayout :: (cls: Class) -> *u8 #foreign libobjc; + +/** +* Returns a description of the layout of weak Ivars for a given class. +* +* @param cls The class to inspect. +* +* @return A description of the layout of the weak \c Ivars for \e cls. +*/ +class_getWeakIvarLayout :: (cls: Class) -> *u8 #foreign libobjc; + +/** +* Adds a new method to a class with a given name and implementation. +* +* @param cls The class to which to add a method. +* @param name A selector that specifies the name of the method being added. +* @param imp A function which is the implementation of the new method. The function must take at least two arguments—self and _cmd. +* @param types An array of characters that describe the types of the arguments to the method. +* +* @return YES if the method was added successfully, otherwise NO +* (for example, the class already contains a method implementation with that name). +* +* @note class_addMethod will add an override of a superclass's implementation, +* but will not replace an existing implementation in this class. +* To change an existing implementation, use method_setImplementation. +*/ +class_addMethod :: (cls: Class, name: SEL, imp: IMP, types: *u8) -> BOOL #foreign libobjc; + +/** +* Replaces the implementation of a method for a given class. +* +* @param cls The class you want to modify. +* @param name A selector that identifies the method whose implementation you want to replace. +* @param imp The new implementation for the method identified by name for the class identified by cls. +* @param types An array of characters that describe the types of the arguments to the method. +* Since the function must take at least two arguments—self and _cmd, the second and third characters +* must be “@:” (the first character is the return type). +* +* @return The previous implementation of the method identified by \e name for the class identified by \e cls. +* +* @note This function behaves in two different ways: +* - If the method identified by \e name does not yet exist, it is added as if \c class_addMethod were called. +* The type encoding specified by \e types is used as given. +* - If the method identified by \e name does exist, its \c IMP is replaced as if \c method_setImplementation were called. +* The type encoding specified by \e types is ignored. +*/ +class_replaceMethod :: (cls: Class, name: SEL, imp: IMP, types: *u8) -> IMP #foreign libobjc; + +/** +* Adds a new instance variable to a class. +* +* @return YES if the instance variable was added successfully, otherwise NO +* (for example, the class already contains an instance variable with that name). +* +* @note This function may only be called after objc_allocateClassPair and before objc_registerClassPair. +* Adding an instance variable to an existing class is not supported. +* @note The class must not be a metaclass. Adding an instance variable to a metaclass is not supported. +* @note The instance variable's minimum alignment in bytes is 1< BOOL #foreign libobjc; + +/** +* Adds a protocol to a class. +* +* @param cls The class to modify. +* @param protocol The protocol to add to \e cls. +* +* @return \c YES if the method was added successfully, otherwise \c NO +* (for example, the class already conforms to that protocol). +*/ +class_addProtocol :: (cls: Class, protocol: *Protocol) -> BOOL #foreign libobjc; + +/** +* Adds a property to a class. +* +* @param cls The class to modify. +* @param name The name of the property. +* @param attributes An array of property attributes. +* @param attributeCount The number of attributes in \e attributes. +* +* @return \c YES if the property was added successfully, otherwise \c NO +* (for example, the class already has that property). +*/ +class_addProperty :: (cls: Class, name: *u8, attributes: *objc_property_attribute_t, attributeCount: u32) -> BOOL #foreign libobjc; + +/** +* Replace a property of a class. +* +* @param cls The class to modify. +* @param name The name of the property. +* @param attributes An array of property attributes. +* @param attributeCount The number of attributes in \e attributes. +*/ +class_replaceProperty :: (cls: Class, name: *u8, attributes: *objc_property_attribute_t, attributeCount: u32) -> void #foreign libobjc; + +/** +* Sets the Ivar layout for a given class. +* +* @param cls The class to modify. +* @param layout The layout of the \c Ivars for \e cls. +*/ +class_setIvarLayout :: (cls: Class, layout: *u8) -> void #foreign libobjc; + +/** +* Sets the layout for weak Ivars for a given class. +* +* @param cls The class to modify. +* @param layout The layout of the weak Ivars for \e cls. +*/ +class_setWeakIvarLayout :: (cls: Class, layout: *u8) -> void #foreign libobjc; + +/** +* Used by CoreFoundation's toll-free bridging. +* Return the id of the named class. +* +* @return The id of the named class, or an uninitialized class +* structure that will be used for the class when and if it does +* get loaded. +* +* @warning Do not call this function yourself. +*/ +objc_getFutureClass :: (name: *u8) -> Class #foreign libobjc; + +/** +* Creates an instance of a class, allocating memory for the class in the +* default malloc memory zone. +* +* @param cls The class that you wish to allocate an instance of. +* @param extraBytes An integer indicating the number of extra bytes to allocate. +* The additional bytes can be used to store additional instance variables beyond +* those defined in the class definition. +* +* @return An instance of the class \e cls. +*/ +class_createInstance :: (cls: Class, extraBytes: u64) -> id #foreign libobjc; + +/** +* Creates an instance of a class at the specific location provided. +* +* @param cls The class that you wish to allocate an instance of. +* @param bytes The location at which to allocate an instance of \e cls. +* Must point to at least \c class_getInstanceSize(cls) bytes of well-aligned, +* zero-filled memory. +* +* @return \e bytes on success, \c nil otherwise. (For example, \e cls or \e bytes +* might be \c nil) +* +* @see class_createInstance +*/ +objc_constructInstance :: (cls: Class, bytes: *void) -> id #foreign libobjc; + +/** +* Destroys an instance of a class without freeing memory and removes any +* associated references this instance might have had. +* +* @param obj The class instance to destroy. +* +* @return \e obj. Does nothing if \e obj is nil. +* +* @note CF and other clients do call this under GC. +*/ +objc_destructInstance :: (obj: id) -> *void #foreign libobjc; + +/** +* Creates a new class and metaclass. +* +* @param superclass The class to use as the new class's superclass, or \c Nil to create a new root class. +* @param name The string to use as the new class's name. The string will be copied. +* @param extraBytes The number of bytes to allocate for indexed ivars at the end of +* the class and metaclass objects. This should usually be \c 0. +* +* @return The new class, or Nil if the class could not be created (for example, the desired name is already in use). +* +* @note You can get a pointer to the new metaclass by calling \c object_getClass(newClass). +* @note To create a new class, start by calling \c objc_allocateClassPair. +* Then set the class's attributes with functions like \c class_addMethod and \c class_addIvar. +* When you are done building the class, call \c objc_registerClassPair. The new class is now ready for use. +* @note Instance methods and instance variables should be added to the class itself. +* Class methods should be added to the metaclass. +*/ +objc_allocateClassPair :: (superclass: Class, name: *u8, extraBytes: u64) -> Class #foreign libobjc; + +/** +* Registers a class that was allocated using \c objc_allocateClassPair. +* +* @param cls The class you want to register. +*/ +objc_registerClassPair :: (cls: Class) -> void #foreign libobjc; + +/** +* Used by Foundation's Key-Value Observing. +* +* @warning Do not call this function yourself. +*/ +objc_duplicateClass :: (original: Class, name: *u8, extraBytes: u64) -> Class #foreign libobjc; + +/** +* Destroy a class and its associated metaclass. +* +* @param cls The class to be destroyed. It must have been allocated with +* \c objc_allocateClassPair +* +* @warning Do not call if instances of this class or a subclass exist. +*/ +objc_disposeClassPair :: (cls: Class) -> void #foreign libobjc; + +/** +* Returns the name of a method. +* +* @param m The method to inspect. +* +* @return A pointer of type SEL. +* +* @note To get the method name as a C string, call \c sel_getName(method_getName(method)). +*/ +method_getName :: (m: Method) -> SEL #foreign libobjc; + +/** +* Returns the implementation of a method. +* +* @param m The method to inspect. +* +* @return A function pointer of type IMP. +*/ +method_getImplementation :: (m: Method) -> IMP #foreign libobjc; + +/** +* Returns a string describing a method's parameter and return types. +* +* @param m The method to inspect. +* +* @return A C string. The string may be \c NULL. +*/ +method_getTypeEncoding :: (m: Method) -> *u8 #foreign libobjc; + +/** +* Returns the number of arguments accepted by a method. +* +* @param m A pointer to a \c Method data structure. Pass the method in question. +* +* @return An integer containing the number of arguments accepted by the given method. +*/ +method_getNumberOfArguments :: (m: Method) -> u32 #foreign libobjc; + +/** +* Returns a string describing a method's return type. +* +* @param m The method to inspect. +* +* @return A C string describing the return type. You must free the string with \c free(). +*/ +method_copyReturnType :: (m: Method) -> *u8 #foreign libobjc; + +/** +* Returns a string describing a single parameter type of a method. +* +* @param m The method to inspect. +* @param index The index of the parameter to inspect. +* +* @return A C string describing the type of the parameter at index \e index, or \c NULL +* if method has no parameter index \e index. You must free the string with \c free(). +*/ +method_copyArgumentType :: (m: Method, index: u32) -> *u8 #foreign libobjc; + +/** +* Returns by reference a string describing a method's return type. +* +* @param m The method you want to inquire about. +* @param dst The reference string to store the description. +* @param dst_len The maximum number of characters that can be stored in \e dst. +* +* @note The method's return type string is copied to \e dst. +* \e dst is filled as if \c strncpy(dst, parameter_type, dst_len) were called. +*/ +method_getReturnType :: (m: Method, dst: *u8, dst_len: u64) -> void #foreign libobjc; + +/** +* Returns by reference a string describing a single parameter type of a method. +* +* @param m The method you want to inquire about. +* @param index The index of the parameter you want to inquire about. +* @param dst The reference string to store the description. +* @param dst_len The maximum number of characters that can be stored in \e dst. +* +* @note The parameter type string is copied to \e dst. \e dst is filled as if \c strncpy(dst, parameter_type, dst_len) +* were called. If the method contains no parameter with that index, \e dst is filled as +* if \c strncpy(dst, "", dst_len) were called. +*/ +method_getArgumentType :: (m: Method, index: u32, dst: *u8, dst_len: u64) -> void #foreign libobjc; + +method_getDescription :: (m: Method) -> *objc_method_description #foreign libobjc; + +/** +* Sets the implementation of a method. +* +* @param m The method for which to set an implementation. +* @param imp The implemention to set to this method. +* +* @return The previous implementation of the method. +*/ +method_setImplementation :: (m: Method, imp: IMP) -> IMP #foreign libobjc; + +/** +* Exchanges the implementations of two methods. +* +* @param m1 Method to exchange with second method. +* @param m2 Method to exchange with first method. +* +* @note This is an atomic version of the following: +* \code +* IMP imp1 = method_getImplementation(m1); +* IMP imp2 = method_getImplementation(m2); +* method_setImplementation(m1, imp2); +* method_setImplementation(m2, imp1); +* \endcode +*/ +method_exchangeImplementations :: (m1: Method, m2: Method) -> void #foreign libobjc; + +/** +* Returns the name of an instance variable. +* +* @param v The instance variable you want to enquire about. +* +* @return A C string containing the instance variable's name. +*/ +ivar_getName :: (v: Ivar) -> *u8 #foreign libobjc; + +/** +* Returns the type string of an instance variable. +* +* @param v The instance variable you want to enquire about. +* +* @return A C string containing the instance variable's type encoding. +* +* @note For possible values, see Objective-C Runtime Programming Guide > Type Encodings. +*/ +ivar_getTypeEncoding :: (v: Ivar) -> *u8 #foreign libobjc; + +/** +* Returns the offset of an instance variable. +* +* @param v The instance variable you want to enquire about. +* +* @return The offset of \e v. +* +* @note For instance variables of type \c id or other object types, call \c object_getIvar +* and \c object_setIvar instead of using this offset to access the instance variable data directly. +*/ +ivar_getOffset :: (v: Ivar) -> ptrdiff_t #foreign libobjc; + +/** +* Returns the name of a property. +* +* @param property The property you want to inquire about. +* +* @return A C string containing the property's name. +*/ +property_getName :: (property: objc_property_t) -> *u8 #foreign libobjc; + +/** +* Returns the attribute string of a property. +* +* @param property A property. +* +* @return A C string containing the property's attributes. +* +* @note The format of the attribute string is described in Declared Properties in Objective-C Runtime Programming Guide. +*/ +property_getAttributes :: (property: objc_property_t) -> *u8 #foreign libobjc; + +/** +* Returns an array of property attributes for a property. +* +* @param property The property whose attributes you want copied. +* @param outCount The number of attributes returned in the array. +* +* @return An array of property attributes; must be free'd() by the caller. +*/ +property_copyAttributeList :: (property: objc_property_t, outCount: *u32) -> *objc_property_attribute_t #foreign libobjc; + +/** +* Returns the value of a property attribute given the attribute name. +* +* @param property The property whose attribute value you are interested in. +* @param attributeName C string representing the attribute name. +* +* @return The value string of the attribute \e attributeName if it exists in +* \e property, \c nil otherwise. +*/ +property_copyAttributeValue :: (property: objc_property_t, attributeName: *u8) -> *u8 #foreign libobjc; + +/** +* Returns a specified protocol. +* +* @param name The name of a protocol. +* +* @return The protocol named \e name, or \c NULL if no protocol named \e name could be found. +* +* @note This function acquires the runtime lock. +*/ +objc_getProtocol :: (name: *u8) -> *Protocol #foreign libobjc; + +/** +* Returns an array of all the protocols known to the runtime. +* +* @param outCount Upon return, contains the number of protocols in the returned array. +* +* @return A C array of all the protocols known to the runtime. The array contains \c *outCount +* pointers followed by a \c NULL terminator. You must free the list with \c free(). +* +* @note This function acquires the runtime lock. +*/ +objc_copyProtocolList :: (outCount: *u32) -> **Protocol #foreign libobjc; + +/** +* Returns a Boolean value that indicates whether one protocol conforms to another protocol. +* +* @param proto A protocol. +* @param other A protocol. +* +* @return \c YES if \e proto conforms to \e other, otherwise \c NO. +* +* @note One protocol can incorporate other protocols using the same syntax +* that classes use to adopt a protocol: +* \code +* @protocol ProtocolName < protocol list > +* \endcode +* All the protocols listed between angle brackets are considered part of the ProtocolName protocol. +*/ +protocol_conformsToProtocol :: (proto: *Protocol, other: *Protocol) -> BOOL #foreign libobjc; + +/** +* Returns a Boolean value that indicates whether two protocols are equal. +* +* @param proto A protocol. +* @param other A protocol. +* +* @return \c YES if \e proto is the same as \e other, otherwise \c NO. +*/ +protocol_isEqual :: (proto: *Protocol, other: *Protocol) -> BOOL #foreign libobjc; + +/** +* Returns the name of a protocol. +* +* @param proto A protocol. +* +* @return The name of the protocol \e p as a C string. +*/ +protocol_getName :: (proto: *Protocol) -> *u8 #foreign libobjc; + +/** +* Returns a method description structure for a specified method of a given protocol. +* +* @param proto A protocol. +* @param aSel A selector. +* @param isRequiredMethod A Boolean value that indicates whether aSel is a required method. +* @param isInstanceMethod A Boolean value that indicates whether aSel is an instance method. +* +* @return An \c objc_method_description structure that describes the method specified by \e aSel, +* \e isRequiredMethod, and \e isInstanceMethod for the protocol \e p. +* If the protocol does not contain the specified method, returns an \c objc_method_description structure +* with the value \c {NULL, \c NULL}. +* +* @note This function recursively searches any protocols that this protocol conforms to. +*/ +protocol_getMethodDescription :: (proto: *Protocol, aSel: SEL, isRequiredMethod: BOOL, isInstanceMethod: BOOL) -> objc_method_description #foreign libobjc; + +/** +* Returns an array of method descriptions of methods meeting a given specification for a given protocol. +* +* @param proto A protocol. +* @param isRequiredMethod A Boolean value that indicates whether returned methods should +* be required methods (pass YES to specify required methods). +* @param isInstanceMethod A Boolean value that indicates whether returned methods should +* be instance methods (pass YES to specify instance methods). +* @param outCount Upon return, contains the number of method description structures in the returned array. +* +* @return A C array of \c objc_method_description structures containing the names and types of \e p's methods +* specified by \e isRequiredMethod and \e isInstanceMethod. The array contains \c *outCount pointers followed +* by a \c NULL terminator. You must free the list with \c free(). +* If the protocol declares no methods that meet the specification, \c NULL is returned and \c *outCount is 0. +* +* @note Methods in other protocols adopted by this protocol are not included. +*/ +protocol_copyMethodDescriptionList :: (proto: *Protocol, isRequiredMethod: BOOL, isInstanceMethod: BOOL, outCount: *u32) -> *objc_method_description #foreign libobjc; + +/** +* Returns the specified property of a given protocol. +* +* @param proto A protocol. +* @param name The name of a property. +* @param isRequiredProperty \c YES searches for a required property, \c NO searches for an optional property. +* @param isInstanceProperty \c YES searches for an instance property, \c NO searches for a class property. +* +* @return The property specified by \e name, \e isRequiredProperty, and \e isInstanceProperty for \e proto, +* or \c NULL if none of \e proto's properties meets the specification. +*/ +protocol_getProperty :: (proto: *Protocol, name: *u8, isRequiredProperty: BOOL, isInstanceProperty: BOOL) -> objc_property_t #foreign libobjc; + +/** +* Returns an array of the required instance properties declared by a protocol. +* +* @note Identical to +* \code +* protocol_copyPropertyList2(proto, outCount, YES, YES); +* \endcode +*/ +protocol_copyPropertyList :: (proto: *Protocol, outCount: *u32) -> *objc_property_t #foreign libobjc; + +/** +* Returns an array of properties declared by a protocol. +* +* @param proto A protocol. +* @param outCount Upon return, contains the number of elements in the returned array. +* @param isRequiredProperty \c YES returns required properties, \c NO returns optional properties. +* @param isInstanceProperty \c YES returns instance properties, \c NO returns class properties. +* +* @return A C array of pointers of type \c objc_property_t describing the properties declared by \e proto. +* Any properties declared by other protocols adopted by this protocol are not included. The array contains +* \c *outCount pointers followed by a \c NULL terminator. You must free the array with \c free(). +* If the protocol declares no matching properties, \c NULL is returned and \c *outCount is \c 0. +*/ +protocol_copyPropertyList2 :: (proto: *Protocol, outCount: *u32, isRequiredProperty: BOOL, isInstanceProperty: BOOL) -> *objc_property_t #foreign libobjc; + +/** +* Returns an array of the protocols adopted by a protocol. +* +* @param proto A protocol. +* @param outCount Upon return, contains the number of elements in the returned array. +* +* @return A C array of protocols adopted by \e proto. The array contains \e *outCount pointers +* followed by a \c NULL terminator. You must free the array with \c free(). +* If the protocol adopts no other protocols, \c NULL is returned and \c *outCount is \c 0. +*/ +protocol_copyProtocolList :: (proto: *Protocol, outCount: *u32) -> **Protocol #foreign libobjc; + +/** +* Creates a new protocol instance that cannot be used until registered with +* \c objc_registerProtocol() +* +* @param name The name of the protocol to create. +* +* @return The Protocol instance on success, \c nil if a protocol +* with the same name already exists. +* @note There is no dispose method for this. +*/ +objc_allocateProtocol :: (name: *u8) -> *Protocol #foreign libobjc; + +/** +* Registers a newly constructed protocol with the runtime. The protocol +* will be ready for use and is immutable after this. +* +* @param proto The protocol you want to register. +*/ +objc_registerProtocol :: (proto: *Protocol) -> void #foreign libobjc; + +/** +* Adds a method to a protocol. The protocol must be under construction. +* +* @param proto The protocol to add a method to. +* @param name The name of the method to add. +* @param types A C string that represents the method signature. +* @param isRequiredMethod YES if the method is not an optional method. +* @param isInstanceMethod YES if the method is an instance method. +*/ +protocol_addMethodDescription :: (proto: *Protocol, name: SEL, types: *u8, isRequiredMethod: BOOL, isInstanceMethod: BOOL) -> void #foreign libobjc; + +/** +* Adds an incorporated protocol to another protocol. The protocol being +* added to must still be under construction, while the additional protocol +* must be already constructed. +* +* @param proto The protocol you want to add to, it must be under construction. +* @param addition The protocol you want to incorporate into \e proto, it must be registered. +*/ +protocol_addProtocol :: (proto: *Protocol, addition: *Protocol) -> void #foreign libobjc; + +/** +* Adds a property to a protocol. The protocol must be under construction. +* +* @param proto The protocol to add a property to. +* @param name The name of the property. +* @param attributes An array of property attributes. +* @param attributeCount The number of attributes in \e attributes. +* @param isRequiredProperty YES if the property (accessor methods) is not optional. +* @param isInstanceProperty YES if the property (accessor methods) are instance methods. +* This is the only case allowed fo a property, as a result, setting this to NO will +* not add the property to the protocol at all. +*/ +protocol_addProperty :: (proto: *Protocol, name: *u8, attributes: *objc_property_attribute_t, attributeCount: u32, isRequiredProperty: BOOL, isInstanceProperty: BOOL) -> void #foreign libobjc; + +/** +* Returns the names of all the loaded Objective-C frameworks and dynamic +* libraries. +* +* @param outCount The number of names returned. +* +* @return An array of C strings of names. Must be free()'d by caller. +*/ +objc_copyImageNames :: (outCount: *u32) -> **u8 #foreign libobjc; + +/** +* Returns the dynamic library name a class originated from. +* +* @param cls The class you are inquiring about. +* +* @return The name of the library containing this class. +*/ +class_getImageName :: (cls: Class) -> *u8 #foreign libobjc; + +/** +* Returns the names of all the classes within a library. +* +* @param image The library or framework you are inquiring about. +* @param outCount The number of class names returned. +* +* @return An array of C strings representing the class names. +*/ +objc_copyClassNamesForImage :: (image: *u8, outCount: *u32) -> **u8 #foreign libobjc; + +/** +* Returns a Boolean value that indicates whether two selectors are equal. +* +* @param lhs The selector to compare with rhs. +* @param rhs The selector to compare with lhs. +* +* @return \c YES if \e lhs and \e rhs are equal, otherwise \c NO. +* +* @note sel_isEqual is equivalent to ==. +*/ +sel_isEqual :: (lhs: SEL, rhs: SEL) -> BOOL #foreign libobjc; + +/** +* This function is inserted by the compiler when a mutation +* is detected during a foreach iteration. It gets called +* when a mutation occurs, and the enumerationMutationHandler +* is enacted if it is set up. A fatal error occurs if a handler is not set up. +* +* @param obj The object being mutated. +* +*/ +objc_enumerationMutation :: (obj: id) -> void #foreign libobjc; + +/** +* Sets the current mutation handler. +* +* @param handler Function pointer to the new mutation handler. +*/ +objc_setEnumerationMutationHandler :: (handler: #type (unknown0: id) -> void #c_call) -> void #foreign libobjc; + +/** +* Set the function to be called by objc_msgForward. +* +* @param fwd Function to be jumped to by objc_msgForward. +* @param fwd_stret Function to be jumped to by objc_msgForward_stret. +* +* @see message.h::_objc_msgForward +*/ +objc_setForwardHandler :: (fwd: *void, fwd_stret: *void) -> void #foreign libobjc; + +/** +* Creates a pointer to a function that will call the block +* when the method is called. +* +* @param block The block that implements this method. Its signature should +* be: method_return_type ^(id self, method_args...). +* The selector is not available as a parameter to this block. +* The block is copied with \c Block_copy(). +* +* @return The IMP that calls this block. Must be disposed of with +* \c imp_removeBlock. +*/ +imp_implementationWithBlock :: (block: id) -> IMP #foreign libobjc; + +/** +* Return the block associated with an IMP that was created using +* \c imp_implementationWithBlock. +* +* @param anImp The IMP that calls this block. +* +* @return The block called by \e anImp. +*/ +imp_getBlock :: (anImp: IMP) -> id #foreign libobjc; + +/** +* Disassociates a block from an IMP that was created using +* \c imp_implementationWithBlock and releases the copy of the +* block that was created. +* +* @param anImp An IMP that was created using \c imp_implementationWithBlock. +* +* @return YES if the block was released successfully, NO otherwise. +* (For example, the block might not have been used to create an IMP previously). +*/ +imp_removeBlock :: (anImp: IMP) -> BOOL #foreign libobjc; + +/** +* This loads the object referenced by a weak pointer and returns it, after +* retaining and autoreleasing the object to ensure that it stays alive +* long enough for the caller to use it. This function would be used +* anywhere a __weak variable is used in an expression. +* +* @param location The weak pointer address +* +* @return The object pointed to by \e location, or \c nil if \e *location is \c nil. +*/ +objc_loadWeak :: (location: *id) -> id #foreign libobjc; + +/** +* This function stores a new value into a __weak variable. It would +* be used anywhere a __weak variable is the target of an assignment. +* +* @param location The address of the weak pointer itself +* @param obj The new object this weak ptr should now point to +* +* @return The value stored into \e location, i.e. \e obj +*/ +objc_storeWeak :: (location: *id, obj: id) -> id #foreign libobjc; + +/** +* Policies related to associative references. +* These are options to objc_setAssociatedObject() +*/ +objc_AssociationPolicy :: u64; +OBJC_ASSOCIATION :: enum u32 { + ASSIGN :: 0; + RETAIN_NONATOMIC :: 1; + + COPY_NONATOMIC :: 3; + + RETAIN :: 769; + + COPY :: 771; + + OBJC_ASSOCIATION_ASSIGN :: ASSIGN; + OBJC_ASSOCIATION_RETAIN_NONATOMIC :: RETAIN_NONATOMIC; + + OBJC_ASSOCIATION_COPY_NONATOMIC :: COPY_NONATOMIC; + + OBJC_ASSOCIATION_RETAIN :: RETAIN; + + OBJC_ASSOCIATION_COPY :: COPY; +} + +/** +* Sets an associated value for a given object using a given key and association policy. +* +* @param object The source object for the association. +* @param key The key for the association. +* @param value The value to associate with the key key for object. Pass nil to clear an existing association. +* @param policy The policy for the association. For possible values, see “Associative Object Behaviors.” +* +* @see objc_setAssociatedObject +* @see objc_removeAssociatedObjects +*/ +objc_setAssociatedObject :: (object: id, key: *void, value: id, policy: objc_AssociationPolicy) -> void #foreign libobjc; + +/** +* Returns the value associated with a given object for a given key. +* +* @param object The source object for the association. +* @param key The key for the association. +* +* @return The value associated with the key \e key for \e object. +* +* @see objc_setAssociatedObject +*/ +objc_getAssociatedObject :: (object: id, key: *void) -> id #foreign libobjc; + +/** +* Removes all associations for a given object. +* +* @param object An object that maintains associated objects. +* +* @note The main purpose of this function is to make it easy to return an object +* to a "pristine state”. You should not use this function for general removal of +* associations from objects, since it also removes associations that other clients +* may have added to the object. Typically you should use \c objc_setAssociatedObject +* with a nil value to clear an association. +* +* @see objc_setAssociatedObject +* @see objc_getAssociatedObject +*/ +objc_removeAssociatedObjects :: (object: id) -> void #foreign libobjc; + +/** +* Function type for a hook that intercepts class_getImageName(). +* +* @param cls The class whose image name is being looked up. +* @param outImageName On return, the result of the image name lookup. +* @return YES if an image name for this class was found, NO otherwise. +* +* @see class_getImageName +* @see objc_setHook_getImageName +*/ +objc_hook_getImageName :: #type (cls: Class, outImageName: **u8) -> BOOL #c_call; + +/** +* Install a hook for class_getImageName(). +* +* @param newValue The hook function to install. +* @param outOldValue The address of a function pointer variable. On return, +* the old hook function is stored in the variable. +* +* @note The store to *outOldValue is thread-safe: the variable will be +* updated before class_getImageName() calls your new hook to read it, +* even if your new hook is called from another thread before this +* setter completes. +* @note The first hook in the chain is the native implementation of +* class_getImageName(). Your hook should call the previous hook for +* classes that you do not recognize. +* +* @see class_getImageName +* @see objc_hook_getImageName +*/ +objc_setHook_getImageName :: (newValue: objc_hook_getImageName, outOldValue: *objc_hook_getImageName) -> void #foreign libobjc; + +/** +* Function type for a hook that assists objc_getClass() and related functions. +* +* @param name The class name to look up. +* @param outClass On return, the result of the class lookup. +* @return YES if a class with this name was found, NO otherwise. +* +* @see objc_getClass +* @see objc_setHook_getClass +*/ +objc_hook_getClass :: #type (name: *u8, outClass: *Class) -> BOOL #c_call; + +objc_setHook_getClass :: (newValue: objc_hook_getClass, outOldValue: *objc_hook_getClass) -> void #foreign libobjc; + +/** +* Function type for a function that is called when an image is loaded. +* +* @param header The newly loaded header. +*/ +mach_header :: struct {} +objc_func_loadImage :: #type (header: *mach_header) -> void #c_call; + +objc_addLoadImageFunc :: (func: objc_func_loadImage) -> void #foreign libobjc; + +/** +* Function type for a hook that provides a name for lazily named classes. +* +* @param cls The class to generate a name for. +* @return The name of the class, or NULL if the name isn't known or can't me generated. +* +* @see objc_setHook_lazyClassNamer +*/ +objc_hook_lazyClassNamer :: #type (cls: Class) -> *u8 #c_call; + +objc_setHook_lazyClassNamer :: (newValue: objc_hook_lazyClassNamer, oldOutValue: *objc_hook_lazyClassNamer) -> void #foreign libobjc; + +_objc_swiftMetadataInitializer :: #type (cls: Class, arg: *void) -> Class #c_call; + +_objc_realizeClassFromSwift :: (cls: Class, previously: *void) -> Class #foreign libobjc; + +objc_method_description_list :: struct { + count: s32; + list: [1] objc_method_description; +} + +objc_protocol_list :: struct { + next: *objc_protocol_list; + count: s64; + list: [1] *Protocol; +} + +objc_category :: struct { + category_name: *u8; + class_name: *u8; + instance_methods: *objc_method_list; + class_methods: *objc_method_list; + protocols: *objc_protocol_list; +} + +objc_ivar :: struct { + ivar_name: *u8; + ivar_type: *u8; + ivar_offset: s32; + + space: s32; +} + +objc_ivar_list :: struct { + ivar_count: s32; + + space: s32; + + /* variable length structure */ + ivar_list: [1] objc_ivar; +} + +objc_method :: struct { + method_name: SEL; + method_types: *u8; + method_imp: IMP; +} + +objc_method_list :: struct { + obsolete: *objc_method_list; + + method_count: s32; + + space: s32; + + /* variable length structure */ + method_list: [1] objc_method; +} + +Symtab :: *objc_symtab; + +objc_symtab :: struct { + sel_ref_cnt: u64; + refs: *SEL; + cls_def_cnt: u16; + cat_def_cnt: u16; + defs: [1] *void; /* variable size */ +} + +Cache :: *objc_cache; + +objc_cache :: struct { + mask: u32; /* total = mask + 1 */ + occupied: u32; + buckets: [1] Method; +} + +Module :: *objc_module; + +objc_module :: struct { + version: u64; + size: u64; + name: *u8; + symtab: Symtab; +} + +/* Obsolete functions */ +class_lookupMethod :: (cls: Class, sel: SEL) -> IMP #foreign libobjc; + +class_respondsToMethod :: (cls: Class, sel: SEL) -> BOOL #foreign libobjc; + +_objc_flush_caches :: (cls: Class) -> void #foreign libobjc; + +object_copyFromZone :: (anObject: id, nBytes: u64, z: *void) -> id #foreign libobjc; + +class_createInstanceFromZone :: (unknown0: Class, idxIvars: u64, z: *void) -> id #foreign libobjc; + +#scope_file + +libobjc :: #library,system "libobjc"; diff --git a/modules/Objective_C/bindings/message.jai b/modules/Objective_C/bindings/x64/message.jai similarity index 98% rename from modules/Objective_C/bindings/message.jai rename to modules/Objective_C/bindings/x64/message.jai index a4e27a6f7..af5495eb5 100644 --- a/modules/Objective_C/bindings/message.jai +++ b/modules/Objective_C/bindings/x64/message.jai @@ -89,4 +89,4 @@ marg_list :: *void; #scope_file -libobjc :: #system_library "libobjc"; +libobjc :: #library,system "libobjc"; diff --git a/modules/Objective_C/bindings/runtime.jai b/modules/Objective_C/bindings/x64/runtime.jai similarity index 99% rename from modules/Objective_C/bindings/runtime.jai rename to modules/Objective_C/bindings/x64/runtime.jai index 10bf2536c..937620177 100644 --- a/modules/Objective_C/bindings/runtime.jai +++ b/modules/Objective_C/bindings/x64/runtime.jai @@ -1575,4 +1575,4 @@ class_createInstanceFromZone :: (unknown0: Class, idxIvars: u64, z: *void) -> id #scope_file -libobjc :: #system_library "libobjc"; +libobjc :: #library,system "libobjc"; diff --git a/modules/Objective_C/generate.jai b/modules/Objective_C/generate.jai index f25e64464..dcb132b9a 100644 --- a/modules/Objective_C/generate.jai +++ b/modules/Objective_C/generate.jai @@ -8,12 +8,15 @@ GENERATE_COMPILE_TIME_STRUCT_CHECKS :: false; DECLARATIONS_TO_OMIT :: string.[ "BOOL", + "objc_setMultithreaded", // Only exists in 10.13, not in later SDKs. ]; #if AT_COMPILE_TIME { #run,stallable { set_build_options_dc(.{do_output=false}); - if !generate_bindings() { + options := get_build_options(); + args := options.compile_time_command_line; + if !generate_bindings(args) { compiler_set_workspace_status(.FAILED); } } @@ -22,26 +25,37 @@ DECLARATIONS_TO_OMIT :: string.[ main :: () { set_working_directory(path_strip_filename(get_path_of_running_executable())); - if !generate_bindings() { + args := get_command_line_arguments(); + if !generate_bindings(args) { exit(1); } } } -BINDINGS_DIRECTORY :: "bindings"; +generate_bindings :: (args: [] string) -> bool { + cpu := CPU; + if array_find(args, "-arm64") { + cpu = .ARM64; + } + + bindings_directory: string; + if cpu == { + case .X64; bindings_directory = "bindings/x64"; + case .ARM64; bindings_directory = "bindings/arm64"; + case; assert(false); + } -generate_bindings :: () -> bool { - make_directory_if_it_does_not_exist(BINDINGS_DIRECTORY, recursive = true); + make_directory_if_it_does_not_exist(bindings_directory, recursive = true); - success := generate_runtime(); - success &= generate_message(); + success := generate_runtime(cpu, bindings_directory); + success &= generate_message(cpu, bindings_directory); // success &= generate_appkit(); return success; } -generate_runtime :: () -> bool { - output_path := tprint("%/runtime.jai", BINDINGS_DIRECTORY); - options := get_common_options(); +generate_runtime :: (cpu: CPU_Tag, bindings_directory: string) -> bool { + output_path := tprint("%/runtime.jai", bindings_directory); + options := get_common_options(cpu); libc_path := get_libc_paths(); array_add(*options.source_files, @@ -57,9 +71,9 @@ generate_runtime :: () -> bool { return generate_bindings(options, output_path); } -generate_message :: () -> bool { - output_path := tprint("%/message.jai", BINDINGS_DIRECTORY); - options := get_common_options(); +generate_message :: (cpu: CPU_Tag, bindings_directory: string) -> bool { + output_path := tprint("%/message.jai", bindings_directory); + options := get_common_options(cpu); libc_path := get_libc_paths(); array_add(*options.source_files, @@ -74,7 +88,7 @@ generate_message :: () -> bool { } // generate_appkit :: () -> bool { -// output_path := tprint("%/appkit_objc.jai", BINDINGS_DIRECTORY); +// output_path := tprint("%/appkit_objc.jai", bindings_directory); // builder: String_Builder; // selectors: [..] string; // define(*builder, "NSApplication", *selectors); @@ -87,14 +101,21 @@ generate_message :: () -> bool { // return write_entire_file(output_path, content); // } -get_common_options :: () -> Generate_Bindings_Options { - options: Generate_Bindings_Options; - array_add(*options.libpaths, "macos"); +get_common_options :: (cpu: CPU_Tag) -> Generate_Bindings_Options { + sdk_path := get_macos_sdk_path(); + build_options := get_build_options(); // @Incomplete: run-time version + target_triple_with_sdk := get_macos_target_triple(cpu, build_options.minimum_os_version.major, build_options.minimum_os_version.minor); - array_add(*options.libnames, "libobjc"); + options: Generate_Bindings_Options; + options.cpu = cpu; + array_add(*options.system_library_names, "libobjc"); - array_add(*options.extra_clang_arguments, "-x", "c"); - array_add(*options.extra_clang_arguments, "-isysroot", get_macos_sdk_path()); + array_add(*options.extra_clang_arguments, + "-x", "c", + "-target", target_triple_with_sdk, + "-isysroot", sdk_path, + ); + array_add(*options.system_library_paths, tprint("%/usr/lib", sdk_path)); options.log_stripped_declarations = true; options.generate_compile_time_struct_checks = GENERATE_COMPILE_TIME_STRUCT_CHECKS; @@ -129,6 +150,17 @@ objc_visitor :: (decl: *Declaration, parent_decl: *Declaration) -> Declaration_V return .STOP; } + if context.generator_options.cpu == .ARM64 { + // Workaround for incorrect symbol information for libobjc on ARM64 in SDKs 11.x-13.x: + // Apple claims that the *_stret functions exist, but when you then open up the DLL, they’re missing. + // You can’t make this stuff up… + // -rluba, 2024-02-23 + if ends_with(decl.name, "_stret") { + decl.decl_flags |= .OMIT_FROM_OUTPUT; + return .STOP; + } + } + if decl.name == "objc_object" { decl.output_name = "NSObject"; } @@ -187,3 +219,4 @@ objc_visitor :: (decl: *Declaration, parent_decl: *Declaration) -> Declaration_V #import "Compiler"; #import "File"; #import "String"; +#import "Toolchains/macOS"; diff --git a/modules/Objective_C/module.jai b/modules/Objective_C/module.jai index 9db53d4c9..09af68cba 100644 --- a/modules/Objective_C/module.jai +++ b/modules/Objective_C/module.jai @@ -96,44 +96,44 @@ to_string :: (str: *NSString) -> string { } objc_alloc :: (class: Class) -> id #no_context { - return objc_msgSend(class, _sel.alloc); + return objc_msgSend_typed(class, _sel.alloc); } objc_copy :: (self: *$instancetype) -> *instancetype #no_context { - return xx objc_msgSend(self, _sel.copy); + return xx objc_msgSend_typed(self, _sel.copy); } autorelease :: (self: *$instancetype) -> id #no_context { - return cast(id) objc_msgSend(self, _sel.autorelease); + return objc_msgSend_typed(self, _sel.autorelease); } release :: (self: *$instancetype) -> id #no_context { - return cast(id) objc_msgSend(self, _sel.release); + return objc_msgSend_typed(self, _sel.release); } retain :: (self: *$instancetype) -> *instancetype #no_context { - return xx objc_msgSend(self, _sel.retain); + return xx objc_msgSend_typed(self, _sel.retain); } class :: (self: id) -> Class #no_context { // I'm pretty sure this is just id.isa // but this is the "correct" way to do this. - return cast(Class) objc_msgSend(self, _sel.class); + return cast(Class) objc_msgSend_typed(self, _sel.class); } superclass :: (self: id) -> Class #no_context { - return cast(Class) objc_msgSend(self, _sel.superclass); + return cast(Class) objc_msgSend_typed(self, _sel.superclass); } isEqual :: (self: id, object: id) -> bool #no_context { - return objc_msgSend(self, _sel.isEqual_, object) != null; + return objc_msgSend_typed(self, _sel.isEqual_, object) != null; } // helper functions so we don't need to have messy // user code objc_init :: (self: *$type) -> *type #no_context { - return cast(*type) objc_msgSend(self, _sel.init); + return cast(*type) objc_msgSend_typed(self, _sel.init); } objc_alloc :: ($type: Type) -> *type #no_context { @@ -211,20 +211,33 @@ selector :: (sel_str: string) -> Selector { // Use this to make sure that our struct declarations of Objective-C classes match the size of their current // implementations on whatever macOS you run this. // This is a lame workaround for the "fragile instance variables" problem. :ObjectiveCFragile: -create_objc_class_member_stub :: (class_name: string) -> string { - #import "Basic"; - #import "String"; +create_objc_class_member_stub :: (class_name: string, framework_name: string) -> string { + Basic :: #import "Basic"; + String :: #import "String"; + Posix :: #import "POSIX"; init_objective_c(); + // The class is only known to Objective C after the library that contains it has been loaded! + // If we’re cross-compiling then the libraries won’t be auto-loaded by the compiler, so we have to manually find & load them here, to be safe. + // @Hack: We should probably look up the framework paths from somewhere and then we should be reading the framework’s Info.plist + // to check what the framework's linking executable is. + // But by convention all the standard frameworks just have FrameworkName.framework/FrameworkName + // -rluba, 2024-01-25 + framework_path := tprint("/System/Library/Frameworks/%1.framework/%1\0", framework_name); + handle := Posix.dlopen(framework_path.data, Posix.RTLD_LAZY | Posix.RTLD_LOCAL); + defer { + if handle Posix.dlclose(handle); + } + class := objc_getClass(class_name.data); // @Stability: This better be null-terminated - assert(class != null, "Unknown Objective-C class \"%\"", class_name); + Basic.assert(class != null, "Unknown Objective-C class \"%\"", class_name); instance_size := cast(s64) class_getInstanceSize(class); super := superclass(class); - assert(super != null, "Couldn’t get Objective-C superclass of \"%\"", class_name); + Basic.assert(super != null, "Couldn’t get Objective-C superclass of \"%\"", class_name); super_size := cast(s64) class_getInstanceSize(super); // log("%: % super: %", class_name, instance_size, super_size); - return sprint("_%_data: [%] u8; // size of % minus size of parent class", to_lower_copy_new(class_name,, temp), instance_size - super_size, class_name); + return Basic.sprint("_%_data: [%] u8; // size of % minus size of parent class", String.to_lower_copy_new(class_name,, temp), instance_size - super_size, class_name); } @@ -643,15 +656,37 @@ Objective_C_Block_Basic :: struct { _NSConcreteStackBlock :: () #foreign libSystem; _NSConcreteGlobalBlock :: () #foreign libSystem; -#load "bindings/runtime.jai"; -#load "bindings/message.jai"; +#if CPU == .X64 { + #load "bindings/x64/runtime.jai"; + #load "bindings/x64/message.jai"; + + // The SDK we use for the x64 bindings still has typed objc_msgSend declarations, + // so the declarations below are almost the same as the orignals, but with target and result changed to *void to avoid some casts. :ObjectiveCMsgSendTypes: + objc_msgSend_typed :: (target: *void, selector: Selector, args: ..Any) -> *void #foreign libobjc "objc_msgSend"; + objc_msgSend_stret_typed :: (target: *void, selector: Selector, args: ..Any) -> void #foreign libobjc "objc_msgSend_stret"; +} else { + #load "bindings/arm64/runtime.jai"; + #load "bindings/arm64/message.jai"; + + // In newer SDKs, Apple dropped the type arguments from objc_msgSend and its cousins, + // so we re-define them here to avoid painful casting everywhere. :ObjectiveCMsgSendTypes: + objc_msgSend_typed :: (target: *void, selector: Selector, args: ..Any) -> *void #foreign libobjc "objc_msgSend"; + objc_msgSend_stret_typed :: objc_msgSend_typed; + + // Arm64 does not have separate *_stret variants because its ABI does not need them. + objc_msgSend_stret :: objc_msgSend; + objc_msgSendSuper_stret :: objc_msgSendSuper; + method_invoke_stret :: method_invoke; + _objc_msgForward_stret :: _objc_msgForward; + class_getMethodImplementation_stret :: class_getMethodImplementation; +} + #load "Foundation.jai"; #scope_module ptrdiff_t :: s64; -size_t :: u64; #import "macos"; @@ -677,3 +712,4 @@ _sel: struct #type_info_no_size_complaint { libc :: #system_library "libc"; c_free :: (memory: *void) #foreign libc "free"; +libobjc :: #library,system "libobjc";