123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888 |
- {
- This file is part of the Pas2JS run time library.
- Copyright (c) 2018 by Mattias Gaertner
- See the file COPYING.FPC, included in this distribution,
- for details about the copyright.
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- **********************************************************************}
- unit System;
- {$mode objfpc}
- {$modeswitch externalclass}
- interface
- {$IFDEF NodeJS}
- var
- LineEnding: string = #10;
- sLineBreak: string = #10;
- {$ELSE}
- const
- LineEnding = #10;
- sLineBreak = LineEnding;
- {$ENDIF}
- Var
- PathDelim : Char = '/';
- AllowDirectorySeparators : Set of Char = ['/'];
- AllowDriveSeparators : Set of Char = [':'];
- ExtensionSeparator : Char = '.';
- const
- MaxSmallint = 32767;
- MinSmallint = -32768;
- MaxShortInt = 127;
- MinShortInt = -128;
- MaxByte = $FF;
- MaxWord = $FFFF;
- MaxLongint = $7fffffff;
- MaxCardinal = LongWord($ffffffff);
- Maxint = MaxLongint;
- IsMultiThread = false;
- {*****************************************************************************
- Base types
- *****************************************************************************}
- type
- Integer = LongInt;
- Cardinal = LongWord;
- DWord = LongWord;
- SizeInt = NativeInt;
- SizeUInt = NativeUInt;
- PtrInt = NativeInt;
- PtrUInt = NativeUInt;
- ValSInt = NativeInt;
- ValUInt = NativeUInt;
- ValReal = Double;
- Real = type Double;
- Extended = type Double;
- TDateTime = type double;
- TTime = type TDateTime;
- TDate = type TDateTime;
- Int64 = type NativeInt unimplemented; // only 53 bits at runtime
- UInt64 = type NativeUInt unimplemented; // only 52 bits at runtime
- QWord = type NativeUInt unimplemented; // only 52 bits at runtime
- Single = type Double unimplemented;
- Comp = type NativeInt unimplemented;
- NativeLargeInt = NativeInt;
- NativeLargeUInt = NativeUInt;
- UnicodeString = type String;
- WideString = type String;
- WideChar = char;
- UnicodeChar = char;
- TDynArrayIndex = NativeInt;
- TTextLineBreakStyle = (tlbsLF,tlbsCRLF,tlbsCR);
- {*****************************************************************************
- TObject, TClass, IUnknown, IInterface, TInterfacedObject
- *****************************************************************************}
- type
- TGuid = record
- D1: DWord;
- D2: word;
- D3: word;
- D4: array[0..7] of byte;
- end;
- TGUIDString = type string;
- TClass = class of TObject;
- { TObject }
- TObject = class
- private
- class var FClassName: String; external name '$classname';
- class var FClassParent: TClass; external name '$ancestor';
- class var FUnitName: String; external name '$module.$name';
- public
- constructor Create;
- destructor Destroy; virtual;
- // Free is using compiler magic.
- // Reasons:
- // 1. In JS calling obj.Free when obj=nil would crash.
- // 2. In JS freeing memory requires to set all references to nil.
- // Therefore any obj.free call is replaced by the compiler with some rtl magic.
- procedure Free;
- class function ClassType: TClass; assembler;
- class property ClassName: String read FClassName;
- class function ClassNameIs(const Name: string): boolean;
- class property ClassParent: TClass read FClassParent;
- class function InheritsFrom(aClass: TClass): boolean; assembler;
- class property UnitName: String read FUnitName;
- procedure AfterConstruction; virtual;
- procedure BeforeDestruction; virtual;
- function GetInterface(const iid: TGuid; out obj): boolean;
- function GetInterface(const iidstr: String; out obj): boolean; inline;
- function GetInterfaceByStr(const iidstr: String; out obj): boolean;
- function GetInterfaceWeak(const iid: TGuid; out obj): boolean; // equal to GetInterface but the interface returned is not referenced
- function Equals(Obj: TObject): boolean; virtual;
- function ToString: String; virtual;
- end;
- const
- { IInterface }
- S_OK = 0;
- S_FALSE = 1;
- E_NOINTERFACE = -2147467262; // FPC: longint($80004002)
- E_UNEXPECTED = -2147418113; // FPC: longint($8000FFFF)
- E_NOTIMPL = -2147467263; // FPC: longint($80004001)
- type
- {$Interfaces COM}
- IUnknown = interface
- ['{00000000-0000-0000-C000-000000000046}']
- function QueryInterface(const iid: TGuid; out obj): Integer;
- function _AddRef: Integer;
- function _Release: Integer;
- end;
- IInterface = IUnknown;
- {$M+}
- IInvokable = interface(IInterface)
- end;
- {$M-}
- { Enumerator support }
- IEnumerator = interface(IInterface)
- function GetCurrent: TObject;
- function MoveNext: Boolean;
- procedure Reset;
- property Current: TObject read GetCurrent;
- end;
- IEnumerable = interface(IInterface)
- function GetEnumerator: IEnumerator;
- end;
- { TInterfacedObject }
- TInterfacedObject = class(TObject,IUnknown)
- protected
- fRefCount: Integer;
- { implement methods of IUnknown }
- function QueryInterface(const iid: TGuid; out obj): Integer; virtual;
- function _AddRef: Integer; virtual;
- function _Release: Integer; virtual;
- public
- procedure BeforeDestruction; override;
- property RefCount: Integer read fRefCount;
- end;
- TInterfacedClass = class of TInterfacedObject;
- { TAggregatedObject - sub or satellite object using same interface as controller }
- TAggregatedObject = class(TObject)
- private
- fController: Pointer;
- function GetController: IUnknown;
- protected
- { implement methods of IUnknown }
- function QueryInterface(const iid: TGuid; out obj): Integer; virtual;
- function _AddRef: Integer; virtual;
- function _Release: Integer; virtual;
- public
- constructor Create(const aController: IUnknown); reintroduce;
- property Controller: IUnknown read GetController;
- end;
- { TContainedObject }
- TContainedObject = class(TAggregatedObject,IInterface)
- protected
- function QueryInterface(const iid: TGuid; out obj): Integer; override;
- end;
- const
- { for safe as operator support }
- IObjectInstance: TGuid = '{D91C9AF4-3C93-420F-A303-BF5BA82BFD23}';
- function GUIDToString(const GUID: TGUID): string; external name 'rtl.guidrToStr';
- {*****************************************************************************
- Array of const support
- *****************************************************************************}
- const
- vtInteger = 0;
- vtBoolean = 1;
- //vtChar = 2; // Delphi/FPC: ansichar
- vtExtended = 3; // Note: double in pas2js, PExtended in Delphi/FPC
- //vtString = 4; // Delphi/FPC: PShortString
- vtPointer = 5;
- //vtPChar = 6;
- vtObject = 7;
- vtClass = 8;
- vtWideChar = 9;
- //vtPWideChar = 10;
- //vtAnsiString = 11;
- vtCurrency = 12; // Note: currency in pas2js, PCurrency in Delphi/FPC
- //vtVariant = 13;
- vtInterface = 14;
- //vtWideString = 15;
- //vtInt64 = 16;
- //vtQWord = 17;
- vtUnicodeString = 18;
- // only pas2js, not in Delphi/FPC:
- vtNativeInt = 19;
- vtJSValue = 20;
- type
- PVarRec = ^TVarRec;
- TVarRec = record
- VType: byte;
- VJSValue: JSValue;
- VInteger: LongInt external name 'VJSValue';
- VBoolean: Boolean external name 'VJSValue';
- VExtended: Double external name 'VJSValue';
- VPointer: Pointer external name 'VJSValue';
- VObject: TObject external name 'VJSValue';
- VClass: TClass external name 'VJSValue';
- VWideChar: WideChar external name 'VJSValue';
- VCurrency: Currency external name 'VJSValue';
- VInterface: Pointer external name 'VJSValue';
- VUnicodeString: UnicodeString external name 'VJSValue';
- VNativeInt: NativeInt external name 'VJSValue';
- end;
- TVarRecArray = array of TVarRec;
- function VarRecs: TVarRecArray; varargs;
- {*****************************************************************************
- Init / Exit / ExitProc
- *****************************************************************************}
- var
- ExitCode: Integer; external name 'rtl.exitcode';
- IsConsole: Boolean = {$IFDEF NodeJS}true{$ELSE}false{$ENDIF};
- FirstDotAtFileNameStartIsExtension : Boolean = False;
- type
- TOnParamCount = function: Longint;
- TOnParamStr = function(Index: Longint): String;
- var
- OnParamCount: TOnParamCount;
- OnParamStr: TOnParamStr;
- function ParamCount: Longint;
- function ParamStr(Index: Longint): String;
- {*****************************************************************************
- Math
- *****************************************************************************}
- const
- PI: Double; external name 'Math.PI';
- MathE: Double; external name 'Math.E'; // Euler's number
- MathLN10: Double; external name 'Math.LN10'; // ln(10)
- MathLN2: Double; external name 'Math.LN2'; // ln(2)
- MathLog10E: Double; external name 'Math.Log10E'; // log10(e)
- MathLog2E: Double; external name 'Math.LOG2E'; // log2(e)
- MathSQRT1_2: Double; external name 'Math.SQRT1_2'; // sqrt(0.5)
- MathSQRT2: Double; external name 'Math.SQRT2'; // sqrt(2)
- function Abs(const A: integer): integer; overload; external name 'Math.abs';
- function Abs(const A: NativeInt): integer; overload; external name 'Math.abs';
- function Abs(const A: Double): Double; overload; external name 'Math.abs';
- function ArcTan(const A: Double): Double; external name 'Math.atan';
- function ArcTan2(const A,B: Double): Double; external name 'Math.atan2';
- function Cos(const A: Double): Double; external name 'Math.cos';
- function Exp(const A: Double): Double; external name 'Math.exp';
- function Frac(const A: Double): Double; assembler;
- function Ln(const A: Double): Double; external name 'Math.log';
- function Odd(const A: Integer): Boolean; assembler;
- function Random(const Range: Integer): Integer; overload; assembler;
- function Random: Double; overload; external name 'Math.random';
- function Round(const A: Double): NativeInt; external name 'Math.round';
- function Sin(const A: Double): Double; external name 'Math.sin';
- function Sqr(const A: Integer): Integer; assembler; overload;
- function Sqr(const A: Double): Double; assembler; overload;
- function sqrt(const A: Double): Double; external name 'Math.sqrt';
- function Trunc(const A: Double): NativeInt;
- {*****************************************************************************
- String functions
- *****************************************************************************}
- const
- DefaultTextLineBreakStyle : TTextLineBreakStyle = tlbsLF;
- function Int(const A: Double): double;
- function Copy(const S: string; Index, Size: Integer): String; assembler; overload;
- function Copy(const S: string; Index: Integer): String; assembler; overload;
- procedure Delete(var S: String; Index, Size: Integer); overload;
- function Pos(const Search, InString: String): Integer; assembler; overload;
- function Pos(const Search, InString: String; StartAt : Integer): Integer; assembler; overload;
- procedure Insert(const Insertion: String; var Target: String; Index: Integer); overload;
- function upcase(c : char) : char; assembler;
- function HexStr(Val: NativeInt; cnt: byte): string; external name 'rtl.hexStr'; overload;
- procedure val(const S: String; out NI : NativeInt; out Code: Integer); overload;
- procedure val(const S: String; out NI : NativeUInt; out Code: Integer); overload;
- procedure val(const S: String; out SI : ShortInt; out Code: Integer); overload;
- procedure val(const S: String; out B : Byte; out Code: Integer); overload;
- procedure val(const S: String; out SI : smallint; out Code: Integer); overload;
- procedure val(const S: String; out W : word; out Code : Integer); overload;
- procedure val(const S: String; out I : integer; out Code : Integer); overload;
- procedure val(const S: String; out C : Cardinal; out Code: Integer); overload;
- procedure val(const S: String; out d : double; out Code : Integer); overload;
- procedure val(const S: String; out b : boolean; out Code: Integer); overload;
- function StringOfChar(c: Char; l: NativeInt): String;
- {*****************************************************************************
- Other functions
- *****************************************************************************}
- procedure Write; varargs; // ToDo: should be compiler built-in function
- procedure Writeln; varargs; // ToDo: should be compiler built-in function
- Type
- TConsoleHandler = Procedure (S : JSValue; NewLine : Boolean);
- Function SetWriteCallBack(H : TConsoleHandler) : TConsoleHandler;
- function Assigned(const V: JSValue): boolean; assembler; overload;
- function StrictEqual(const A: JSValue; const B): boolean; assembler;
- function StrictInequal(const A: JSValue; const B): boolean; assembler;
- implementation
- type
- { TJSObj - simple access to JS Object }
- TJSObj = class external name 'Object'
- private
- function GetProperties(Name: String): JSValue; external name '[]';
- procedure SetProperties(Name: String; const AValue: JSValue); external name '[]';
- public
- //constructor new;
- //function hasOwnProperty(prop: String): boolean;
- property Properties[Name: String]: JSValue read GetProperties write SetProperties; default;
- end;
- TJSArray = class external name 'Array'
- public
- //length: nativeint;
- //constructor new; overload;
- function push(aElement : JSValue) : NativeInt; varargs;
- end;
- TJSArguments = class external name 'arguments'
- private
- FLength: NativeInt; external name 'length';
- function GetElements(Index: NativeInt): JSValue; external name '[]';
- public
- property Length: NativeInt read FLength;
- property Elements[Index: NativeInt]: JSValue read GetElements; default;
- end;
- var
- JSArguments: TJSArguments; external name 'arguments';
- // function parseInt(s: String; Radix: NativeInt): NativeInt; external name 'parseInt'; // may result NaN
- function isNaN(i: JSValue): boolean; external name 'isNaN'; // may result NaN
- // needed by ClassNameIs, the real SameText is in SysUtils
- function SameText(const s1, s2: String): Boolean; assembler;
- asm
- return s1.toLowerCase() == s2.toLowerCase();
- end;
- function VarRecs: TVarRecArray;
- var
- i: nativeint;
- v: PVarRec;
- begin
- Result:=nil;
- while i<JSArguments.Length do
- begin
- new(v);
- v^.VType:=byte(JSArguments[i]);
- inc(i);
- v^.VJSValue:=JSArguments[i];
- inc(i);
- TJSArray(Result).push(v^);
- end;
- end;
- function ParamCount: Longint;
- begin
- if Assigned(OnParamCount) then
- Result:=OnParamCount()
- else
- Result:=0;
- end;
- function ParamStr(Index: Longint): String;
- begin
- if Assigned(OnParamStr) then
- Result:=OnParamStr(Index)
- else if Index=0 then
- Result:='js'
- else
- Result:='';
- end;
- function Frac(const A: Double): Double; assembler;
- asm
- return A % 1;
- end;
- function Odd(const A: Integer): Boolean; assembler;
- asm
- return A&1 != 0;
- end;
- function Random(const Range: Integer): Integer; assembler;
- asm
- return Math.floor(Math.random()*Range);
- end;
- function Sqr(const A: Integer): Integer; assembler;
- asm
- return A*A;
- end;
- function Sqr(const A: Double): Double; assembler;
- asm
- return A*A;
- end;
- function Trunc(const A: Double): NativeInt; assembler;
- asm
- if (!Math.trunc) {
- Math.trunc = function(v) {
- v = +v;
- if (!isFinite(v)) return v;
- return (v - v % 1) || (v < 0 ? -0 : v === 0 ? v : 0);
- };
- }
- $mod.Trunc = Math.trunc;
- return Math.trunc(A);
- end;
- function Copy(const S: string; Index, Size: Integer): String; assembler;
- asm
- if (Index<1) Index = 1;
- return (Size>0) ? S.substring(Index-1,Index+Size-1) : "";
- end;
- function Copy(const S: string; Index: Integer): String; assembler;
- asm
- if (Index<1) Index = 1;
- return S.substr(Index-1);
- end;
- procedure Delete(var S: String; Index, Size: Integer);
- var
- h: String;
- begin
- if (Index<1) or (Index>length(S)) or (Size<=0) then exit;
- h:=S;
- S:=copy(h,1,Index-1)+copy(h,Index+Size);
- end;
- function Pos(const Search, InString: String): Integer; assembler;
- asm
- return InString.indexOf(Search)+1;
- end;
- function Pos(const Search, InString: String; StartAt : Integer): Integer; assembler; overload;
- asm
- return InString.indexOf(Search,StartAt-1)+1;
- end;
- procedure Insert(const Insertion: String; var Target: String; Index: Integer);
- var
- t: String;
- begin
- if Insertion='' then exit;
- t:=Target;
- if Index<1 then
- Target:=Insertion+t
- else if Index>length(t) then
- Target:=t+Insertion
- else
- Target:=copy(t,1,Index-1)+Insertion+copy(t,Index,length(t));
- end;
- var
- WriteBuf: String;
- WriteCallBack : TConsoleHandler;
- Function SetWriteCallBack(H : TConsoleHandler) : TConsoleHandler;
- begin
- Result:=WriteCallBack;
- WriteCallBack:=H;
- end;
- procedure Write;
- var
- i: Integer;
- begin
- for i:=0 to JSArguments.Length-1 do
- if Assigned(WriteCallBack) then
- WriteCallBack(JSArguments[i],False)
- else
- WriteBuf:=WriteBuf+String(JSArguments[i]);
- end;
- procedure Writeln;
- var
- i,l: Integer;
- s: String;
- begin
- L:=JSArguments.Length-1;
- if Assigned(WriteCallBack) then
- begin
- for i:=0 to L do
- WriteCallBack(JSArguments[i],I=L);
- end
- else
- begin
- s:=WriteBuf;
- for i:=0 to L do
- s:=s+String(JSArguments[i]);
- asm
- console.log(s);
- end;
- WriteBuf:='';
- end;
- end;
- function Int(const A: Double): double;
- begin
- // trunc contains fix for missing Math.trunc in IE
- Result:=Trunc(A);
- end;
- function Number(S: String): Double; external name 'Number';
- function valint(const S: String; MinVal, MaxVal: NativeInt; out Code: Integer): NativeInt;
- var
- x: double;
- begin
- x:=Number(S);
- if isNaN(x) then
- case copy(s,1,1) of
- '$': x:=Number('0x'+copy(S,2));
- '&': x:=Number('0o'+copy(S,2));
- '%': x:=Number('0b'+copy(S,2));
- else
- Code:=1;
- exit;
- end;
- if isNaN(x) or (X<>Int(X)) then
- Code:=1
- else if (x<MinVal) or (x>MaxVal) then
- Code:=2
- else
- begin
- Result:=Trunc(x);
- Code:=0;
- end;
- end;
- procedure val(const S: String; out NI : NativeInt; out Code: Integer);
- begin
- NI:=valint(S,low(NI),high(NI),Code);
- end;
- procedure val(const S: String; out NI: NativeUInt; out Code: Integer);
- var
- x : double;
- begin
- x:=Number(S);
- if isNaN(x) or (X<>Int(X)) or (X<0) then
- Code:=1
- else
- begin
- Code:=0;
- NI:=Trunc(x);
- end;
- end;
- procedure val(const S: String; out SI : ShortInt; out Code: Integer);
- begin
- SI:=valint(S,low(SI),high(SI),Code);
- end;
- procedure val(const S: String; out SI: smallint; out Code: Integer);
- begin
- SI:=valint(S,low(SI),high(SI),Code);
- end;
- procedure val(const S: String; out C: Cardinal; out Code: Integer);
- begin
- C:=valint(S,low(C),high(C),Code);
- end;
- procedure val(const S: String; out B: Byte; out Code: Integer);
- begin
- B:=valint(S,low(B),high(B),Code);
- end;
- procedure val(const S: String; out W: word; out Code: Integer);
- begin
- W:=valint(S,low(W),high(W),Code);
- end;
- procedure val(const S : String; out I : integer; out Code : Integer);
- begin
- I:=valint(S,low(I),high(I),Code);
- end;
- procedure val(const S : String; out d : double; out Code : Integer);
- Var
- x: double;
- begin
- x:=Number(S);
- if isNaN(x) then
- Code:=1
- else
- begin
- Code:=0;
- d:=x;
- end;
- end;
- procedure val(const S: String; out b: boolean; out Code: Integer);
- begin
- if SameText(S,'true') then
- begin
- Code:=0;
- b:=true;
- end
- else if SameText(S,'false') then
- begin
- Code:=0;
- b:=false;
- end
- else
- Code:=1;
- end;
- function upcase(c : char) : char; assembler;
- asm
- return c.toUpperCase();
- end;
- function StringOfChar(c: Char; l: NativeInt): String;
- var
- i: Integer;
- begin
- asm
- if ((l>0) && c.repeat) return c.repeat(l);
- end;
- Result:='';
- for i:=1 to l do Result:=Result+c;
- end;
- function Assigned(const V: JSValue): boolean; assembler;
- asm
- return (V!=undefined) && (V!=null) && (!rtl.isArray(V) || (V.length > 0));
- end;
- function StrictEqual(const A: JSValue; const B): boolean; assembler;
- asm
- return A === B;
- end;
- function StrictInequal(const A: JSValue; const B): boolean; assembler;
- asm
- return A !== B;
- end;
- { TContainedObject }
- function TContainedObject.QueryInterface(const iid: TGuid; out obj): Integer;
- begin
- if GetInterface(iid,obj) then
- Result:=S_OK
- else
- Result:=Integer(E_NOINTERFACE);
- end;
- { TAggregatedObject }
- function TAggregatedObject.GetController: IUnknown;
- begin
- Result := IUnknown(fController);
- end;
- function TAggregatedObject.QueryInterface(const iid: TGuid; out obj): Integer;
- begin
- Result := IUnknown(fController).QueryInterface(iid, obj);
- end;
- function TAggregatedObject._AddRef: Integer;
- begin
- Result := IUnknown(fController)._AddRef;
- end;
- function TAggregatedObject._Release: Integer;
- begin
- Result := IUnknown(fController)._Release;
- end;
- constructor TAggregatedObject.Create(const aController: IUnknown);
- begin
- inherited Create;
- { do not keep a counted reference to the controller! }
- fController := Pointer(aController);
- end;
- { TInterfacedObject }
- function TInterfacedObject.QueryInterface(const iid: TGuid; out obj): Integer;
- begin
- if GetInterface(iid,obj) then
- Result:=S_OK
- else
- Result:=Integer(E_NOINTERFACE);
- end;
- function TInterfacedObject._AddRef: Integer;
- begin
- inc(fRefCount);
- Result:=fRefCount;
- end;
- function TInterfacedObject._Release: Integer;
- begin
- dec(fRefCount);
- Result:=fRefCount;
- if fRefCount=0 then
- Destroy;
- end;
- procedure TInterfacedObject.BeforeDestruction;
- begin
- if fRefCount<>0 then
- asm
- rtl.raiseE('EHeapMemoryError');
- end;
- end;
- { TObject }
- constructor TObject.Create;
- begin
- end;
- destructor TObject.Destroy;
- begin
- end;
- procedure TObject.Free;
- begin
- Destroy;
- end;
- class function TObject.ClassType: TClass; assembler;
- asm
- return this;
- end;
- class function TObject.ClassNameIs(const Name: string): boolean;
- begin
- Result:=SameText(Name,ClassName);
- end;
- class function TObject.InheritsFrom(aClass: TClass): boolean; assembler;
- asm
- return (aClass!=null) && ((this==aClass) || aClass.isPrototypeOf(this));
- end;
- procedure TObject.AfterConstruction;
- begin
- end;
- procedure TObject.BeforeDestruction;
- begin
- end;
- function TObject.GetInterface(const iid: TGuid; out obj): boolean;
- begin
- asm
- var i = iid.$intf;
- if (i){
- // iid is the private TGuid of an interface
- i = rtl.getIntfG(this,i.$guid,2);
- if (i){
- obj.set(i);
- return true;
- }
- }
- end;
- Result := GetInterfaceByStr(GUIDToString(iid),obj);
- end;
- function TObject.GetInterface(const iidstr: String; out obj): boolean;
- begin
- Result := GetInterfaceByStr(iidstr,obj);
- end;
- function TObject.GetInterfaceByStr(const iidstr: String; out obj): boolean;
- begin
- if not TJSObj(IObjectInstance)['$str'] then
- TJSObj(IObjectInstance)['$str']:=GUIDToString(IObjectInstance);
- if iidstr = TJSObj(IObjectInstance)['$str'] then
- begin
- obj:=Self;
- exit(true);
- end;
- asm
- var i = rtl.getIntfG(this,iidstr,2);
- obj.set(i);
- return i!==null;
- end;
- Result:=false;
- end;
- function TObject.GetInterfaceWeak(const iid: TGuid; out obj): boolean;
- begin
- Result:=GetInterface(iid,obj);
- asm
- if (Result){
- var o = obj.get();
- if (o.$kind==='com'){
- o._Release();
- }
- }
- end;
- end;
- function TObject.Equals(Obj: TObject): boolean;
- begin
- Result:=Obj=Self;
- end;
- function TObject.ToString: String;
- begin
- Result:=ClassName;
- end;
- initialization
- ExitCode:=0; // set it here, so that WPO does not remove it
- end.
|