objc1.inc 12 KB

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