objc1.inc 12 KB

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