rtti.pas 34 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397
  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 RTTI;
  11. {$mode objfpc}
  12. {$ModeSwitch advancedrecords}
  13. interface
  14. uses
  15. JS, RTLConsts, Types, SysUtils, TypInfo;
  16. resourcestring
  17. SErrInvokeInvalidCodeAddr = 'CodeAddress is not a function';
  18. SErrTypeIsNotEnumerated = 'Type %s is not an enumerated type';
  19. type
  20. { TValue }
  21. TValue = record
  22. private
  23. FTypeInfo: TTypeInfo;
  24. FData: JSValue;
  25. function GetIsEmpty: boolean;
  26. function GetTypeKind: TTypeKind;
  27. public
  28. class function FromJSValue(v: JSValue): TValue; static;
  29. property Kind: TTypeKind read GetTypeKind;
  30. property TypeInfo: TTypeInfo read FTypeInfo;
  31. property IsEmpty: boolean read GetIsEmpty; // check if nil or undefined
  32. function IsObject: boolean;
  33. function AsObject: TObject;
  34. function IsObjectInstance: boolean;
  35. function IsArray: boolean;
  36. function IsClass: boolean;
  37. function AsClass: TClass;
  38. function IsOrdinal: boolean;
  39. function AsOrdinal: NativeInt;
  40. function AsBoolean: boolean;
  41. //ToDo: function AsCurrency: Currency;
  42. function AsInteger: Integer;
  43. function AsNativeInt: NativeInt;
  44. function AsInterface: IInterface;
  45. function AsString: string;
  46. function AsUnicodeString: UnicodeString;
  47. function AsExtended: Extended;
  48. function ToString: String;
  49. function GetArrayLength: SizeInt;
  50. function GetArrayElement(aIndex: SizeInt): TValue;
  51. //ToDo: procedure SetArrayElement(aIndex: SizeInt; constref AValue: TValue);
  52. function IsType(ATypeInfo: PTypeInfo): boolean;
  53. function AsJSValue: JSValue;
  54. class function Empty: TValue; static;
  55. end;
  56. TRttiType = class;
  57. { TRTTIContext }
  58. TRTTIContext = record
  59. private
  60. FPool: TJSObject; // maps 'modulename.typename' to TRTTIType
  61. class constructor Init;
  62. public
  63. class function Create: TRTTIContext; static;
  64. procedure Free;
  65. function GetType(aTypeInfo: PTypeInfo): TRTTIType; overload;
  66. function GetType(aClass: TClass): TRTTIType; overload;
  67. end;
  68. { TRttiObject }
  69. TRttiObject = class abstract
  70. public
  71. //property Handle: Pointer read GetHandle; not supported in pas2js
  72. function GetAttributes: TCustomAttributeArray; virtual;
  73. end;
  74. { TRttiNamedObject }
  75. TRttiNamedObject = class(TRttiObject)
  76. protected
  77. function GetName: string; virtual;
  78. public
  79. property Name: string read GetName;
  80. end;
  81. { TRttiMember }
  82. TMemberVisibility=(
  83. mvPrivate,
  84. mvProtected,
  85. mvPublic,
  86. mvPublished);
  87. TRttiMember = class(TRttiNamedObject)
  88. private
  89. FTypeInfo: TTypeMember;
  90. FParent: TRttiType;
  91. protected
  92. function GetMemberTypeInfo: TTypeMember;
  93. function GetName: string; override;
  94. function GetVisibility: TMemberVisibility; virtual;
  95. public
  96. constructor Create(AParent: TRttiType; ATypeInfo: TTypeMember);
  97. function GetAttributes: TCustomAttributeArray; override;
  98. property MemberTypeInfo: TTypeMember read GetMemberTypeInfo;
  99. property Visibility: TMemberVisibility read GetVisibility;
  100. property Parent: TRttiType read FParent;
  101. end;
  102. { TRttiField }
  103. TRttiField = class(TRttiMember)
  104. private
  105. function GetFieldType: TRttiType;
  106. public
  107. property FieldType: TRttiType read GetFieldType;
  108. //function GetValue(Instance: Pointer): TValue;
  109. //procedure SetValue(Instance: Pointer; const AValue: TValue);
  110. //function ToString: string; override;
  111. end;
  112. TRttiFieldArray = specialize TArray<TRttiField>;
  113. TRttiParameter = class(TRttiNamedObject)
  114. private
  115. FParamType: TRttiType;
  116. FFlags: TParamFlags;
  117. FName: String;
  118. protected
  119. function GetName: string; override;
  120. public
  121. property Flags: TParamFlags read FFlags;
  122. property ParamType: TRttiType read FParamType;
  123. end;
  124. TRttiParameterArray = specialize TArray<TRttiParameter>;
  125. { TRttiMethod }
  126. TRttiMethod = class(TRttiMember)
  127. private
  128. FParameters: TRttiParameterArray;
  129. function GetMethodTypeInfo: TTypeMemberMethod;
  130. function GetIsClassMethod: boolean;
  131. function GetIsConstructor: boolean;
  132. function GetIsDestructor: boolean;
  133. function GetIsExternal: boolean;
  134. function GetIsStatic: boolean;
  135. function GetIsVarArgs: boolean;
  136. function GetMethodKind: TMethodKind;
  137. function GetReturnType: TRttiType;
  138. procedure LoadParameters;
  139. public
  140. function GetParameters: TRttiParameterArray;
  141. property MethodTypeInfo: TTypeMemberMethod read GetMethodTypeInfo;
  142. property ReturnType: TRttiType read GetReturnType;
  143. property MethodKind: TMethodKind read GetMethodKind;
  144. property IsConstructor: boolean read GetIsConstructor;
  145. property IsDestructor: boolean read GetIsDestructor;
  146. property IsClassMethod: boolean read GetIsClassMethod;
  147. property IsExternal: boolean read GetIsExternal;
  148. property IsStatic: boolean read GetIsStatic;// true = has Self argument
  149. property IsVarArgs: boolean read GetIsVarArgs;
  150. end;
  151. TRttiMethodArray = specialize TArray<TRttiMethod>;
  152. { TRttiProperty }
  153. TRttiProperty = class(TRttiMember)
  154. private
  155. function GetPropertyTypeInfo: TTypeMemberProperty;
  156. function GetPropertyType: TRttiType;
  157. function GetIsWritable: boolean;
  158. function GetIsReadable: boolean;
  159. protected
  160. function GetVisibility: TMemberVisibility; override;
  161. public
  162. constructor Create(AParent: TRttiType; ATypeInfo: TTypeMember);
  163. function GetValue(Instance: TObject): TValue;
  164. procedure SetValue(Instance: TObject; const AValue: JSValue); overload;
  165. procedure SetValue(Instance: TObject; const AValue: TValue); overload;
  166. property PropertyTypeInfo: TTypeMemberProperty read GetPropertyTypeInfo;
  167. property PropertyType: TRttiType read GetPropertyType;
  168. property IsReadable: boolean read GetIsReadable;
  169. property IsWritable: boolean read GetIsWritable;
  170. property Visibility: TMemberVisibility read GetVisibility;
  171. end;
  172. TRttiPropertyArray = specialize TArray<TRttiProperty>;
  173. { TRttiType }
  174. TRttiType = class(TRttiNamedObject)
  175. private
  176. FAttributes: TCustomAttributeArray;
  177. FTypeInfo: TTypeInfo;
  178. //FMethods: specialize TArray<TRttiMethod>;
  179. //function GetAsInstance: TRttiInstanceType;
  180. protected
  181. function GetName: string; override;
  182. //function GetHandle: Pointer; override;
  183. function GetIsInstance: boolean; virtual;
  184. //function GetIsManaged: boolean; virtual;
  185. function GetIsOrdinal: boolean; virtual;
  186. function GetIsRecord: boolean; virtual;
  187. function GetIsSet: boolean; virtual;
  188. function GetTypeKind: TTypeKind; virtual;
  189. //function GetTypeSize: integer; virtual;
  190. //function GetBaseType: TRttiType; virtual;
  191. public
  192. constructor Create(ATypeInfo : PTypeInfo);
  193. destructor Destroy; override;
  194. function GetAttributes: TCustomAttributeArray; override;
  195. function GetField(const AName: string): TRttiField; virtual;
  196. function GetMethods: TRttiMethodArray; virtual;
  197. function GetMethods(const aName: String): TRttiMethodArray; virtual;
  198. function GetMethod(const aName: String): TRttiMethod; virtual;
  199. function GetProperty(const AName: string): TRttiProperty; virtual;
  200. //function GetIndexedProperty(const AName: string): TRttiIndexedProperty; virtual;
  201. function GetDeclaredProperties: TRttiPropertyArray; virtual;
  202. //function GetDeclaredIndexedProperties: TRttiIndexedPropertyArray; virtual;
  203. function GetDeclaredMethods: TRttiMethodArray; virtual;
  204. function GetDeclaredFields: TRttiFieldArray; virtual;
  205. property Handle: TTypeInfo read FTypeInfo;
  206. property IsInstance: boolean read GetIsInstance;
  207. //property isManaged: boolean read GetIsManaged;
  208. property IsOrdinal: boolean read GetIsOrdinal;
  209. property IsRecord: boolean read GetIsRecord;
  210. property IsSet: boolean read GetIsSet;
  211. //property BaseType: TRttiType read GetBaseType;
  212. //property AsInstance: TRttiInstanceType read GetAsInstance;
  213. property TypeKind: TTypeKind read GetTypeKind;
  214. //property TypeSize: integer read GetTypeSize;
  215. end;
  216. TRttiTypeClass = class of TRttiType;
  217. { TRttiStructuredType }
  218. TRttiStructuredType = class abstract(TRttiType)
  219. private
  220. FMethods: TRttiMethodArray;
  221. FProperties: TRttiPropertyArray;
  222. protected
  223. function GetAncestor: TRttiStructuredType; virtual; abstract;
  224. function GetStructTypeInfo: TTypeInfoStruct;
  225. public
  226. constructor Create(ATypeInfo: PTypeInfo);
  227. destructor Destroy; override;
  228. function GetDeclaredMethods: TRttiMethodArray;
  229. function GetDeclaredProperties: TRttiPropertyArray; override;
  230. function GetMethod(const aName: String): TRttiMethod; override;
  231. function GetMethods: TRttiMethodArray; override;
  232. function GetMethods(const aName: String): TRttiMethodArray; override;
  233. function GetProperties: TRttiPropertyArray;
  234. function GetProperty(const AName: string): TRttiProperty; override;
  235. property StructTypeInfo: TTypeInfoStruct read GetStructTypeInfo;
  236. end;
  237. { TRttiInstanceType }
  238. TRttiInstanceType = class(TRttiStructuredType)
  239. private
  240. function GetClassTypeInfo: TTypeInfoClass;
  241. function GetMetaClassType: TClass;
  242. protected
  243. function GetAncestor: TRttiStructuredType; override;
  244. public
  245. constructor Create(ATypeInfo: PTypeInfo);
  246. function GetIsInstance: boolean; override;
  247. property ClassTypeInfo: TTypeInfoClass read GetClassTypeInfo;
  248. property MetaClassType: TClass read GetMetaClassType;
  249. end;
  250. { TRttiInterfaceType }
  251. TRttiInterfaceType = class(TRttiStructuredType)
  252. private
  253. function GetGUID: TGUID;
  254. function GetInterfaceTypeInfo: TTypeInfoInterface;
  255. protected
  256. function GetAncestor: TRttiStructuredType; override;
  257. public
  258. constructor Create(ATypeInfo: PTypeInfo);
  259. property GUID: TGUID read GetGUID;
  260. property InterfaceTypeInfo: TTypeInfoInterface read GetInterfaceTypeInfo;
  261. end;
  262. { TRttiOrdinalType }
  263. TRttiOrdinalType = class(TRttiType)
  264. private
  265. function GetMaxValue: Integer; virtual;
  266. function GetMinValue: Integer; virtual;
  267. function GetOrdType: TOrdType;
  268. function GetOrdinalTypeInfo: TTypeInfoInteger;
  269. public
  270. constructor Create(ATypeInfo: PTypeInfo);
  271. property OrdType: TOrdType read GetOrdType;
  272. property MinValue: Integer read GetMinValue;
  273. property MaxValue: Integer read GetMaxValue;
  274. property OrdinalTypeInfo: TTypeInfoInteger read GetOrdinalTypeInfo;
  275. end;
  276. { TRttiEnumerationType }
  277. TRttiEnumerationType = class(TRttiOrdinalType)
  278. private
  279. function GetEnumerationTypeInfo: TTypeInfoEnum;
  280. public
  281. constructor Create(ATypeInfo: PTypeInfo);
  282. property EnumerationTypeInfo: TTypeInfoEnum read GetEnumerationTypeInfo;
  283. function GetNames: TStringArray;
  284. generic class function GetName<T>(AValue: T): String;
  285. generic class function GetValue<T>(const AValue: String): T;
  286. end;
  287. { TRttiDynamicArrayType }
  288. TRttiDynamicArrayType = class(TRttiType)
  289. private
  290. function GetDynArrayTypeInfo: TTypeInfoDynArray;
  291. function GetElementType: TRttiType;
  292. public
  293. constructor Create(ATypeInfo: PTypeInfo);
  294. property DynArrayTypeInfo: TTypeInfoDynArray read GetDynArrayTypeInfo;
  295. property ElementType: TRttiType read GetElementType;
  296. end;
  297. EInvoke = EJS;
  298. TVirtualInterfaceInvokeEvent = function(const aMethodName: string;
  299. const Args: TJSValueDynArray): JSValue of object;
  300. { TVirtualInterface: A class that can implement any IInterface. Any method
  301. call is handled by the OnInvoke event. }
  302. TVirtualInterface = class(TInterfacedObject, IInterface)
  303. private
  304. FOnInvoke: TVirtualInterfaceInvokeEvent;
  305. public
  306. constructor Create(InterfaceTypeInfo: Pointer); overload; assembler;
  307. constructor Create(InterfaceTypeInfo: Pointer;
  308. const InvokeEvent: TVirtualInterfaceInvokeEvent); overload;
  309. function QueryInterface(const iid: TGuid; out obj): Integer; override;
  310. property OnInvoke: TVirtualInterfaceInvokeEvent read FOnInvoke write FOnInvoke;
  311. end;
  312. procedure CreateVirtualCorbaInterface(InterfaceTypeInfo: Pointer;
  313. const MethodImplementation: TVirtualInterfaceInvokeEvent; out IntfVar); assembler;
  314. function Invoke(ACodeAddress: Pointer; const AArgs: TJSValueDynArray;
  315. ACallConv: TCallConv; AResultType: PTypeInfo; AIsStatic: Boolean;
  316. AIsConstructor: Boolean): TValue;
  317. implementation
  318. var
  319. GRttiContext: TRTTIContext;
  320. procedure CreateVirtualCorbaInterface(InterfaceTypeInfo: Pointer;
  321. const MethodImplementation: TVirtualInterfaceInvokeEvent; out IntfVar); assembler;
  322. asm
  323. var IntfType = InterfaceTypeInfo.interface;
  324. var i = Object.create(IntfType);
  325. var o = { $name: "virtual", $fullname: "virtual" };
  326. i.$o = o;
  327. do {
  328. var names = IntfType.$names;
  329. if (!names) break;
  330. for (var j=0; j<names.length; j++){
  331. let fnname = names[j];
  332. i[fnname] = function(){ return MethodImplementation(fnname,arguments); };
  333. }
  334. IntfType = Object.getPrototypeOf(IntfType);
  335. } while(IntfType!=null);
  336. IntfVar.set(i);
  337. end;
  338. { TRttiDynamicArrayType }
  339. function TRttiDynamicArrayType.GetDynArrayTypeInfo: TTypeInfoDynArray;
  340. begin
  341. Result := TTypeInfoDynArray(FTypeInfo);
  342. end;
  343. function TRttiDynamicArrayType.GetElementType: TRttiType;
  344. begin
  345. Result := GRttiContext.GetType(DynArrayTypeInfo.ElType);
  346. end;
  347. constructor TRttiDynamicArrayType.Create(ATypeInfo: PTypeInfo);
  348. begin
  349. if not (TTypeInfo(ATypeInfo) is TTypeInfoDynArray) then
  350. raise EInvalidCast.Create('');
  351. inherited Create(ATypeInfo);
  352. end;
  353. { TRttiOrdinalType }
  354. function TRttiOrdinalType.GetMaxValue: Integer;
  355. begin
  356. Result := OrdinalTypeInfo.MaxValue;
  357. end;
  358. function TRttiOrdinalType.GetMinValue: Integer;
  359. begin
  360. Result := OrdinalTypeInfo.MinValue;
  361. end;
  362. function TRttiOrdinalType.GetOrdType: TOrdType;
  363. begin
  364. Result := OrdinalTypeInfo.OrdType;
  365. end;
  366. function TRttiOrdinalType.GetOrdinalTypeInfo: TTypeInfoInteger;
  367. begin
  368. Result := TTypeInfoInteger(FTypeInfo);
  369. end;
  370. constructor TRttiOrdinalType.Create(ATypeInfo: PTypeInfo);
  371. begin
  372. if not (TTypeInfo(ATypeInfo) is TTypeInfoInteger) then
  373. raise EInvalidCast.Create('');
  374. inherited Create(ATypeInfo);
  375. end;
  376. { TRttiEnumerationType }
  377. function TRttiEnumerationType.GetEnumerationTypeInfo: TTypeInfoEnum;
  378. begin
  379. Result := TTypeInfoEnum(FTypeInfo);
  380. end;
  381. function TRttiEnumerationType.GetNames: TStringArray;
  382. var
  383. A, NamesSize: Integer;
  384. begin
  385. NamesSize := GetEnumNameCount(EnumerationTypeInfo);
  386. SetLength(Result, NamesSize);
  387. for A := 0 to Pred(NamesSize) do
  388. Result[A] := EnumerationTypeInfo.EnumType.IntToName[A + MinValue];
  389. end;
  390. generic class function TRttiEnumerationType.GetName<T>(AValue: T): String;
  391. Var
  392. P : PTypeInfo;
  393. begin
  394. P:=TypeInfo(T);
  395. if not (TTypeInfo(P).kind=tkEnumeration) then
  396. raise EInvalidCast.CreateFmt(SErrTypeIsNotEnumerated,[TTypeInfo(P).Name]);
  397. Result := GetEnumName(TTypeInfoEnum(P), Integer(JSValue(AValue)));
  398. end;
  399. generic class function TRttiEnumerationType.GetValue<T>(const AValue: String): T;
  400. Var
  401. P : PTypeInfo;
  402. begin
  403. P:=TypeInfo(T);
  404. if not (TTypeInfo(P).kind=tkEnumeration) then
  405. raise EInvalidCast.CreateFmt(SErrTypeIsNotEnumerated,[TTypeInfo(P).Name]);
  406. Result := T(JSValue(GetEnumValue(TTypeInfoEnum(TypeInfo(T)), AValue)));
  407. end;
  408. constructor TRttiEnumerationType.Create(ATypeInfo: PTypeInfo);
  409. begin
  410. if not (TTypeInfo(ATypeInfo) is TTypeInfoEnum) then
  411. raise EInvalidCast.Create('');
  412. inherited Create(ATypeInfo);
  413. end;
  414. { TValue }
  415. function TValue.GetTypeKind: TTypeKind;
  416. begin
  417. if TypeInfo=nil then
  418. Result:=tkUnknown
  419. else
  420. Result:=FTypeInfo.Kind;
  421. end;
  422. class function TValue.FromJSValue(v: JSValue): TValue;
  423. var
  424. i: NativeInt;
  425. begin
  426. Result.FData:=v;
  427. case jsTypeOf(v) of
  428. 'number':
  429. if JS.isInteger(v) then
  430. begin
  431. i:=NativeInt(v);
  432. if (i>=low(integer)) and (i<=high(integer)) then
  433. Result.FTypeInfo:=system.TypeInfo(Integer)
  434. else
  435. Result.FTypeInfo:=system.TypeInfo(NativeInt);
  436. end
  437. else
  438. Result.FTypeInfo:=system.TypeInfo(Double);
  439. 'string': Result.FTypeInfo:=system.TypeInfo(String);
  440. 'boolean': Result.FTypeInfo:=system.TypeInfo(Boolean);
  441. 'object':
  442. begin
  443. if v=nil then
  444. Result.FTypeInfo:=system.TypeInfo(Pointer)
  445. else if JS.isClass(v) and JS.isExt(v,TObject) then
  446. Result.FTypeInfo:=system.TypeInfo(TClass(v))
  447. else if JS.isObject(v) and JS.isExt(v,TObject) then
  448. Result.FTypeInfo:=system.TypeInfo(TObject(v))
  449. else
  450. Result.FTypeInfo:=system.TypeInfo(Pointer);
  451. if (Result.FTypeInfo=JS.Undefined) or (Result.FTypeInfo=nil) then
  452. Result.FTypeInfo:=system.TypeInfo(Pointer);
  453. end
  454. else
  455. Result.FTypeInfo:=system.TypeInfo(JSValue);
  456. end;
  457. end;
  458. function TValue.IsObject: boolean;
  459. begin
  460. Result:=IsEmpty or (TypeInfo.Kind=tkClass);
  461. end;
  462. function TValue.AsObject: TObject;
  463. begin
  464. if IsObject or (IsClass and not js.isObject(FData)) then
  465. Result := TObject(FData)
  466. else
  467. raise EInvalidCast.Create(SErrInvalidTypecast);
  468. end;
  469. function TValue.IsObjectInstance: boolean;
  470. begin
  471. Result:=(TypeInfo<>nil) and (TypeInfo.Kind=tkClass);
  472. end;
  473. function TValue.IsArray: boolean;
  474. begin
  475. Result := Kind in [tkArray, tkDynArray];
  476. end;
  477. function TValue.IsClass: boolean;
  478. var
  479. k: TTypeKind;
  480. begin
  481. k:=Kind;
  482. Result := (k = tkClassRef)
  483. or ((k in [tkClass,tkUnknown]) and not JS.IsObject(FData));
  484. end;
  485. function TValue.AsClass: TClass;
  486. begin
  487. if IsClass then
  488. Result := TClass(FData)
  489. else
  490. raise EInvalidCast.Create(SErrInvalidTypecast);
  491. end;
  492. function TValue.IsOrdinal: boolean;
  493. var
  494. k: TTypeKind;
  495. begin
  496. k:=Kind;
  497. Result := (k in [tkInteger, tkBool]) or
  498. ((k in [tkClass, tkClassRef, tkUnknown]) and not JS.isObject(FData));
  499. end;
  500. function TValue.AsOrdinal: NativeInt;
  501. begin
  502. if IsOrdinal then
  503. Result:=NativeInt(FData)
  504. else
  505. raise EInvalidCast.Create(SErrInvalidTypecast);
  506. end;
  507. function TValue.AsBoolean: boolean;
  508. begin
  509. if (Kind = tkBool) then
  510. Result:=boolean(FData)
  511. else
  512. raise EInvalidCast.Create(SErrInvalidTypecast);
  513. end;
  514. function TValue.AsInteger: Integer;
  515. begin
  516. if JS.isInteger(FData) then
  517. Result:=NativeInt(FData)
  518. else
  519. raise EInvalidCast.Create(SErrInvalidTypecast);
  520. end;
  521. function TValue.AsNativeInt: NativeInt;
  522. begin
  523. if JS.isInteger(FData) then
  524. Result:=NativeInt(FData)
  525. else
  526. raise EInvalidCast.Create(SErrInvalidTypecast);
  527. end;
  528. function TValue.AsInterface: IInterface;
  529. var
  530. k: TTypeKind;
  531. begin
  532. k:=Kind;
  533. if k = tkInterface then
  534. Result := IInterface(FData)// ToDo
  535. else if (k in [tkClass, tkClassRef, tkUnknown]) and not JS.isObject(FData) then
  536. Result := Nil
  537. else
  538. raise EInvalidCast.Create(SErrInvalidTypecast);
  539. end;
  540. function TValue.AsString: string;
  541. begin
  542. if js.isString(FData) then
  543. Result:=String(FData)
  544. else
  545. raise EInvalidCast.Create(SErrInvalidTypecast);
  546. end;
  547. function TValue.AsUnicodeString: UnicodeString;
  548. begin
  549. Result:=AsString;
  550. end;
  551. function TValue.AsExtended: Extended;
  552. begin
  553. if js.isNumber(FData) then
  554. Result:=Double(FData)
  555. else
  556. raise EInvalidCast.Create(SErrInvalidTypecast);
  557. end;
  558. function TValue.ToString: String;
  559. begin
  560. case Kind of
  561. tkString: Result := AsString;
  562. tkInteger: Result := IntToStr(AsNativeInt);
  563. tkBool: Result := BoolToStr(AsBoolean, True);
  564. else
  565. Result := '';
  566. end;
  567. end;
  568. function TValue.GetArrayLength: SizeInt;
  569. begin
  570. if not IsArray then
  571. raise EInvalidCast.Create(SErrInvalidTypecast);
  572. Result:=length(TJSValueDynArray(FData));
  573. end;
  574. function TValue.GetArrayElement(aIndex: SizeInt): TValue;
  575. var
  576. StaticTI: TTypeInfoStaticArray;
  577. DynIT: TTypeInfoDynArray;
  578. begin
  579. case Kind of
  580. tkDynArray:
  581. begin
  582. DynIT:=TTypeInfoDynArray(FTypeInfo);
  583. Result.FTypeInfo:=DynIT.ElType;
  584. if DynIT.DimCount<>1 then
  585. raise EInvalidCast.Create(SErrInvalidTypecast);
  586. end;
  587. tkArray:
  588. begin
  589. StaticTI:=TTypeInfoStaticArray(FTypeInfo);
  590. if length(StaticTI.Dims)<>1 then
  591. raise EInvalidCast.Create(SErrInvalidTypecast);
  592. Result.FTypeInfo:=StaticTI.ElType;
  593. end;
  594. else
  595. raise EInvalidCast.Create(SErrInvalidTypecast);
  596. end;
  597. Result.FData:=TJSValueDynArray(FData)[aIndex];
  598. end;
  599. function TValue.IsType(ATypeInfo: PTypeInfo): boolean;
  600. begin
  601. Result := ATypeInfo = TypeInfo;
  602. end;
  603. function TValue.GetIsEmpty: boolean;
  604. begin
  605. if (TypeInfo=nil) or (FData=Undefined) or (FData=nil) then
  606. exit(true);
  607. case TypeInfo.Kind of
  608. tkDynArray:
  609. Result:=TJSArray(FData).Length=0;
  610. else
  611. Result:=false;
  612. end;
  613. end;
  614. function TValue.AsJSValue: JSValue;
  615. begin
  616. Result := FData;
  617. end;
  618. class function TValue.Empty: TValue;
  619. begin
  620. Result.FTypeInfo := nil;
  621. end;
  622. { TRttiStructuredType }
  623. function TRttiStructuredType.GetMethods: TRttiMethodArray;
  624. var
  625. A, Start: Integer;
  626. BaseClass: TRttiStructuredType;
  627. Declared: TRttiMethodArray;
  628. begin
  629. BaseClass := Self;
  630. Result := nil;
  631. while Assigned(BaseClass) do
  632. begin
  633. Declared := BaseClass.GetDeclaredMethods;
  634. Start := Length(Result);
  635. SetLength(Result, Start + Length(Declared));
  636. for A := Low(Declared) to High(Declared) do
  637. Result[Start + A] := Declared[A];
  638. BaseClass := BaseClass.GetAncestor;
  639. end;
  640. end;
  641. function TRttiStructuredType.GetMethods(const aName: String): TRttiMethodArray;
  642. var
  643. Method: TRttiMethod;
  644. MethodCount: Integer;
  645. begin
  646. MethodCount := 0;
  647. for Method in GetMethods do
  648. if aName = Method.Name then
  649. Inc(MethodCount);
  650. SetLength(Result, MethodCount);
  651. for Method in GetMethods do
  652. if aName = Method.Name then
  653. begin
  654. Dec(MethodCount);
  655. Result[MethodCount] := Method;
  656. end;
  657. end;
  658. function TRttiStructuredType.GetProperties: TRttiPropertyArray;
  659. var
  660. A, Start: Integer;
  661. BaseClass: TRttiStructuredType;
  662. Declared: TRttiPropertyArray;
  663. begin
  664. BaseClass := Self;
  665. Result := nil;
  666. while Assigned(BaseClass) do
  667. begin
  668. Declared := BaseClass.GetDeclaredProperties;
  669. Start := Length(Result);
  670. SetLength(Result, Start + Length(Declared));
  671. for A := Low(Declared) to High(Declared) do
  672. Result[Start + A] := Declared[A];
  673. BaseClass := BaseClass.GetAncestor;
  674. end;
  675. end;
  676. function TRttiStructuredType.GetMethod(const aName: String): TRttiMethod;
  677. var
  678. Method: TRttiMethod;
  679. begin
  680. for Method in GetMethods do
  681. if aName = Method.Name then
  682. Exit(Method);
  683. end;
  684. function TRttiStructuredType.GetProperty(const AName: string): TRttiProperty;
  685. var
  686. Prop: TRttiProperty;
  687. begin
  688. for Prop in GetProperties do
  689. if Prop.Name = AName then
  690. Exit(Prop);
  691. end;
  692. function TRttiStructuredType.GetDeclaredProperties: TRttiPropertyArray;
  693. var
  694. A, PropCount: Integer;
  695. begin
  696. if not Assigned(FProperties) then
  697. begin
  698. PropCount := StructTypeInfo.PropCount;
  699. SetLength(FProperties, PropCount);
  700. for A := 0 to Pred(PropCount) do
  701. FProperties[A] := TRttiProperty.Create(Self, StructTypeInfo.GetProp(A));
  702. end;
  703. Result := FProperties;
  704. end;
  705. function TRttiStructuredType.GetStructTypeInfo: TTypeInfoStruct;
  706. begin
  707. Result:=TTypeInfoStruct(FTypeInfo);
  708. end;
  709. constructor TRttiStructuredType.Create(ATypeInfo: PTypeInfo);
  710. begin
  711. if not (TTypeInfo(ATypeInfo) is TTypeInfoStruct) then
  712. raise EInvalidCast.Create('');
  713. inherited Create(ATypeInfo);
  714. end;
  715. destructor TRttiStructuredType.Destroy;
  716. var
  717. Method: TRttiMethod;
  718. Prop: TRttiProperty;
  719. begin
  720. for Method in FMethods do
  721. Method.Free;
  722. for Prop in FProperties do
  723. Prop.Free;
  724. inherited Destroy;
  725. end;
  726. function TRttiStructuredType.GetDeclaredMethods: TRttiMethodArray;
  727. var
  728. A, MethodCount: Integer;
  729. BaseClass: TRttiStructuredType;
  730. begin
  731. if not Assigned(FMethods) then
  732. begin
  733. MethodCount := StructTypeInfo.MethodCount;
  734. SetLength(FMethods, MethodCount);
  735. for A := 0 to Pred(MethodCount) do
  736. FMethods[A] := TRttiMethod.Create(Self, StructTypeInfo.GetMethod(A));
  737. end;
  738. Result := FMethods;
  739. end;
  740. { TRttiInstanceType }
  741. function TRttiInstanceType.GetClassTypeInfo: TTypeInfoClass;
  742. begin
  743. Result:=TTypeInfoClass(FTypeInfo);
  744. end;
  745. function TRttiInstanceType.GetMetaClassType: TClass;
  746. begin
  747. Result:=ClassTypeInfo.ClassType;
  748. end;
  749. function TRttiInstanceType.GetAncestor: TRttiStructuredType;
  750. begin
  751. Result := GRttiContext.GetType(ClassTypeInfo.Ancestor) as TRttiStructuredType;
  752. end;
  753. constructor TRttiInstanceType.Create(ATypeInfo: PTypeInfo);
  754. begin
  755. if not (TTypeInfo(ATypeInfo) is TTypeInfoClass) then
  756. raise EInvalidCast.Create('');
  757. inherited Create(ATypeInfo);
  758. end;
  759. function TRttiInstanceType.GetIsInstance: boolean;
  760. begin
  761. Result:=True;
  762. end;
  763. { TRttiInterfaceType }
  764. constructor TRttiInterfaceType.Create(ATypeInfo: PTypeInfo);
  765. begin
  766. if not (TTypeInfo(ATypeInfo) is TTypeInfoInterface) then
  767. raise EInvalidCast.Create('');
  768. inherited Create(ATypeInfo);
  769. end;
  770. function TRttiInterfaceType.GetGUID: TGUID;
  771. var
  772. Guid: String;
  773. begin
  774. Guid := String(InterfaceTypeInfo.InterfaceType['$guid']);
  775. TryStringToGUID(Guid, Result);
  776. end;
  777. function TRttiInterfaceType.GetInterfaceTypeInfo: TTypeInfoInterface;
  778. begin
  779. Result := TTypeInfoInterface(FTypeInfo);
  780. end;
  781. function TRttiInterfaceType.GetAncestor: TRttiStructuredType;
  782. begin
  783. Result := GRttiContext.GetType(InterfaceTypeInfo.Ancestor) as TRttiStructuredType;
  784. end;
  785. { TRTTIContext }
  786. class constructor TRTTIContext.Init;
  787. begin
  788. GRttiContext:=TRTTIContext.Create;
  789. end;
  790. class function TRTTIContext.Create: TRTTIContext;
  791. begin
  792. Result.FPool:=TJSObject.new;
  793. end;
  794. procedure TRTTIContext.Free;
  795. var
  796. key: string;
  797. o: TRttiType;
  798. begin
  799. for key in FPool do
  800. if FPool.hasOwnProperty(key) then begin
  801. o:=TRTTIType(FPool[key]);
  802. o.Free;
  803. end;
  804. FPool:=nil;
  805. end;
  806. function TRTTIContext.GetType(aTypeInfo: PTypeInfo): TRTTIType;
  807. var
  808. RttiTypeClass: array[TTypeKind] of TRttiTypeClass = (
  809. nil, // tkUnknown
  810. TRttiOrdinalType, // tkInteger
  811. TRttiOrdinalType, // tkChar
  812. TRttiType, // tkString
  813. TRttiEnumerationType, // tkEnumeration
  814. TRttiType, // tkSet
  815. TRttiOrdinalType, // tkDouble
  816. TRttiEnumerationType, // tkBool
  817. TRttiType, // tkProcVar
  818. nil, // tkMethod
  819. TRttiType, // tkArray
  820. TRttiDynamicArrayType, // tkDynArray
  821. TRttiType, // tkRecord
  822. TRttiInstanceType, // tkClass
  823. TRttiType, // tkClassRef
  824. TRttiType, // tkPointer
  825. TRttiType, // tkJSValue
  826. TRttiType, // tkRefToProcVar
  827. TRttiInterfaceType, // tkInterface
  828. TRttiType, // tkHelper
  829. TRttiInstanceType // tkExtClass
  830. );
  831. t: TTypeinfo absolute aTypeInfo;
  832. Name: String;
  833. begin
  834. if aTypeInfo=nil then exit(nil);
  835. Name:=t.Name;
  836. if isModule(t.Module) then
  837. Name:=t.Module.Name+'.'+Name;
  838. if FPool.hasOwnProperty(Name) then
  839. Result:=TRttiType(FPool[Name])
  840. else
  841. begin
  842. Result := RttiTypeClass[T.Kind].Create(aTypeInfo);
  843. FPool[Name]:=Result;
  844. end;
  845. end;
  846. function TRTTIContext.GetType(aClass: TClass): TRTTIType;
  847. begin
  848. if aClass=nil then exit(nil);
  849. Result:=GetType(TypeInfo(aClass));
  850. end;
  851. { TRttiObject }
  852. function TRttiObject.GetAttributes: TCustomAttributeArray;
  853. begin
  854. Result:=nil;
  855. end;
  856. { TRttiNamedObject }
  857. function TRttiNamedObject.GetName: string;
  858. begin
  859. Result:='';
  860. end;
  861. { TRttiMember }
  862. function TRttiMember.GetName: string;
  863. begin
  864. Result:=FTypeInfo.Name;
  865. end;
  866. function TRttiMember.GetVisibility: TMemberVisibility;
  867. begin
  868. Result:=mvPublished;
  869. end;
  870. constructor TRttiMember.Create(AParent: TRttiType; ATypeInfo: TTypeMember);
  871. begin
  872. if not (ATypeInfo is TTypeMember) then
  873. raise EInvalidCast.Create('');
  874. inherited Create();
  875. FParent := AParent;
  876. FTypeInfo:=ATypeInfo;
  877. end;
  878. function TRttiMember.GetAttributes: TCustomAttributeArray;
  879. begin
  880. Result:=inherited GetAttributes;
  881. end;
  882. function TRttiMember.GetMemberTypeInfo: TTypeMember;
  883. begin
  884. Result := TTypeMember(FTypeInfo);
  885. end;
  886. { TRttiField }
  887. function TRttiField.GetFieldType: TRttiType;
  888. begin
  889. Result := GRttiContext.GetType(FTypeInfo);
  890. end;
  891. { TRttiParameter }
  892. function TRttiParameter.GetName: String;
  893. begin
  894. Result := FName;
  895. end;
  896. { TRttiMethod }
  897. function TRttiMethod.GetMethodTypeInfo: TTypeMemberMethod;
  898. begin
  899. Result := TTypeMemberMethod(FTypeInfo);
  900. end;
  901. function TRttiMethod.GetIsClassMethod: boolean;
  902. begin
  903. Result:=MethodTypeInfo.MethodKind in [mkClassFunction,mkClassProcedure];
  904. end;
  905. function TRttiMethod.GetIsConstructor: boolean;
  906. begin
  907. Result:=MethodTypeInfo.MethodKind=mkConstructor;
  908. end;
  909. function TRttiMethod.GetIsDestructor: boolean;
  910. begin
  911. Result:=MethodTypeInfo.MethodKind=mkDestructor;
  912. end;
  913. function TRttiMethod.GetIsExternal: boolean;
  914. begin
  915. Result:=(MethodTypeInfo.ProcSig.Flags and 4)>0; // pfExternal
  916. end;
  917. function TRttiMethod.GetIsStatic: boolean;
  918. begin
  919. Result:=(MethodTypeInfo.ProcSig.Flags and 1)>0; // pfStatic
  920. end;
  921. function TRttiMethod.GetIsVarArgs: boolean;
  922. begin
  923. Result:=(MethodTypeInfo.ProcSig.Flags and 2)>0; // pfVarargs
  924. end;
  925. function TRttiMethod.GetMethodKind: TMethodKind;
  926. begin
  927. Result:=MethodTypeInfo.MethodKind;;
  928. end;
  929. function TRttiMethod.GetReturnType: TRttiType;
  930. begin
  931. Result := GRttiContext.GetType(MethodTypeInfo.ProcSig.ResultType);
  932. end;
  933. procedure TRttiMethod.LoadParameters;
  934. const
  935. FLAGS_CONVERSION: array[TParamFlag] of Integer = (1, 2, 4, 8, 16, 32);
  936. var
  937. A, Flag: Integer;
  938. Param: TProcedureParam;
  939. RttiParam: TRttiParameter;
  940. begin
  941. SetLength(FParameters, Length(MethodTypeInfo.ProcSig.Params));
  942. for A := Low(FParameters) to High(FParameters) do
  943. begin
  944. Param := MethodTypeInfo.ProcSig.Params[A];
  945. RttiParam := TRttiParameter.Create;
  946. RttiParam.FName := Param.Name;
  947. RttiParam.FParamType := GRttiContext.GetType(Param.TypeInfo);
  948. for Flag in FLAGS_CONVERSION do
  949. if Flag and Param.Flags > 0 then
  950. RttiParam.FFlags := RttiParam.FFlags + [TParamFlag(A)];
  951. FParameters[A] := RttiParam;
  952. end;
  953. end;
  954. function TRttiMethod.GetParameters: TRttiParameterArray;
  955. begin
  956. if not Assigned(FParameters) then
  957. LoadParameters;
  958. Result := FParameters;
  959. end;
  960. { TRttiProperty }
  961. constructor TRttiProperty.Create(AParent: TRttiType; ATypeInfo: TTypeMember);
  962. begin
  963. if not (ATypeInfo is TTypeMemberProperty) then
  964. raise EInvalidCast.Create('');
  965. inherited;
  966. end;
  967. function TRttiProperty.GetPropertyTypeInfo: TTypeMemberProperty;
  968. begin
  969. Result := TTypeMemberProperty(FTypeInfo);
  970. end;
  971. function TRttiProperty.GetValue(Instance: TObject): TValue;
  972. begin
  973. Result := TValue.FromJSValue(GetJSValueProp(Instance, PropertyTypeInfo));
  974. end;
  975. procedure TRttiProperty.SetValue(Instance: TObject; const AValue: TValue);
  976. begin
  977. SetJSValueProp(Instance, PropertyTypeInfo, AValue);
  978. end;
  979. procedure TRttiProperty.SetValue(Instance: TObject; const AValue: JSValue);
  980. begin
  981. SetJSValueProp(Instance, PropertyTypeInfo, AValue);
  982. end;
  983. function TRttiProperty.GetPropertyType: TRttiType;
  984. begin
  985. Result := GRttiContext.GetType(PropertyTypeInfo.TypeInfo);
  986. end;
  987. function TRttiProperty.GetIsWritable: boolean;
  988. begin
  989. Result := PropertyTypeInfo.Setter<>'';
  990. end;
  991. function TRttiProperty.GetIsReadable: boolean;
  992. begin
  993. Result := PropertyTypeInfo.Getter<>'';
  994. end;
  995. function TRttiProperty.GetVisibility: TMemberVisibility;
  996. begin
  997. // At this moment only pulished rtti-property-info is supported by pas2js
  998. Result := mvPublished;
  999. end;
  1000. { TRttiType }
  1001. function TRttiType.GetName: string;
  1002. begin
  1003. Result:=FTypeInfo.Name;
  1004. end;
  1005. function TRttiType.GetIsInstance: boolean;
  1006. begin
  1007. Result:=false;
  1008. end;
  1009. function TRttiType.GetIsOrdinal: boolean;
  1010. begin
  1011. Result:=false;
  1012. end;
  1013. function TRttiType.GetIsRecord: boolean;
  1014. begin
  1015. Result:=false;
  1016. end;
  1017. function TRttiType.GetIsSet: boolean;
  1018. begin
  1019. Result:=false;
  1020. end;
  1021. function TRttiType.GetTypeKind: TTypeKind;
  1022. begin
  1023. Result:=FTypeInfo.Kind;
  1024. end;
  1025. constructor TRttiType.Create(ATypeInfo: PTypeInfo);
  1026. begin
  1027. inherited Create();
  1028. FTypeInfo:=TTypeInfo(ATypeInfo);
  1029. end;
  1030. destructor TRttiType.Destroy;
  1031. var
  1032. o: TCustomAttribute;
  1033. begin
  1034. for o in FAttributes do
  1035. o.Free;
  1036. FAttributes:=nil;
  1037. inherited Destroy;
  1038. end;
  1039. function TRttiType.GetAttributes: TCustomAttributeArray;
  1040. begin
  1041. FAttributes:=GetRTTIAttributes(FTypeInfo.Attributes);
  1042. Result:=FAttributes;
  1043. end;
  1044. function TRttiType.GetDeclaredProperties: TRttiPropertyArray;
  1045. begin
  1046. Result:=nil;
  1047. end;
  1048. function TRttiType.GetProperty(const AName: string): TRttiProperty;
  1049. begin
  1050. Result:=nil;
  1051. if AName='' then ;
  1052. end;
  1053. function TRttiType.GetMethods: TRttiMethodArray;
  1054. begin
  1055. Result:=nil;
  1056. end;
  1057. function TRttiType.GetMethods(const aName: String): TRttiMethodArray;
  1058. begin
  1059. Result:=nil;
  1060. end;
  1061. function TRttiType.GetMethod(const aName: String): TRttiMethod;
  1062. begin
  1063. Result:=nil;
  1064. if aName='' then ;
  1065. end;
  1066. function TRttiType.GetDeclaredMethods: TRttiMethodArray;
  1067. begin
  1068. Result:=nil;
  1069. end;
  1070. function TRttiType.GetDeclaredFields: TRttiFieldArray;
  1071. begin
  1072. Result:=nil;
  1073. end;
  1074. function TRttiType.GetField(const AName: string): TRttiField;
  1075. begin
  1076. Result:=nil;
  1077. if AName='' then ;
  1078. end;
  1079. { TVirtualInterface }
  1080. constructor TVirtualInterface.Create(InterfaceTypeInfo: Pointer); assembler;
  1081. asm
  1082. var IntfType = InterfaceTypeInfo.interface;
  1083. if (IntfType.$kind !== 'com') rtl.raiseE('EInvalidCast');
  1084. var guid = IntfType.$guid;
  1085. var i = Object.create(IntfType); // needed by IntfVar is IntfType
  1086. i.$o = this;
  1087. // copy IInterface methods: _AddRef, _Release, QueryInterface
  1088. var iinterfaceguid = '{00000000-0000-0000-C000-000000000046}';
  1089. var map = this.$intfmaps[iinterfaceguid];
  1090. for (var key in map){
  1091. var v = map[key];
  1092. if (typeof(v)!=='function') continue;
  1093. i[key] = map[key];
  1094. }
  1095. // all other methods call OnInvoke
  1096. do {
  1097. var names = IntfType.$names;
  1098. if (!names) break;
  1099. for (var j=0; j<names.length; j++){
  1100. let fnname = names[j];
  1101. if (i[fnname]) continue;
  1102. i[fnname] = function(){ return this.$o.FOnInvoke(fnname,arguments); };
  1103. }
  1104. IntfType = Object.getPrototypeOf(IntfType);
  1105. } while(IntfType!=null);
  1106. // create a new list of interface map, supporting IInterface and IntfType
  1107. this.$intfmaps = {};
  1108. this.$intfmaps[iinterfaceguid] = map;
  1109. this.$intfmaps[guid] = {};
  1110. // store the implementation of IntfType (used by the as-operator)
  1111. this.$interfaces = {};
  1112. this.$interfaces[guid] = i;
  1113. end;
  1114. constructor TVirtualInterface.Create(InterfaceTypeInfo: Pointer;
  1115. const InvokeEvent: TVirtualInterfaceInvokeEvent);
  1116. begin
  1117. Create(InterfaceTypeInfo);
  1118. OnInvoke:=InvokeEvent;
  1119. end;
  1120. function TVirtualInterface.QueryInterface(const iid: TGuid; out obj): Integer;
  1121. begin
  1122. Result := inherited QueryInterface(iid, obj);
  1123. end;
  1124. function Invoke(ACodeAddress: Pointer; const AArgs: TJSValueDynArray;
  1125. ACallConv: TCallConv; AResultType: PTypeInfo; AIsStatic: Boolean;
  1126. AIsConstructor: Boolean): TValue;
  1127. begin
  1128. if ACallConv=ccReg then ;
  1129. if AIsStatic then ;
  1130. if AIsConstructor then
  1131. raise EInvoke.Create('not supported');
  1132. if isFunction(ACodeAddress) then
  1133. begin
  1134. Result.FData := TJSFunction(ACodeAddress).apply(nil, AArgs);
  1135. if AResultType<>nil then
  1136. Result.FTypeInfo:=AResultType
  1137. else
  1138. Result.FTypeInfo:=TypeInfo(JSValue);
  1139. end
  1140. else
  1141. raise EInvoke.Create(SErrInvokeInvalidCodeAddr);
  1142. end;
  1143. end.