2
0

rtti.pas 50 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982
  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 Empty: TValue; static;
  29. generic class function From<T>(const Value: T): TValue; static;
  30. class function FromArray(TypeInfo: TTypeInfo; const Values: specialize TArray<TValue>): TValue; static;
  31. class function FromJSValue(v: JSValue): TValue; static;
  32. class function FromOrdinal(ATypeInfo: TTypeInfo; AValue: JSValue): TValue; static;
  33. class procedure Make(ABuffer: JSValue; ATypeInfo: PTypeInfo; var Result: TValue); overload; static;
  34. generic class procedure Make<T>(const Value: T; var Result: TValue); overload; static;
  35. function AsBoolean: boolean;
  36. function AsClass: TClass;
  37. //ToDo: function AsCurrency: Currency;
  38. function AsExtended: Extended;
  39. function AsInteger: Integer;
  40. function AsInterface: IInterface;
  41. function AsJSValue: JSValue;
  42. function AsNativeInt: NativeInt;
  43. function AsObject: TObject;
  44. function AsOrdinal: NativeInt;
  45. function AsString: string;
  46. generic function AsType<T>: T;
  47. function AsUnicodeString: UnicodeString;
  48. function Cast(ATypeInfo: TTypeInfo; const EmptyAsAnyType: Boolean = True): TValue; overload;
  49. generic function Cast<T>(const EmptyAsAnyType: Boolean = True): TValue; overload;
  50. function IsType(ATypeInfo: TTypeInfo; const EmptyAsAnyType: Boolean = True): Boolean; overload;
  51. generic function IsType<T>(const EmptyAsAnyType: Boolean = True): Boolean; overload;
  52. function GetArrayElement(aIndex: SizeInt): TValue;
  53. function GetArrayLength: SizeInt;
  54. function IsArray: boolean;
  55. function IsClass: boolean;
  56. function IsObject: boolean;
  57. function IsObjectInstance: boolean;
  58. function IsOrdinal: boolean;
  59. function IsType(ATypeInfo: TTypeInfo): boolean;
  60. function ToString: String;
  61. function TryCast(ATypeInfo: TTypeInfo; out AResult: TValue; const EmptyAsAnyType: Boolean = True): Boolean;
  62. procedure SetArrayElement(aIndex: SizeInt; const AValue: TValue);
  63. procedure SetArrayLength(const Size: SizeInt);
  64. property IsEmpty: boolean read GetIsEmpty; // check if nil or undefined
  65. property Kind: TTypeKind read GetTypeKind;
  66. property TypeInfo: TTypeInfo read FTypeInfo;
  67. end;
  68. TRttiType = class;
  69. TRttiInstanceType = class;
  70. TRttiInstanceExternalType = class;
  71. { TRTTIContext }
  72. TRTTIContext = record
  73. private
  74. FPool: TJSObject; // maps 'modulename.typename' to TRTTIType
  75. FReferenceCount: Integer;
  76. public
  77. class function Create: TRTTIContext; static;
  78. procedure Free;
  79. function FindType(const AQualifiedName: String): TRttiType;
  80. function GetType(aTypeInfo: PTypeInfo): TRTTIType; overload;
  81. function GetType(aClass: TClass): TRTTIType; overload;
  82. function GetTypes: specialize TArray<TRttiType>;
  83. end;
  84. { TRttiObject }
  85. TRttiObject = class abstract
  86. private
  87. FAttributesLoaded: Boolean;
  88. FAttributes: TCustomAttributeArray;
  89. FParent: TRttiObject;
  90. FHandle: Pointer;
  91. protected
  92. function LoadCustomAttributes: TCustomAttributeArray; virtual;
  93. public
  94. constructor Create(AParent: TRttiObject; AHandle: Pointer); virtual;
  95. destructor Destroy; override;
  96. function GetAttributes: TCustomAttributeArray;
  97. property Attributes: TCustomAttributeArray read GetAttributes;
  98. property Handle: Pointer read FHandle;
  99. property Parent: TRttiObject read FParent;
  100. end;
  101. { TRttiNamedObject }
  102. TRttiNamedObject = class(TRttiObject)
  103. protected
  104. function GetName: string; virtual;
  105. public
  106. property Name: string read GetName;
  107. end;
  108. { TRttiMember }
  109. TMemberVisibility=(
  110. mvPrivate,
  111. mvProtected,
  112. mvPublic,
  113. mvPublished);
  114. TRttiMember = class(TRttiNamedObject)
  115. protected
  116. function GetMemberTypeInfo: TTypeMember;
  117. function GetName: String; override;
  118. function GetParent: TRttiType;
  119. function GetVisibility: TMemberVisibility; virtual;
  120. function LoadCustomAttributes: TCustomAttributeArray; override;
  121. public
  122. constructor Create(AParent: TRttiType; ATypeInfo: TTypeMember);
  123. property MemberTypeInfo: TTypeMember read GetMemberTypeInfo;
  124. property Parent: TRttiType read GetParent;
  125. property Visibility: TMemberVisibility read GetVisibility;
  126. end;
  127. { TRttiField }
  128. TRttiField = class(TRttiMember)
  129. private
  130. function GetFieldType: TRttiType;
  131. function GetFieldTypeInfo: TTypeMemberField;
  132. public
  133. constructor Create(AParent: TRttiType; ATypeInfo: TTypeMember);
  134. function GetValue(Instance: JSValue): TValue;
  135. procedure SetValue(Instance: JSValue; const AValue: TValue);
  136. property FieldType: TRttiType read GetFieldType;
  137. property FieldTypeInfo: TTypeMemberField read GetFieldTypeInfo;
  138. end;
  139. TRttiFieldArray = specialize TArray<TRttiField>;
  140. { TRttiParameter }
  141. TRttiParameter = class(TRttiNamedObject)
  142. private
  143. FParamType: TRttiType;
  144. FFlags: TParamFlags;
  145. FName: String;
  146. protected
  147. function GetName: string; override;
  148. public
  149. property Flags: TParamFlags read FFlags;
  150. property ParamType: TRttiType read FParamType;
  151. end;
  152. TRttiParameterArray = specialize TArray<TRttiParameter>;
  153. { TRttiMethod }
  154. TRttiMethod = class(TRttiMember)
  155. private
  156. FParameters: TRttiParameterArray;
  157. FParametersLoaded: Boolean;
  158. function GetIsAsyncCall: Boolean;
  159. function GetIsClassMethod: Boolean;
  160. function GetIsConstructor: Boolean;
  161. function GetIsDestructor: Boolean;
  162. function GetIsExternal: Boolean;
  163. function GetIsSafeCall: Boolean;
  164. function GetIsStatic: Boolean;
  165. function GetIsVarArgs: Boolean;
  166. function GetMethodKind: TMethodKind;
  167. function GetMethodTypeInfo: TTypeMemberMethod;
  168. function GetProcedureFlags: TProcedureFlags;
  169. function GetReturnType: TRttiType;
  170. procedure LoadParameters;
  171. public
  172. function GetParameters: TRttiParameterArray;
  173. property IsAsyncCall: Boolean read GetIsAsyncCall;
  174. property IsClassMethod: Boolean read GetIsClassMethod;
  175. property IsConstructor: Boolean read GetIsConstructor;
  176. property IsDestructor: Boolean read GetIsDestructor;
  177. property IsExternal: Boolean read GetIsExternal;
  178. property IsSafeCall: Boolean read GetIsSafeCall;
  179. property IsStatic: Boolean read GetIsStatic;
  180. property MethodKind: TMethodKind read GetMethodKind;
  181. property MethodTypeInfo: TTypeMemberMethod read GetMethodTypeInfo;
  182. property ReturnType: TRttiType read GetReturnType;
  183. end;
  184. TRttiMethodArray = specialize TArray<TRttiMethod>;
  185. { TRttiProperty }
  186. TRttiProperty = class(TRttiMember)
  187. private
  188. function GetPropertyTypeInfo: TTypeMemberProperty;
  189. function GetPropertyType: TRttiType;
  190. function GetIsWritable: boolean;
  191. function GetIsReadable: boolean;
  192. protected
  193. function GetVisibility: TMemberVisibility; override;
  194. public
  195. constructor Create(AParent: TRttiType; ATypeInfo: TTypeMember);
  196. function GetValue(Instance: JSValue): TValue;
  197. procedure SetValue(Instance: JSValue; const AValue: TValue);
  198. property PropertyTypeInfo: TTypeMemberProperty read GetPropertyTypeInfo;
  199. property PropertyType: TRttiType read GetPropertyType;
  200. property IsReadable: boolean read GetIsReadable;
  201. property IsWritable: boolean read GetIsWritable;
  202. property Visibility: TMemberVisibility read GetVisibility;
  203. end;
  204. TRttiPropertyArray = specialize TArray<TRttiProperty>;
  205. { TRttiType }
  206. TRttiType = class(TRttiNamedObject)
  207. private
  208. //FMethods: specialize TArray<TRttiMethod>;
  209. function GetAsInstance: TRttiInstanceType;
  210. function GetAsInstanceExternal: TRttiInstanceExternalType;
  211. function GetHandle: TTypeInfo;
  212. function GetQualifiedName: String;
  213. protected
  214. function GetName: string; override;
  215. //function GetHandle: Pointer; override;
  216. function GetIsInstance: Boolean;
  217. function GetIsInstanceExternal: Boolean;
  218. //function GetIsManaged: Boolean; virtual;
  219. function GetIsOrdinal: Boolean; virtual;
  220. function GetIsRecord: Boolean; virtual;
  221. function GetIsSet: Boolean; virtual;
  222. function GetTypeKind: TTypeKind; virtual;
  223. //function GetTypeSize: integer; virtual;
  224. function GetBaseType: TRttiType; virtual;
  225. function LoadCustomAttributes: TCustomAttributeArray; override;
  226. public
  227. function GetField(const AName: string): TRttiField; virtual;
  228. function GetFields: TRttiFieldArray; virtual;
  229. function GetMethods: TRttiMethodArray; virtual;
  230. function GetMethods(const aName: String): TRttiMethodArray; virtual;
  231. function GetMethod(const aName: String): TRttiMethod; virtual;
  232. function GetProperty(const AName: string): TRttiProperty; virtual;
  233. //function GetIndexedProperty(const AName: string): TRttiIndexedProperty; virtual;
  234. function GetProperties: TRttiPropertyArray; virtual;
  235. function GetDeclaredProperties: TRttiPropertyArray; virtual;
  236. //function GetDeclaredIndexedProperties: TRttiIndexedPropertyArray; virtual;
  237. function GetDeclaredMethods: TRttiMethodArray; virtual;
  238. function GetDeclaredFields: TRttiFieldArray; virtual;
  239. property Handle: TTypeInfo read GetHandle;
  240. property IsInstance: Boolean read GetIsInstance;
  241. property IsInstanceExternal: Boolean read GetIsInstanceExternal;
  242. //property isManaged: Boolean read GetIsManaged;
  243. property IsOrdinal: Boolean read GetIsOrdinal;
  244. property IsRecord: Boolean read GetIsRecord;
  245. property IsSet: Boolean read GetIsSet;
  246. property BaseType: TRttiType read GetBaseType;
  247. property AsInstance: TRttiInstanceType read GetAsInstance;
  248. property AsInstanceExternal: TRttiInstanceExternalType read GetAsInstanceExternal;
  249. property TypeKind: TTypeKind read GetTypeKind;
  250. //property TypeSize: integer read GetTypeSize;
  251. property QualifiedName: String read GetQualifiedName;
  252. end;
  253. TRttiTypeClass = class of TRttiType;
  254. { TRttiStructuredType }
  255. TRttiStructuredType = class abstract(TRttiType)
  256. private
  257. FFields: TRttiFieldArray;
  258. FMethods: TRttiMethodArray;
  259. FProperties: TRttiPropertyArray;
  260. protected
  261. function GetAncestor: TRttiStructuredType; virtual;
  262. function GetStructTypeInfo: TTypeInfoStruct;
  263. public
  264. constructor Create(AParent: TRttiObject; ATypeInfo: PTypeInfo); override;
  265. destructor Destroy; override;
  266. function GetDeclaredFields: TRttiFieldArray; override;
  267. function GetDeclaredMethods: TRttiMethodArray; override;
  268. function GetDeclaredProperties: TRttiPropertyArray; override;
  269. function GetFields: TRttiFieldArray; override;
  270. function GetMethod(const aName: String): TRttiMethod; override;
  271. function GetMethods: TRttiMethodArray; override;
  272. function GetMethods(const aName: String): TRttiMethodArray; override;
  273. function GetProperties: TRttiPropertyArray; override;
  274. function GetProperty(const AName: string): TRttiProperty; override;
  275. property StructTypeInfo: TTypeInfoStruct read GetStructTypeInfo;
  276. end;
  277. { TRttiInstanceType }
  278. TRttiInstanceType = class(TRttiStructuredType)
  279. private
  280. function GetAncestorType: TRttiInstanceType;
  281. function GetClassTypeInfo: TTypeInfoClass;
  282. function GetMetaClassType: TClass;
  283. protected
  284. function GetAncestor: TRttiStructuredType; override;
  285. function GetBaseType : TRttiType; override;
  286. public
  287. constructor Create(AParent: TRttiObject; ATypeInfo: PTypeInfo); override;
  288. property BaseType : TRttiInstanceType read GetAncestorType;
  289. property Ancestor: TRttiInstanceType read GetAncestorType;
  290. property ClassTypeInfo: TTypeInfoClass read GetClassTypeInfo;
  291. property MetaClassType: TClass read GetMetaClassType;
  292. end;
  293. { TRttiInterfaceType }
  294. TRttiInterfaceType = class(TRttiStructuredType)
  295. private
  296. function GetAncestorType: TRttiInterfaceType;
  297. function GetGUID: TGUID;
  298. function GetInterfaceTypeInfo: TTypeInfoInterface;
  299. protected
  300. function GetAncestor: TRttiStructuredType; override;
  301. function GetBaseType : TRttiType; override;
  302. public
  303. constructor Create(AParent: TRttiObject; ATypeInfo: PTypeInfo); override;
  304. property BaseType : TRttiInterfaceType read GetAncestorType;
  305. property Ancestor: TRttiInterfaceType read GetAncestorType;
  306. property GUID: TGUID read GetGUID;
  307. property InterfaceTypeInfo: TTypeInfoInterface read GetInterfaceTypeInfo;
  308. end;
  309. { TRttiRecordType }
  310. TRttiRecordType = class(TRttiStructuredType)
  311. private
  312. function GetRecordTypeInfo: TTypeInfoRecord;
  313. protected
  314. function GetIsRecord: Boolean; override;
  315. public
  316. constructor Create(AParent: TRttiObject; ATypeInfo: PTypeInfo); override;
  317. property RecordTypeInfo: TTypeInfoRecord read GetRecordTypeInfo;
  318. end;
  319. { TRttiClassRefType }
  320. TRttiClassRefType = class(TRttiType)
  321. private
  322. function GetClassRefTypeInfo: TTypeInfoClassRef;
  323. function GetInstanceType: TRttiInstanceType;
  324. function GetMetaclassType: TClass;
  325. public
  326. constructor Create(AParent: TRttiObject; ATypeInfo: PTypeInfo); override;
  327. property ClassRefTypeInfo: TTypeInfoClassRef read GetClassRefTypeInfo;
  328. property InstanceType: TRttiInstanceType read GetInstanceType;
  329. property MetaclassType: TClass read GetMetaclassType;
  330. end;
  331. { TRttiInstanceExternalType }
  332. TRttiInstanceExternalType = class(TRttiType)
  333. private
  334. function GetAncestor: TRttiInstanceExternalType;
  335. function GetExternalName: String;
  336. function GetExternalClassTypeInfo: TTypeInfoExtClass;
  337. public
  338. constructor Create(AParent: TRttiObject; ATypeInfo: PTypeInfo); override;
  339. property Ancestor: TRttiInstanceExternalType read GetAncestor;
  340. property ExternalClassTypeInfo: TTypeInfoExtClass read GetExternalClassTypeInfo;
  341. property ExternalName: String read GetExternalName;
  342. end;
  343. { TRttiOrdinalType }
  344. TRttiOrdinalType = class(TRttiType)
  345. private
  346. function GetMaxValue: Integer; virtual;
  347. function GetMinValue: Integer; virtual;
  348. function GetOrdType: TOrdType;
  349. function GetOrdinalTypeInfo: TTypeInfoInteger;
  350. public
  351. constructor Create(AParent: TRttiObject; ATypeInfo: PTypeInfo); override;
  352. property OrdType: TOrdType read GetOrdType;
  353. property MinValue: Integer read GetMinValue;
  354. property MaxValue: Integer read GetMaxValue;
  355. property OrdinalTypeInfo: TTypeInfoInteger read GetOrdinalTypeInfo;
  356. end;
  357. { TRttiEnumerationType }
  358. TRttiEnumerationType = class(TRttiOrdinalType)
  359. private
  360. function GetEnumerationTypeInfo: TTypeInfoEnum;
  361. public
  362. constructor Create(AParent: TRttiObject; ATypeInfo: PTypeInfo); override;
  363. property EnumerationTypeInfo: TTypeInfoEnum read GetEnumerationTypeInfo;
  364. function GetNames: TStringArray;
  365. generic class function GetName<T>(AValue: T): String; reintroduce;
  366. generic class function GetValue<T>(const AValue: String): T;
  367. end;
  368. { TRttiDynamicArrayType }
  369. TRttiDynamicArrayType = class(TRttiType)
  370. private
  371. function GetDynArrayTypeInfo: TTypeInfoDynArray;
  372. function GetElementType: TRttiType;
  373. public
  374. constructor Create(AParent: TRttiObject; ATypeInfo: PTypeInfo); override;
  375. property DynArrayTypeInfo: TTypeInfoDynArray read GetDynArrayTypeInfo;
  376. property ElementType: TRttiType read GetElementType;
  377. end;
  378. EInvoke = EJS;
  379. TVirtualInterfaceInvokeEvent = function(const aMethodName: string;
  380. const Args: TJSValueDynArray): JSValue of object;
  381. { TVirtualInterface: A class that can implement any IInterface. Any method
  382. call is handled by the OnInvoke event. }
  383. TVirtualInterface = class(TInterfacedObject, IInterface)
  384. private
  385. FOnInvoke: TVirtualInterfaceInvokeEvent;
  386. public
  387. constructor Create(InterfaceTypeInfo: Pointer); overload; assembler;
  388. constructor Create(InterfaceTypeInfo: Pointer;
  389. const InvokeEvent: TVirtualInterfaceInvokeEvent); overload;
  390. function QueryInterface(const iid: TGuid; out obj): Integer; override;
  391. property OnInvoke: TVirtualInterfaceInvokeEvent read FOnInvoke write FOnInvoke;
  392. end;
  393. procedure CreateVirtualCorbaInterface(InterfaceTypeInfo: Pointer;
  394. const MethodImplementation: TVirtualInterfaceInvokeEvent; out IntfVar); assembler;
  395. function Invoke(ACodeAddress: Pointer; const AArgs: TJSValueDynArray;
  396. ACallConv: TCallConv; AResultType: PTypeInfo; AIsStatic: Boolean;
  397. AIsConstructor: Boolean): TValue;
  398. implementation
  399. var
  400. GRttiContext: TRTTIContext;
  401. pas: TJSObject; external name 'pas';
  402. procedure CreateVirtualCorbaInterface(InterfaceTypeInfo: Pointer;
  403. const MethodImplementation: TVirtualInterfaceInvokeEvent; out IntfVar); assembler;
  404. asm
  405. var IntfType = InterfaceTypeInfo.interface;
  406. var i = Object.create(IntfType);
  407. var o = { $name: "virtual", $fullname: "virtual" };
  408. i.$o = o;
  409. do {
  410. var names = IntfType.$names;
  411. if (!names) break;
  412. for (var j=0; j<names.length; j++){
  413. let fnname = names[j];
  414. i[fnname] = function(){ return MethodImplementation(fnname,arguments); };
  415. }
  416. IntfType = Object.getPrototypeOf(IntfType);
  417. } while(IntfType!=null);
  418. IntfVar.set(i);
  419. end;
  420. { TRttiDynamicArrayType }
  421. function TRttiDynamicArrayType.GetDynArrayTypeInfo: TTypeInfoDynArray;
  422. begin
  423. Result := TTypeInfoDynArray(inherited Handle);
  424. end;
  425. function TRttiDynamicArrayType.GetElementType: TRttiType;
  426. begin
  427. Result := GRttiContext.GetType(DynArrayTypeInfo.ElType);
  428. end;
  429. constructor TRttiDynamicArrayType.Create(AParent: TRttiObject; ATypeInfo: PTypeInfo);
  430. begin
  431. if not (TTypeInfo(ATypeInfo) is TTypeInfoDynArray) then
  432. raise EInvalidCast.Create('');
  433. inherited;
  434. end;
  435. { TRttiOrdinalType }
  436. function TRttiOrdinalType.GetMaxValue: Integer;
  437. begin
  438. Result := OrdinalTypeInfo.MaxValue;
  439. end;
  440. function TRttiOrdinalType.GetMinValue: Integer;
  441. begin
  442. Result := OrdinalTypeInfo.MinValue;
  443. end;
  444. function TRttiOrdinalType.GetOrdType: TOrdType;
  445. begin
  446. Result := OrdinalTypeInfo.OrdType;
  447. end;
  448. function TRttiOrdinalType.GetOrdinalTypeInfo: TTypeInfoInteger;
  449. begin
  450. Result := TTypeInfoInteger(inherited Handle);
  451. end;
  452. constructor TRttiOrdinalType.Create(AParent: TRttiObject; ATypeInfo: PTypeInfo);
  453. begin
  454. if not (TTypeInfo(ATypeInfo) is TTypeInfoInteger) then
  455. raise EInvalidCast.Create('');
  456. inherited;
  457. end;
  458. { TRttiEnumerationType }
  459. function TRttiEnumerationType.GetEnumerationTypeInfo: TTypeInfoEnum;
  460. begin
  461. Result := TTypeInfoEnum(inherited Handle);
  462. end;
  463. function TRttiEnumerationType.GetNames: TStringArray;
  464. var
  465. A, NamesSize: Integer;
  466. begin
  467. NamesSize := GetEnumNameCount(EnumerationTypeInfo);
  468. SetLength(Result, NamesSize);
  469. for A := 0 to Pred(NamesSize) do
  470. Result[A] := EnumerationTypeInfo.EnumType.IntToName[A + MinValue];
  471. end;
  472. generic class function TRttiEnumerationType.GetName<T>(AValue: T): String;
  473. Var
  474. P : PTypeInfo;
  475. begin
  476. P:=TypeInfo(T);
  477. if not (TTypeInfo(P).kind=tkEnumeration) then
  478. raise EInvalidCast.CreateFmt(SErrTypeIsNotEnumerated,[TTypeInfo(P).Name]);
  479. Result := GetEnumName(TTypeInfoEnum(P), Integer(JSValue(AValue)));
  480. end;
  481. generic class function TRttiEnumerationType.GetValue<T>(const AValue: String): T;
  482. Var
  483. P : PTypeInfo;
  484. begin
  485. P:=TypeInfo(T);
  486. if not (TTypeInfo(P).kind=tkEnumeration) then
  487. raise EInvalidCast.CreateFmt(SErrTypeIsNotEnumerated,[TTypeInfo(P).Name]);
  488. Result := T(JSValue(GetEnumValue(TTypeInfoEnum(TypeInfo(T)), AValue)));
  489. end;
  490. constructor TRttiEnumerationType.Create(AParent: TRttiObject; ATypeInfo: PTypeInfo);
  491. begin
  492. if not (TTypeInfo(ATypeInfo) is TTypeInfoEnum) then
  493. raise EInvalidCast.Create('');
  494. inherited;
  495. end;
  496. { TValue }
  497. function TValue.GetTypeKind: TTypeKind;
  498. begin
  499. if TypeInfo=nil then
  500. Result:=tkUnknown
  501. else
  502. Result:=FTypeInfo.Kind;
  503. end;
  504. generic function TValue.AsType<T>: T;
  505. begin
  506. if IsEmpty then
  507. Result := Default(T)
  508. else
  509. Result := T(AsJSValue)
  510. end;
  511. generic class function TValue.From<T>(const Value: T): TValue;
  512. begin
  513. Make(Value, System.TypeInfo(T), Result);
  514. end;
  515. class procedure TValue.Make(ABuffer: JSValue; ATypeInfo: PTypeInfo; var Result: TValue);
  516. begin
  517. Result.FData := ABuffer;
  518. Result.FTypeInfo := ATypeInfo;
  519. end;
  520. generic class procedure TValue.Make<T>(const Value: T; var Result: TValue);
  521. begin
  522. TValue.Make(Value, System.TypeInfo(T), Result);
  523. end;
  524. function TValue.Cast(ATypeInfo: TTypeInfo; const EmptyAsAnyType: Boolean): TValue;
  525. begin
  526. if not TryCast(ATypeInfo, Result, EmptyAsAnyType) then
  527. raise EInvalidCast.Create('');
  528. end;
  529. generic function TValue.Cast<T>(const EmptyAsAnyType: Boolean): TValue;
  530. begin
  531. Result := Cast(System.TypeInfo(T), EmptyAsAnyType);
  532. end;
  533. function TValue.IsType(ATypeInfo: TTypeInfo; const EmptyAsAnyType: Boolean): Boolean;
  534. var
  535. AnyValue: TValue;
  536. begin
  537. Result := TryCast(ATypeInfo, AnyValue, EmptyAsAnyType);
  538. end;
  539. generic function TValue.IsType<T>(const EmptyAsAnyType: Boolean): Boolean;
  540. begin
  541. Result := IsType(System.TypeInfo(T), EmptyAsAnyType);
  542. end;
  543. function TValue.TryCast(ATypeInfo: TTypeInfo; out AResult: TValue; const EmptyAsAnyType: Boolean): Boolean;
  544. function ConversionAccepted: TTypeKinds;
  545. begin
  546. case TypeInfo.Kind of
  547. tkString: Exit([tkChar, tkString]);
  548. tkDouble: Exit([tkInteger, tkDouble]);
  549. tkEnumeration: Exit([tkInteger, tkEnumeration]);
  550. else Exit([TypeInfo.Kind]);
  551. end;
  552. end;
  553. begin
  554. if EmptyAsAnyType and IsEmpty then
  555. begin
  556. AResult := TValue.Empty;
  557. if ATypeInfo <> nil then
  558. begin
  559. AResult.FTypeInfo := ATypeInfo;
  560. case ATypeInfo.Kind of
  561. tkBool: AResult.FData := False;
  562. tkChar: AResult.FData := #0;
  563. tkString: AResult.FData := EmptyStr;
  564. tkDouble,
  565. tkEnumeration,
  566. tkInteger: AResult.FData := 0;
  567. end;
  568. Exit(True);
  569. end;
  570. end;
  571. if not EmptyAsAnyType and (FTypeInfo = nil) then
  572. Exit(False);
  573. if FTypeInfo = ATypeInfo then
  574. begin
  575. AResult := Self;
  576. Exit(True);
  577. end;
  578. if ATypeInfo = nil then
  579. Exit(False);
  580. if ATypeInfo = System.TypeInfo(TValue) then
  581. begin
  582. TValue.Make(Self, System.TypeInfo(TValue), AResult);
  583. Exit(True);
  584. end;
  585. Result := ATypeInfo.Kind in ConversionAccepted;
  586. if Result then
  587. begin
  588. AResult.FData := FData;
  589. AResult.FTypeInfo := ATypeInfo;
  590. end;
  591. end;
  592. class function TValue.FromJSValue(v: JSValue): TValue;
  593. var
  594. i: NativeInt;
  595. TypeOfValue: TTypeInfo;
  596. begin
  597. case jsTypeOf(v) of
  598. 'number':
  599. if JS.isInteger(v) then
  600. begin
  601. i:=NativeInt(v);
  602. if (i>=low(integer)) and (i<=high(integer)) then
  603. TypeOfValue:=System.TypeInfo(Integer)
  604. else
  605. TypeOfValue:=System.TypeInfo(NativeInt);
  606. end
  607. else
  608. TypeOfValue:=system.TypeInfo(Double);
  609. 'string': TypeOfValue:=System.TypeInfo(String);
  610. 'boolean': TypeOfValue:=System.TypeInfo(Boolean);
  611. 'object':
  612. if v=nil then
  613. Exit(TValue.Empty)
  614. else if JS.isClass(v) and JS.isExt(v,TObject) then
  615. TypeOfValue:=System.TypeInfo(TClass(v))
  616. else if JS.isObject(v) and JS.isExt(v,TObject) then
  617. TypeOfValue:=System.TypeInfo(TObject(v))
  618. else if isRecord(v) then
  619. TypeOfValue:=System.TypeInfo(TObject(v))
  620. else if TJSArray.IsArray(V) then
  621. TypeOfValue:=System.TypeInfo(TObject(v))
  622. else
  623. raise EInvalidCast.Create('Type not recognized in FromJSValue!');
  624. else
  625. TypeOfValue:=System.TypeInfo(JSValue);
  626. end;
  627. Make(v, TypeOfValue, Result);
  628. end;
  629. class function TValue.FromArray(TypeInfo: TTypeInfo; const Values: specialize TArray<TValue>): TValue;
  630. var
  631. A: Integer;
  632. DynTypeInfo: TTypeInfoDynArray absolute TypeInfo;
  633. NewArray: TJSArray;
  634. ElementType: TTypeInfo;
  635. begin
  636. if TypeInfo.Kind <> tkDynArray then
  637. raise EInvalidCast.Create('Type not an array in FromArray!');
  638. ElementType := DynTypeInfo.ElType;
  639. NewArray := TJSArray.new;
  640. NewArray.Length := Length(Values);
  641. for A := 0 to High(Values) do
  642. NewArray[A] := Values[A].Cast(ElementType).AsJSValue;
  643. Result.FData := NewArray;
  644. Result.FTypeInfo := TypeInfo;
  645. end;
  646. class function TValue.FromOrdinal(ATypeInfo: TTypeInfo; AValue: JSValue): TValue;
  647. begin
  648. if (ATypeInfo = nil) or not (ATypeInfo.Kind in [tkBool, tkEnumeration, tkInteger]) then
  649. raise EInvalidCast.Create('Invalid type in FromOrdinal');
  650. if ATypeInfo.Kind = tkBool then
  651. TValue.Make(AValue = True, ATypeInfo, Result)
  652. else
  653. TValue.Make(NativeInt(AValue), ATypeInfo, Result);
  654. end;
  655. function TValue.IsObject: boolean;
  656. begin
  657. Result:=IsEmpty or (TypeInfo.Kind=tkClass);
  658. end;
  659. function TValue.AsObject: TObject;
  660. begin
  661. if IsObject or (IsClass and not js.isObject(FData)) then
  662. Result := TObject(FData)
  663. else
  664. raise EInvalidCast.Create(SErrInvalidTypecast);
  665. end;
  666. function TValue.IsObjectInstance: boolean;
  667. begin
  668. Result:=(TypeInfo<>nil) and (TypeInfo.Kind=tkClass);
  669. end;
  670. function TValue.IsArray: boolean;
  671. begin
  672. case Kind of
  673. tkDynArray: Exit(True);
  674. tkArray: Exit(Length(TTypeInfoStaticArray(FTypeInfo).Dims) = 1);
  675. else Result := False;
  676. end;
  677. end;
  678. function TValue.IsClass: boolean;
  679. var
  680. k: TTypeKind;
  681. begin
  682. k:=Kind;
  683. Result := (k = tkClassRef)
  684. or ((k in [tkClass,tkUnknown]) and not JS.IsObject(FData));
  685. end;
  686. function TValue.AsClass: TClass;
  687. begin
  688. if IsClass then
  689. Result := TClass(FData)
  690. else
  691. raise EInvalidCast.Create(SErrInvalidTypecast);
  692. end;
  693. function TValue.IsOrdinal: boolean;
  694. var
  695. k: TTypeKind;
  696. begin
  697. k:=Kind;
  698. Result := (k in [tkInteger, tkBool]) or
  699. ((k in [tkClass, tkClassRef, tkUnknown]) and not JS.isObject(FData));
  700. end;
  701. function TValue.AsOrdinal: NativeInt;
  702. begin
  703. if IsOrdinal then
  704. Result:=NativeInt(FData)
  705. else
  706. raise EInvalidCast.Create(SErrInvalidTypecast);
  707. end;
  708. function TValue.AsBoolean: boolean;
  709. begin
  710. if (Kind = tkBool) then
  711. Result:=boolean(FData)
  712. else
  713. raise EInvalidCast.Create(SErrInvalidTypecast);
  714. end;
  715. function TValue.AsInteger: Integer;
  716. begin
  717. if JS.isInteger(FData) then
  718. Result:=NativeInt(FData)
  719. else
  720. raise EInvalidCast.Create(SErrInvalidTypecast);
  721. end;
  722. function TValue.AsNativeInt: NativeInt;
  723. begin
  724. if JS.isInteger(FData) then
  725. Result:=NativeInt(FData)
  726. else
  727. raise EInvalidCast.Create(SErrInvalidTypecast);
  728. end;
  729. function TValue.AsInterface: IInterface;
  730. var
  731. k: TTypeKind;
  732. begin
  733. k:=Kind;
  734. if k = tkInterface then
  735. Result := IInterface(FData)// ToDo
  736. else if (k in [tkClass, tkClassRef, tkUnknown]) and not JS.isObject(FData) then
  737. Result := Nil
  738. else
  739. raise EInvalidCast.Create(SErrInvalidTypecast);
  740. end;
  741. function TValue.AsString: string;
  742. begin
  743. if js.isString(FData) then
  744. Result:=String(FData)
  745. else
  746. raise EInvalidCast.Create(SErrInvalidTypecast);
  747. end;
  748. function TValue.AsUnicodeString: UnicodeString;
  749. begin
  750. Result:=AsString;
  751. end;
  752. function TValue.AsExtended: Extended;
  753. begin
  754. if js.isNumber(FData) then
  755. Result:=Double(FData)
  756. else
  757. raise EInvalidCast.Create(SErrInvalidTypecast);
  758. end;
  759. function TValue.ToString: String;
  760. begin
  761. case Kind of
  762. tkString: Result := AsString;
  763. tkInteger: Result := IntToStr(AsNativeInt);
  764. tkBool: Result := BoolToStr(AsBoolean, True);
  765. else
  766. Result := '';
  767. end;
  768. end;
  769. function TValue.GetArrayLength: SizeInt;
  770. begin
  771. if IsArray then
  772. Exit(Length(TJSValueDynArray(FData)));
  773. raise EInvalidCast.Create(SErrInvalidTypecast);
  774. end;
  775. function TValue.GetArrayElement(aIndex: SizeInt): TValue;
  776. begin
  777. if IsArray then
  778. begin
  779. case Kind of
  780. tkArray: Result.FTypeInfo:=TTypeInfoStaticArray(FTypeInfo).ElType;
  781. tkDynArray: Result.FTypeInfo:=TTypeInfoDynArray(FTypeInfo).ElType;
  782. end;
  783. Result.FData:=TJSValueDynArray(FData)[aIndex];
  784. end
  785. else
  786. raise EInvalidCast.Create(SErrInvalidTypecast);
  787. end;
  788. procedure TValue.SetArrayLength(const Size: SizeInt);
  789. var
  790. NewArray: TJSValueDynArray;
  791. begin
  792. NewArray := TJSValueDynArray(FData);
  793. SetLength(NewArray, Size);
  794. FData := NewArray;
  795. end;
  796. procedure TValue.SetArrayElement(aIndex: SizeInt; const AValue: TValue);
  797. begin
  798. if IsArray then
  799. TJSValueDynArray(FData)[aIndex] := AValue.AsJSValue
  800. else
  801. raise EInvalidCast.Create(SErrInvalidTypecast);
  802. end;
  803. function TValue.IsType(ATypeInfo: TTypeInfo): boolean;
  804. begin
  805. Result := ATypeInfo = TypeInfo;
  806. end;
  807. function TValue.GetIsEmpty: boolean;
  808. begin
  809. if (TypeInfo=nil) or (FData=Undefined) or (FData=nil) then
  810. exit(true);
  811. case TypeInfo.Kind of
  812. tkDynArray:
  813. Result:=TJSArray(FData).Length=0;
  814. else
  815. Result:=false;
  816. end;
  817. end;
  818. function TValue.AsJSValue: JSValue;
  819. begin
  820. Result := FData;
  821. end;
  822. class function TValue.Empty: TValue;
  823. begin
  824. Result.FData := nil;
  825. Result.FTypeInfo := nil;
  826. end;
  827. { TRttiStructuredType }
  828. function TRttiStructuredType.GetMethods: TRttiMethodArray;
  829. var
  830. A, Start: Integer;
  831. BaseClass: TRttiStructuredType;
  832. Declared: TRttiMethodArray;
  833. begin
  834. BaseClass := Self;
  835. Result := nil;
  836. while Assigned(BaseClass) do
  837. begin
  838. Declared := BaseClass.GetDeclaredMethods;
  839. Start := Length(Result);
  840. SetLength(Result, Start + Length(Declared));
  841. for A := Low(Declared) to High(Declared) do
  842. Result[Start + A] := Declared[A];
  843. BaseClass := BaseClass.GetAncestor;
  844. end;
  845. end;
  846. function TRttiStructuredType.GetMethods(const aName: String): TRttiMethodArray;
  847. var
  848. Method: TRttiMethod;
  849. MethodCount: Integer;
  850. begin
  851. MethodCount := 0;
  852. for Method in GetMethods do
  853. if aName = Method.Name then
  854. Inc(MethodCount);
  855. SetLength(Result, MethodCount);
  856. for Method in GetMethods do
  857. if aName = Method.Name then
  858. begin
  859. Dec(MethodCount);
  860. Result[MethodCount] := Method;
  861. end;
  862. end;
  863. function TRttiStructuredType.GetProperties: TRttiPropertyArray;
  864. var
  865. A, Start: Integer;
  866. BaseClass: TRttiStructuredType;
  867. Declared: TRttiPropertyArray;
  868. begin
  869. BaseClass := Self;
  870. Result := nil;
  871. while Assigned(BaseClass) do
  872. begin
  873. Declared := BaseClass.GetDeclaredProperties;
  874. Start := Length(Result);
  875. SetLength(Result, Start + Length(Declared));
  876. for A := Low(Declared) to High(Declared) do
  877. Result[Start + A] := Declared[A];
  878. BaseClass := BaseClass.GetAncestor;
  879. end;
  880. end;
  881. function TRttiStructuredType.GetMethod(const aName: String): TRttiMethod;
  882. var
  883. Method: TRttiMethod;
  884. begin
  885. for Method in GetMethods do
  886. if aName = Method.Name then
  887. Exit(Method);
  888. end;
  889. function TRttiStructuredType.GetProperty(const AName: string): TRttiProperty;
  890. var
  891. Prop: TRttiProperty;
  892. begin
  893. for Prop in GetProperties do
  894. if Prop.Name = AName then
  895. Exit(Prop);
  896. end;
  897. function TRttiStructuredType.GetDeclaredProperties: TRttiPropertyArray;
  898. var
  899. A, PropCount: Integer;
  900. begin
  901. if not Assigned(FProperties) then
  902. begin
  903. PropCount := StructTypeInfo.PropCount;
  904. SetLength(FProperties, PropCount);
  905. for A := 0 to Pred(PropCount) do
  906. FProperties[A] := TRttiProperty.Create(Self, StructTypeInfo.GetProp(A));
  907. end;
  908. Result := FProperties;
  909. end;
  910. function TRttiStructuredType.GetAncestor: TRttiStructuredType;
  911. begin
  912. Result := nil;
  913. end;
  914. function TRttiStructuredType.GetStructTypeInfo: TTypeInfoStruct;
  915. begin
  916. Result:=TTypeInfoStruct(inherited Handle);
  917. end;
  918. constructor TRttiStructuredType.Create(AParent: TRttiObject; ATypeInfo: PTypeInfo);
  919. begin
  920. if not (TTypeInfo(ATypeInfo) is TTypeInfoStruct) then
  921. raise EInvalidCast.Create('');
  922. inherited;
  923. end;
  924. destructor TRttiStructuredType.Destroy;
  925. var
  926. Method: TRttiMethod;
  927. Prop: TRttiProperty;
  928. begin
  929. for Method in FMethods do
  930. Method.Free;
  931. for Prop in FProperties do
  932. Prop.Free;
  933. inherited Destroy;
  934. end;
  935. function TRttiStructuredType.GetDeclaredMethods: TRttiMethodArray;
  936. var
  937. A, MethodCount: Integer;
  938. begin
  939. if not Assigned(FMethods) then
  940. begin
  941. MethodCount := StructTypeInfo.MethodCount;
  942. SetLength(FMethods, MethodCount);
  943. for A := 0 to Pred(MethodCount) do
  944. FMethods[A] := TRttiMethod.Create(Self, StructTypeInfo.GetMethod(A));
  945. end;
  946. Result := FMethods;
  947. end;
  948. function TRttiStructuredType.GetDeclaredFields: TRttiFieldArray;
  949. var
  950. A, FieldCount: Integer;
  951. begin
  952. if not Assigned(FFields) then
  953. begin
  954. FieldCount := StructTypeInfo.FieldCount;
  955. SetLength(FFields, FieldCount);
  956. for A := 0 to Pred(FieldCount) do
  957. FFields[A] := TRttiField.Create(Self, StructTypeInfo.GetField(A));
  958. end;
  959. Result := FFields;
  960. end;
  961. function TRttiStructuredType.GetFields: TRttiFieldArray;
  962. var
  963. A, Start: Integer;
  964. BaseClass: TRttiStructuredType;
  965. Declared: TRttiFieldArray;
  966. begin
  967. BaseClass := Self;
  968. Result := nil;
  969. while Assigned(BaseClass) do
  970. begin
  971. Declared := BaseClass.GetDeclaredFields;
  972. Start := Length(Result);
  973. SetLength(Result, Start + Length(Declared));
  974. for A := Low(Declared) to High(Declared) do
  975. Result[Start + A] := Declared[A];
  976. BaseClass := BaseClass.GetAncestor;
  977. end;
  978. end;
  979. { TRttiInstanceType }
  980. function TRttiInstanceType.GetClassTypeInfo: TTypeInfoClass;
  981. begin
  982. Result:=TTypeInfoClass(inherited Handle);
  983. end;
  984. function TRttiInstanceType.GetMetaClassType: TClass;
  985. begin
  986. Result:=ClassTypeInfo.ClassType;
  987. end;
  988. function TRttiInstanceType.GetAncestor: TRttiStructuredType;
  989. begin
  990. Result := GetAncestorType;
  991. end;
  992. function TRttiInstanceType.GetBaseType: TRttiType;
  993. begin
  994. Result:=GetAncestorType;
  995. end;
  996. function TRttiInstanceType.GetAncestorType: TRttiInstanceType;
  997. begin
  998. Result := inherited Parent as TRttiInstanceType;
  999. end;
  1000. constructor TRttiInstanceType.Create(AParent: TRttiObject; ATypeInfo: PTypeInfo);
  1001. begin
  1002. if not (TTypeInfo(ATypeInfo) is TTypeInfoClass) then
  1003. raise EInvalidCast.Create('');
  1004. inherited;
  1005. end;
  1006. { TRttiInterfaceType }
  1007. constructor TRttiInterfaceType.Create(AParent: TRttiObject; ATypeInfo: PTypeInfo);
  1008. begin
  1009. if not (TTypeInfo(ATypeInfo) is TTypeInfoInterface) then
  1010. raise EInvalidCast.Create('');
  1011. inherited;
  1012. end;
  1013. function TRttiInterfaceType.GetGUID: TGUID;
  1014. var
  1015. Guid: String;
  1016. begin
  1017. Guid := String(InterfaceTypeInfo.InterfaceType['$guid']);
  1018. TryStringToGUID(Guid, Result);
  1019. end;
  1020. function TRttiInterfaceType.GetInterfaceTypeInfo: TTypeInfoInterface;
  1021. begin
  1022. Result := TTypeInfoInterface(inherited Handle);
  1023. end;
  1024. function TRttiInterfaceType.GetAncestor: TRttiStructuredType;
  1025. begin
  1026. Result := GetAncestorType;
  1027. end;
  1028. function TRttiInterfaceType.GetBaseType: TRttiType;
  1029. begin
  1030. Result:=GetAncestorType;
  1031. end;
  1032. function TRttiInterfaceType.GetAncestorType: TRttiInterfaceType;
  1033. begin
  1034. Result := GRttiContext.GetType(InterfaceTypeInfo.Ancestor) as TRttiInterfaceType;
  1035. end;
  1036. { TRttiRecordType }
  1037. function TRttiRecordType.GetRecordTypeInfo: TTypeInfoRecord;
  1038. begin
  1039. Result := TTypeInfoRecord(inherited Handle);
  1040. end;
  1041. function TRttiRecordType.GetIsRecord: Boolean;
  1042. begin
  1043. Result := True;
  1044. end;
  1045. constructor TRttiRecordType.Create(AParent: TRttiObject; ATypeInfo: PTypeInfo);
  1046. begin
  1047. if not (TTypeInfo(ATypeInfo) is TTypeInfoRecord) then
  1048. raise EInvalidCast.Create('');
  1049. inherited;
  1050. end;
  1051. { TRttiClassRefType }
  1052. constructor TRttiClassRefType.Create(AParent: TRttiObject; ATypeInfo: PTypeInfo);
  1053. begin
  1054. if not (TTypeInfo(ATypeInfo) is TTypeInfoClassRef) then
  1055. raise EInvalidCast.Create('');
  1056. inherited;
  1057. end;
  1058. function TRttiClassRefType.GetClassRefTypeInfo: TTypeInfoClassRef;
  1059. begin
  1060. Result := TTypeInfoClassRef(inherited Handle);
  1061. end;
  1062. function TRttiClassRefType.GetInstanceType: TRttiInstanceType;
  1063. begin
  1064. Result := GRttiContext.GetType(ClassRefTypeInfo.InstanceType) as TRttiInstanceType;
  1065. end;
  1066. function TRttiClassRefType.GetMetaclassType: TClass;
  1067. begin
  1068. Result := InstanceType.MetaClassType;
  1069. end;
  1070. { TRttiInstanceExternalType }
  1071. function TRttiInstanceExternalType.GetAncestor: TRttiInstanceExternalType;
  1072. begin
  1073. Result := GRttiContext.GetType(ExternalClassTypeInfo.Ancestor) as TRttiInstanceExternalType;
  1074. end;
  1075. function TRttiInstanceExternalType.GetExternalClassTypeInfo: TTypeInfoExtClass;
  1076. begin
  1077. Result := TTypeInfoExtClass(inherited Handle);
  1078. end;
  1079. function TRttiInstanceExternalType.GetExternalName: String;
  1080. begin
  1081. Result := ExternalClassTypeInfo.JSClassName;
  1082. end;
  1083. constructor TRttiInstanceExternalType.Create(AParent: TRttiObject; ATypeInfo: PTypeInfo);
  1084. begin
  1085. if not (TTypeInfo(ATypeInfo) is TTypeInfoExtClass) then
  1086. raise EInvalidCast.Create('');
  1087. inherited;
  1088. end;
  1089. { TRTTIContext }
  1090. class function TRTTIContext.Create: TRTTIContext;
  1091. begin
  1092. if GRttiContext.FPool = Undefined then
  1093. GRttiContext.FPool := TJSObject.new;
  1094. Inc(GRttiContext.FReferenceCount);
  1095. Result := GRttiContext;
  1096. end;
  1097. procedure TRTTIContext.Free;
  1098. var
  1099. key: string;
  1100. o: TRttiType;
  1101. begin
  1102. Dec(GRttiContext.FReferenceCount);
  1103. if GRttiContext.FReferenceCount = 0 then
  1104. begin
  1105. for key in FPool do
  1106. if FPool.hasOwnProperty(key) then
  1107. begin
  1108. o:=TRttiType(FPool[key]);
  1109. o.Free;
  1110. end;
  1111. FPool := nil;
  1112. end;
  1113. end;
  1114. function TRTTIContext.GetType(aTypeInfo: PTypeInfo): TRttiType;
  1115. var
  1116. RttiTypeClass: array[TTypeKind] of TRttiTypeClass = (
  1117. nil, // tkUnknown
  1118. TRttiOrdinalType, // tkInteger
  1119. TRttiOrdinalType, // tkChar
  1120. TRttiType, // tkString
  1121. TRttiEnumerationType, // tkEnumeration
  1122. TRttiType, // tkSet
  1123. TRttiType, // tkDouble
  1124. TRttiType, // tkBool
  1125. TRttiType, // tkProcVar
  1126. TRttiType, // tkMethod
  1127. TRttiType, // tkArray
  1128. TRttiDynamicArrayType, // tkDynArray
  1129. TRttiRecordType, // tkRecord
  1130. TRttiInstanceType, // tkClass
  1131. TRttiClassRefType, // tkClassRef
  1132. TRttiType, // tkPointer
  1133. TRttiType, // tkJSValue
  1134. TRttiType, // tkRefToProcVar
  1135. TRttiInterfaceType, // tkInterface
  1136. TRttiType, // tkHelper
  1137. TRttiInstanceExternalType // tkExtClass
  1138. );
  1139. t: TTypeInfo absolute aTypeInfo;
  1140. Name: String;
  1141. Parent: TRttiObject;
  1142. begin
  1143. if IsNull(aTypeInfo) or IsUndefined(aTypeInfo) then
  1144. Exit(nil);
  1145. Name:=t.Name;
  1146. if isModule(t.Module) then
  1147. Name:=t.Module.Name+'.'+Name;
  1148. if GRttiContext.FPool.hasOwnProperty(Name) then
  1149. Result:=TRttiType(GRttiContext.FPool[Name])
  1150. else
  1151. begin
  1152. if (T.Kind in [tkClass, tkInterface, tkHelper, tkExtClass]) and TJSObject(t).hasOwnProperty('ancestor') then
  1153. Parent := GetType(PTypeInfo(TJSObject(t)['ancestor']))
  1154. else
  1155. Parent := nil;
  1156. Result := RttiTypeClass[T.Kind].Create(Parent, ATypeInfo);
  1157. GRttiContext.FPool[Name]:=Result;
  1158. end;
  1159. end;
  1160. function TRTTIContext.GetType(aClass: TClass): TRTTIType;
  1161. begin
  1162. if aClass=nil then Exit(nil);
  1163. Result:=GetType(TypeInfo(aClass));
  1164. end;
  1165. function TRTTIContext.FindType(const AQualifiedName: String): TRttiType;
  1166. var
  1167. ModuleName, TypeName: String;
  1168. Module: TTypeInfoModule;
  1169. TypeFound: PTypeInfo;
  1170. begin
  1171. if GRttiContext.FPool.hasOwnProperty(AQualifiedName) then
  1172. Result := TRttiType(GRttiContext.FPool[AQualifiedName])
  1173. else
  1174. begin
  1175. Result := nil;
  1176. for ModuleName in TJSObject.Keys(pas) do
  1177. if AQualifiedName.StartsWith(ModuleName + '.') then
  1178. begin
  1179. Module := TTypeInfoModule(pas[ModuleName]);
  1180. TypeName := Copy(AQualifiedName, Length(ModuleName) + 2, Length(AQualifiedName));
  1181. if Module.RTTI.HasOwnProperty(TypeName) then
  1182. begin
  1183. TypeFound := PTypeInfo(Module.RTTI[TypeName]);
  1184. Exit(GetType(TypeFound));
  1185. end;
  1186. end;
  1187. end;
  1188. end;
  1189. function TRTTIContext.GetTypes: specialize TArray<TRttiType>;
  1190. var
  1191. ModuleName, ClassName: String;
  1192. ModuleTypes: TJSObject;
  1193. begin
  1194. for ModuleName in TJSObject.Keys(pas) do
  1195. begin
  1196. ModuleTypes := TTypeInfoModule(pas[ModuleName]).RTTI;
  1197. for ClassName in ModuleTypes do
  1198. if TJSObject(ModuleTypes[ClassName]).HasOwnProperty('name') and (ClassName[1] <> '$') then
  1199. GetType(PTypeInfo(ModuleTypes[ClassName]));
  1200. end;
  1201. Result := specialize TArray<TRttiType>(TJSObject.Values(Self.FPool));
  1202. end;
  1203. { TRttiObject }
  1204. constructor TRttiObject.Create(AParent: TRttiObject; AHandle: Pointer);
  1205. begin
  1206. FParent := AParent;
  1207. FHandle := AHandle;
  1208. end;
  1209. destructor TRttiObject.Destroy;
  1210. var
  1211. Attribute: TCustomAttribute;
  1212. begin
  1213. for Attribute in FAttributes do
  1214. Attribute.Free;
  1215. FAttributes := nil;
  1216. inherited Destroy;
  1217. end;
  1218. function TRttiObject.LoadCustomAttributes: TCustomAttributeArray;
  1219. begin
  1220. Result := nil;
  1221. end;
  1222. function TRttiObject.GetAttributes: TCustomAttributeArray;
  1223. begin
  1224. if not FAttributesLoaded then
  1225. begin
  1226. FAttributes := LoadCustomAttributes;
  1227. FAttributesLoaded := True;
  1228. end;
  1229. Result := FAttributes;
  1230. end;
  1231. { TRttiNamedObject }
  1232. function TRttiNamedObject.GetName: string;
  1233. begin
  1234. Result:='';
  1235. end;
  1236. { TRttiMember }
  1237. function TRttiMember.GetName: string;
  1238. begin
  1239. Result := MemberTypeInfo.Name;
  1240. end;
  1241. function TRttiMember.GetParent: TRttiType;
  1242. begin
  1243. Result := TRttiType(inherited Parent);
  1244. end;
  1245. function TRttiMember.GetVisibility: TMemberVisibility;
  1246. begin
  1247. Result := mvPublished;
  1248. end;
  1249. constructor TRttiMember.Create(AParent: TRttiType; ATypeInfo: TTypeMember);
  1250. begin
  1251. if not (ATypeInfo is TTypeMember) then
  1252. raise EInvalidCast.Create('');
  1253. inherited Create(AParent, ATypeInfo);
  1254. end;
  1255. function TRttiMember.LoadCustomAttributes: TCustomAttributeArray;
  1256. begin
  1257. Result := GetRTTIAttributes(MemberTypeInfo.Attributes);
  1258. end;
  1259. function TRttiMember.GetMemberTypeInfo: TTypeMember;
  1260. begin
  1261. Result := TTypeMember(inherited Handle);
  1262. end;
  1263. { TRttiField }
  1264. constructor TRttiField.Create(AParent: TRttiType; ATypeInfo: TTypeMember);
  1265. begin
  1266. if not (ATypeInfo is TTypeMemberField) then
  1267. raise EInvalidCast.Create('');
  1268. inherited;
  1269. end;
  1270. function TRttiField.GetFieldType: TRttiType;
  1271. begin
  1272. Result := GRttiContext.GetType(FieldTypeInfo.TypeInfo);
  1273. end;
  1274. function TRttiField.GetFieldTypeInfo: TTypeMemberField;
  1275. begin
  1276. Result := TTypeMemberField(inherited Handle);
  1277. end;
  1278. function TRttiField.GetValue(Instance: JSValue): TValue;
  1279. var
  1280. JSInstance: TJSObject absolute Instance;
  1281. begin
  1282. Result := TValue.FromJSValue(JSInstance[Name]);
  1283. end;
  1284. procedure TRttiField.SetValue(Instance: JSValue; const AValue: TValue);
  1285. var
  1286. JSInstance: TJSObject absolute Instance;
  1287. begin
  1288. JSInstance[Name] := AValue.Cast(FieldType.Handle, True).ASJSValue;
  1289. end;
  1290. { TRttiParameter }
  1291. function TRttiParameter.GetName: String;
  1292. begin
  1293. Result := FName;
  1294. end;
  1295. { TRttiMethod }
  1296. function TRttiMethod.GetMethodTypeInfo: TTypeMemberMethod;
  1297. begin
  1298. Result := TTypeMemberMethod(inherited Handle);
  1299. end;
  1300. function TRttiMethod.GetIsClassMethod: Boolean;
  1301. begin
  1302. Result:=MethodTypeInfo.MethodKind in [mkClassFunction,mkClassProcedure];
  1303. end;
  1304. function TRttiMethod.GetIsConstructor: Boolean;
  1305. begin
  1306. Result:=MethodTypeInfo.MethodKind=mkConstructor;
  1307. end;
  1308. function TRttiMethod.GetIsDestructor: Boolean;
  1309. begin
  1310. Result:=MethodTypeInfo.MethodKind=mkDestructor;
  1311. end;
  1312. function TRttiMethod.GetIsExternal: Boolean;
  1313. begin
  1314. Result := pfExternal in GetProcedureFlags;
  1315. end;
  1316. function TRttiMethod.GetIsStatic: Boolean;
  1317. begin
  1318. Result := pfStatic in GetProcedureFlags;
  1319. end;
  1320. function TRttiMethod.GetIsVarArgs: Boolean;
  1321. begin
  1322. Result := pfVarargs in GetProcedureFlags;
  1323. end;
  1324. function TRttiMethod.GetIsAsyncCall: Boolean;
  1325. begin
  1326. Result := (pfAsync in GetProcedureFlags) or Assigned(ReturnType) and ReturnType.IsInstanceExternal and (ReturnType.AsInstanceExternal.ExternalName = 'Promise');
  1327. end;
  1328. function TRttiMethod.GetIsSafeCall: Boolean;
  1329. begin
  1330. Result := pfSafeCall in GetProcedureFlags;
  1331. end;
  1332. function TRttiMethod.GetMethodKind: TMethodKind;
  1333. begin
  1334. Result:=MethodTypeInfo.MethodKind;;
  1335. end;
  1336. function TRttiMethod.GetProcedureFlags: TProcedureFlags;
  1337. const
  1338. PROCEDURE_FLAGS: array[TProcedureFlag] of NativeInt = (1, 2, 4, 8, 16);
  1339. var
  1340. Flag: TProcedureFlag;
  1341. ProcedureFlags: NativeInt;
  1342. begin
  1343. ProcedureFlags := MethodTypeInfo.ProcSig.Flags;
  1344. Result := [];
  1345. for Flag := Low(PROCEDURE_FLAGS) to High(PROCEDURE_FLAGS) do
  1346. if PROCEDURE_FLAGS[Flag] and ProcedureFlags > 0 then
  1347. Result := Result + [Flag];
  1348. end;
  1349. function TRttiMethod.GetReturnType: TRttiType;
  1350. begin
  1351. Result := GRttiContext.GetType(MethodTypeInfo.ProcSig.ResultType);
  1352. end;
  1353. procedure TRttiMethod.LoadParameters;
  1354. const
  1355. FLAGS_CONVERSION: array[TParamFlag] of NativeInt = (1, 2, 4, 8, 16, 32);
  1356. var
  1357. A: Integer;
  1358. Flag: TParamFlag;
  1359. Param: TProcedureParam;
  1360. RttiParam: TRttiParameter;
  1361. MethodParams: TProcedureParams;
  1362. begin
  1363. FParametersLoaded := True;
  1364. MethodParams := MethodTypeInfo.ProcSig.Params;
  1365. SetLength(FParameters, Length(MethodParams));
  1366. for A := Low(FParameters) to High(FParameters) do
  1367. begin
  1368. Param := MethodParams[A];
  1369. RttiParam := TRttiParameter.Create;
  1370. RttiParam.FName := Param.Name;
  1371. RttiParam.FParamType := GRttiContext.GetType(Param.TypeInfo);
  1372. for Flag := Low(FLAGS_CONVERSION) to High(FLAGS_CONVERSION) do
  1373. if FLAGS_CONVERSION[Flag] and Param.Flags > 0 then
  1374. RttiParam.FFlags := RttiParam.FFlags + [Flag];
  1375. FParameters[A] := RttiParam;
  1376. end;
  1377. end;
  1378. function TRttiMethod.GetParameters: TRttiParameterArray;
  1379. begin
  1380. if not FParametersLoaded then
  1381. LoadParameters;
  1382. Result := FParameters;
  1383. end;
  1384. { TRttiProperty }
  1385. constructor TRttiProperty.Create(AParent: TRttiType; ATypeInfo: TTypeMember);
  1386. begin
  1387. if not (ATypeInfo is TTypeMemberProperty) then
  1388. raise EInvalidCast.Create('');
  1389. inherited;
  1390. end;
  1391. function TRttiProperty.GetPropertyTypeInfo: TTypeMemberProperty;
  1392. begin
  1393. Result := TTypeMemberProperty(inherited Handle);
  1394. end;
  1395. function TRttiProperty.GetValue(Instance: JSValue): TValue;
  1396. var
  1397. JSObject: TJSObject absolute Instance;
  1398. begin
  1399. TValue.Make(GetJSValueProp(JSObject, PropertyTypeInfo), PropertyType.Handle, Result);
  1400. end;
  1401. procedure TRttiProperty.SetValue(Instance: JSValue; const AValue: TValue);
  1402. var
  1403. JSInstance: TJSObject absolute Instance;
  1404. begin
  1405. SetJSValueProp(JSInstance, PropertyTypeInfo, AValue.Cast(PropertyType.Handle, True).AsJSValue);
  1406. end;
  1407. function TRttiProperty.GetPropertyType: TRttiType;
  1408. begin
  1409. Result := GRttiContext.GetType(PropertyTypeInfo.TypeInfo);
  1410. end;
  1411. function TRttiProperty.GetIsWritable: boolean;
  1412. begin
  1413. Result := PropertyTypeInfo.Setter<>'';
  1414. end;
  1415. function TRttiProperty.GetIsReadable: boolean;
  1416. begin
  1417. Result := PropertyTypeInfo.Getter<>'';
  1418. end;
  1419. function TRttiProperty.GetVisibility: TMemberVisibility;
  1420. begin
  1421. // At this moment only published rtti-property-info is supported by pas2js
  1422. Result := mvPublished;
  1423. end;
  1424. { TRttiType }
  1425. function TRttiType.GetName: string;
  1426. begin
  1427. Result := Handle.Name;
  1428. end;
  1429. function TRttiType.GetIsInstance: boolean;
  1430. begin
  1431. Result:=Self is TRttiInstanceType;
  1432. end;
  1433. function TRttiType.GetIsInstanceExternal: boolean;
  1434. begin
  1435. Result:=Self is TRttiInstanceExternalType;
  1436. end;
  1437. function TRttiType.GetIsOrdinal: boolean;
  1438. begin
  1439. Result:=false;
  1440. end;
  1441. function TRttiType.GetIsRecord: boolean;
  1442. begin
  1443. Result:=false;
  1444. end;
  1445. function TRttiType.GetIsSet: boolean;
  1446. begin
  1447. Result:=false;
  1448. end;
  1449. function TRttiType.GetTypeKind: TTypeKind;
  1450. begin
  1451. Result:=Handle.Kind;
  1452. end;
  1453. function TRttiType.GetHandle: TTypeInfo;
  1454. begin
  1455. Result := TTypeInfo(inherited Handle);
  1456. end;
  1457. function TRttiType.GetBaseType: TRttiType;
  1458. begin
  1459. Result:=Nil;
  1460. end;
  1461. function TRttiType.GetAsInstance: TRttiInstanceType;
  1462. begin
  1463. Result := Self as TRttiInstanceType;
  1464. end;
  1465. function TRttiType.GetAsInstanceExternal: TRttiInstanceExternalType;
  1466. begin
  1467. Result := Self as TRttiInstanceExternalType;
  1468. end;
  1469. function TRttiType.LoadCustomAttributes: TCustomAttributeArray;
  1470. begin
  1471. Result:=GetRTTIAttributes(Handle.Attributes);
  1472. end;
  1473. function TRttiType.GetDeclaredProperties: TRttiPropertyArray;
  1474. begin
  1475. Result:=nil;
  1476. end;
  1477. function TRttiType.GetProperties: TRttiPropertyArray;
  1478. begin
  1479. Result:=nil;
  1480. end;
  1481. function TRttiType.GetProperty(const AName: string): TRttiProperty;
  1482. begin
  1483. Result:=nil;
  1484. if AName='' then ;
  1485. end;
  1486. function TRttiType.GetMethods: TRttiMethodArray;
  1487. begin
  1488. Result:=nil;
  1489. end;
  1490. function TRttiType.GetMethods(const aName: String): TRttiMethodArray;
  1491. begin
  1492. Result:=nil;
  1493. end;
  1494. function TRttiType.GetMethod(const aName: String): TRttiMethod;
  1495. begin
  1496. Result:=nil;
  1497. if aName='' then ;
  1498. end;
  1499. function TRttiType.GetDeclaredMethods: TRttiMethodArray;
  1500. begin
  1501. Result:=nil;
  1502. end;
  1503. function TRttiType.GetDeclaredFields: TRttiFieldArray;
  1504. begin
  1505. Result:=nil;
  1506. end;
  1507. function TRttiType.GetField(const AName: string): TRttiField;
  1508. var
  1509. AField: TRttiField;
  1510. begin
  1511. Result:=nil;
  1512. for AField in GetFields do
  1513. if AField.Name = AName then
  1514. Exit(AField);
  1515. end;
  1516. function TRttiType.GetFields: TRttiFieldArray;
  1517. begin
  1518. Result := nil;
  1519. end;
  1520. function TRttiType.GetQualifiedName: String;
  1521. begin
  1522. Result := Format('%s.%s', [Handle.Module.Name, Name]);
  1523. end;
  1524. { TVirtualInterface }
  1525. constructor TVirtualInterface.Create(InterfaceTypeInfo: Pointer); assembler;
  1526. asm
  1527. var IntfType = InterfaceTypeInfo.interface;
  1528. if (IntfType.$kind !== 'com') rtl.raiseE('EInvalidCast');
  1529. var guid = IntfType.$guid;
  1530. var i = Object.create(IntfType); // needed by IntfVar is IntfType
  1531. i.$o = this;
  1532. // copy IInterface methods: _AddRef, _Release, QueryInterface
  1533. var iinterfaceguid = '{00000000-0000-0000-C000-000000000046}';
  1534. var map = this.$intfmaps[iinterfaceguid];
  1535. for (var key in map){
  1536. var v = map[key];
  1537. if (typeof(v)!=='function') continue;
  1538. i[key] = map[key];
  1539. }
  1540. // all other methods call OnInvoke
  1541. do {
  1542. var names = IntfType.$names;
  1543. if (!names) break;
  1544. for (var j=0; j<names.length; j++){
  1545. let fnname = names[j];
  1546. if (i[fnname]) continue;
  1547. i[fnname] = function(){ return this.$o.FOnInvoke(fnname,arguments); };
  1548. }
  1549. IntfType = Object.getPrototypeOf(IntfType);
  1550. } while(IntfType!=null);
  1551. // create a new list of interface map, supporting IInterface and IntfType
  1552. this.$intfmaps = {};
  1553. this.$intfmaps[iinterfaceguid] = map;
  1554. this.$intfmaps[guid] = {};
  1555. // store the implementation of IntfType (used by the as-operator)
  1556. this.$interfaces = {};
  1557. this.$interfaces[guid] = i;
  1558. end;
  1559. constructor TVirtualInterface.Create(InterfaceTypeInfo: Pointer;
  1560. const InvokeEvent: TVirtualInterfaceInvokeEvent);
  1561. begin
  1562. Create(InterfaceTypeInfo);
  1563. OnInvoke:=InvokeEvent;
  1564. end;
  1565. function TVirtualInterface.QueryInterface(const iid: TGuid; out obj): Integer;
  1566. begin
  1567. Result := inherited QueryInterface(iid, obj);
  1568. end;
  1569. function Invoke(ACodeAddress: Pointer; const AArgs: TJSValueDynArray;
  1570. ACallConv: TCallConv; AResultType: PTypeInfo; AIsStatic: Boolean;
  1571. AIsConstructor: Boolean): TValue;
  1572. begin
  1573. if ACallConv=ccReg then ;
  1574. if AIsStatic then ;
  1575. if AIsConstructor then
  1576. raise EInvoke.Create('not supported');
  1577. if isFunction(ACodeAddress) then
  1578. begin
  1579. Result.FData := TJSFunction(ACodeAddress).apply(nil, AArgs);
  1580. if AResultType<>nil then
  1581. Result.FTypeInfo:=AResultType
  1582. else
  1583. Result.FTypeInfo:=TypeInfo(JSValue);
  1584. end
  1585. else
  1586. raise EInvoke.Create(SErrInvokeInvalidCodeAddr);
  1587. end;
  1588. end.