objc1.inc 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368
  1. {
  2. This file is part of the Free Pascal run time library.
  3. Copyright (c) 2009 by the Free Pascal development team
  4. This unit provides an interface to the Objective-C 1.0
  5. run time as defined by Apple
  6. See the file COPYING.FPC, included in this distribution,
  7. for details about the copyright.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  11. **********************************************************************}
  12. interface
  13. {$inline on}
  14. uses
  15. ctypes
  16. {$ifdef unix}
  17. ,unixtype
  18. {$endif}
  19. ;
  20. {$packrecords c}
  21. {$ifdef darwin}
  22. const
  23. libname = 'objc';
  24. {$linkframework Foundation}
  25. {$define targetok}
  26. {$endif}
  27. {$ifndef targetok}
  28. {$error Add support for the current target to the objc1 unit }
  29. {$endif}
  30. const
  31. CLS_CLASS = $1;
  32. CLS_META = $2;
  33. type
  34. { make all opaque types assignment-incompatible with other typed pointers by
  35. declaring them as pointers to empty records
  36. WARNING: do NOT change the names, types or field names/types of these
  37. types, as many are used internally by the compiler.
  38. }
  39. { BOOL is one byte and uses 0/1, just like Pascal }
  40. BOOL = boolean;
  41. tobjc_class = record
  42. end;
  43. pobjc_class = ^tobjc_class;
  44. _Class = pobjc_class;
  45. objc_object = record
  46. isa: pobjc_class;
  47. superclass: pobjc_class;
  48. end;
  49. id = ^objc_object;
  50. pobjc_object = id;
  51. _fpc_objc_sel_type = record
  52. end;
  53. SEL = ^_fpc_objc_sel_type;
  54. objc_method = record
  55. end;
  56. Pobjc_method = ^objc_method;
  57. Method = Pobjc_method;
  58. PMethod = ^Method;
  59. IMP = function(target: id; msg: SEL): id; varargs; cdecl;
  60. objc_super = record
  61. receiver: id;
  62. _class: pobjc_class;
  63. end;
  64. pobjc_super = ^objc_super;
  65. _fpc_objc_protocol_type = record
  66. end;
  67. pobjc_protocol = ^_fpc_objc_protocol_type;
  68. ppobjc_protocol = ^pobjc_protocol;
  69. objc_ivar = packed record
  70. end;
  71. Pobjc_ivar = ^objc_ivar;
  72. Ivar = Pobjc_ivar;
  73. PIvar = ^Ivar;
  74. { type that certainly will be returned by address }
  75. tdummyrecbyaddrresult = record
  76. a: array[0..1000] of shortstring;
  77. end;
  78. TEnumerationMutationHandler = procedure(obj: id); cdecl;
  79. ptrdiff_t = ptrint;
  80. { sending messages }
  81. function objc_msgSend(self: id; op: SEL): id; cdecl; varargs; external libname;
  82. function objc_msgSendSuper(const super: pobjc_super; op: SEL): id; cdecl; varargs; external libname;
  83. { The following two are declared as procedures with the hidden result pointer
  84. as their first parameter. This corresponds to the declaration below as far
  85. as the code generator is concerned (and is easier to handle in the compiler). }
  86. function objc_msgSend_stret(self: id; op: SEL): tdummyrecbyaddrresult; cdecl; varargs; external libname;
  87. function objc_msgSendSuper_stret(const super: pobjc_super; op: SEL): tdummyrecbyaddrresult; cdecl; varargs; external libname;
  88. {$ifdef cpui386}
  89. function objc_msgSend_fpret (self: id; op: SEL): double; cdecl; varargs; external libname;
  90. {$else cpui386}
  91. function objc_msgSend_fpret (self: id; op: SEL): double; cdecl; varargs; external libname name 'objc_msgSend';
  92. {$endif cpui386}
  93. function sel_getName(sel: SEL): PChar; cdecl; external libname;
  94. function sel_registerName(str: PChar): SEL; cdecl; external libname;
  95. function object_getClassName(obj: id): PChar; cdecl; external libname;
  96. function object_getIndexedIvars(obj: id ): Pointer; cdecl; external libname;
  97. function sel_getUid(const str: PChar): SEL; cdecl; external libname;
  98. function object_copy(obj:id; size:size_t):id; cdecl; external libname;
  99. function object_dispose(obj:id):id; cdecl; external libname;
  100. function object_getClass(obj:id): pobjc_class; cdecl;
  101. function object_setClass(obj:id; cls: pobjc_class):pobjc_class; cdecl;
  102. function object_getIvar(obj:id; _ivar:Ivar):id; cdecl;
  103. procedure object_setIvar(obj:id; _ivar:Ivar; value:id); cdecl;
  104. function object_setInstanceVariable(obj:id; name:pchar; value:pointer):Ivar; cdecl; external libname;
  105. function object_getInstanceVariable(obj:id; name:pchar; var outValue: Pointer):Ivar; cdecl; external libname;
  106. function objc_getClass(name:pchar):id; cdecl; external libname;
  107. function objc_getMetaClass(name:pchar):id; cdecl; external libname;
  108. function objc_lookUpClass(name:pchar):id; cdecl; external libname;
  109. function objc_getClassList(buffer:pClass; bufferCount:cint):cint; cdecl; external libname;
  110. {$ifdef FPC_HAS_FEATURE_OBJECTIVEC1}
  111. function objc_getProtocol(name:pchar): pobjc_protocol; cdecl; weakexternal libname;
  112. function objc_copyProtocolList(outCount:pdword):ppobjc_protocol; cdecl; weakexternal libname;
  113. {$endif}
  114. function class_getName(cls:pobjc_class):PChar; cdecl; inline;
  115. function class_isMetaClass(cls:pobjc_class):BOOL; cdecl;
  116. function class_getSuperclass(cls:pobjc_class):pobjc_class; cdecl; inline;
  117. function class_getVersion(cls:pobjc_class):longint; cdecl; external libname;
  118. procedure class_setVersion(cls:pobjc_class; version:longint); cdecl; external libname;
  119. function class_getInstanceSize(cls:pobjc_class):size_t; cdecl; external libname;
  120. function class_getInstanceVariable(cls:pobjc_class; name:pchar):Ivar; cdecl; external libname;
  121. function class_getClassVariable(cls:pobjc_class; name:pchar):Ivar; cdecl; external libname;
  122. function class_copyIvarList(cls:pobjc_class; outCount:pdword):PIvar; cdecl; external libname;
  123. function class_getInstanceMethod(cls:pobjc_class; name:SEL):Method; cdecl; external libname;
  124. function class_getClassMethod(cls:pobjc_class; name:SEL):Method; cdecl; external libname;
  125. function class_getMethodImplementation(cls:pobjc_class; name:SEL):IMP; cdecl; external libname;
  126. function class_getMethodImplementation_stret(cls:pobjc_class; name:SEL):IMP; cdecl; external libname;
  127. function class_respondsToSelector(cls:pobjc_class; sel:SEL):BOOL; cdecl; external libname;
  128. function class_copyMethodList(cls:pobjc_class; outCount:pdword):PMethod; cdecl; external libname;
  129. function class_conformsToProtocol(cls:pobjc_class; var protocol: pobjc_protocol):BOOL; cdecl; external libname;
  130. function class_copyProtocolList(cls:pobjc_class; var outCount: dword):ppobjc_protocol; cdecl; external libname;
  131. function class_createInstance(cls:pobjc_class; extraBytes:size_t):id; cdecl; external libname;
  132. (*
  133. function objc_allocateClassPair(superclass:pobjc_class; name:pchar; extraBytes:size_t):pobjc_class; cdecl; external libname;
  134. procedure objc_registerClassPair(cls:pobjc_class); cdecl; external libname;
  135. function objc_duplicateClass(original:pobjc_class; name:pchar; extraBytes:size_t):pobjc_class; cdecl; external libname;
  136. procedure objc_disposeClassPair(cls:pobjc_class); cdecl; external libname;
  137. function class_addMethod(cls:pobjc_class; name:SEL; imp:IMP; types:pchar):BOOL; cdecl; external libname;
  138. function class_addIvar(cls:pobjc_class; name:pchar; size:size_t; alignment:uint8_t; types:pchar):BOOL; cdecl; external libname;
  139. function class_addProtocol(cls:pobjc_class; protocol:pProtocol):BOOL; cdecl; external libname;
  140. *)
  141. function method_getName(m:Method):SEL; cdecl; inline;
  142. function method_getImplementation(m:Method):IMP; cdecl; inline;
  143. function method_getTypeEncoding(m:Method):Pchar; cdecl; inline;
  144. function method_getNumberOfArguments(m:Method):dword; cdecl; external libname;
  145. (*
  146. function method_copyReturnType(m:Method):Pchar; cdecl; weakexternal libname;
  147. function method_copyArgumentType(m:Method; index:dword):Pchar; cdecl; weakexternal libname;
  148. procedure method_getReturnType(m:Method; dst:pchar; dst_len:size_t); cdecl; external libname;
  149. function method_setImplementation(m:Method; imp:IMP):IMP; cdecl; external libname;
  150. *)
  151. function ivar_getName(v:Ivar):Pchar; cdecl; inline;
  152. function ivar_getTypeEncoding(v:Ivar):Pchar; cdecl; inline;
  153. function ivar_getOffset(v:Ivar):ptrdiff_t; cdecl; inline;
  154. (*
  155. function sel_isEqual(lhs:SEL; rhs:SEL):BOOL; cdecl; external libname;
  156. *)
  157. { fast enumeration support (available on Mac OS X 10.5 and later) }
  158. procedure objc_enumerationMutation(obj: id); cdecl; external libname;
  159. procedure objc_setEnumerationMutationHandler(handler: TEnumerationMutationHandler); cdecl; external libname;
  160. implementation
  161. type
  162. {* Method Template }
  163. Pobjc_method1 = ^objc_method1;
  164. Method1 = Pobjc_method1;
  165. objc_method1 = packed record
  166. method_name : SEL;
  167. method_types : PChar;
  168. method_imp : IMP;
  169. end;
  170. Pobjc_method_list1 = ^objc_method_list1;
  171. PPobjc_method_list1 = ^Pobjc_method_list1;
  172. objc_method_list1 = packed record
  173. obsolete : Pobjc_method_list1;
  174. method_count : cint;
  175. {$ifdef __alpha__}
  176. space: cint;
  177. {$endif}
  178. method_list1 : array[0..0] of objc_method1; { variable length structure }
  179. end;
  180. {* Instance Variable Template}
  181. Pobjc_ivar1 = ^objc_ivar1;
  182. Ivar1 = Pobjc_ivar1;
  183. PIvar1 = ^Ivar1;
  184. objc_ivar1 = packed record
  185. ivar_name : PChar;
  186. ivar_type : PChar;
  187. ivar_offset : cint;
  188. {$ifdef __alpha__}
  189. space: cint;
  190. {$endif}
  191. end;
  192. Pobjc_ivar_list1 = ^objc_ivar_list1;
  193. objc_ivar_list1 = packed record
  194. ivar_count: cint;
  195. {$ifdef __alpha__}
  196. space: cint;
  197. {$endif}
  198. ivar_list: array[0..0] of objc_ivar1; { variable length structure }
  199. end;
  200. Pobjc_cache1 = ^objc_cache1;
  201. objc_cache1 = record
  202. mask : cuint; { total = mask + 1 }
  203. occupied : cuint;
  204. buckets : array[0..0] of Method1;
  205. end;
  206. Protocol1 = objc_object;
  207. Pobjc_protocol_list1 = ^objc_protocol_list1;
  208. objc_protocol_list1 = record
  209. next : Pobjc_protocol_list1;
  210. count : cint;
  211. list : array[0..0] of Protocol1;
  212. end;
  213. pobjc_class1 = ^objc_class1;
  214. objc_class1 = packed record
  215. isa : Pobjc_class1;
  216. super_class : Pobjc_class1;
  217. name : PChar;
  218. version : culong;
  219. info : culong;
  220. instance_size : culong;
  221. ivars : Pobjc_ivar_list1;
  222. methodLists : PPobjc_method_list1;
  223. cache : Pobjc_cache1;
  224. protocols : Pobjc_protocol_list1;
  225. end;
  226. Pid = ^id;
  227. function object_getClass(obj:id): pobjc_class; cdecl;
  228. begin
  229. if obj = nil then
  230. object_getClass := nil
  231. else
  232. begin
  233. object_getClass := pobjc_class(Pobjc_object(obj)^.isa);
  234. end;
  235. end;
  236. function object_setClass(obj:id; cls: pobjc_class): pobjc_class; cdecl;
  237. begin
  238. // can this be done in that way?
  239. object_setClass := pobjc_class(Pobjc_object(obj)^.isa);
  240. Pobjc_object(obj)^.isa := pobjc_class(cls);
  241. end;
  242. function object_getIvar(obj:id; _ivar:Ivar):id; cdecl;
  243. begin
  244. object_getIvar := nil;
  245. if not Assigned(obj) or
  246. not Assigned(_ivar) then
  247. Exit;
  248. object_getIvar := Pid(PtrUInt(obj) + ivar_getOffset(_ivar))^;
  249. end;
  250. procedure object_setIvar(obj:id; _ivar:Ivar; value:id); cdecl;
  251. begin
  252. if not Assigned(obj) or
  253. not Assigned(_ivar) then
  254. Exit;
  255. Pid(PtrUInt(obj) + ivar_getOffset(_ivar))^ := value;
  256. end;
  257. function class_getName(cls:pobjc_class):PChar; cdecl; inline;
  258. begin
  259. class_getName := pobjc_class1(cls)^.name;
  260. end;
  261. function class_getSuperclass(cls:pobjc_class):pobjc_class; cdecl; inline;
  262. begin
  263. class_getSuperclass := pobjc_class(pobjc_class1(cls)^.super_class);
  264. end;
  265. function class_isMetaClass(cls:_Class):BOOL; cdecl;
  266. begin
  267. class_isMetaClass := Assigned(cls) and (pobjc_class1(cls)^.Info = CLS_META);
  268. end;
  269. function method_getName(m:Method):SEL; cdecl; inline;
  270. begin
  271. method_getName := Method1(m)^.method_name;
  272. end;
  273. function method_getImplementation(m:Method):IMP; cdecl; inline;
  274. begin
  275. method_getImplementation := IMP(Method1(m)^.method_imp);
  276. end;
  277. function method_getTypeEncoding(m:Method):Pchar; cdecl; inline;
  278. begin
  279. method_getTypeEncoding := Method1(m)^.method_types;
  280. end;
  281. function ivar_getName(v:Ivar):Pchar; cdecl; inline;
  282. begin
  283. ivar_getName := IVar1(v)^.ivar_name;
  284. end;
  285. function ivar_getTypeEncoding(v:Ivar):Pchar; cdecl; inline;
  286. begin
  287. ivar_getTypeEncoding := IVar1(v)^.ivar_type;
  288. end;
  289. function ivar_getOffset(v:Ivar):ptrdiff_t; cdecl; inline;
  290. begin
  291. ivar_getOffset := ptrdiff_t(IVar1(v)^.ivar_offset);
  292. end;
  293. end.