system.pas 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888
  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. Array of const support
  181. *****************************************************************************}
  182. const
  183. vtInteger = 0;
  184. vtBoolean = 1;
  185. //vtChar = 2; // Delphi/FPC: ansichar
  186. vtExtended = 3; // Note: double in pas2js, PExtended in Delphi/FPC
  187. //vtString = 4; // Delphi/FPC: PShortString
  188. vtPointer = 5;
  189. //vtPChar = 6;
  190. vtObject = 7;
  191. vtClass = 8;
  192. vtWideChar = 9;
  193. //vtPWideChar = 10;
  194. //vtAnsiString = 11;
  195. vtCurrency = 12; // Note: currency in pas2js, PCurrency in Delphi/FPC
  196. //vtVariant = 13;
  197. vtInterface = 14;
  198. //vtWideString = 15;
  199. //vtInt64 = 16;
  200. //vtQWord = 17;
  201. vtUnicodeString = 18;
  202. // only pas2js, not in Delphi/FPC:
  203. vtNativeInt = 19;
  204. vtJSValue = 20;
  205. type
  206. PVarRec = ^TVarRec;
  207. TVarRec = record
  208. VType: byte;
  209. VJSValue: JSValue;
  210. VInteger: LongInt external name 'VJSValue';
  211. VBoolean: Boolean external name 'VJSValue';
  212. VExtended: Double external name 'VJSValue';
  213. VPointer: Pointer external name 'VJSValue';
  214. VObject: TObject external name 'VJSValue';
  215. VClass: TClass external name 'VJSValue';
  216. VWideChar: WideChar external name 'VJSValue';
  217. VCurrency: Currency external name 'VJSValue';
  218. VInterface: Pointer external name 'VJSValue';
  219. VUnicodeString: UnicodeString external name 'VJSValue';
  220. VNativeInt: NativeInt external name 'VJSValue';
  221. end;
  222. TVarRecArray = array of TVarRec;
  223. function VarRecs: TVarRecArray; varargs;
  224. {*****************************************************************************
  225. Init / Exit / ExitProc
  226. *****************************************************************************}
  227. var
  228. ExitCode: Integer; external name 'rtl.exitcode';
  229. IsConsole: Boolean = {$IFDEF NodeJS}true{$ELSE}false{$ENDIF};
  230. FirstDotAtFileNameStartIsExtension : Boolean = False;
  231. type
  232. TOnParamCount = function: Longint;
  233. TOnParamStr = function(Index: Longint): String;
  234. var
  235. OnParamCount: TOnParamCount;
  236. OnParamStr: TOnParamStr;
  237. function ParamCount: Longint;
  238. function ParamStr(Index: Longint): String;
  239. {*****************************************************************************
  240. Math
  241. *****************************************************************************}
  242. const
  243. PI: Double; external name 'Math.PI';
  244. MathE: Double; external name 'Math.E'; // Euler's number
  245. MathLN10: Double; external name 'Math.LN10'; // ln(10)
  246. MathLN2: Double; external name 'Math.LN2'; // ln(2)
  247. MathLog10E: Double; external name 'Math.Log10E'; // log10(e)
  248. MathLog2E: Double; external name 'Math.LOG2E'; // log2(e)
  249. MathSQRT1_2: Double; external name 'Math.SQRT1_2'; // sqrt(0.5)
  250. MathSQRT2: Double; external name 'Math.SQRT2'; // sqrt(2)
  251. function Abs(const A: integer): integer; overload; external name 'Math.abs';
  252. function Abs(const A: NativeInt): integer; overload; external name 'Math.abs';
  253. function Abs(const A: Double): Double; overload; external name 'Math.abs';
  254. function ArcTan(const A: Double): Double; external name 'Math.atan';
  255. function ArcTan2(const A,B: Double): Double; external name 'Math.atan2';
  256. function Cos(const A: Double): Double; external name 'Math.cos';
  257. function Exp(const A: Double): Double; external name 'Math.exp';
  258. function Frac(const A: Double): Double; assembler;
  259. function Ln(const A: Double): Double; external name 'Math.log';
  260. function Odd(const A: Integer): Boolean; assembler;
  261. function Random(const Range: Integer): Integer; overload; assembler;
  262. function Random: Double; overload; external name 'Math.random';
  263. function Round(const A: Double): NativeInt; external name 'Math.round';
  264. function Sin(const A: Double): Double; external name 'Math.sin';
  265. function Sqr(const A: Integer): Integer; assembler; overload;
  266. function Sqr(const A: Double): Double; assembler; overload;
  267. function sqrt(const A: Double): Double; external name 'Math.sqrt';
  268. function Trunc(const A: Double): NativeInt;
  269. {*****************************************************************************
  270. String functions
  271. *****************************************************************************}
  272. const
  273. DefaultTextLineBreakStyle : TTextLineBreakStyle = tlbsLF;
  274. function Int(const A: Double): double;
  275. function Copy(const S: string; Index, Size: Integer): String; assembler; overload;
  276. function Copy(const S: string; Index: Integer): String; assembler; overload;
  277. procedure Delete(var S: String; Index, Size: Integer); overload;
  278. function Pos(const Search, InString: String): Integer; assembler; overload;
  279. function Pos(const Search, InString: String; StartAt : Integer): Integer; assembler; overload;
  280. procedure Insert(const Insertion: String; var Target: String; Index: Integer); overload;
  281. function upcase(c : char) : char; assembler;
  282. function HexStr(Val: NativeInt; cnt: byte): string; external name 'rtl.hexStr'; overload;
  283. procedure val(const S: String; out NI : NativeInt; out Code: Integer); overload;
  284. procedure val(const S: String; out NI : NativeUInt; out Code: Integer); overload;
  285. procedure val(const S: String; out SI : ShortInt; out Code: Integer); overload;
  286. procedure val(const S: String; out B : Byte; out Code: Integer); overload;
  287. procedure val(const S: String; out SI : smallint; out Code: Integer); overload;
  288. procedure val(const S: String; out W : word; out Code : Integer); overload;
  289. procedure val(const S: String; out I : integer; out Code : Integer); overload;
  290. procedure val(const S: String; out C : Cardinal; out Code: Integer); overload;
  291. procedure val(const S: String; out d : double; out Code : Integer); overload;
  292. procedure val(const S: String; out b : boolean; out Code: Integer); overload;
  293. function StringOfChar(c: Char; l: NativeInt): String;
  294. {*****************************************************************************
  295. Other functions
  296. *****************************************************************************}
  297. procedure Write; varargs; // ToDo: should be compiler built-in function
  298. procedure Writeln; varargs; // ToDo: should be compiler built-in function
  299. Type
  300. TConsoleHandler = Procedure (S : JSValue; NewLine : Boolean);
  301. Function SetWriteCallBack(H : TConsoleHandler) : TConsoleHandler;
  302. function Assigned(const V: JSValue): boolean; assembler; overload;
  303. function StrictEqual(const A: JSValue; const B): boolean; assembler;
  304. function StrictInequal(const A: JSValue; const B): boolean; assembler;
  305. implementation
  306. type
  307. { TJSObj - simple access to JS Object }
  308. TJSObj = class external name 'Object'
  309. private
  310. function GetProperties(Name: String): JSValue; external name '[]';
  311. procedure SetProperties(Name: String; const AValue: JSValue); external name '[]';
  312. public
  313. //constructor new;
  314. //function hasOwnProperty(prop: String): boolean;
  315. property Properties[Name: String]: JSValue read GetProperties write SetProperties; default;
  316. end;
  317. TJSArray = class external name 'Array'
  318. public
  319. //length: nativeint;
  320. //constructor new; overload;
  321. function push(aElement : JSValue) : NativeInt; varargs;
  322. end;
  323. TJSArguments = class external name 'arguments'
  324. private
  325. FLength: NativeInt; external name 'length';
  326. function GetElements(Index: NativeInt): JSValue; external name '[]';
  327. public
  328. property Length: NativeInt read FLength;
  329. property Elements[Index: NativeInt]: JSValue read GetElements; default;
  330. end;
  331. var
  332. JSArguments: TJSArguments; external name 'arguments';
  333. // function parseInt(s: String; Radix: NativeInt): NativeInt; external name 'parseInt'; // may result NaN
  334. function isNaN(i: JSValue): boolean; external name 'isNaN'; // may result NaN
  335. // needed by ClassNameIs, the real SameText is in SysUtils
  336. function SameText(const s1, s2: String): Boolean; assembler;
  337. asm
  338. return s1.toLowerCase() == s2.toLowerCase();
  339. end;
  340. function VarRecs: TVarRecArray;
  341. var
  342. i: nativeint;
  343. v: PVarRec;
  344. begin
  345. Result:=nil;
  346. while i<JSArguments.Length do
  347. begin
  348. new(v);
  349. v^.VType:=byte(JSArguments[i]);
  350. inc(i);
  351. v^.VJSValue:=JSArguments[i];
  352. inc(i);
  353. TJSArray(Result).push(v^);
  354. end;
  355. end;
  356. function ParamCount: Longint;
  357. begin
  358. if Assigned(OnParamCount) then
  359. Result:=OnParamCount()
  360. else
  361. Result:=0;
  362. end;
  363. function ParamStr(Index: Longint): String;
  364. begin
  365. if Assigned(OnParamStr) then
  366. Result:=OnParamStr(Index)
  367. else if Index=0 then
  368. Result:='js'
  369. else
  370. Result:='';
  371. end;
  372. function Frac(const A: Double): Double; assembler;
  373. asm
  374. return A % 1;
  375. end;
  376. function Odd(const A: Integer): Boolean; assembler;
  377. asm
  378. return A&1 != 0;
  379. end;
  380. function Random(const Range: Integer): Integer; assembler;
  381. asm
  382. return Math.floor(Math.random()*Range);
  383. end;
  384. function Sqr(const A: Integer): Integer; assembler;
  385. asm
  386. return A*A;
  387. end;
  388. function Sqr(const A: Double): Double; assembler;
  389. asm
  390. return A*A;
  391. end;
  392. function Trunc(const A: Double): NativeInt; assembler;
  393. asm
  394. if (!Math.trunc) {
  395. Math.trunc = function(v) {
  396. v = +v;
  397. if (!isFinite(v)) return v;
  398. return (v - v % 1) || (v < 0 ? -0 : v === 0 ? v : 0);
  399. };
  400. }
  401. $mod.Trunc = Math.trunc;
  402. return Math.trunc(A);
  403. end;
  404. function Copy(const S: string; Index, Size: Integer): String; assembler;
  405. asm
  406. if (Index<1) Index = 1;
  407. return (Size>0) ? S.substring(Index-1,Index+Size-1) : "";
  408. end;
  409. function Copy(const S: string; Index: Integer): String; assembler;
  410. asm
  411. if (Index<1) Index = 1;
  412. return S.substr(Index-1);
  413. end;
  414. procedure Delete(var S: String; Index, Size: Integer);
  415. var
  416. h: String;
  417. begin
  418. if (Index<1) or (Index>length(S)) or (Size<=0) then exit;
  419. h:=S;
  420. S:=copy(h,1,Index-1)+copy(h,Index+Size);
  421. end;
  422. function Pos(const Search, InString: String): Integer; assembler;
  423. asm
  424. return InString.indexOf(Search)+1;
  425. end;
  426. function Pos(const Search, InString: String; StartAt : Integer): Integer; assembler; overload;
  427. asm
  428. return InString.indexOf(Search,StartAt-1)+1;
  429. end;
  430. procedure Insert(const Insertion: String; var Target: String; Index: Integer);
  431. var
  432. t: String;
  433. begin
  434. if Insertion='' then exit;
  435. t:=Target;
  436. if Index<1 then
  437. Target:=Insertion+t
  438. else if Index>length(t) then
  439. Target:=t+Insertion
  440. else
  441. Target:=copy(t,1,Index-1)+Insertion+copy(t,Index,length(t));
  442. end;
  443. var
  444. WriteBuf: String;
  445. WriteCallBack : TConsoleHandler;
  446. Function SetWriteCallBack(H : TConsoleHandler) : TConsoleHandler;
  447. begin
  448. Result:=WriteCallBack;
  449. WriteCallBack:=H;
  450. end;
  451. procedure Write;
  452. var
  453. i: Integer;
  454. begin
  455. for i:=0 to JSArguments.Length-1 do
  456. if Assigned(WriteCallBack) then
  457. WriteCallBack(JSArguments[i],False)
  458. else
  459. WriteBuf:=WriteBuf+String(JSArguments[i]);
  460. end;
  461. procedure Writeln;
  462. var
  463. i,l: Integer;
  464. s: String;
  465. begin
  466. L:=JSArguments.Length-1;
  467. if Assigned(WriteCallBack) then
  468. begin
  469. for i:=0 to L do
  470. WriteCallBack(JSArguments[i],I=L);
  471. end
  472. else
  473. begin
  474. s:=WriteBuf;
  475. for i:=0 to L do
  476. s:=s+String(JSArguments[i]);
  477. asm
  478. console.log(s);
  479. end;
  480. WriteBuf:='';
  481. end;
  482. end;
  483. function Int(const A: Double): double;
  484. begin
  485. // trunc contains fix for missing Math.trunc in IE
  486. Result:=Trunc(A);
  487. end;
  488. function Number(S: String): Double; external name 'Number';
  489. function valint(const S: String; MinVal, MaxVal: NativeInt; out Code: Integer): NativeInt;
  490. var
  491. x: double;
  492. begin
  493. x:=Number(S);
  494. if isNaN(x) then
  495. case copy(s,1,1) of
  496. '$': x:=Number('0x'+copy(S,2));
  497. '&': x:=Number('0o'+copy(S,2));
  498. '%': x:=Number('0b'+copy(S,2));
  499. else
  500. Code:=1;
  501. exit;
  502. end;
  503. if isNaN(x) or (X<>Int(X)) then
  504. Code:=1
  505. else if (x<MinVal) or (x>MaxVal) then
  506. Code:=2
  507. else
  508. begin
  509. Result:=Trunc(x);
  510. Code:=0;
  511. end;
  512. end;
  513. procedure val(const S: String; out NI : NativeInt; out Code: Integer);
  514. begin
  515. NI:=valint(S,low(NI),high(NI),Code);
  516. end;
  517. procedure val(const S: String; out NI: NativeUInt; out Code: Integer);
  518. var
  519. x : double;
  520. begin
  521. x:=Number(S);
  522. if isNaN(x) or (X<>Int(X)) or (X<0) then
  523. Code:=1
  524. else
  525. begin
  526. Code:=0;
  527. NI:=Trunc(x);
  528. end;
  529. end;
  530. procedure val(const S: String; out SI : ShortInt; out Code: Integer);
  531. begin
  532. SI:=valint(S,low(SI),high(SI),Code);
  533. end;
  534. procedure val(const S: String; out SI: smallint; out Code: Integer);
  535. begin
  536. SI:=valint(S,low(SI),high(SI),Code);
  537. end;
  538. procedure val(const S: String; out C: Cardinal; out Code: Integer);
  539. begin
  540. C:=valint(S,low(C),high(C),Code);
  541. end;
  542. procedure val(const S: String; out B: Byte; out Code: Integer);
  543. begin
  544. B:=valint(S,low(B),high(B),Code);
  545. end;
  546. procedure val(const S: String; out W: word; out Code: Integer);
  547. begin
  548. W:=valint(S,low(W),high(W),Code);
  549. end;
  550. procedure val(const S : String; out I : integer; out Code : Integer);
  551. begin
  552. I:=valint(S,low(I),high(I),Code);
  553. end;
  554. procedure val(const S : String; out d : double; out Code : Integer);
  555. Var
  556. x: double;
  557. begin
  558. x:=Number(S);
  559. if isNaN(x) then
  560. Code:=1
  561. else
  562. begin
  563. Code:=0;
  564. d:=x;
  565. end;
  566. end;
  567. procedure val(const S: String; out b: boolean; out Code: Integer);
  568. begin
  569. if SameText(S,'true') then
  570. begin
  571. Code:=0;
  572. b:=true;
  573. end
  574. else if SameText(S,'false') then
  575. begin
  576. Code:=0;
  577. b:=false;
  578. end
  579. else
  580. Code:=1;
  581. end;
  582. function upcase(c : char) : char; assembler;
  583. asm
  584. return c.toUpperCase();
  585. end;
  586. function StringOfChar(c: Char; l: NativeInt): String;
  587. var
  588. i: Integer;
  589. begin
  590. asm
  591. if ((l>0) && c.repeat) return c.repeat(l);
  592. end;
  593. Result:='';
  594. for i:=1 to l do Result:=Result+c;
  595. end;
  596. function Assigned(const V: JSValue): boolean; assembler;
  597. asm
  598. return (V!=undefined) && (V!=null) && (!rtl.isArray(V) || (V.length > 0));
  599. end;
  600. function StrictEqual(const A: JSValue; const B): boolean; assembler;
  601. asm
  602. return A === B;
  603. end;
  604. function StrictInequal(const A: JSValue; const B): boolean; assembler;
  605. asm
  606. return A !== B;
  607. end;
  608. { TContainedObject }
  609. function TContainedObject.QueryInterface(const iid: TGuid; out obj): Integer;
  610. begin
  611. if GetInterface(iid,obj) then
  612. Result:=S_OK
  613. else
  614. Result:=Integer(E_NOINTERFACE);
  615. end;
  616. { TAggregatedObject }
  617. function TAggregatedObject.GetController: IUnknown;
  618. begin
  619. Result := IUnknown(fController);
  620. end;
  621. function TAggregatedObject.QueryInterface(const iid: TGuid; out obj): Integer;
  622. begin
  623. Result := IUnknown(fController).QueryInterface(iid, obj);
  624. end;
  625. function TAggregatedObject._AddRef: Integer;
  626. begin
  627. Result := IUnknown(fController)._AddRef;
  628. end;
  629. function TAggregatedObject._Release: Integer;
  630. begin
  631. Result := IUnknown(fController)._Release;
  632. end;
  633. constructor TAggregatedObject.Create(const aController: IUnknown);
  634. begin
  635. inherited Create;
  636. { do not keep a counted reference to the controller! }
  637. fController := Pointer(aController);
  638. end;
  639. { TInterfacedObject }
  640. function TInterfacedObject.QueryInterface(const iid: TGuid; out obj): Integer;
  641. begin
  642. if GetInterface(iid,obj) then
  643. Result:=S_OK
  644. else
  645. Result:=Integer(E_NOINTERFACE);
  646. end;
  647. function TInterfacedObject._AddRef: Integer;
  648. begin
  649. inc(fRefCount);
  650. Result:=fRefCount;
  651. end;
  652. function TInterfacedObject._Release: Integer;
  653. begin
  654. dec(fRefCount);
  655. Result:=fRefCount;
  656. if fRefCount=0 then
  657. Destroy;
  658. end;
  659. procedure TInterfacedObject.BeforeDestruction;
  660. begin
  661. if fRefCount<>0 then
  662. asm
  663. rtl.raiseE('EHeapMemoryError');
  664. end;
  665. end;
  666. { TObject }
  667. constructor TObject.Create;
  668. begin
  669. end;
  670. destructor TObject.Destroy;
  671. begin
  672. end;
  673. procedure TObject.Free;
  674. begin
  675. Destroy;
  676. end;
  677. class function TObject.ClassType: TClass; assembler;
  678. asm
  679. return this;
  680. end;
  681. class function TObject.ClassNameIs(const Name: string): boolean;
  682. begin
  683. Result:=SameText(Name,ClassName);
  684. end;
  685. class function TObject.InheritsFrom(aClass: TClass): boolean; assembler;
  686. asm
  687. return (aClass!=null) && ((this==aClass) || aClass.isPrototypeOf(this));
  688. end;
  689. procedure TObject.AfterConstruction;
  690. begin
  691. end;
  692. procedure TObject.BeforeDestruction;
  693. begin
  694. end;
  695. function TObject.GetInterface(const iid: TGuid; out obj): boolean;
  696. begin
  697. asm
  698. var i = iid.$intf;
  699. if (i){
  700. // iid is the private TGuid of an interface
  701. i = rtl.getIntfG(this,i.$guid,2);
  702. if (i){
  703. obj.set(i);
  704. return true;
  705. }
  706. }
  707. end;
  708. Result := GetInterfaceByStr(GUIDToString(iid),obj);
  709. end;
  710. function TObject.GetInterface(const iidstr: String; out obj): boolean;
  711. begin
  712. Result := GetInterfaceByStr(iidstr,obj);
  713. end;
  714. function TObject.GetInterfaceByStr(const iidstr: String; out obj): boolean;
  715. begin
  716. if not TJSObj(IObjectInstance)['$str'] then
  717. TJSObj(IObjectInstance)['$str']:=GUIDToString(IObjectInstance);
  718. if iidstr = TJSObj(IObjectInstance)['$str'] then
  719. begin
  720. obj:=Self;
  721. exit(true);
  722. end;
  723. asm
  724. var i = rtl.getIntfG(this,iidstr,2);
  725. obj.set(i);
  726. return i!==null;
  727. end;
  728. Result:=false;
  729. end;
  730. function TObject.GetInterfaceWeak(const iid: TGuid; out obj): boolean;
  731. begin
  732. Result:=GetInterface(iid,obj);
  733. asm
  734. if (Result){
  735. var o = obj.get();
  736. if (o.$kind==='com'){
  737. o._Release();
  738. }
  739. }
  740. end;
  741. end;
  742. function TObject.Equals(Obj: TObject): boolean;
  743. begin
  744. Result:=Obj=Self;
  745. end;
  746. function TObject.ToString: String;
  747. begin
  748. Result:=ClassName;
  749. end;
  750. initialization
  751. ExitCode:=0; // set it here, so that WPO does not remove it
  752. end.