system.pas 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862
  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. function Lo(i: word): byte; overload;
  249. function Lo(i: smallint): byte; overload;
  250. function Lo(i: longword): word; overload;
  251. function Lo(i: longint): word; overload;
  252. function Hi(i: word): byte; overload;
  253. function Hi(i: smallint): byte; overload;
  254. function Hi(i: longword): word; overload;
  255. function Hi(i: longint): word; overload;
  256. {*****************************************************************************
  257. Other functions
  258. *****************************************************************************}
  259. procedure Write; varargs; // ToDo: should be compiler built-in function
  260. procedure Writeln; varargs; // ToDo: should be compiler built-in function
  261. Type
  262. TConsoleHandler = Procedure (S : JSValue; NewLine : Boolean);
  263. Function SetWriteCallBack(H : TConsoleHandler) : TConsoleHandler;
  264. function Assigned(const V: JSValue): boolean; assembler; overload;
  265. function StrictEqual(const A: JSValue; const B): boolean; assembler;
  266. function StrictInequal(const A: JSValue; const B): boolean; assembler;
  267. implementation
  268. type
  269. { TJSObj - simple access to JS Object }
  270. TJSObj = class external name 'Object'
  271. private
  272. function GetProperties(Name: String): JSValue; external name '[]';
  273. procedure SetProperties(Name: String; const AValue: JSValue); external name '[]';
  274. public
  275. //constructor new;
  276. //function hasOwnProperty(prop: String): boolean;
  277. property Properties[Name: String]: JSValue read GetProperties write SetProperties; default;
  278. end;
  279. // function parseInt(s: String; Radix: NativeInt): NativeInt; external name 'parseInt'; // may result NaN
  280. function isNaN(i: JSValue): boolean; external name 'isNaN'; // may result NaN
  281. // needed by ClassNameIs, the real SameText is in SysUtils
  282. function SameText(const s1, s2: String): Boolean; assembler;
  283. asm
  284. return s1.toLowerCase() == s2.toLowerCase();
  285. end;
  286. function ParamCount: Longint;
  287. begin
  288. if Assigned(OnParamCount) then
  289. Result:=OnParamCount()
  290. else
  291. Result:=0;
  292. end;
  293. function ParamStr(Index: Longint): String;
  294. begin
  295. if Assigned(OnParamStr) then
  296. Result:=OnParamStr(Index)
  297. else if Index=0 then
  298. Result:='js'
  299. else
  300. Result:='';
  301. end;
  302. function Frac(const A: Double): Double; assembler;
  303. asm
  304. return A % 1;
  305. end;
  306. function Odd(const A: Integer): Boolean; assembler;
  307. asm
  308. return A&1 != 0;
  309. end;
  310. function Random(const Range: Integer): Integer; assembler;
  311. asm
  312. return Math.floor(Math.random()*Range);
  313. end;
  314. function Sqr(const A: Integer): Integer; assembler;
  315. asm
  316. return A*A;
  317. end;
  318. function Sqr(const A: Double): Double; assembler;
  319. asm
  320. return A*A;
  321. end;
  322. function Trunc(const A: Double): NativeInt; assembler;
  323. asm
  324. if (!Math.trunc) {
  325. Math.trunc = function(v) {
  326. v = +v;
  327. if (!isFinite(v)) return v;
  328. return (v - v % 1) || (v < 0 ? -0 : v === 0 ? v : 0);
  329. };
  330. }
  331. $mod.Trunc = Math.trunc;
  332. return Math.trunc(A);
  333. end;
  334. function Copy(const S: string; Index, Size: Integer): String; assembler;
  335. asm
  336. if (Index<1) Index = 1;
  337. return (Size>0) ? S.substring(Index-1,Index+Size-1) : "";
  338. end;
  339. function Copy(const S: string; Index: Integer): String; assembler;
  340. asm
  341. if (Index<1) Index = 1;
  342. return S.substr(Index-1);
  343. end;
  344. procedure Delete(var S: String; Index, Size: Integer);
  345. var
  346. h: String;
  347. begin
  348. if (Index<1) or (Index>length(S)) or (Size<=0) then exit;
  349. h:=S;
  350. S:=copy(h,1,Index-1)+copy(h,Index+Size);
  351. end;
  352. function Pos(const Search, InString: String): Integer; assembler;
  353. asm
  354. return InString.indexOf(Search)+1;
  355. end;
  356. function Pos(const Search, InString: String; StartAt : Integer): Integer; assembler; overload;
  357. asm
  358. return InString.indexOf(Search,StartAt-1)+1;
  359. end;
  360. procedure Insert(const Insertion: String; var Target: String; Index: Integer);
  361. var
  362. t: String;
  363. begin
  364. if Insertion='' then exit;
  365. t:=Target;
  366. if Index<1 then
  367. Target:=Insertion+t
  368. else if Index>length(t) then
  369. Target:=t+Insertion
  370. else
  371. Target:=copy(t,1,Index-1)+Insertion+copy(t,Index,length(t));
  372. end;
  373. type
  374. TJSArguments = class external name 'arguments'
  375. private
  376. FLength: NativeInt; external name 'length';
  377. function GetElements(Index: NativeInt): JSValue; external name '[]';
  378. public
  379. property Length: NativeInt read FLength;
  380. property Elements[Index: NativeInt]: JSValue read GetElements; default;
  381. end;
  382. var
  383. WriteBuf: String;
  384. JSArguments: TJSArguments; external name 'arguments';
  385. WriteCallBack : TConsoleHandler;
  386. Function SetWriteCallBack(H : TConsoleHandler) : TConsoleHandler;
  387. begin
  388. Result:=WriteCallBack;
  389. WriteCallBack:=H;
  390. end;
  391. procedure Write;
  392. var
  393. i: Integer;
  394. begin
  395. for i:=0 to JSArguments.Length-1 do
  396. if Assigned(WriteCallBack) then
  397. WriteCallBack(JSArguments[i],False)
  398. else
  399. WriteBuf:=WriteBuf+String(JSArguments[i]);
  400. end;
  401. procedure Writeln;
  402. var
  403. i,l: Integer;
  404. s: String;
  405. begin
  406. L:=JSArguments.Length-1;
  407. if Assigned(WriteCallBack) then
  408. begin
  409. for i:=0 to L do
  410. WriteCallBack(JSArguments[i],I=L);
  411. end
  412. else
  413. begin
  414. s:=WriteBuf;
  415. for i:=0 to L do
  416. s:=s+String(JSArguments[i]);
  417. asm
  418. console.log(s);
  419. end;
  420. WriteBuf:='';
  421. end;
  422. end;
  423. function Int(const A: Double): double;
  424. begin
  425. // trunc contains fix for missing Math.trunc in IE
  426. Result:=Trunc(A);
  427. end;
  428. function Number(S: String): Double; external name 'Number';
  429. function valint(const S: String; MinVal, MaxVal: NativeInt; out Code: Integer): NativeInt;
  430. var
  431. x: double;
  432. begin
  433. x:=Number(S);
  434. if isNaN(x) then
  435. case copy(s,1,1) of
  436. '$': x:=Number('0x'+copy(S,2));
  437. '&': x:=Number('0o'+copy(S,2));
  438. '%': x:=Number('0b'+copy(S,2));
  439. else
  440. Code:=1;
  441. exit;
  442. end;
  443. if isNaN(x) or (X<>Int(X)) then
  444. Code:=1
  445. else if (x<MinVal) or (x>MaxVal) then
  446. Code:=2
  447. else
  448. begin
  449. Result:=Trunc(x);
  450. Code:=0;
  451. end;
  452. end;
  453. procedure val(const S: String; out NI : NativeInt; out Code: Integer);
  454. begin
  455. NI:=valint(S,low(NI),high(NI),Code);
  456. end;
  457. procedure val(const S: String; out NI: NativeUInt; out Code: Integer);
  458. var
  459. x : double;
  460. begin
  461. x:=Number(S);
  462. if isNaN(x) or (X<>Int(X)) or (X<0) then
  463. Code:=1
  464. else
  465. begin
  466. Code:=0;
  467. NI:=Trunc(x);
  468. end;
  469. end;
  470. procedure val(const S: String; out SI : ShortInt; out Code: Integer);
  471. begin
  472. SI:=valint(S,low(SI),high(SI),Code);
  473. end;
  474. procedure val(const S: String; out SI: smallint; out Code: Integer);
  475. begin
  476. SI:=valint(S,low(SI),high(SI),Code);
  477. end;
  478. procedure val(const S: String; out C: Cardinal; out Code: Integer);
  479. begin
  480. C:=valint(S,low(C),high(C),Code);
  481. end;
  482. procedure val(const S: String; out B: Byte; out Code: Integer);
  483. begin
  484. B:=valint(S,low(B),high(B),Code);
  485. end;
  486. procedure val(const S: String; out W: word; out Code: Integer);
  487. begin
  488. W:=valint(S,low(W),high(W),Code);
  489. end;
  490. procedure val(const S : String; out I : integer; out Code : Integer);
  491. begin
  492. I:=valint(S,low(I),high(I),Code);
  493. end;
  494. procedure val(const S : String; out d : double; out Code : Integer);
  495. Var
  496. x: double;
  497. begin
  498. x:=Number(S);
  499. if isNaN(x) then
  500. Code:=1
  501. else
  502. begin
  503. Code:=0;
  504. d:=x;
  505. end;
  506. end;
  507. procedure val(const S: String; out b: boolean; out Code: Integer);
  508. begin
  509. if SameText(S,'true') then
  510. begin
  511. Code:=0;
  512. b:=true;
  513. end
  514. else if SameText(S,'false') then
  515. begin
  516. Code:=0;
  517. b:=false;
  518. end
  519. else
  520. Code:=1;
  521. end;
  522. function upcase(c : char) : char; assembler;
  523. asm
  524. return c.toUpperCase();
  525. end;
  526. function StringOfChar(c: Char; l: NativeInt): String;
  527. var
  528. i: Integer;
  529. begin
  530. asm
  531. if ((l>0) && c.repeat) return c.repeat(l);
  532. end;
  533. Result:='';
  534. for i:=1 to l do Result:=Result+c;
  535. end;
  536. function Lo(i: word): byte;
  537. begin
  538. Result:=i and $ff;
  539. end;
  540. function Lo(i: smallint): byte;
  541. begin
  542. Result:=i and $ff;
  543. end;
  544. function Lo(i: longword): word;
  545. begin
  546. Result:=i and $ffff;
  547. end;
  548. function Lo(i: longint): word;
  549. begin
  550. Result:=i and $ffff;
  551. end;
  552. function Hi(i: word): byte;
  553. begin
  554. Result:=(i shr 8) and $ff;
  555. end;
  556. function Hi(i: smallint): byte;
  557. begin
  558. Result:=(i shr 8) and $ff;
  559. end;
  560. function Hi(i: longword): word;
  561. begin
  562. Result:=(i shr 16) and $ffff;
  563. end;
  564. function Hi(i: longint): word;
  565. begin
  566. Result:=(i shr 16) and $ffff;
  567. end;
  568. function Assigned(const V: JSValue): boolean; assembler;
  569. asm
  570. return (V!=undefined) && (V!=null) && (!rtl.isArray(V) || (V.length > 0));
  571. end;
  572. function StrictEqual(const A: JSValue; const B): boolean; assembler;
  573. asm
  574. return A === B;
  575. end;
  576. function StrictInequal(const A: JSValue; const B): boolean; assembler;
  577. asm
  578. return A !== B;
  579. end;
  580. { TContainedObject }
  581. function TContainedObject.QueryInterface(const iid: TGuid; out obj): Integer;
  582. begin
  583. if GetInterface(iid,obj) then
  584. Result:=S_OK
  585. else
  586. Result:=Integer(E_NOINTERFACE);
  587. end;
  588. { TAggregatedObject }
  589. function TAggregatedObject.GetController: IUnknown;
  590. begin
  591. Result := IUnknown(fController);
  592. end;
  593. function TAggregatedObject.QueryInterface(const iid: TGuid; out obj): Integer;
  594. begin
  595. Result := IUnknown(fController).QueryInterface(iid, obj);
  596. end;
  597. function TAggregatedObject._AddRef: Integer;
  598. begin
  599. Result := IUnknown(fController)._AddRef;
  600. end;
  601. function TAggregatedObject._Release: Integer;
  602. begin
  603. Result := IUnknown(fController)._Release;
  604. end;
  605. constructor TAggregatedObject.Create(const aController: IUnknown);
  606. begin
  607. inherited Create;
  608. { do not keep a counted reference to the controller! }
  609. fController := Pointer(aController);
  610. end;
  611. { TInterfacedObject }
  612. function TInterfacedObject.QueryInterface(const iid: TGuid; out obj): Integer;
  613. begin
  614. if GetInterface(iid,obj) then
  615. Result:=S_OK
  616. else
  617. Result:=Integer(E_NOINTERFACE);
  618. end;
  619. function TInterfacedObject._AddRef: Integer;
  620. begin
  621. inc(fRefCount);
  622. Result:=fRefCount;
  623. end;
  624. function TInterfacedObject._Release: Integer;
  625. begin
  626. dec(fRefCount);
  627. Result:=fRefCount;
  628. if fRefCount=0 then
  629. Destroy;
  630. end;
  631. procedure TInterfacedObject.BeforeDestruction;
  632. begin
  633. if fRefCount<>0 then
  634. asm
  635. rtl.raiseE('EHeapMemoryError');
  636. end;
  637. end;
  638. { TObject }
  639. constructor TObject.Create;
  640. begin
  641. end;
  642. destructor TObject.Destroy;
  643. begin
  644. end;
  645. procedure TObject.Free;
  646. begin
  647. Destroy;
  648. end;
  649. class function TObject.ClassType: TClass; assembler;
  650. asm
  651. return this;
  652. end;
  653. class function TObject.ClassNameIs(const Name: string): boolean;
  654. begin
  655. Result:=SameText(Name,ClassName);
  656. end;
  657. class function TObject.InheritsFrom(aClass: TClass): boolean; assembler;
  658. asm
  659. return (aClass!=null) && ((this==aClass) || aClass.isPrototypeOf(this));
  660. end;
  661. procedure TObject.AfterConstruction;
  662. begin
  663. end;
  664. procedure TObject.BeforeDestruction;
  665. begin
  666. end;
  667. function TObject.GetInterface(const iid: TGuid; out obj): boolean;
  668. begin
  669. asm
  670. var i = iid.$intf;
  671. if (i){
  672. // iid is the private TGuid of an interface
  673. i = rtl.getIntfG(this,i.$guid,2);
  674. if (i){
  675. obj.set(i);
  676. return true;
  677. }
  678. }
  679. end;
  680. Result := GetInterfaceByStr(GUIDToString(iid),obj);
  681. end;
  682. function TObject.GetInterface(const iidstr: String; out obj): boolean;
  683. begin
  684. Result := GetInterfaceByStr(iidstr,obj);
  685. end;
  686. function TObject.GetInterfaceByStr(const iidstr: String; out obj): boolean;
  687. begin
  688. if not TJSObj(IObjectInstance)['$str'] then
  689. TJSObj(IObjectInstance)['$str']:=GUIDToString(IObjectInstance);
  690. if iidstr = TJSObj(IObjectInstance)['$str'] then
  691. begin
  692. obj:=Self;
  693. exit(true);
  694. end;
  695. asm
  696. var i = rtl.getIntfG(this,iidstr,2);
  697. obj.set(i);
  698. return i!==null;
  699. end;
  700. Result:=false;
  701. end;
  702. function TObject.GetInterfaceWeak(const iid: TGuid; out obj): boolean;
  703. begin
  704. Result:=GetInterface(iid,obj);
  705. asm
  706. if (Result){
  707. var o = obj.get();
  708. if (o.$kind==='com'){
  709. o._Release();
  710. }
  711. }
  712. end;
  713. end;
  714. function TObject.Equals(Obj: TObject): boolean;
  715. begin
  716. Result:=Obj=Self;
  717. end;
  718. function TObject.ToString: String;
  719. begin
  720. Result:=ClassName;
  721. end;
  722. initialization
  723. ExitCode:=0; // set it here, so that WPO does not remove it
  724. end.