system.pas 20 KB

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