system.pas 20 KB

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