2
0

objc1.inc 12 KB

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