From c7e777a8e007a7cfa13b0e7a7046aef7ad87c826 Mon Sep 17 00:00:00 2001 From: skalogryz Date: Thu, 12 Mar 2009 12:03:21 +0000 Subject: [PATCH] started dynamic obj-c runtime lib support. added base units git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@735 8e941d3f-bd1b-0410-a28a-d453659cc2b4 --- bindings/objc/objcrtl.pas | 353 +++++++++++++++++++++++++++++++ bindings/objc/objcrtl10.pas | 403 ++++++++++++++++++++++++++++++++++++ bindings/objc/objcrtl20.pas | 163 +++++++++++++++ 3 files changed, 919 insertions(+) create mode 100644 bindings/objc/objcrtl.pas create mode 100644 bindings/objc/objcrtl10.pas create mode 100644 bindings/objc/objcrtl20.pas diff --git a/bindings/objc/objcrtl.pas b/bindings/objc/objcrtl.pas new file mode 100644 index 000000000..5d546e68f --- /dev/null +++ b/bindings/objc/objcrtl.pas @@ -0,0 +1,353 @@ +{ + objcrtl.pas + + Copyright (C) 2009 Dmitry Boyarintsev + + This unit is a pascal binding for dynamic Objective-C Run-time Library + headers included with XCode 3.1.2 + The original copyright note of is kept on each include file +} +unit objcrtl; + +{$mode objfpc}{$H+} + +interface + +uses + dynlibs; + +const + OSXObjCLibName : AnsiString = 'libobjc.A.dylib'; + + +{ Overview + -------- + + This document describes the Mac OS X Objective-C 2.0 runtime library support + functions and data structures. The functions are implemented in the shared + library found at /usr/lib/libobjc.A.dylib. This shared library provides support + for the dynamic properties of the Objective-C language, and as such is linked + to by all Objective-C applications. + + This reference is useful primarily for developing bridge layers between + Objective-C and other languages, or for low-level debugging. You typically do + not need to use the Objective-C runtime library directly when programming + in Objective-C. + + The Mac OS X implementation of the Objective-C runtime library is unique + to the Mac OS X platform. For other platforms, the GNU Compiler Collection + provides a different implementation with a similar API. This document covers + only the Mac OS X implementation. + + The low-level Objective-C runtime API is significantly updated in Mac OS X + version 10.5. Many functions and all existing data structures are replaced + with new functions. The old functions and structures are deprecated in 32-bit + and absent in 64-bit mode. The API constrains several values to 32-bit ints + even in 64-bit mode—class count, protocol count, methods per class, ivars + per class, arguments per method, sizeof(all arguments) per method, and + class version number. In addition, the new Objective-C ABI (not described here) + further constrains sizeof(anInstance) to 32 bits, and three other values + to 24 bits—methods per class, ivars per class, and sizeof(a single ivar). + Finally, the obsolete NXHashTable and NXMapTable are limited to 4 billion items. + + “Deprecated” below means “deprecated in Mac OS X version 10.5 for 32-bit code, + and disallowed for 64-bit code. + + Legacy and Modern Versions + -------------------------- + + There are two versions of the Objective-C runtime—“modern” and “legacy”. + The modern version was introduced with Objective-C 2.0 and includes a number + of new features. The programming interface for the legacy version of the runtime + is described in Objective-C 1 Runtime Reference; the programming interface + for the modern version of the runtime is described in Objective-C 2.0 Runtime + Reference. + + The most notable new feature is that instance variables in the modern runtime are “non-fragile”: + * In the legacy runtime, if you change the layout of instance variables in a class, + you must recompile classes that inherit from it. + * In the modern runtime, if you change the layout of instance variables in a class, + you do not have to recompile classes that inherit from it. + + In addition, the modern runtime supports instance variable synthesis + for declared properties (see Declared Properties in The Objective-C 2.0 Programming Language). + + Platforms + --------- + + iPhone applications and 64-bit programs on Mac OS X v10.5 and later use + the modern version of the runtime. + + Other programs (32-bit programs on Mac OS X desktop) use the legacy version + of the runtime. +} + +type + //todo: types MUST BE declared properly as 2.0 opaques + SEL = Pointer; + IMP = Pointer; + id = PtrInt; + size_t = LongWord; + _Class = Pointer; + Ivar = Pointer; + PProtocol = Pointer; + PArrayPProtocol = Pointer; + BOOL = Boolean; + PIvar = Pointer; + Method = Pointer; + PMethod = Pointer; + Protocol = Pointer; + objc_property_t = Pointer; + Pobjc_property_t = Pointer; + uint8_t = byte; + Pobjc_method_description = Pointer; + ptrdiff_t = Pointer; + objc_method_description = Pointer; + TMutationHandlerProc = Pointer; + objc_super = Pointer; + +var + sel_getName : function (sel: SEL): PChar; cdecl = nil; + sel_registerName : function (str: PChar): SEL; cdecl = nil; + object_getClassName : function (obj: id): PChar; cdecl = nil; + object_getIndexedIvars : function (obj: id ): Pointer; cdecl = nil; + + sel_isMapped: function (sel: SEL): Boolean; cdecl = nil; + sel_getUid: function (const str: PChar): SEL; cdecl = nil; + + object_copy : function (obj:id; size:size_t):id; cdecl = nil; + object_dispose : function (obj:id):id; cdecl = nil; + + object_getClass : function (obj:id): _Class; cdecl = nil; + object_setClass : function (obj:id; cls: _Class):_Class; cdecl = nil; + + object_getIvar : function (obj:id; ivar:Ivar):id; cdecl = nil; + object_setIvar : procedure (obj:id; ivar:Ivar; value:id); cdecl = nil; + + object_setInstanceVariable : function (obj:id; name:pchar; value:pointer):Ivar; cdecl = nil; + object_getInstanceVariable : function (obj:id; name:pchar; var outValue: Pointer):Ivar; cdecl = nil; + + objc_getClass : function (name:pchar):id; cdecl = nil; + objc_getMetaClass : function (name:pchar):id; cdecl = nil; + objc_lookUpClass : function (name:pchar):id; cdecl = nil; + objc_getRequiredClass : function (name:pchar):id; cdecl = nil; + objc_getFutureClass : function (name:pchar):_Class; cdecl = nil; + objc_setFutureClass : procedure (cls:_Class; name:pchar); cdecl = nil; + objc_getClassList : function (buffer:pClass; bufferCount:longint):longint; cdecl = nil; + + objc_getProtocol : function (name:pchar): PProtocol; cdecl = nil; + objc_copyProtocolList : function (outCount:pdword):PArrayPProtocol; cdecl = nil; + + class_getName : function (cls:_Class):PChar; cdecl = nil; + class_isMetaClass : function (cls:_Class):BOOL; cdecl = nil; + class_getSuperclass : function (cls:_Class):_Class; cdecl = nil; + class_setSuperclass : function (cls: _Class; newSuper: _Class): _Class; cdecl = nil; + + + class_getVersion : function (cls:_Class):longint; cdecl = nil; + class_setVersion : procedure (cls:_Class; version:longint); cdecl = nil; + + class_getInstanceSize : function (cls:_Class):size_t; cdecl = nil; + + class_getInstanceVariable : function (cls:_Class; name:pchar):Ivar; cdecl = nil; + class_getClassVariable : function (cls:_Class; name:pchar):Ivar; cdecl = nil; + class_copyIvarList : function (cls:_Class; outCount:pdword):PIvar; cdecl = nil; + + class_getInstanceMethod : function (cls:_Class; name:SEL):Method; cdecl = nil; + class_getClassMethod : function (cls:_Class; name:SEL):Method; cdecl = nil; + class_getMethodImplementation : function (cls:_Class; name:SEL):IMP; cdecl = nil; + class_getMethodImplementation_stret : function (cls:_Class; name:SEL):IMP; cdecl = nil; + class_respondsToSelector : function (cls:_Class; sel:SEL):BOOL; cdecl = nil; + class_copyMethodList : function (cls:_Class; outCount:pdword):PMethod; cdecl = nil; + + class_conformsToProtocol : function (cls:_Class; var protocol: Protocol):BOOL; cdecl = nil; + class_copyProtocolList : function (cls:_Class; var outCount: dword):PArrayPProtocol; cdecl = nil; + + class_getProperty : function (cls:_Class; name: pchar): objc_property_t; cdecl = nil; + class_copyPropertyList : function (cls:_Class; var Count:dword):Pobjc_property_t; cdecl = nil; + + class_getIvarLayout : function (cls:_Class):Pchar; cdecl = nil; + class_getWeakIvarLayout : function (cls:_Class):Pchar; cdecl = nil; + + class_createInstance : function (cls:_Class; extraBytes:size_t):id; cdecl = nil; + + objc_allocateClassPair : function (superclass:_Class; name:pchar; extraBytes:size_t):_Class; cdecl = nil; + objc_registerClassPair : procedure (cls:_Class); cdecl = nil; + objc_duplicateClass : function (original:_Class; name:pchar; extraBytes:size_t):_Class; cdecl = nil; + objc_disposeClassPair : procedure (cls:_Class); cdecl = nil; + + class_addMethod : function (cls:_Class; name:SEL; imp:IMP; types:pchar):BOOL; cdecl = nil; + class_replaceMethod : function (cls:_Class; name:SEL; imp:IMP; types:pchar):IMP; cdecl = nil; + class_addIvar: function (cls:_Class; name:pchar; size:size_t; alignment:uint8_t; types:pchar):BOOL; cdecl = nil; + class_addProtocol : function (cls:_Class; protocol:pProtocol):BOOL; cdecl = nil; + class_setIvarLayout : procedure (cls:_Class; layout:pchar); cdecl = nil; + class_setWeakIvarLayout : procedure (cls:_Class; layout:pchar); cdecl = nil; + + method_getName : function (m:Method):SEL; cdecl = nil; + method_getImplementation : function (m:Method):IMP; cdecl = nil; + method_getTypeEncoding : function (m:Method):Pchar; cdecl = nil; + + method_getNumberOfArguments : function (m:Method):dword; cdecl = nil; + method_copyReturnType : function (m:Method):Pchar; cdecl = nil; + method_copyArgumentType : function (m:Method; index:dword):Pchar; cdecl = nil; + method_getReturnType : procedure (m:Method; dst:pchar; dst_len:size_t); cdecl = nil; + method_getArgumentType : procedure (m:Method; index:dword; dst:pchar; dst_len:size_t); cdecl = nil; + method_getDescription : function (m: Method) : Pobjc_method_description; cdecl = nil; + + method_setImplementation: function (m:Method; imp:IMP):IMP; cdecl = nil; + method_exchangeImplementations : procedure (m1:Method; m2:Method); cdecl = nil; + + ivar_getName : function (v:Ivar):Pchar; cdecl = nil; + ivar_getTypeEncoding : function (v:Ivar):Pchar; cdecl = nil; + ivar_getOffset : function (v:Ivar):ptrdiff_t; cdecl = nil; + + property_getName :function (_property:objc_property_t):Pchar; cdecl = nil; + property_getAttributes : function (_property:objc_property_t):Pchar; cdecl = nil; + + + protocol_conformsToProtocol : function (proto:pProtocol; other:pProtocol):BOOL; cdecl = nil; + protocol_isEqual : function (proto:pProtocol; other:pProtocol):BOOL; cdecl = nil; + protocol_getMethodDescription : function (p: PProtocol; aSel: SEL; isRequiredMethod, isInstanceMethod: BOOL): objc_method_description; cdecl = nil; + protocol_copyMethodDescriptionList : function (p: PProtocol; isRequiredMethod, isInstanceMethod: BOOL ; var outCount: LongWord): Pobjc_method_description; cdecl = nil; + protocol_getProperty : function (proto:PProtocol; name:pchar; isRequiredProperty:BOOL; isInstanceProperty:BOOL):objc_property_t; cdecl = nil; + protocol_copyPropertyList : function (proto:PProtocol; outCount:pdword):Pobjc_property_t; cdecl = nil; + protocol_copyProtocolList : function (proto:PProtocol; outCount:pdword):PArrayPProtocol; cdecl = nil; + + objc_copyImageNames : function (var outCount:dword): PPchar; cdecl = nil; + class_getImageName : function (cls:_Class):Pchar; cdecl = nil; + objc_copyClassNamesForImage : function (image:pchar; var outCount: Dword):PPchar; cdecl = nil; + + sel_isEqual : function (lhs:SEL; rhs:SEL):BOOL; cdecl = nil; + objc_enumerationMutation : procedure (_para1:id); cdecl = nil; + objc_setEnumerationMutationHandler : procedure (handler:TMutationHandlerProc); cdecl = nil; + objc_setForwardHandler: procedure (fwd:pointer; fwd_stret:pointer); cdecl = nil; + + objc_msgSend : function (self: id; op: SEL{; ...}): id; cdecl = nil; + objc_msgSendSuper : function (const super: objc_super; op: SEL{; ...}): id = nil; + objc_msgSend_stret : procedure (self: id; op: SEL{; ...}); cdecl= nil; + objc_msgSendSuper_stret : procedure (const super: objc_super; op: SEL{, ...})= nil; + + objc_msgSend_fpret : function (self: id; op: SEL{ , ...}): double= nil; + + method_invoke : function (receiver: id; m: Method {, ...}): id= nil; + method_invoke_stret : procedure (receiver: id; m: Method{ , ...})= nil; + objc_collect : procedure (options: LongWord); cdecl= nil; + objc_collectingEnabled : function : BOOL; cdecl= nil; + +// objc-exception.h + +// compiler reserves a setjmp buffer + 4 words as localExceptionData + +type + Tobjc_exception_throw = procedure (exception: id); cdecl; + Tobjc_exception_try_enter = procedure (localExceptionData: Pointer); cdecl; + Tobjc_exception_try_exit = procedure (localExceptionData: Pointer); cdecl; + Tobjc_exception_extract = function (localExceptionData: Pointer): id; cdecl; + Tobjc_exception_match = function (exceptionClass:_Class; exception:id ): Integer; cdecl; + +var + objc_exception_throw : Tobjc_exception_throw = nil; + objc_exception_try_enter : Tobjc_exception_try_enter = nil; + objc_exception_try_exit : Tobjc_exception_try_exit = nil; + objc_exception_extract : Tobjc_exception_extract = nil; + objc_exception_match : Tobjc_exception_match = nil; + +type + objc_exception_functions_t = packed record + version : Integer; + throw_exc : Tobjc_exception_throw; // version 0 + try_enter : Tobjc_exception_try_enter; // version 0 + try_exit : Tobjc_exception_try_exit; // version 0 + extract : Tobjc_exception_extract; // version 0 + match : Tobjc_exception_match; // version 0 + end; + +// get table; version tells how many +var + objc_exception_get_functions : procedure (var table: objc_exception_functions_t); cdecl = nil; + objc_exception_set_functions : procedure (const table: objc_exception_functions_t); cdecl = nil; + + +// __LP64__ // 64-bit only functions +{ +typedef id (*objc_exception_preprocessor)(id exception); +typedef int (*objc_exception_matcher)(Class catch_type, id exception); +typedef void (*objc_uncaught_exception_handler)(id exception); +typedef void (*objc_exception_handler)(id unused, void *context); + +OBJC_EXPORT void objc_exception_throw(id exception); +OBJC_EXPORT void objc_exception_rethrow(void); +OBJC_EXPORT id objc_begin_catch(void *exc_buf); +OBJC_EXPORT void objc_end_catch(void); + +OBJC_EXPORT uintptr_t objc_addExceptionHandler(objc_exception_handler fn, void *context); +OBJC_EXPORT void objc_removeExceptionHandler(uintptr_t token); + +OBJC_EXPORT objc_exception_preprocessor objc_setExceptionPreprocessor(objc_exception_preprocessor fn); +OBJC_EXPORT objc_exception_matcher objc_setExceptionMatcher(objc_exception_matcher fn); +OBJC_EXPORT objc_uncaught_exception_handler objc_setUncaughtExceptionHandler(objc_uncaught_exception_handler fn); +} + + +// since exception handling does not change from version to version +// it's nice to make a common RTL loading function for exception functions. +// this proc, MUST BE called by run-time initialization proc! +function LoadDefaultObjCExepction(hnd: TLibHandle): Boolean; + +// objc-sync.h + +var + // Begin synchronizing on 'obj'. + // Allocates recursive pthread_mutex associated with 'obj' if needed. + // Returns OBJC_SYNC_SUCCESS once lock is acquired. + objc_sync_enter: function (obj: id ): Integer; cdecl = nil; + // End synchronizing on 'obj'. + // Returns OBJC_SYNC_SUCCESS or OBJC_SYNC_NOT_OWNING_THREAD_ERROR + objc_sync_exit : function (obj: id) : Integer; cdecl = nil; + // Temporarily release lock on 'obj' and wait for another thread to notify on 'obj' + // Return OBJC_SYNC_SUCCESS, OBJC_SYNC_NOT_OWNING_THREAD_ERROR, OBJC_SYNC_TIMED_OUT + objc_sync_wait : function (obj: id; milliSecondsMaxWait: Int64): Integer; cdecl = nil; + // Wake up another thread waiting on 'obj' + // Return OBJC_SYNC_SUCCESS, OBJC_SYNC_NOT_OWNING_THREAD_ERROR + objc_sync_notify : function (obj: id): Integer; cdecl = nil; + // Wake up all threads waiting on 'obj' + // Return OBJC_SYNC_SUCCESS, OBJC_SYNC_NOT_OWNING_THREAD_ERROR + objc_sync_notifyAll : function (obj: id): Integer; cdecl = nil; + +const + OBJC_SYNC_SUCCESS = 0; + OBJC_SYNC_NOT_OWNING_THREAD_ERROR = -1; + OBJC_SYNC_TIMED_OUT = -2; + OBJC_SYNC_NOT_INITIALIZED = -3; + +function LoadDefaultObjCSync(hnd: TLibHandle): Boolean; + +implementation + +function LoadDefaultObjCExepction(hnd: TLibHandle): Boolean; +begin + Result := hnd <> 0; + if not Result then Exit; + + objc_exception_throw := Tobjc_exception_throw( GetProcedureAddress(hnd, 'objc_exception_throw')); + objc_exception_try_enter := Tobjc_exception_try_enter( GetProcedureAddress(hnd, 'objc_exception_try_enter')); + objc_exception_try_exit := Tobjc_exception_try_exit(GetProcedureAddress(hnd, 'objc_exception_try_exit')); + objc_exception_extract := Tobjc_exception_extract(GetProcedureAddress(hnd, 'objc_exception_extract')); + objc_exception_match := Tobjc_exception_match(GetProcedureAddress(hnd, 'objc_exception_match')); +end; + +function LoadDefaultObjCSync(hnd: TLibHandle): Boolean; +begin + Result := hnd <> 0; + if not Result then Exit; + Pointer(objc_sync_enter) := GetProcedureAddress(hnd, 'objc_sync_enter'); + Pointer(objc_sync_exit) := GetProcedureAddress(hnd, 'objc_sync_exit'); + Pointer(objc_sync_wait) := GetProcedureAddress(hnd, 'objc_sync_wait'); + Pointer(objc_sync_notify) := GetProcedureAddress(hnd, 'objc_sync_notify'); + Pointer(objc_sync_notifyAll) := GetProcedureAddress(hnd, 'objc_sync_notifyAll'); +end; + +initialization + +end. + diff --git a/bindings/objc/objcrtl10.pas b/bindings/objc/objcrtl10.pas new file mode 100644 index 000000000..874dbe713 --- /dev/null +++ b/bindings/objc/objcrtl10.pas @@ -0,0 +1,403 @@ +{ + objcrtl10.pas + + Copyright (C) 2009 Dmitry Boyarintsev + + This unit is implementation for dynamic Objective-C Run-time Library based on run-time version 1.0 + headers included with XCode 3.1.2 + The original copyright note of is kept on each include file +} + +unit objcrtl10; + +{$mode objfpc}{$H+} + +interface + +//todo: *10 WRAPPERS! + +{ + Mac OS X Version 10.5 Delta + --------------------------- + + The low-level Objective-C runtime API is significantly updated + in Mac OS X version 10.5. Many functions and all existing data structures + are replaced with new functions. This document describes the differences + between the 10.5 version and previous versions. + + http://developer.apple.com/documentation/Cocoa/Reference/ObjCRuntimeRef/Articles/ocr10_5delta.html#//apple_ref/doc/uid/TP40002981-TPXREF101 +} + + +uses + objcrtl, dynlibs; + +function InitializeObjCRtl10(const ObjCLibName: AnsiString): Boolean; + +implementation + +function object_getClass10(obj:id): _Class; cdecl; +begin + Result := nil; +end; + +function object_setClass10(obj:id; cls: _Class):_Class; cdecl; +begin + Result := nil; +end; + +function object_getIvar10(obj:id; ivar:Ivar):id; cdecl; +begin + Result := 0; +end; + +procedure object_setIvar10(obj:id; ivar:Ivar; value:id); cdecl; +begin +end; + +function class_getName10(cls:_Class):PChar; cdecl; +begin + Result := nil; +end; + +function class_getSuperclass10(cls:_Class):_Class; cdecl; +begin + Result := nil; +end; + +function class_isMetaClass10(cls:_Class):BOOL; cdecl; +begin + Result := false; +end; + +function class_copyMethodList10(cls:_Class; outCount:pdword):PMethod; cdecl; +begin + Result := nil; +end; + +function class_getMethodImplementation10(cls:_Class; name:SEL):IMP; cdecl; +begin + Result := nil; +end; + +function class_respondsToSelector10(cls:_Class; sel:SEL):BOOL; cdecl; +begin + Result := false; +end; + +function class_conformsToProtocol10(cls:_Class; var protocol: Protocol):BOOL; cdecl; +begin + Result := false; +end; + +function class_copyProtocolList10(cls:_Class; var outCount: dword):PArrayPProtocol; cdecl; +begin + Result := nil; +end; + +function class_copyIvarList10(cls:_Class; outCount:pdword):PIvar; cdecl; +begin + Result := nil; +end; + +function class_getMethodImplementation_stret10(cls:_Class; name:SEL):IMP; cdecl; +begin + Result := nil; +end; + + +function objc_allocateClassPair10(superclass:_Class; name:pchar; extraBytes:size_t):_Class; cdecl; +begin + Result := nil; +end; + +procedure objc_registerClassPair10(cls:_Class); cdecl; +begin + +end; + +function objc_duplicateClass10(original:_Class; name:pchar; extraBytes:size_t):_Class; cdecl; +begin + Result := nil; +end; + +procedure objc_disposeClassPair10(cls:_Class); cdecl; +begin + +end; + +function class_addMethod10(cls:_Class; name:SEL; imp:IMP; types:pchar):BOOL; cdecl; +begin + Result := false; +end; + +function class_addIvar10(cls:_Class; name:pchar; size:size_t; alignment:uint8_t; types:pchar):BOOL; cdecl; +begin + Result := false; +end; + +function class_addProtocol10(cls:_Class; protocol:pProtocol):BOOL; cdecl; +begin + Result := false; +end; + + +function method_getName10(m:Method):SEL; cdecl; +begin + Result := nil; +end; + +function method_getImplementation10(m:Method):IMP; cdecl; +begin + Result := nil; +end; + +function method_getTypeEncoding10(m:Method):Pchar; cdecl; +begin + Result := nil; +end; + +function method_copyReturnType10(m:Method):Pchar; cdecl; +begin + Result := nil; +end; + +function method_copyArgumentType10(m:Method; index:dword):Pchar; cdecl; +begin + Result := nil; +end; + +function method_setImplementation10(m:Method; imp:IMP):IMP; cdecl; +begin + Result := nil; +end; + +function sel_getName10(sel: SEL ): PChar; cdecl; +begin + Result := nil; +end; + +function sel_registerName10(str: PChar): SEL; cdecl; +begin + Result := nil; +end; + +function sel_getUid10(const str: PChar): SEL; cdecl; +begin + Result := nil; +end; + +function ivar_getName10(v:Ivar):Pchar; cdecl; +begin + Result := nil; +end; + +function ivar_getTypeEncoding10(v:Ivar):Pchar; cdecl; +begin + Result := nil; +end; + +function ivar_getOffset10(v:Ivar):ptrdiff_t; cdecl; +begin + Result := nil; +end; + +function sel_isEqual10(lhs:SEL; rhs:SEL):BOOL; cdecl; +begin + Result := false; +end; + +function objc_getProtocol10(name:pchar): PProtocol; cdecl; +begin + Result := nil; +end; + +function objc_copyProtocolList10(outCount:pdword):PArrayPProtocol; cdecl; +begin + Result := nil; +end; + +function InitializeObjCRtl10(const ObjCLibName: AnsiString): Boolean; +var + hnd : TLibHandle; +begin + hnd := LoadLibrary(ObjCLibName); + Result := hnd <> 0; + if not Result then Exit; + + //Exceptions - are unchanged: + LoadDefaultObjCExepction(hnd); + //Synchronization - unchanged: + LoadDefaultObjCSync(hnd); + + // Instances + + // The following functions are unchanged: + Pointer(object_dispose) := GetProcedureAddress(hnd, 'object_dispose'); + Pointer(object_getClassName) := GetProcedureAddress(hnd, 'object_getClassName'); + Pointer(object_getIndexedIvars) := GetProcedureAddress(hnd, 'object_getIndexedIvars'); + Pointer(object_setInstanceVariable) := GetProcedureAddress(hnd, 'object_setInstanceVariable'); + Pointer(object_getInstanceVariable) := GetProcedureAddress(hnd, 'object_getInstanceVariable'); + + //The following function is modified: + // needs wrapper? + // object_copy (The nBytes parameter is changed from unsigned to size_t.) + Pointer(object_copy) := GetProcedureAddress(hnd, 'object_copy'); + + //The following functions are added: + object_getClass := @object_getClass10; + object_setClass := @object_setClass10; + object_getIvar := @object_getIvar10; + object_setIvar := @object_setIVar10; + + // The following functions are deprecated: + //object_copyFromZone: deprecated in favor of object_copy + //object_realloc + //object_reallocFromZone: no substitute + //_alloc: no substitute + //_copy: no substitute + //_realloc: no substitute + //_dealloc: no substitute + //_zoneAlloc: no substitute + //_zoneRealloc: no substitute + //_zoneCopy: no substitute + //_error: no substitute + + + //Class Inspection + + //The following functions are unchanged: + Pointer(objc_getClassList) := GetProcedureAddress(hnd, 'objc_getClassList'); + Pointer(objc_lookUpClass) := GetProcedureAddress(hnd, 'objc_lookUpClass'); + Pointer(objc_getClass) := GetProcedureAddress(hnd, 'objc_getClass'); + Pointer(objc_getMetaClass) := GetProcedureAddress(hnd, 'objc_getMetaClass'); + Pointer(class_getVersion) := GetProcedureAddress(hnd, 'class_getVersion'); + Pointer(class_getInstanceVariable) := GetProcedureAddress(hnd, 'class_getInstanceVariable'); + Pointer(class_getInstanceMethod) := GetProcedureAddress(hnd, 'class_getInstanceMethod'); + Pointer(class_getClassMethod) := GetProcedureAddress(hnd, 'class_getClassMethod'); + + // The following function is modified: + // needs wrapper? + // class_createInstance: idxIvars parameter Changed from unsigned to size_t + Pointer(class_createInstance) := GetProcedureAddress(hnd, 'class_createInstance'); + + // The following functions are added: + class_getName:=@class_getName10; + class_getSuperclass:=@class_getSuperclass10; + class_isMetaClass:=@class_isMetaClass10; + class_copyMethodList:=@class_copyMethodList10; + class_getMethodImplementation:=@class_getMethodImplementation10; + class_getMethodImplementation_stret:=@class_getMethodImplementation_stret10; + class_respondsToSelector:=@class_respondsToSelector10; + class_conformsToProtocol:=@class_conformsToProtocol10; + class_copyProtocolList:=@class_copyProtocolList10; + class_copyIvarList:=@class_copyIvarList10; + + //The following functions are deprecated: + //objc_getClasses: deprecated in favor of objc_getClassList + //class_createInstanceFromZone: deprecated in favor of class_createInstance + //class_nextMethodList: deprecated in favor of new class_copyMethodList + //class_lookupMethod: deprecated in favor of class_getMethodImplementation + //class_respondsToMethod: deprecated in favor of class_respondsToSelector + + //The following function is used only by ZeroLink: + //objc_getRequiredClass + + // Class Manipulation + + //The following function is unchanged: + Pointer(class_setVersion) := GetProcedureAddress(hnd, 'class_setVersion'); + + //The following functions are added: + objc_allocateClassPair := @objc_allocateClassPair10; + objc_registerClassPair := @objc_registerClassPair10; + objc_duplicateClass := @objc_duplicateClass10; + class_addMethod := @class_addMethod10; + class_addIvar := @class_addIvar10; + class_addProtocol := @class_addProtocol10; + + //The following functions are deprecated: + //objc_addClass: deprecated in favor of objc_allocateClassPair and objc_registerClassPair + //class_addMethods: deprecated in favor of new class_addMethod + //class_removeMethods: deprecated with no substitute + //class_poseAs: deprecated in favor of categories and method_setImplementation + + + //Methods + + //The following function is unchanged: + Pointer(method_getNumberOfArguments) := GetProcedureAddress(hnd, 'method_getNumberOfArguments'); + + //The following functions are added: + method_getName := @method_getName10; + method_getImplementation := @method_getImplementation10; + method_getTypeEncoding := @method_getTypeEncoding10; + method_copyReturnType := @method_copyReturnType10; + method_copyArgumentType := @method_copyArgumentType10; + method_setImplementation := @method_setImplementation10; + + //The following functions are deprecated: + //method_getArgumentInfo + //method_getSizeOfArguments + + + //Instance Variables + + //The following functions are added: + ivar_getName := @ivar_getName10; + ivar_getTypeEncoding := @ivar_getTypeEncoding10; + ivar_getOffset := @ivar_getOffset10; + + //Selectors + //The following functions are unchanged: + Pointer(sel_getName) := GetProcedureAddress(hnd, 'sel_getName'); + Pointer(sel_registerName) := GetProcedureAddress(hnd, 'sel_registerName'); + Pointer(sel_getUid) := GetProcedureAddress(hnd, 'sel_getUid'); + + //The following function is added: + sel_isEqual := @sel_isEqual10; + + //The following function is deprecated: + //sel_isMapped: deprecated with no substitute + + + //Runtime + //The following functions are deprecated favor of dyld: + //objc_loadModules + //objc_loadModule + //objc_unloadModules + + //The following functions are deprecated: + //objc_setClassHandler: deprecated with no substitute + //objc_setMultithreaded: deprecated with no substitute + + //The following previously undocumented functions are deprecated with no substitute: + //objc_getOrigClass, _objc_create_zone, _objc_error, _objc_flush_caches, + //_objc_resolve_categories_for_class, _objc_setClassLoader,_ objc_setNilReceiver, + //_objc_getNilReceiver,_ objcInit + + //The following undocumented functions are unchanged: + //_objc_getFreedObjectClass, instrumentObjcMessageSends, _objc_debug_class_hash + //_class_printDuplicateCacheEntries, _class_printMethodCaches, _class_printMethodCacheStatistics + + + //Messaging + //The following functions are unchanged: + Pointer(objc_msgSend) := GetProcedureAddress(hnd, 'objc_msgSend'); + Pointer(objc_msgSend_stret) := GetProcedureAddress(hnd, 'objc_msgSend_stret'); + Pointer(objc_msgSendSuper) := GetProcedureAddress(hnd, 'objc_msgSendSuper'); + Pointer(objc_msgSendSuper_stret) := GetProcedureAddress(hnd, 'objc_msgSendSuper_stret'); + //todo: + Pointer(objc_msgSend_fpret) := GetProcedureAddress(hnd, 'objc_msgSend_fpret'); + + //The following functions are removed:objc_msgSendv Given an argument list, send a message with a simple return value. + //objc_msgSendv_stret Given an argument list, send a message with a data-structure return value. + //objc_msgSendv_fpret Given an argument list, send a message with a floating point return value. + + //Protocols + //The following functions are added: + objc_getProtocol := @objc_getProtocol10; + objc_copyProtocolList := @objc_copyProtocolList10; +end; + +end. diff --git a/bindings/objc/objcrtl20.pas b/bindings/objc/objcrtl20.pas new file mode 100644 index 000000000..7a8ac565f --- /dev/null +++ b/bindings/objc/objcrtl20.pas @@ -0,0 +1,163 @@ +{ + objcrtl20.pas + + Copyright (C) 2009 Dmitry Boyarintsev + + This unit is implementation for dynamic Objective-C Run-time Library based on run-time version 2.0 + headers included with XCode 3.1.2 + The original copyright note of is kept on each include file +} + +unit objcrtl20; + +{$mode objfpc}{$H+} + +interface + +uses + objcrtl, dynlibs; + +function InitializeObjcRtl20(const ObjCLibName: AnsiString): Boolean; + +implementation + +function InitializeObjcRtl20(const ObjCLibName: AnsiString): Boolean; +var + hnd : TLibHandle; +begin + hnd := LoadLibrary(ObjCLibName); + Result := hnd <> 0; + if not Result then Exit; + + LoadDefaultObjCExepction(hnd); + LoadDefaultObjCSync(hnd); + + Pointer(sel_getName) := GetProcedureAddress(hnd, 'sel_getName'); + Pointer(sel_registerName) := GetProcedureAddress(hnd, 'sel_registerName'); + Pointer(object_getClassName) := GetProcedureAddress(hnd, 'object_getClassName'); + Pointer(object_getIndexedIvars) := GetProcedureAddress(hnd, 'object_getIndexedIvars'); + + Pointer(sel_isMapped) := GetProcedureAddress(hnd, 'sel_isMapped'); + Pointer(sel_getUid) := GetProcedureAddress(hnd, 'sel_getUid'); + + Pointer(object_copy) := GetProcedureAddress(hnd, 'object_copy'); + Pointer(object_dispose) := GetProcedureAddress(hnd, 'object_dispose'); + + Pointer(object_getClass) := GetProcedureAddress(hnd, 'object_getClass'); + Pointer(object_setClass) := GetProcedureAddress(hnd, 'object_setClass'); + + Pointer(object_getIvar) := GetProcedureAddress(hnd, 'object_getIvar'); + Pointer(object_setIvar) := GetProcedureAddress(hnd, 'object_setIvar'); + + Pointer(object_setInstanceVariable) := GetProcedureAddress(hnd, 'object_setInstanceVariable'); + Pointer(object_getInstanceVariable) := GetProcedureAddress(hnd, 'object_getInstanceVariable'); + + Pointer(objc_getClass) := GetProcedureAddress(hnd, 'objc_getClass'); + Pointer(objc_getMetaClass) := GetProcedureAddress(hnd, 'objc_getMetaClass'); + Pointer(objc_lookUpClass) := GetProcedureAddress(hnd, 'objc_lookUpClass'); + Pointer(objc_getRequiredClass) := GetProcedureAddress(hnd, 'objc_getRequiredClass'); + Pointer(objc_getFutureClass) := GetProcedureAddress(hnd, 'objc_getFutureClass'); + Pointer(objc_setFutureClass) := GetProcedureAddress(hnd, 'objc_setFutureClass'); + Pointer(objc_getClassList) := GetProcedureAddress(hnd, 'objc_getClassList'); + + Pointer(objc_getProtocol) := GetProcedureAddress(hnd, 'objc_getProtocol'); + Pointer(objc_copyProtocolList) := GetProcedureAddress(hnd, 'objc_copyProtocolList'); + + Pointer(class_getName) := GetProcedureAddress(hnd, 'class_getName'); + Pointer(class_isMetaClass) := GetProcedureAddress(hnd, 'class_isMetaClass'); + Pointer(class_getSuperclass) := GetProcedureAddress(hnd, 'class_getSuperclass'); + Pointer(class_setSuperclass) := GetProcedureAddress(hnd, 'class_setSuperclass'); + + Pointer(class_getVersion) := GetProcedureAddress(hnd, 'class_getVersion'); + Pointer(class_setVersion) := GetProcedureAddress(hnd, 'class_setVersion'); + + Pointer(class_getInstanceSize) := GetProcedureAddress(hnd, 'class_getInstanceSize'); + + Pointer(class_getInstanceVariable) := GetProcedureAddress(hnd, 'class_getInstanceVariable'); + Pointer(class_getClassVariable) := GetProcedureAddress(hnd, 'class_getClassVariable'); + Pointer(class_copyIvarList) := GetProcedureAddress(hnd, 'class_copyIvarList'); + + Pointer(class_getInstanceMethod) := GetProcedureAddress(hnd, 'class_getInstanceMethod'); + Pointer(class_getClassMethod) := GetProcedureAddress(hnd, 'class_getClassMethod'); + Pointer(class_getMethodImplementation) := GetProcedureAddress(hnd, 'class_getMethodImplementation'); + Pointer(class_getMethodImplementation_stret) := GetProcedureAddress(hnd, 'class_getMethodImplementation_stret'); + Pointer(class_respondsToSelector) := GetProcedureAddress(hnd, 'class_respondsToSelector'); + Pointer(class_copyMethodList) := GetProcedureAddress(hnd, 'class_copyMethodList'); + + Pointer(class_conformsToProtocol) := GetProcedureAddress(hnd, 'class_conformsToProtocol'); + Pointer(class_copyProtocolList) := GetProcedureAddress(hnd, 'class_copyProtocolList'); + + Pointer(class_getProperty) := GetProcedureAddress(hnd, 'class_getProperty'); + Pointer(class_copyPropertyList) := GetProcedureAddress(hnd, 'class_copyPropertyList'); + + Pointer(class_getIvarLayout) := GetProcedureAddress(hnd, 'class_getIvarLayout'); + Pointer(class_getWeakIvarLayout) := GetProcedureAddress(hnd, 'class_getWeakIvarLayout'); + + Pointer(class_createInstance) := GetProcedureAddress(hnd, 'class_createInstance'); + + Pointer(objc_allocateClassPair) := GetProcedureAddress(hnd, 'objc_allocateClassPair'); + Pointer(objc_registerClassPair) := GetProcedureAddress(hnd, 'objc_registerClassPair'); + Pointer(objc_duplicateClass) := GetProcedureAddress(hnd, 'objc_duplicateClass'); + Pointer(objc_disposeClassPair) := GetProcedureAddress(hnd, 'objc_disposeClassPair'); + + Pointer(class_addMethod) := GetProcedureAddress(hnd, 'class_addMethod'); + Pointer(class_replaceMethod) := GetProcedureAddress(hnd, 'class_replaceMethod'); + Pointer(class_addIvar) := GetProcedureAddress(hnd, 'class_addIvar'); + Pointer(class_addProtocol) := GetProcedureAddress(hnd, 'class_addProtocol'); + Pointer(class_setIvarLayout) := GetProcedureAddress(hnd, 'class_setIvarLayout'); + Pointer(class_setWeakIvarLayout) := GetProcedureAddress(hnd, 'class_setWeakIvarLayout'); + + Pointer(method_getName) := GetProcedureAddress(hnd, 'method_getName'); + Pointer(method_getImplementation) := GetProcedureAddress(hnd, 'method_getImplementation'); + Pointer(method_getTypeEncoding) := GetProcedureAddress(hnd, 'method_getTypeEncoding'); + + Pointer(method_getNumberOfArguments) := GetProcedureAddress(hnd, 'method_getNumberOfArguments'); + Pointer(method_copyReturnType) := GetProcedureAddress(hnd, 'method_copyReturnType'); + Pointer(method_copyArgumentType) := GetProcedureAddress(hnd, 'method_copyArgumentType'); + Pointer(method_getReturnType) := GetProcedureAddress(hnd, 'method_getReturnType'); + Pointer(method_getArgumentType) := GetProcedureAddress(hnd, 'method_getArgumentType'); + Pointer(method_getDescription) := GetProcedureAddress(hnd, 'method_getDescription'); + + Pointer(method_setImplementation) := GetProcedureAddress(hnd, 'method_setImplementation'); + Pointer(method_exchangeImplementations) := GetProcedureAddress(hnd, 'method_exchangeImplementations'); + + Pointer(ivar_getName) := GetProcedureAddress(hnd, 'ivar_getName'); + Pointer(ivar_getTypeEncoding) := GetProcedureAddress(hnd, 'ivar_getTypeEncoding'); + Pointer(ivar_getOffset) := GetProcedureAddress(hnd, 'ivar_getOffset'); + + Pointer(property_getName) := GetProcedureAddress(hnd, 'property_getName'); + Pointer(property_getAttributes) := GetProcedureAddress(hnd, 'property_getAttributes'); + + Pointer(protocol_conformsToProtocol) := GetProcedureAddress(hnd, 'protocol_conformsToProtocol'); + Pointer(protocol_isEqual) := GetProcedureAddress(hnd, 'protocol_isEqual'); + Pointer(protocol_getMethodDescription) := GetProcedureAddress(hnd, 'protocol_getMethodDescription'); + Pointer(protocol_copyMethodDescriptionList) := GetProcedureAddress(hnd, 'protocol_copyMethodDescriptionList'); + Pointer(protocol_getProperty) := GetProcedureAddress(hnd, 'protocol_getProperty'); + Pointer(protocol_copyPropertyList) := GetProcedureAddress(hnd, 'protocol_copyPropertyList'); + Pointer(protocol_copyProtocolList) := GetProcedureAddress(hnd, 'protocol_copyProtocolList'); + + Pointer(objc_copyImageNames) := GetProcedureAddress(hnd, 'objc_copyImageNames'); + Pointer(class_getImageName) := GetProcedureAddress(hnd, 'class_getImageName'); + Pointer(objc_copyClassNamesForImage) := GetProcedureAddress(hnd, 'objc_copyClassNamesForImage'); + + Pointer(sel_isEqual) := GetProcedureAddress(hnd, 'sel_isEqual'); + Pointer(objc_enumerationMutation) := GetProcedureAddress(hnd, 'objc_enumerationMutation'); + Pointer(objc_setEnumerationMutationHandler) := GetProcedureAddress(hnd, 'objc_setEnumerationMutationHandler'); + Pointer(objc_setForwardHandler) := GetProcedureAddress(hnd, 'objc_setForwardHandler'); + + Pointer(objc_msgSend) := GetProcedureAddress(hnd, 'objc_msgSend'); + Pointer(objc_msgSendSuper) := GetProcedureAddress(hnd, 'objc_msgSendSuper'); + Pointer(objc_msgSend_stret) := GetProcedureAddress(hnd, 'objc_msgSend_stret'); + Pointer(objc_msgSendSuper_stret) := GetProcedureAddress(hnd, 'objc_msgSendSuper_stret'); + Pointer(objc_msgSend_fpret) := GetProcedureAddress(hnd, 'objc_msgSend_fpret'); + + Pointer(method_invoke) := GetProcedureAddress(hnd, 'method_invoke'); + Pointer(method_invoke_stret) := GetProcedureAddress(hnd, 'method_invoke_stret'); + Pointer(objc_collect) := GetProcedureAddress(hnd, 'objc_collect'); + Pointer(objc_collectingEnabled) := GetProcedureAddress(hnd, 'objc_collectingEnabled'); + +end; + + +end. +