system.pas 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803
  1. {
  2. This file is part of the Pas2JS run time library.
  3. Copyright (c) 2018 by Mattias Gaertner
  4. See the file COPYING.FPC, included in this distribution,
  5. for details about the copyright.
  6. This program is distributed in the hope that it will be useful,
  7. but WITHOUT ANY WARRANTY; without even the implied warranty of
  8. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  9. **********************************************************************}
  10. unit System;
  11. {$mode objfpc}
  12. {$modeswitch externalclass}
  13. interface
  14. const
  15. LineEnding = #10;
  16. sLineBreak = LineEnding;
  17. MaxSmallint = 32767;
  18. MinSmallint = -32768;
  19. MaxShortInt = 127;
  20. MinShortInt = -128;
  21. MaxByte = $FF;
  22. MaxWord = $FFFF;
  23. MaxLongint = $7fffffff;
  24. MaxCardinal = LongWord($ffffffff);
  25. Maxint = MaxLongint;
  26. IsMultiThread = false;
  27. {*****************************************************************************
  28. Base types
  29. *****************************************************************************}
  30. type
  31. Integer = LongInt;
  32. Cardinal = LongWord;
  33. DWord = LongWord;
  34. SizeInt = NativeInt;
  35. SizeUInt = NativeUInt;
  36. PtrInt = NativeInt;
  37. PtrUInt = NativeUInt;
  38. ValSInt = NativeInt;
  39. ValUInt = NativeUInt;
  40. ValReal = Double;
  41. Real = type Double;
  42. Extended = type Double;
  43. TDateTime = type double;
  44. TTime = type TDateTime;
  45. TDate = type TDateTime;
  46. Int64 = type NativeInt unimplemented; // only 53 bits at runtime
  47. UInt64 = type NativeUInt unimplemented; // only 52 bits at runtime
  48. QWord = type NativeUInt unimplemented; // only 52 bits at runtime
  49. Single = type Double unimplemented;
  50. Comp = type NativeInt unimplemented;
  51. NativeLargeInt = NativeInt;
  52. NativeLargeUInt = NativeUInt;
  53. UnicodeString = type String;
  54. WideString = type String;
  55. WideChar = char;
  56. UnicodeChar = char;
  57. TDynArrayIndex = NativeInt;
  58. TTextLineBreakStyle = (tlbsLF,tlbsCRLF,tlbsCR);
  59. {*****************************************************************************
  60. TObject, TClass, IUnknown, IInterface, TInterfacedObject
  61. *****************************************************************************}
  62. type
  63. TGuid = record
  64. D1: DWord;
  65. D2: word;
  66. D3: word;
  67. D4: array[0..7] of byte;
  68. end;
  69. TGUIDString = type string;
  70. TClass = class of TObject;
  71. { TObject }
  72. TObject = class
  73. private
  74. class var FClassName: String; external name '$classname';
  75. class var FClassParent: TClass; external name '$ancestor';
  76. class var FUnitName: String; external name '$module.$name';
  77. public
  78. constructor Create;
  79. destructor Destroy; virtual;
  80. // Free is using compiler magic.
  81. // Reasons:
  82. // 1. In JS calling obj.Free when obj=nil would crash.
  83. // 2. In JS freeing memory requires to set all references to nil.
  84. // Therefore any obj.free call is replaced by the compiler with some rtl magic.
  85. procedure Free;
  86. class function ClassType: TClass; assembler;
  87. class property ClassName: String read FClassName;
  88. class function ClassNameIs(const Name: string): boolean;
  89. class property ClassParent: TClass read FClassParent;
  90. class function InheritsFrom(aClass: TClass): boolean; assembler;
  91. class property UnitName: String read FUnitName;
  92. procedure AfterConstruction; virtual;
  93. procedure BeforeDestruction; virtual;
  94. function GetInterface(const iid: TGuid; out obj): boolean;
  95. function GetInterface(const iidstr: String; out obj): boolean; inline;
  96. function GetInterfaceByStr(const iidstr: String; out obj): boolean;
  97. function GetInterfaceWeak(const iid: TGuid; out obj): boolean; // equal to GetInterface but the interface returned is not referenced
  98. function Equals(Obj: TObject): boolean; virtual;
  99. function ToString: String; virtual;
  100. end;
  101. const
  102. { IInterface }
  103. S_OK = 0;
  104. S_FALSE = 1;
  105. E_NOINTERFACE = -2147467262; // FPC: longint($80004002)
  106. E_UNEXPECTED = -2147418113; // FPC: longint($8000FFFF)
  107. E_NOTIMPL = -2147467263; // FPC: longint($80004001)
  108. type
  109. {$Interfaces COM}
  110. IUnknown = interface
  111. ['{00000000-0000-0000-C000-000000000046}']
  112. function QueryInterface(const iid: TGuid; out obj): Integer;
  113. function _AddRef: Integer;
  114. function _Release: Integer;
  115. end;
  116. IInterface = IUnknown;
  117. {$M+}
  118. IInvokable = interface(IInterface)
  119. end;
  120. {$M-}
  121. { Enumerator support }
  122. IEnumerator = interface(IInterface)
  123. function GetCurrent: TObject;
  124. function MoveNext: Boolean;
  125. procedure Reset;
  126. property Current: TObject read GetCurrent;
  127. end;
  128. IEnumerable = interface(IInterface)
  129. function GetEnumerator: IEnumerator;
  130. end;
  131. { TInterfacedObject }
  132. TInterfacedObject = class(TObject,IUnknown)
  133. protected
  134. fRefCount: Integer;
  135. { implement methods of IUnknown }
  136. function QueryInterface(const iid: TGuid; out obj): Integer; virtual;
  137. function _AddRef: Integer; virtual;
  138. function _Release: Integer; virtual;
  139. public
  140. procedure BeforeDestruction; override;
  141. property RefCount: Integer read fRefCount;
  142. end;
  143. TInterfacedClass = class of TInterfacedObject;
  144. { TAggregatedObject - sub or satellite object using same interface as controller }
  145. TAggregatedObject = class(TObject)
  146. private
  147. fController: Pointer;
  148. function GetController: IUnknown;
  149. protected
  150. { implement methods of IUnknown }
  151. function QueryInterface(const iid: TGuid; out obj): Integer; virtual;
  152. function _AddRef: Integer; virtual;
  153. function _Release: Integer; virtual;
  154. public
  155. constructor Create(const aController: IUnknown); reintroduce;
  156. property Controller: IUnknown read GetController;
  157. end;
  158. { TContainedObject }
  159. TContainedObject = class(TAggregatedObject,IInterface)
  160. protected
  161. function QueryInterface(const iid: TGuid; out obj): Integer; override;
  162. end;
  163. const
  164. { for safe as operator support }
  165. IObjectInstance: TGuid = '{D91C9AF4-3C93-420F-A303-BF5BA82BFD23}';
  166. function GUIDToString(const GUID: TGUID): string; external name 'rtl.guidrToStr';
  167. {*****************************************************************************
  168. Init / Exit / ExitProc
  169. *****************************************************************************}
  170. var
  171. ExitCode: Integer; external name 'rtl.exitcode';
  172. IsConsole: Boolean = {$IFDEF NodeJS}true{$ELSE}false{$ENDIF};
  173. type
  174. TOnParamCount = function: Longint;
  175. TOnParamStr = function(Index: Longint): String;
  176. var
  177. OnParamCount: TOnParamCount;
  178. OnParamStr: TOnParamStr;
  179. function ParamCount: Longint;
  180. function ParamStr(Index: Longint): String;
  181. {*****************************************************************************
  182. Math
  183. *****************************************************************************}
  184. const
  185. PI: Double; external name 'Math.PI';
  186. MathE: Double; external name 'Math.E'; // Euler's number
  187. MathLN10: Double; external name 'Math.LN10'; // ln(10)
  188. MathLN2: Double; external name 'Math.LN2'; // ln(2)
  189. MathLog10E: Double; external name 'Math.Log10E'; // log10(e)
  190. MathLog2E: Double; external name 'Math.LOG2E'; // log2(e)
  191. MathSQRT1_2: Double; external name 'Math.SQRT1_2'; // sqrt(0.5)
  192. MathSQRT2: Double; external name 'Math.SQRT2'; // sqrt(2)
  193. function Abs(const A: integer): integer; overload; external name 'Math.abs';
  194. function Abs(const A: NativeInt): integer; overload; external name 'Math.abs';
  195. function Abs(const A: Double): Double; overload; external name 'Math.abs';
  196. function ArcTan(const A, B: Double): Double; external name 'Math.atan';
  197. function Cos(const A: Double): Double; external name 'Math.cos';
  198. function Exp(const A: Double): Double; external name 'Math.exp';
  199. function Frac(const A: Double): Double; assembler;
  200. function Ln(const A: Double): Double; external name 'Math.log';
  201. function Odd(const A: Integer): Boolean; assembler;
  202. function Random(const Range: Integer): Integer; overload; assembler;
  203. function Random: Double; overload; external name 'Math.random';
  204. function Round(const A: Double): NativeInt; external name 'Math.round';
  205. function Sin(const A: Double): Double; external name 'Math.sin';
  206. function Sqr(const A: Integer): Integer; assembler; overload;
  207. function Sqr(const A: Double): Double; assembler; overload;
  208. function sqrt(const A: Double): Double; external name 'Math.sqrt';
  209. function Trunc(const A: Double): NativeInt;
  210. {*****************************************************************************
  211. String functions
  212. *****************************************************************************}
  213. const
  214. DefaultTextLineBreakStyle : TTextLineBreakStyle = tlbsLF;
  215. function Int(const A: Double): double;
  216. function Copy(const S: string; Index, Size: Integer): String; assembler; overload;
  217. function Copy(const S: string; Index: Integer): String; assembler; overload;
  218. procedure Delete(var S: String; Index, Size: Integer); assembler; overload;
  219. function Pos(const Search, InString: String): Integer; assembler; overload;
  220. function Pos(const Search, InString: String; StartAt : Integer): Integer; assembler; overload;
  221. procedure Insert(const Insertion: String; var Target: String; Index: Integer); overload;
  222. function upcase(c : char) : char; assembler;
  223. function HexStr(Val: NativeInt; cnt: byte): string; external name 'rtl.hexStr'; overload;
  224. procedure val(const S: String; out NI : NativeInt; out Code: Integer); overload;
  225. procedure val(const S: String; out NI : NativeUInt; out Code: Integer); overload;
  226. procedure val(const S: String; out SI : ShortInt; out Code: Integer); overload;
  227. procedure val(const S: String; out B : Byte; out Code: Integer); overload;
  228. procedure val(const S: String; out SI : smallint; out Code: Integer); overload;
  229. procedure val(const S: String; out W : word; out Code : Integer); overload;
  230. procedure val(const S: String; out I : integer; out Code : Integer); overload;
  231. procedure val(const S: String; out C : Cardinal; out Code: Integer); overload;
  232. procedure val(const S: String; out d : double; out Code : Integer); overload;
  233. function StringOfChar(c: Char; l: NativeInt): String;
  234. {*****************************************************************************
  235. Other functions
  236. *****************************************************************************}
  237. procedure Write; varargs; // ToDo: should be compiler built-in function
  238. procedure Writeln; varargs; // ToDo: should be compiler built-in function
  239. Type
  240. TConsoleHandler = Procedure (S : JSValue; NewLine : Boolean);
  241. Function SetWriteCallBack(H : TConsoleHandler) : TConsoleHandler;
  242. function Assigned(const V: JSValue): boolean; assembler; overload;
  243. function StrictEqual(const A: JSValue; const B): boolean; assembler;
  244. function StrictInequal(const A: JSValue; const B): boolean; assembler;
  245. implementation
  246. // function parseInt(s: String; Radix: NativeInt): NativeInt; external name 'parseInt'; // may result NaN
  247. function isNaN(i: JSValue): boolean; external name 'isNaN'; // may result NaN
  248. // needed by ClassNameIs, the real SameText is in SysUtils
  249. function SameText(const s1, s2: String): Boolean; assembler;
  250. asm
  251. return s1.toLowerCase() == s2.toLowerCase();
  252. end;
  253. function ParamCount: Longint;
  254. begin
  255. if Assigned(OnParamCount) then
  256. Result:=OnParamCount()
  257. else
  258. Result:=0;
  259. end;
  260. function ParamStr(Index: Longint): String;
  261. begin
  262. if Assigned(OnParamStr) then
  263. Result:=OnParamStr(Index)
  264. else if Index=0 then
  265. Result:='js'
  266. else
  267. Result:='';
  268. end;
  269. function Frac(const A: Double): Double; assembler;
  270. asm
  271. return A % 1;
  272. end;
  273. function Odd(const A: Integer): Boolean; assembler;
  274. asm
  275. return A&1 != 0;
  276. end;
  277. function Random(const Range: Integer): Integer; assembler;
  278. asm
  279. return Math.floor(Math.random()*Range);
  280. end;
  281. function Sqr(const A: Integer): Integer; assembler;
  282. asm
  283. return A*A;
  284. end;
  285. function Sqr(const A: Double): Double; assembler;
  286. asm
  287. return A*A;
  288. end;
  289. function Trunc(const A: Double): NativeInt; assembler;
  290. asm
  291. if (!Math.trunc) {
  292. Math.trunc = function(v) {
  293. v = +v;
  294. if (!isFinite(v)) return v;
  295. return (v - v % 1) || (v < 0 ? -0 : v === 0 ? v : 0);
  296. };
  297. }
  298. $mod.Trunc = Math.trunc;
  299. return Math.trunc(A);
  300. end;
  301. function Copy(const S: string; Index, Size: Integer): String; assembler;
  302. asm
  303. if (Index<1) Index = 1;
  304. return (Size>0) ? S.substring(Index-1,Index+Size-1) : "";
  305. end;
  306. function Copy(const S: string; Index: Integer): String; assembler;
  307. asm
  308. if (Index<1) Index = 1;
  309. return S.substr(Index-1);
  310. end;
  311. procedure Delete(var S: String; Index, Size: Integer);
  312. var
  313. h: String;
  314. begin
  315. if (Index<1) or (Index>length(S)) or (Size<=0) then exit;
  316. h:=S;
  317. S:=copy(h,1,Index-1)+copy(h,Index+Size);
  318. end;
  319. function Pos(const Search, InString: String): Integer; assembler;
  320. asm
  321. return InString.indexOf(Search)+1;
  322. end;
  323. function Pos(const Search, InString: String; StartAt : Integer): Integer; assembler; overload;
  324. asm
  325. return InString.indexOf(Search,StartAt-1)+1;
  326. end;
  327. procedure Insert(const Insertion: String; var Target: String; Index: Integer);
  328. var
  329. t: String;
  330. begin
  331. if Insertion='' then exit;
  332. t:=Target;
  333. if Index<1 then
  334. Target:=Insertion+t
  335. else if Index>length(t) then
  336. Target:=t+Insertion
  337. else
  338. Target:=copy(t,1,Index-1)+Insertion+copy(t,Index,length(t));
  339. end;
  340. var
  341. WriteBuf: String;
  342. JSArguments: array of JSValue; external name 'arguments';
  343. WriteCallBack : TConsoleHandler;
  344. Function SetWriteCallBack(H : TConsoleHandler) : TConsoleHandler;
  345. begin
  346. Result:=WriteCallBack;
  347. WriteCallBack:=H;
  348. end;
  349. procedure Write;
  350. var
  351. i: Integer;
  352. begin
  353. for i:=0 to length(JSArguments)-1 do
  354. if Assigned(WriteCallBack) then
  355. WriteCallBack(JSArguments[i],False)
  356. else
  357. WriteBuf:=WriteBuf+String(JSArguments[i]);
  358. end;
  359. procedure Writeln;
  360. var
  361. i,l: Integer;
  362. s: String;
  363. begin
  364. L:=length(JSArguments)-1;
  365. if Assigned(WriteCallBack) then
  366. begin
  367. for i:=0 to L do
  368. WriteCallBack(JSArguments[i],I=L);
  369. end
  370. else
  371. begin
  372. s:=WriteBuf;
  373. for i:=0 to L do
  374. s:=s+String(JSArguments[i]);
  375. asm
  376. console.log(s);
  377. end;
  378. WriteBuf:='';
  379. end;
  380. end;
  381. function Int(const A: Double): double;
  382. begin
  383. // trunc contains fix for missing Math.trunc in IE
  384. Result:=Trunc(A);
  385. end;
  386. function Number(S: String): Double; external name 'Number';
  387. procedure val(const S: String; out NI : NativeInt; out Code: Integer);
  388. var
  389. x : double;
  390. begin
  391. Code:=0;
  392. x:=Number(S);
  393. if isNaN(x) or (X<>Int(X)) then
  394. Code:=1
  395. else
  396. NI:=Trunc(x);
  397. end;
  398. procedure val(const S: String; out NI: NativeUInt; out Code: Integer);
  399. var
  400. x : double;
  401. begin
  402. Code:=0;
  403. x:=Number(S);
  404. if isNaN(x) or (X<>Int(X)) or (X<0) then
  405. Code:=1
  406. else
  407. NI:=Trunc(x);
  408. end;
  409. procedure val(const S: String; out SI : ShortInt; out Code: Integer);
  410. var
  411. X:Double;
  412. begin
  413. Code:=0;
  414. x:=Number(S);
  415. if isNaN(x) or (X<>Int(X)) then
  416. Code:=1
  417. else if (x<MinShortInt) or (x>MaxShortInt) then
  418. Code:=2
  419. else
  420. SI:=Trunc(x);
  421. end;
  422. procedure val(const S: String; out SI: smallint; out Code: Integer);
  423. var
  424. x: double;
  425. begin
  426. Code:=0;
  427. x:=Number(S);
  428. if isNaN(x) or (X<>Int(X)) then
  429. Code:=1
  430. else if (x<MinSmallint) or (x>MaxSmallint) then
  431. Code:=2
  432. else
  433. SI:=Trunc(x);
  434. end;
  435. procedure val(const S: String; out C: Cardinal; out Code: Integer);
  436. var
  437. x: double;
  438. begin
  439. Code:=0;
  440. x:=Number(S);
  441. if isNaN(x) or (X<>Int(X)) then
  442. Code:=1
  443. else if (x<0) or (x>MaxCardinal) then
  444. Code:=2
  445. else
  446. C:=trunc(x);
  447. end;
  448. procedure val(const S: String; out B: Byte; out Code: Integer);
  449. var
  450. x: double;
  451. begin
  452. Code:=0;
  453. x:=Number(S);
  454. if isNaN(x) or (X<>Int(X)) then
  455. Code:=1
  456. else if (x<0) or (x>MaxByte) then
  457. Code:=2
  458. else
  459. B:=Trunc(x);
  460. end;
  461. procedure val(const S: String; out W: word; out Code: Integer);
  462. var
  463. x: double;
  464. begin
  465. Code:=0;
  466. x:=Number(S);
  467. if isNaN(x) then
  468. Code:=1
  469. else if (x<0) or (x>MaxWord) then
  470. Code:=2
  471. else
  472. W:=Trunc(x);
  473. end;
  474. procedure val(const S : String; out I : integer; out Code : Integer);
  475. var
  476. x: double;
  477. begin
  478. Code:=0;
  479. x:=Number(S);
  480. if isNaN(x) then
  481. Code:=1
  482. else if x>MaxInt then
  483. Code:=2
  484. else
  485. I:=Trunc(x);
  486. end;
  487. procedure val(const S : String; out d : double; out Code : Integer);
  488. Var
  489. x: double;
  490. begin
  491. x:=Number(S);
  492. if isNaN(x) then
  493. Code:=1
  494. else
  495. begin
  496. Code:=0;
  497. d:=x;
  498. end;
  499. end;
  500. function upcase(c : char) : char; assembler;
  501. asm
  502. return c.toUpperCase();
  503. end;
  504. function StringOfChar(c: Char; l: NativeInt): String;
  505. var
  506. i: Integer;
  507. begin
  508. asm
  509. if ((l>0) && c.repeat) return c.repeat(l);
  510. end;
  511. Result:='';
  512. for i:=1 to l do Result:=Result+c;
  513. end;
  514. function Assigned(const V: JSValue): boolean; assembler;
  515. asm
  516. return (V!=undefined) && (V!=null) && (!rtl.isArray(V) || (V.length > 0));
  517. end;
  518. function StrictEqual(const A: JSValue; const B): boolean; assembler;
  519. asm
  520. return A === B;
  521. end;
  522. function StrictInequal(const A: JSValue; const B): boolean; assembler;
  523. asm
  524. return A !== B;
  525. end;
  526. { TContainedObject }
  527. function TContainedObject.QueryInterface(const iid: TGuid; out obj): Integer;
  528. begin
  529. if GetInterface(iid,obj) then
  530. Result:=S_OK
  531. else
  532. Result:=Integer(E_NOINTERFACE);
  533. end;
  534. { TAggregatedObject }
  535. function TAggregatedObject.GetController: IUnknown;
  536. begin
  537. Result := IUnknown(fController);
  538. end;
  539. function TAggregatedObject.QueryInterface(const iid: TGuid; out obj): Integer;
  540. begin
  541. Result := IUnknown(fController).QueryInterface(iid, obj);
  542. end;
  543. function TAggregatedObject._AddRef: Integer;
  544. begin
  545. Result := IUnknown(fController)._AddRef;
  546. end;
  547. function TAggregatedObject._Release: Integer;
  548. begin
  549. Result := IUnknown(fController)._Release;
  550. end;
  551. constructor TAggregatedObject.Create(const aController: IUnknown);
  552. begin
  553. inherited Create;
  554. { do not keep a counted reference to the controller! }
  555. fController := Pointer(aController);
  556. end;
  557. { TInterfacedObject }
  558. function TInterfacedObject.QueryInterface(const iid: TGuid; out obj): Integer;
  559. begin
  560. if GetInterface(iid,obj) then
  561. Result:=S_OK
  562. else
  563. Result:=Integer(E_NOINTERFACE);
  564. end;
  565. function TInterfacedObject._AddRef: Integer;
  566. begin
  567. inc(fRefCount);
  568. Result:=fRefCount;
  569. end;
  570. function TInterfacedObject._Release: Integer;
  571. begin
  572. dec(fRefCount);
  573. Result:=fRefCount;
  574. if fRefCount=0 then
  575. Destroy;
  576. end;
  577. procedure TInterfacedObject.BeforeDestruction;
  578. begin
  579. if fRefCount<>0 then
  580. asm
  581. rtl.raiseE('EHeapMemoryError');
  582. end;
  583. end;
  584. { TObject }
  585. constructor TObject.Create;
  586. begin
  587. end;
  588. destructor TObject.Destroy;
  589. begin
  590. end;
  591. procedure TObject.Free;
  592. begin
  593. Destroy;
  594. end;
  595. class function TObject.ClassType: TClass; assembler;
  596. asm
  597. return this;
  598. end;
  599. class function TObject.ClassNameIs(const Name: string): boolean;
  600. begin
  601. Result:=SameText(Name,ClassName);
  602. end;
  603. class function TObject.InheritsFrom(aClass: TClass): boolean; assembler;
  604. asm
  605. return (aClass!=null) && ((this==aClass) || aClass.isPrototypeOf(this));
  606. end;
  607. procedure TObject.AfterConstruction;
  608. begin
  609. end;
  610. procedure TObject.BeforeDestruction;
  611. begin
  612. end;
  613. function TObject.GetInterface(const iid: TGuid; out obj): boolean;
  614. begin
  615. asm
  616. var i = iid.$intf;
  617. if (i){
  618. i = rtl.getIntfG(this,i.$guid,2);
  619. if (i){
  620. obj.set(i);
  621. return true;
  622. }
  623. }
  624. end;
  625. Result := GetInterfaceByStr(GUIDToString(iid),obj);
  626. end;
  627. function TObject.GetInterface(const iidstr: String; out obj): boolean;
  628. begin
  629. Result := GetInterfaceByStr(iidstr,obj);
  630. end;
  631. function TObject.GetInterfaceByStr(const iidstr: String; out obj): boolean;
  632. begin
  633. if (iidstr = IObjectInstance) then
  634. begin
  635. obj:=Self;
  636. exit(true);
  637. end;
  638. asm
  639. var i = rtl.getIntfG(this,iidstr,2);
  640. obj.set(i);
  641. return i!==null;
  642. end;
  643. Result:=false;
  644. end;
  645. function TObject.GetInterfaceWeak(const iid: TGuid; out obj): boolean;
  646. begin
  647. Result:=GetInterface(iid,obj);
  648. asm
  649. if (Result){
  650. var o = obj.get();
  651. if (o.$kind==='com'){
  652. o._Release();
  653. }
  654. }
  655. end;
  656. end;
  657. function TObject.Equals(Obj: TObject): boolean;
  658. begin
  659. Result:=Obj=Self;
  660. end;
  661. function TObject.ToString: String;
  662. begin
  663. Result:=ClassName;
  664. end;
  665. initialization
  666. ExitCode:=0; // set it here, so that WPO does not remove it
  667. end.