TTSnapObjects.h 53 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188
  1. //-------------------------------------------------------------------------------------------------------
  2. // Copyright (C) Microsoft. All rights reserved.
  3. // Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
  4. //-------------------------------------------------------------------------------------------------------
  5. #pragma once
  6. #if ENABLE_TTD
  7. namespace TTD
  8. {
  9. namespace NSSnapObjects
  10. {
  11. //////////////////
  12. //We basically build a fake vtable here and use it to fake class behavior without needing a virtual type features we don't need
  13. typedef Js::RecyclableObject*(*fPtr_DoObjectInflation)(const SnapObject* snpObject, InflateMap* inflator);
  14. typedef void(*fPtr_DoAddtlValueInstantiation)(const SnapObject* snpObject, Js::RecyclableObject* obj, InflateMap* inflator);
  15. typedef void(*fPtr_EmitAddtlInfo)(const SnapObject* snpObject, FileWriter* writer);
  16. typedef void(*fPtr_ParseAddtlInfo)(SnapObject* snpObject, FileReader* reader, SlabAllocator& alloc);
  17. //Since may types don't need to do anything more in some cases we have a nop functions we set the fptr to null
  18. struct SnapObjectVTable
  19. {
  20. fPtr_DoObjectInflation InflationFunc;
  21. fPtr_DoAddtlValueInstantiation AddtlInstationationFunc;
  22. fPtr_EmitAddtlInfo EmitAddtlInfoFunc;
  23. fPtr_ParseAddtlInfo ParseAddtlInfoFunc;
  24. };
  25. struct DependsOnInfo
  26. {
  27. uint32 DepOnCount;
  28. TTD_PTR_ID* DepOnPtrArray;
  29. };
  30. //////////////////
  31. //Base struct for each kind of object we have in the system also used to represent user defined objects directly
  32. //Although enumerators are not technically subtypes of Dynamic Object we include them here since they have ptrs and such
  33. struct SnapObject
  34. {
  35. //The id (address of the object)
  36. TTD_PTR_ID ObjectPtrId;
  37. //The tag we use to distinguish between kinds of snap objects
  38. SnapObjectType SnapObjectTag;
  39. //The type for the object
  40. NSSnapType::SnapType* SnapType;
  41. //The optional well known token for this object (or INVALID)
  42. TTD_WELLKNOWN_TOKEN OptWellKnownToken;
  43. //Return true if the object has the cross site vtable
  44. BOOL IsCrossSite;
  45. #if ENABLE_OBJECT_SOURCE_TRACKING
  46. DiagnosticOrigin DiagOriginInfo;
  47. #endif
  48. //The basic slots of the object the sizes are reproduced in a single array (VarArrayCount should be the same as MaxUsedSlotIndex from the type)
  49. uint32 VarArrayCount;
  50. TTDVar* VarArray;
  51. //The numeric indexed properties associated with the object (or invalid if no associated array)
  52. TTD_PTR_ID OptIndexedObjectArray;
  53. //Objects this depends on when creating (or nullptr if no dependencies)
  54. DependsOnInfo* OptDependsOnInfo;
  55. //A ptr for the remaining info which must be cast when needed by handler methods
  56. void* AddtlSnapObjectInfo;
  57. };
  58. //Access the AddtlSnapObjectInfo for the snap object as the specified kind (asserts on the tag and casts the data)
  59. template <typename T, SnapObjectType tag>
  60. T SnapObjectGetAddtlInfoAs(const SnapObject* snpObject)
  61. {
  62. TTDAssert(snpObject->SnapObjectTag == tag, "Tag does not match.");
  63. return reinterpret_cast<T>(snpObject->AddtlSnapObjectInfo);
  64. }
  65. template <typename T, SnapObjectType tag>
  66. void SnapObjectSetAddtlInfoAs(SnapObject* snpObject, T addtlInfo)
  67. {
  68. TTDAssert(sizeof(T) <= sizeof(void*), "Make sure your info fits into the space we have for it.");
  69. TTDAssert(snpObject->SnapObjectTag == tag, "Tag does not match.");
  70. snpObject->AddtlSnapObjectInfo = (void*)addtlInfo;
  71. }
  72. //The main method that should be called to extract the information from a snap object
  73. void ExtractCompoundObject(NSSnapObjects::SnapObject* sobj, Js::RecyclableObject* obj, bool isWellKnown, const TTDIdentifierDictionary<TTD_PTR_ID, NSSnapType::SnapType*>& idToTypeMap, SlabAllocator& alloc);
  74. //Extract the basic information for a snap object (helpers)
  75. void StdPropertyExtract_StaticType(SnapObject* snpObject, Js::RecyclableObject* obj);
  76. void StdPropertyExtract_DynamicType(SnapObject* snpObject, Js::DynamicObject* dynObj, SlabAllocator& alloc);
  77. //a simple helper that we can call during the extract to make sure all needed fields are initialized (in cases where the are *no* depends on pointers)
  78. template <typename T, SnapObjectType tag>
  79. void StdExtractSetKindSpecificInfo(SnapObject* snpObject, T addtlInfo)
  80. {
  81. SnapObjectSetAddtlInfoAs<T, tag>(snpObject, addtlInfo);
  82. }
  83. //a simple helper that we can call during the extract to make sure all needed fields are initialized (in cases where the *are* depends on pointers)
  84. template <typename T, SnapObjectType tag>
  85. void StdExtractSetKindSpecificInfo(SnapObject* snpObject, T addtlInfo, SlabAllocator& alloc, uint32 dependsOnArrayCount, TTD_PTR_ID* dependsOnArray)
  86. {
  87. SnapObjectSetAddtlInfoAs<T, tag>(snpObject, addtlInfo);
  88. TTDAssert(dependsOnArrayCount != 0 && dependsOnArray != nullptr, "Why are you calling this then?");
  89. snpObject->OptDependsOnInfo = alloc.SlabAllocateStruct<DependsOnInfo>();
  90. snpObject->OptDependsOnInfo->DepOnCount = dependsOnArrayCount;
  91. snpObject->OptDependsOnInfo->DepOnPtrArray = dependsOnArray;
  92. }
  93. //Check to see if we have an old version of this object around and, if so, clean up its type/handler/standard properties and return it
  94. Js::DynamicObject* ReuseObjectCheckAndReset(const SnapObject* snpObject, InflateMap* inflator);
  95. //TODO: this is a workaround check until we can reliably reset objects -- allows us to early check for non-resetability and fall back to fully recreating script contexts
  96. bool DoesObjectBlockScriptContextReuse(const SnapObject* snpObject, Js::DynamicObject* dynObj, InflateMap* inflator);
  97. Js::DynamicObject* ObjectPropertyReset_WellKnown(const SnapObject* snpObject, Js::DynamicObject* dynObj, InflateMap* inflator);
  98. Js::DynamicObject* ObjectPropertyReset_General(const SnapObject* snpObject, Js::DynamicObject* dynObj, InflateMap* inflator);
  99. //Set all the general properties for the object
  100. void StdPropertyRestore(const SnapObject* snpObject, Js::DynamicObject* obj, InflateMap* inflator);
  101. //serialize the object data
  102. void EmitObject(const SnapObject* snpObject, FileWriter* writer, NSTokens::Separator separator, const SnapObjectVTable* vtable, ThreadContext* threadContext);
  103. //de-serialize a SnapObject
  104. void ParseObject(SnapObject* snpObject, bool readSeparator, FileReader* reader, SlabAllocator& alloc, const SnapObjectVTable* vtable, const TTDIdentifierDictionary<TTD_PTR_ID, NSSnapType::SnapType*>& ptrIdToTypeMap);
  105. #if ENABLE_SNAPSHOT_COMPARE
  106. void AssertSnapEquiv(const SnapObject* sobj1, const SnapObject* sobj2, TTDCompareMap& compareMap);
  107. #endif
  108. ////
  109. //Functions for the VTable for DynamicObject tags
  110. Js::RecyclableObject* DoObjectInflation_SnapDynamicObject(const SnapObject* snpObject, InflateMap* inflator);
  111. //DoAddtlValueInstantiation is a nop
  112. //EmitAddtlInfo is a nop
  113. //ParseAddtlInfo is a nop
  114. //AssertSnapEquiv is a nop
  115. Js::RecyclableObject* DoObjectInflation_SnapExternalObject(const SnapObject* snpObject, InflateMap* inflator);
  116. //DoAddtlValueInstantiation is a nop
  117. //EmitAddtlInfo is a nop
  118. //ParseAddtlInfo is a nop
  119. //AssertSnapEquiv is a nop
  120. //////////////////
  121. //A struct that represents a script function object
  122. struct SnapScriptFunctionInfo
  123. {
  124. //The display name of the function
  125. TTString DebugFunctionName;
  126. //The function body reference id (if not library)
  127. TTD_PTR_ID BodyRefId;
  128. //The scope info for this function
  129. TTD_PTR_ID ScopeId;
  130. //The cached scope object for the function (if it has one)
  131. TTD_PTR_ID CachedScopeObjId;
  132. //The home object for the function (if it has one)
  133. TTD_PTR_ID HomeObjId;
  134. //If the function has computed name information and what it is (check if this is an invalid ptr)
  135. TTDVar ComputedNameInfo;
  136. };
  137. ////
  138. //Functions for the VTable for SnapScriptFunction tags
  139. Js::RecyclableObject* DoObjectInflation_SnapScriptFunctionInfo(const SnapObject* snpObject, InflateMap* inflator);
  140. void DoAddtlValueInstantiation_SnapScriptFunctionInfo(const SnapObject* snpObject, Js::RecyclableObject* obj, InflateMap* inflator);
  141. void DoAddtlValueInstantiation_SnapScriptFunctionInfoEx(const SnapScriptFunctionInfo* snapFuncInfo, Js::ScriptFunction* fobj, InflateMap* inflator);
  142. void EmitAddtlInfo_SnapScriptFunctionInfo(const SnapObject* snpObject, FileWriter* writer);
  143. void ParseAddtlInfo_SnapScriptFunctionInfo(SnapObject* snpObject, FileReader* reader, SlabAllocator& alloc);
  144. void EmitAddtlInfo_SnapScriptFunctionInfoEx(const SnapScriptFunctionInfo* snapFuncInfo, FileWriter* writer);
  145. void ParseAddtlInfo_SnapScriptFunctionInfoEx(SnapScriptFunctionInfo* snapFuncInfo, FileReader* reader, SlabAllocator& alloc);
  146. #if ENABLE_SNAPSHOT_COMPARE
  147. void AssertSnapEquiv_SnapScriptFunctionInfo(const SnapObject* sobj1, const SnapObject* sobj2, TTDCompareMap& compareMap);
  148. #endif
  149. ////
  150. //RuntimeFunction is resolved via a wellknowntag so we don't worry about it
  151. //DoObjectInflation is a nop (should either be wellknown or handled as a sub-type)
  152. //DoAddtlValueInstantiation is a nop
  153. //EmitAddtlInfo is a nop
  154. //ParseAddtlInfo is a nop
  155. //AssertSnapEquiv is a nop
  156. ////
  157. //ExternalFunction always traps to log so we don't need any special information
  158. Js::RecyclableObject* DoObjectInflation_SnapExternalFunctionInfo(const SnapObject* snpObject, InflateMap* inflator);
  159. //DoAddtlValueInstantiation is a nop
  160. void EmitAddtlInfo_SnapExternalFunctionInfo(const SnapObject* snpObject, FileWriter* writer);
  161. void ParseAddtlInfo_SnapExternalFunctionInfo(SnapObject* snpObject, FileReader* reader, SlabAllocator& alloc);
  162. #if ENABLE_SNAPSHOT_COMPARE
  163. void AssertSnapEquiv_SnapExternalFunctionInfo(const SnapObject* sobj1, const SnapObject* sobj2, TTDCompareMap& compareMap);
  164. #endif
  165. ////
  166. //RevokerFunction needs TTD_PTR_ID* for the proxy value
  167. Js::RecyclableObject* DoObjectInflation_SnapRevokerFunctionInfo(const SnapObject* snpObject, InflateMap* inflator);
  168. //DoAddtlValueInstantiation is a nop
  169. void EmitAddtlInfo_SnapRevokerFunctionInfo(const SnapObject* snpObject, FileWriter* writer);
  170. void ParseAddtlInfo_SnapRevokerFunctionInfo(SnapObject* snpObject, FileReader* reader, SlabAllocator& alloc);
  171. #if ENABLE_SNAPSHOT_COMPARE
  172. void AssertSnapEquiv_SnapRevokerFunctionInfo(const SnapObject* sobj1, const SnapObject* sobj2, TTDCompareMap& compareMap);
  173. #endif
  174. ////
  175. //Functions for the VTable for SnapBoundFunctionObject tags
  176. //A class that represents a script function object
  177. struct SnapBoundFunctionInfo
  178. {
  179. //The function that is bound
  180. TTD_PTR_ID TargetFunction;
  181. //The "this" parameter to use
  182. TTD_PTR_ID BoundThis;
  183. //The count of bound arguments
  184. uint32 ArgCount;
  185. //The arguments
  186. TTDVar* ArgArray;
  187. };
  188. Js::RecyclableObject* DoObjectInflation_SnapBoundFunctionInfo(const SnapObject* snpObject, InflateMap* inflator);
  189. //DoAddtlValueInstantiation is a nop
  190. void EmitAddtlInfo_SnapBoundFunctionInfo(const SnapObject* snpObject, FileWriter* writer);
  191. void ParseAddtlInfo_SnapBoundFunctionInfo(SnapObject* snpObject, FileReader* reader, SlabAllocator& alloc);
  192. #if ENABLE_SNAPSHOT_COMPARE
  193. void AssertSnapEquiv_SnapBoundFunctionInfo(const SnapObject* sobj1, const SnapObject* sobj2, TTDCompareMap& compareMap);
  194. #endif
  195. //////////////////
  196. ////
  197. //Functions for the VTable for ActivationObject tags
  198. Js::RecyclableObject* DoObjectInflation_SnapActivationInfo(const SnapObject* snpObject, InflateMap* inflator);
  199. Js::RecyclableObject* DoObjectInflation_SnapBlockActivationObject(const SnapObject* snpObject, InflateMap* inflator);
  200. Js::RecyclableObject* DoObjectInflation_SnapPseudoActivationObject(const SnapObject* snpObject, InflateMap* inflator);
  201. Js::RecyclableObject* DoObjectInflation_SnapConsoleScopeActivationObject(const SnapObject* snpObject, InflateMap* inflator);
  202. //DoAddtlValueInstantiation is a nop
  203. //EmitAddtlInfo is a nop
  204. //ParseAddtlInfo is a nop
  205. //AssertSnapEquiv is a nop
  206. //////////////////
  207. //A class that represents an arguments object info
  208. struct SnapHeapArgumentsInfo
  209. {
  210. //number of arguments
  211. uint32 NumOfArguments;
  212. //The frame object
  213. bool IsFrameNullPtr;
  214. TTD_PTR_ID FrameObject;
  215. uint32 FormalCount;
  216. byte* DeletedArgFlags;
  217. };
  218. ////
  219. //Functions for the VTable for ArgumentsObject tags
  220. Js::RecyclableObject* DoObjectInflation_SnapHeapArgumentsInfo(const SnapObject* snpObject, InflateMap* inflator);
  221. Js::RecyclableObject* DoObjectInflation_SnapES5HeapArgumentsInfo(const SnapObject* snpObject, InflateMap* inflator);
  222. template <SnapObjectType argsKind>
  223. void EmitAddtlInfo_SnapHeapArgumentsInfo(const SnapObject* snpObject, FileWriter* writer)
  224. {
  225. SnapHeapArgumentsInfo* argsInfo = SnapObjectGetAddtlInfoAs<SnapHeapArgumentsInfo*, argsKind>(snpObject);
  226. writer->WriteUInt32(NSTokens::Key::numberOfArgs, argsInfo->NumOfArguments, NSTokens::Separator::CommaAndBigSpaceSeparator);
  227. writer->WriteBool(NSTokens::Key::boolVal, argsInfo->IsFrameNullPtr, NSTokens::Separator::CommaSeparator);
  228. writer->WriteAddr(NSTokens::Key::objectId, argsInfo->FrameObject, NSTokens::Separator::CommaSeparator);
  229. writer->WriteLengthValue(argsInfo->FormalCount, NSTokens::Separator::CommaSeparator);
  230. writer->WriteKey(NSTokens::Key::deletedArgs, NSTokens::Separator::CommaSeparator);
  231. writer->WriteSequenceStart();
  232. for(uint32 i = 0; i < argsInfo->FormalCount; ++i)
  233. {
  234. writer->WriteNakedByte(argsInfo->DeletedArgFlags[i], i != 0 ? NSTokens::Separator::CommaSeparator : NSTokens::Separator::NoSeparator);
  235. }
  236. writer->WriteSequenceEnd();
  237. }
  238. template <SnapObjectType argsKind>
  239. void ParseAddtlInfo_SnapHeapArgumentsInfo(SnapObject* snpObject, FileReader* reader, SlabAllocator& alloc)
  240. {
  241. SnapHeapArgumentsInfo* argsInfo = alloc.SlabAllocateStruct<SnapHeapArgumentsInfo>();
  242. argsInfo->NumOfArguments = reader->ReadUInt32(NSTokens::Key::numberOfArgs, true);
  243. argsInfo->IsFrameNullPtr = reader->ReadBool(NSTokens::Key::boolVal, true);
  244. argsInfo->FrameObject = reader->ReadAddr(NSTokens::Key::objectId, true);
  245. argsInfo->FormalCount = reader->ReadLengthValue(true);
  246. if(argsInfo->FormalCount == 0)
  247. {
  248. argsInfo->DeletedArgFlags = nullptr;
  249. }
  250. else
  251. {
  252. argsInfo->DeletedArgFlags = alloc.SlabAllocateArray<byte>(argsInfo->FormalCount);
  253. }
  254. reader->ReadKey(NSTokens::Key::deletedArgs, true);
  255. reader->ReadSequenceStart();
  256. for(uint32 i = 0; i < argsInfo->FormalCount; ++i)
  257. {
  258. argsInfo->DeletedArgFlags[i] = reader->ReadNakedByte(i != 0);
  259. }
  260. reader->ReadSequenceEnd();
  261. SnapObjectSetAddtlInfoAs<SnapHeapArgumentsInfo*, argsKind>(snpObject, argsInfo);
  262. }
  263. #if ENABLE_SNAPSHOT_COMPARE
  264. template <SnapObjectType argsKind>
  265. void AssertSnapEquiv_SnapHeapArgumentsInfo(const SnapObject* sobj1, const SnapObject* sobj2, TTDCompareMap& compareMap)
  266. {
  267. SnapHeapArgumentsInfo* argsInfo1 = SnapObjectGetAddtlInfoAs<SnapHeapArgumentsInfo*, argsKind>(sobj1);
  268. SnapHeapArgumentsInfo* argsInfo2 = SnapObjectGetAddtlInfoAs<SnapHeapArgumentsInfo*, argsKind>(sobj2);
  269. compareMap.DiagnosticAssert(argsInfo1->NumOfArguments == argsInfo2->NumOfArguments);
  270. compareMap.DiagnosticAssert(argsInfo1->IsFrameNullPtr == argsInfo2->IsFrameNullPtr);
  271. compareMap.CheckConsistentAndAddPtrIdMapping_Special(argsInfo1->FrameObject, argsInfo2->FrameObject, _u("frameObject"));
  272. compareMap.DiagnosticAssert(argsInfo1->FormalCount == argsInfo2->FormalCount);
  273. for(uint32 i = 0; i < argsInfo1->FormalCount; ++i)
  274. {
  275. compareMap.DiagnosticAssert(argsInfo1->DeletedArgFlags[i] == argsInfo2->DeletedArgFlags[i]);
  276. }
  277. }
  278. #endif
  279. //////////////////
  280. ////
  281. //Promise Info
  282. struct SnapPromiseInfo
  283. {
  284. uint32 Status;
  285. bool isHandled;
  286. TTDVar Result;
  287. //
  288. //We have the reaction info's inline even theought we want to preserve their pointer identity when inflating.
  289. //So we duplicate data here but avoid needed to add more kinds to the mark/extract logic and will check on inflation.
  290. //
  291. uint32 ResolveReactionCount;
  292. NSSnapValues::SnapPromiseReactionInfo* ResolveReactions;
  293. uint32 RejectReactionCount;
  294. NSSnapValues::SnapPromiseReactionInfo* RejectReactions;
  295. };
  296. Js::RecyclableObject* DoObjectInflation_SnapPromiseInfo(const SnapObject* snpObject, InflateMap* inflator);
  297. //DoAddtlValueInstantiation is a nop
  298. void EmitAddtlInfo_SnapPromiseInfo(const SnapObject* snpObject, FileWriter* writer);
  299. void ParseAddtlInfo_SnapPromiseInfo(SnapObject* snpObject, FileReader* reader, SlabAllocator& alloc);
  300. #if ENABLE_SNAPSHOT_COMPARE
  301. void AssertSnapEquiv_SnapPromiseInfo(const SnapObject* sobj1, const SnapObject* sobj2, TTDCompareMap& compareMap);
  302. #endif
  303. ////
  304. //PromiseResolveOrRejectFunction Info
  305. struct SnapPromiseResolveOrRejectFunctionInfo
  306. {
  307. TTD_PTR_ID PromiseId;
  308. bool IsReject;
  309. //This has a pointer identity but we duplicate here and check on inflate
  310. TTD_PTR_ID AlreadyResolvedWrapperId;
  311. bool AlreadyResolvedValue;
  312. };
  313. Js::RecyclableObject* DoObjectInflation_SnapPromiseResolveOrRejectFunctionInfo(const SnapObject* snpObject, InflateMap* inflator);
  314. //DoAddtlValueInstantiation is a nop
  315. void EmitAddtlInfo_SnapPromiseResolveOrRejectFunctionInfo(const SnapObject* snpObject, FileWriter* writer);
  316. void ParseAddtlInfo_SnapPromiseResolveOrRejectFunctionInfo(SnapObject* snpObject, FileReader* reader, SlabAllocator& alloc);
  317. #if ENABLE_SNAPSHOT_COMPARE
  318. void AssertSnapEquiv_SnapPromiseResolveOrRejectFunctionInfo(const SnapObject* sobj1, const SnapObject* sobj2, TTDCompareMap& compareMap);
  319. #endif
  320. ////
  321. //ReactionTaskFunction Info
  322. struct SnapPromiseReactionTaskFunctionInfo
  323. {
  324. TTDVar Argument;
  325. TTD::NSSnapValues::SnapPromiseReactionInfo Reaction;
  326. };
  327. Js::RecyclableObject* DoObjectInflation_SnapPromiseReactionTaskFunctionInfo(const SnapObject* snpObject, InflateMap* inflator);
  328. //DoAddtlValueInstantiation is a nop
  329. void EmitAddtlInfo_SnapPromiseReactionTaskFunctionInfo(const SnapObject* snpObject, FileWriter* writer);
  330. void ParseAddtlInfo_SnapPromiseReactionTaskFunctionInfo(SnapObject* snpObject, FileReader* reader, SlabAllocator& alloc);
  331. #if ENABLE_SNAPSHOT_COMPARE
  332. void AssertSnapEquiv_SnapPromiseReactionTaskFunctionInfo(const SnapObject* sobj1, const SnapObject* sobj2, TTDCompareMap& compareMap);
  333. #endif
  334. ////
  335. //AllResolveElementFunctionObject Info
  336. struct SnapPromiseAllResolveElementFunctionInfo
  337. {
  338. NSSnapValues::SnapPromiseCapabilityInfo Capabilities;
  339. uint32 Index;
  340. TTD_PTR_ID RemainingElementsWrapperId;
  341. uint32 RemainingElementsValue;
  342. TTD_PTR_ID Values;
  343. bool AlreadyCalled;
  344. };
  345. Js::RecyclableObject* DoObjectInflation_SnapPromiseAllResolveElementFunctionInfo(const SnapObject* snpObject, InflateMap* inflator);
  346. //DoAddtlValueInstantiation is a nop
  347. void EmitAddtlInfo_SnapPromiseAllResolveElementFunctionInfo(const SnapObject* snpObject, FileWriter* writer);
  348. void ParseAddtlInfo_SnapPromiseAllResolveElementFunctionInfo(SnapObject* snpObject, FileReader* reader, SlabAllocator& alloc);
  349. #if ENABLE_SNAPSHOT_COMPARE
  350. void AssertSnapEquiv_SnapPromiseAllResolveElementFunctionInfo(const SnapObject* sobj1, const SnapObject* sobj2, TTDCompareMap& compareMap);
  351. #endif
  352. //////////////////
  353. ////
  354. //SnapBoxedValueObject is resolved via a TTDVar to the underlying value or ptrId
  355. Js::RecyclableObject* DoObjectInflation_SnapBoxedValue(const SnapObject* snpObject, InflateMap* inflator);
  356. void DoAddtlValueInstantiation_SnapBoxedValue(const SnapObject* snpObject, Js::RecyclableObject* obj, InflateMap* inflator);
  357. void EmitAddtlInfo_SnapBoxedValue(const SnapObject* snpObject, FileWriter* writer);
  358. void ParseAddtlInfo_SnapBoxedValue(SnapObject* snpObject, FileReader* reader, SlabAllocator& alloc);
  359. #if ENABLE_SNAPSHOT_COMPARE
  360. void AssertSnapEquiv_SnapBoxedValue(const SnapObject* sobj1, const SnapObject* sobj2, TTDCompareMap& compareMap);
  361. #endif
  362. ////
  363. //SnapDateObject is resolved via a double* value
  364. Js::RecyclableObject* DoObjectInflation_SnapDate(const SnapObject* snpObject, InflateMap* inflator);
  365. //DoAddtlValueInstantiation is a nop
  366. void EmitAddtlInfo_SnapDate(const SnapObject* snpObject, FileWriter* writer);
  367. void ParseAddtlInfo_SnapDate(SnapObject* snpObject, FileReader* reader, SlabAllocator& alloc);
  368. #if ENABLE_SNAPSHOT_COMPARE
  369. void AssertSnapEquiv_SnapDate(const SnapObject* sobj1, const SnapObject* sobj2, TTDCompareMap& compareMap);
  370. #endif
  371. //A struct that represents a regular expression object
  372. struct SnapRegexInfo
  373. {
  374. //The underlying regex string value
  375. TTString RegexStr;
  376. //Regex flags value
  377. UnifiedRegex::RegexFlags Flags;
  378. //The char count or flag value from the regex object
  379. CharCount LastIndexOrFlag;
  380. //The last index var from the regex object
  381. TTDVar LastIndexVar;
  382. };
  383. ////
  384. //Functions for the VTable for SnapRegexObject
  385. Js::RecyclableObject* DoObjectInflation_SnapRegexInfo(const SnapObject* snpObject, InflateMap* inflator);
  386. //DoAddtlValueInstantiation is a nop
  387. void EmitAddtlInfo_SnapRegexInfo(const SnapObject* snpObject, FileWriter* writer);
  388. void ParseAddtlInfo_SnapRegexInfo(SnapObject* snpObject, FileReader* reader, SlabAllocator& alloc);
  389. #if ENABLE_SNAPSHOT_COMPARE
  390. void AssertSnapEquiv_SnapRegexInfo(const SnapObject* sobj1, const SnapObject* sobj2, TTDCompareMap& compareMap);
  391. #endif
  392. ////
  393. //SnapErrorObject has no data currently so we nop on most things
  394. Js::RecyclableObject* DoObjectInflation_SnapError(const SnapObject* snpObject, InflateMap* inflator);
  395. //DoAddtlValueInstantiation is a nop
  396. //EmitAddtlInfo is a nop
  397. //ParseAddtlInfo is a nop
  398. //AssertSnapEquiv is a nop
  399. //////////////////
  400. //A struct that represents Javascript arrays and Native arrays (T can be Var, int32, or double)
  401. template<typename T>
  402. struct SnapArrayInfoBlock
  403. {
  404. //The index ranges that this info holds
  405. uint32 FirstIndex;
  406. uint32 LastIndex;
  407. //The contents of this array range [FirstIndex, LastIndex)
  408. T* ArrayRangeContents;
  409. byte* ArrayValidTags; //0 is invalid 1 is valid
  410. //The next slice of array elements
  411. SnapArrayInfoBlock<T>* Next;
  412. };
  413. //A struct that represents Javascript arrays and Native arrays (T can be Var, int32, or double)
  414. template<typename T>
  415. struct SnapArrayInfo
  416. {
  417. //The index ranges that this info holds
  418. uint32 Length;
  419. //The array elements or null if this is empty
  420. SnapArrayInfoBlock<T>* Data;
  421. };
  422. template<typename T, bool zeroFillValid>
  423. SnapArrayInfoBlock<T>* AllocateArrayInfoBlock(SlabAllocator& alloc, uint32 firstIndex, uint32 lastIndex)
  424. {
  425. SnapArrayInfoBlock<T>* sai = alloc.SlabAllocateStruct< SnapArrayInfoBlock<T> >();
  426. sai->FirstIndex = firstIndex;
  427. sai->LastIndex = lastIndex;
  428. sai->ArrayRangeContents = alloc.SlabAllocateArray<T>(lastIndex - firstIndex);
  429. sai->ArrayValidTags = alloc.SlabAllocateArray<byte>(lastIndex - firstIndex);
  430. //only zero valid flags (which guard the contents values)
  431. if(zeroFillValid)
  432. {
  433. memset(sai->ArrayValidTags, 0, lastIndex - firstIndex);
  434. }
  435. sai->Next = nullptr;
  436. return sai;
  437. }
  438. template<typename T>
  439. SnapArrayInfo<T>* ExtractArrayValues(Js::JavascriptArray* arrayObject, SlabAllocator& alloc)
  440. {
  441. SnapArrayInfoBlock<T>* sai = nullptr;
  442. uint32 length = arrayObject->GetLength();
  443. if(length == 0)
  444. {
  445. ; //just leave it as a null ptr
  446. }
  447. else if(length <= TTD_ARRAY_SMALL_ARRAY)
  448. {
  449. sai = AllocateArrayInfoBlock<T, false>(alloc, 0, length);
  450. for(uint32 i = 0; i < length; ++i)
  451. {
  452. sai->ArrayValidTags[i] = (byte)arrayObject->DirectGetItemAt<T>(i, sai->ArrayRangeContents + i);
  453. }
  454. }
  455. else
  456. {
  457. SnapArrayInfoBlock<T>* curr = nullptr;
  458. for(uint32 idx = arrayObject->GetNextIndex(Js::JavascriptArray::InvalidIndex); idx != Js::JavascriptArray::InvalidIndex; idx = arrayObject->GetNextIndex(idx))
  459. {
  460. if(sai == nullptr)
  461. {
  462. uint32 endIdx = (idx <= (Js::JavascriptArray::MaxArrayLength - TTD_ARRAY_BLOCK_SIZE)) ? (idx + TTD_ARRAY_BLOCK_SIZE) : Js::JavascriptArray::MaxArrayLength;
  463. sai = AllocateArrayInfoBlock<T, true>(alloc, idx, endIdx);
  464. curr = sai;
  465. }
  466. TTDAssert(curr != nullptr, "Should get set with variable sai above when needed!");
  467. if(idx >= curr->LastIndex)
  468. {
  469. uint32 endIdx = (idx <= (Js::JavascriptArray::MaxArrayLength - TTD_ARRAY_BLOCK_SIZE)) ? (idx + TTD_ARRAY_BLOCK_SIZE) : Js::JavascriptArray::MaxArrayLength;
  470. curr->Next = AllocateArrayInfoBlock<T, true>(alloc, idx, endIdx);
  471. curr = curr->Next;
  472. }
  473. curr->ArrayValidTags[idx - curr->FirstIndex] = TRUE;
  474. arrayObject->DirectGetItemAt<T>(idx, curr->ArrayRangeContents + (idx - curr->FirstIndex));
  475. }
  476. }
  477. SnapArrayInfo<T>* res = alloc.SlabAllocateStruct< SnapArrayInfo<T> >();
  478. res->Length = arrayObject->GetLength();
  479. res->Data = sai;
  480. return res;
  481. }
  482. int32 SnapArrayInfo_InflateValue(int32 value, InflateMap* inflator);
  483. void SnapArrayInfo_EmitValue(int32 value, FileWriter* writer);
  484. void SnapArrayInfo_ParseValue(int32* into, FileReader* reader, SlabAllocator& alloc);
  485. double SnapArrayInfo_InflateValue(double value, InflateMap* inflator);
  486. void SnapArrayInfo_EmitValue(double value, FileWriter* writer);
  487. void SnapArrayInfo_ParseValue(double* into, FileReader* reader, SlabAllocator& alloc);
  488. Js::Var SnapArrayInfo_InflateValue(TTDVar value, InflateMap* inflator);
  489. void SnapArrayInfo_EmitValue(TTDVar value, FileWriter* writer);
  490. void SnapArrayInfo_ParseValue(TTDVar* into, FileReader* reader, SlabAllocator& alloc);
  491. #if ENABLE_SNAPSHOT_COMPARE
  492. void SnapArrayInfo_EquivValue(int32 val1, int32 val2, TTDCompareMap& compareMap, int32 i);
  493. void SnapArrayInfo_EquivValue(double val1, double val2, TTDCompareMap& compareMap, int32 i);
  494. void SnapArrayInfo_EquivValue(TTDVar val1, TTDVar val2, TTDCompareMap& compareMap, int32 i);
  495. #endif
  496. ////
  497. //Functions for the VTable for SnapArrayObject tags
  498. template<typename T, SnapObjectType snapArrayKind>
  499. Js::RecyclableObject* DoObjectInflation_SnapArrayInfo(const SnapObject* snpObject, InflateMap* inflator)
  500. {
  501. //Arrays can change type on us so seems easiest to always re-create them.
  502. //We can re-evaluate this choice later if needed and add checks for same type-ness.
  503. const SnapArrayInfo<T>* arrayInfo = SnapObjectGetAddtlInfoAs<SnapArrayInfo<T>*, snapArrayKind>(snpObject);
  504. const SnapArrayInfoBlock<T>* dataBlock = arrayInfo->Data;
  505. Js::ScriptContext* ctx = inflator->LookupScriptContext(snpObject->SnapType->ScriptContextLogId);
  506. Js::JavascriptLibrary* jslib = ctx->GetLibrary();
  507. uint32 preAllocSpace = 0;
  508. if(dataBlock != nullptr && dataBlock->Next == nullptr && dataBlock->FirstIndex == 0 && dataBlock->LastIndex <= TTD_ARRAY_SMALL_ARRAY)
  509. {
  510. preAllocSpace = dataBlock->LastIndex; //first index is 0
  511. }
  512. if(snpObject->SnapType->JsTypeId == Js::TypeIds_Array)
  513. {
  514. if(preAllocSpace == 0)
  515. {
  516. return jslib->CreateArray();
  517. }
  518. else
  519. {
  520. Js::DynamicObject* rcObj = ReuseObjectCheckAndReset(snpObject, inflator);
  521. if(rcObj != nullptr)
  522. {
  523. Js::JavascriptArray::FromVar(rcObj)->SetLength(preAllocSpace);
  524. return rcObj;
  525. }
  526. else
  527. {
  528. return jslib->CreateArray(preAllocSpace);
  529. }
  530. }
  531. }
  532. else if(snpObject->SnapType->JsTypeId == Js::TypeIds_NativeIntArray)
  533. {
  534. return (preAllocSpace > 0) ? ctx->GetLibrary()->CreateNativeIntArray(preAllocSpace) : ctx->GetLibrary()->CreateNativeIntArray();
  535. }
  536. else if(snpObject->SnapType->JsTypeId == Js::TypeIds_NativeFloatArray)
  537. {
  538. return (preAllocSpace > 0) ? ctx->GetLibrary()->CreateNativeFloatArray(preAllocSpace) : ctx->GetLibrary()->CreateNativeFloatArray();
  539. }
  540. else
  541. {
  542. TTDAssert(false, "Unknown array type!");
  543. return nullptr;
  544. }
  545. }
  546. template<typename T, typename U>
  547. void DoAddtlValueInstantiation_SnapArrayInfoCore(SnapArrayInfo<T>* arrayInfo, Js::JavascriptArray* arrayObj, InflateMap* inflator)
  548. {
  549. const SnapArrayInfoBlock<T>* dataBlock = arrayInfo->Data;
  550. while(dataBlock != nullptr)
  551. {
  552. for(uint32 i = 0; i < (dataBlock->LastIndex - dataBlock->FirstIndex); ++i)
  553. {
  554. if(dataBlock->ArrayValidTags[i])
  555. {
  556. T ttdVal = dataBlock->ArrayRangeContents[i];
  557. U jsVal = SnapArrayInfo_InflateValue(ttdVal, inflator);
  558. arrayObj->DirectSetItemAt<U>(i + dataBlock->FirstIndex, jsVal);
  559. }
  560. }
  561. dataBlock = dataBlock->Next;
  562. }
  563. //Ensure this value is set correctly in case of sparse arrays
  564. arrayObj->SetLength(arrayInfo->Length);
  565. }
  566. template<typename T, typename U, SnapObjectType snapArrayKind>
  567. void DoAddtlValueInstantiation_SnapArrayInfo(const SnapObject* snpObject, Js::RecyclableObject* obj, InflateMap* inflator)
  568. {
  569. SnapArrayInfo<T>* arrayInfo = SnapObjectGetAddtlInfoAs<SnapArrayInfo<T>*, snapArrayKind>(snpObject);
  570. Js::JavascriptArray* arrayObj = static_cast<Js::JavascriptArray*>(obj);
  571. DoAddtlValueInstantiation_SnapArrayInfoCore<T, U>(arrayInfo, arrayObj, inflator);
  572. }
  573. template<typename T>
  574. void EmitAddtlInfo_SnapArrayInfoCore(SnapArrayInfo<T>* arrayInfo, FileWriter* writer)
  575. {
  576. writer->WriteLengthValue(arrayInfo->Length, NSTokens::Separator::CommaSeparator);
  577. uint32 blockCount = 0;
  578. for(SnapArrayInfoBlock<T>* currInfo = arrayInfo->Data; currInfo != nullptr; currInfo = currInfo->Next)
  579. {
  580. blockCount++;
  581. }
  582. writer->WriteLengthValue(blockCount, NSTokens::Separator::CommaAndBigSpaceSeparator);
  583. writer->WriteSequenceStart_DefaultKey(NSTokens::Separator::CommaSeparator);
  584. writer->AdjustIndent(1);
  585. for(SnapArrayInfoBlock<T>* currInfo = arrayInfo->Data; currInfo != nullptr; currInfo = currInfo->Next)
  586. {
  587. writer->WriteRecordStart(currInfo == arrayInfo->Data ? NSTokens::Separator::BigSpaceSeparator : NSTokens::Separator::CommaAndBigSpaceSeparator);
  588. writer->WriteUInt32(NSTokens::Key::index, currInfo->FirstIndex);
  589. writer->WriteUInt32(NSTokens::Key::offset, currInfo->LastIndex, NSTokens::Separator::CommaSeparator);
  590. writer->WriteSequenceStart_DefaultKey(NSTokens::Separator::CommaSeparator);
  591. for(uint32 i = currInfo->FirstIndex; i < currInfo->LastIndex; ++i)
  592. {
  593. uint32 j = (i - currInfo->FirstIndex);
  594. writer->WriteRecordStart(j == 0 ? NSTokens::Separator::NoSeparator : NSTokens::Separator::CommaSeparator);
  595. writer->WriteInt32(NSTokens::Key::isValid, currInfo->ArrayValidTags[j]);
  596. if(currInfo->ArrayValidTags[j])
  597. {
  598. SnapArrayInfo_EmitValue(currInfo->ArrayRangeContents[j], writer);
  599. }
  600. writer->WriteRecordEnd();
  601. }
  602. writer->WriteSequenceEnd();
  603. writer->WriteRecordEnd();
  604. }
  605. writer->AdjustIndent(-1);
  606. writer->WriteSequenceEnd(NSTokens::Separator::BigSpaceSeparator);
  607. }
  608. template<typename T, SnapObjectType snapArrayKind>
  609. void EmitAddtlInfo_SnapArrayInfo(const SnapObject* snpObject, FileWriter* writer)
  610. {
  611. SnapArrayInfo<T>* arrayInfo = SnapObjectGetAddtlInfoAs<SnapArrayInfo<T>*, snapArrayKind>(snpObject);
  612. EmitAddtlInfo_SnapArrayInfoCore<T>(arrayInfo, writer);
  613. }
  614. template<typename T>
  615. SnapArrayInfo<T>* ParseAddtlInfo_SnapArrayInfoCore(FileReader* reader, SlabAllocator& alloc)
  616. {
  617. uint32 alength = reader->ReadLengthValue(true);
  618. SnapArrayInfoBlock<T>* arrayInfo = nullptr;
  619. SnapArrayInfoBlock<T>* curr = nullptr;
  620. uint32 blockCount = reader->ReadLengthValue(true);
  621. reader->ReadSequenceStart_WDefaultKey(true);
  622. for(uint32 k = 0; k < blockCount; ++k)
  623. {
  624. reader->ReadRecordStart(k != 0);
  625. SnapArrayInfoBlock<T>* tmp = alloc.SlabAllocateStruct< SnapArrayInfoBlock<T> >();
  626. tmp->FirstIndex = reader->ReadUInt32(NSTokens::Key::index);
  627. tmp->LastIndex = reader->ReadUInt32(NSTokens::Key::offset, true);
  628. tmp->ArrayValidTags = alloc.SlabAllocateArray<byte>(tmp->LastIndex - tmp->FirstIndex);
  629. tmp->ArrayRangeContents = alloc.SlabAllocateArray<T>(tmp->LastIndex - tmp->FirstIndex);
  630. tmp->Next = nullptr;
  631. if(curr != nullptr)
  632. {
  633. curr->Next = tmp;
  634. }
  635. curr = tmp;
  636. TTDAssert(curr != nullptr, "Sanity assert failed.");
  637. if(arrayInfo == nullptr)
  638. {
  639. arrayInfo = curr;
  640. }
  641. reader->ReadSequenceStart_WDefaultKey(true);
  642. for(uint32 i = curr->FirstIndex; i < curr->LastIndex; ++i)
  643. {
  644. uint32 j = (i - curr->FirstIndex);
  645. reader->ReadRecordStart(j != 0);
  646. curr->ArrayValidTags[j] = (byte)reader->ReadInt32(NSTokens::Key::isValid);
  647. if(curr->ArrayValidTags[j])
  648. {
  649. SnapArrayInfo_ParseValue(curr->ArrayRangeContents + j, reader, alloc);
  650. }
  651. reader->ReadRecordEnd();
  652. }
  653. reader->ReadSequenceEnd();
  654. reader->ReadRecordEnd();
  655. }
  656. reader->ReadSequenceEnd();
  657. SnapArrayInfo<T>* res = alloc.SlabAllocateStruct< SnapArrayInfo<T> >();
  658. res->Length = alength;
  659. res->Data = arrayInfo;
  660. return res;
  661. }
  662. template<typename T, SnapObjectType snapArrayKind>
  663. void ParseAddtlInfo_SnapArrayInfo(SnapObject* snpObject, FileReader* reader, SlabAllocator& alloc)
  664. {
  665. SnapArrayInfo<T>* arrayInfo = ParseAddtlInfo_SnapArrayInfoCore<T>(reader, alloc);
  666. SnapObjectSetAddtlInfoAs<SnapArrayInfo<T>*, snapArrayKind>(snpObject, arrayInfo);
  667. }
  668. #if ENABLE_SNAPSHOT_COMPARE
  669. template<typename T>
  670. void AdvanceArrayIndex_SnapArrayInfoCompare(uint32* index, uint32* pos, const SnapArrayInfoBlock<T>** segment)
  671. {
  672. *index = *index + 1;
  673. if(*index >= (*segment)->LastIndex)
  674. {
  675. *segment = (*segment)->Next;
  676. *pos = 0;
  677. if(*segment != nullptr)
  678. {
  679. *index = (*segment)->FirstIndex;
  680. }
  681. }
  682. else
  683. {
  684. TTDAssert(*index >= (*segment)->FirstIndex, "Something went wrong.");
  685. *pos = *index - (*segment)->FirstIndex;
  686. }
  687. }
  688. template<typename T>
  689. void AssertSnapEquiv_SnapArrayInfoCore(const SnapArrayInfoBlock<T>* arrayInfo1, const SnapArrayInfoBlock<T>* arrayInfo2, TTDCompareMap& compareMap)
  690. {
  691. uint32 index1 = (arrayInfo1 != nullptr) ? arrayInfo1->FirstIndex : 0;
  692. uint32 pos1 = 0;
  693. uint32 index2 = (arrayInfo2 != nullptr) ? arrayInfo2->FirstIndex : 0;
  694. uint32 pos2 = 0;
  695. while(arrayInfo1 != nullptr && arrayInfo2 != nullptr)
  696. {
  697. if(index1 < index2)
  698. {
  699. compareMap.DiagnosticAssert(!arrayInfo1->ArrayValidTags[pos1]);
  700. AdvanceArrayIndex_SnapArrayInfoCompare(&index1, &pos1, &arrayInfo1);
  701. }
  702. else if(index1 > index2)
  703. {
  704. compareMap.DiagnosticAssert(!arrayInfo2->ArrayValidTags[pos2]);
  705. AdvanceArrayIndex_SnapArrayInfoCompare(&index2, &pos2, &arrayInfo2);
  706. }
  707. else
  708. {
  709. compareMap.DiagnosticAssert(arrayInfo1->ArrayValidTags[pos1] == arrayInfo2->ArrayValidTags[pos2]);
  710. if(arrayInfo1->ArrayValidTags[pos1])
  711. {
  712. SnapArrayInfo_EquivValue(arrayInfo1->ArrayRangeContents[pos1], arrayInfo2->ArrayRangeContents[pos2], compareMap, index1);
  713. }
  714. AdvanceArrayIndex_SnapArrayInfoCompare(&index1, &pos1, &arrayInfo1);
  715. AdvanceArrayIndex_SnapArrayInfoCompare(&index2, &pos2, &arrayInfo2);
  716. }
  717. }
  718. //make sure any remaining entries an empty
  719. while(arrayInfo1 != nullptr)
  720. {
  721. compareMap.DiagnosticAssert(!arrayInfo1->ArrayValidTags[pos1]);
  722. AdvanceArrayIndex_SnapArrayInfoCompare(&index1, &pos1, &arrayInfo1);
  723. }
  724. while(arrayInfo1 != nullptr)
  725. {
  726. compareMap.DiagnosticAssert(!arrayInfo2->ArrayValidTags[pos2]);
  727. AdvanceArrayIndex_SnapArrayInfoCompare(&index2, &pos2, &arrayInfo2);
  728. }
  729. }
  730. template<typename T, SnapObjectType snapArrayKind>
  731. void AssertSnapEquiv_SnapArrayInfo(const SnapObject* sobj1, const SnapObject* sobj2, TTDCompareMap& compareMap)
  732. {
  733. const SnapArrayInfo<T>* arrayInfo1 = SnapObjectGetAddtlInfoAs<SnapArrayInfo<T>*, snapArrayKind>(sobj1);
  734. const SnapArrayInfo<T>* arrayInfo2 = SnapObjectGetAddtlInfoAs<SnapArrayInfo<T>*, snapArrayKind>(sobj2);
  735. compareMap.DiagnosticAssert(arrayInfo1->Length == arrayInfo2->Length);
  736. AssertSnapEquiv_SnapArrayInfoCore<T>(arrayInfo1->Data, arrayInfo2->Data, compareMap);
  737. }
  738. #endif
  739. //////////////////
  740. //A struct that represents a single getter/setter value in an ES5 array
  741. struct SnapES5ArrayGetterSetterEntry
  742. {
  743. uint32 Index;
  744. Js::PropertyAttributes Attributes;
  745. TTDVar Getter;
  746. TTDVar Setter;
  747. };
  748. //A struct that represents Javascript ES5 arrays
  749. struct SnapES5ArrayInfo
  750. {
  751. //Values copied from the ES5ArrayTypeHandler indexed data map
  752. uint32 GetterSetterCount;
  753. SnapES5ArrayGetterSetterEntry* GetterSetterEntries;
  754. //Values that are copied from the underlying data array
  755. SnapArrayInfo<TTDVar>* BasicArrayData;
  756. //True if the length is writable
  757. bool IsLengthWritable;
  758. };
  759. Js::RecyclableObject* DoObjectInflation_SnapES5ArrayInfo(const SnapObject* snpObject, InflateMap* inflator);
  760. void DoAddtlValueInstantiation_SnapES5ArrayInfo(const SnapObject* snpObject, Js::RecyclableObject* obj, InflateMap* inflator);
  761. void EmitAddtlInfo_SnapES5ArrayInfo(const SnapObject* snpObject, FileWriter* writer);
  762. void ParseAddtlInfo_SnapES5ArrayInfo(SnapObject* snpObject, FileReader* reader, SlabAllocator& alloc);
  763. #if ENABLE_SNAPSHOT_COMPARE
  764. void AssertSnapEquiv_SnapES5ArrayInfo(const SnapObject* sobj1, const SnapObject* sobj2, TTDCompareMap& compareMap);
  765. #endif
  766. //////////////////
  767. //A struct that represents an array buffer
  768. struct SnapArrayBufferInfo
  769. {
  770. //The length of the array in bytes
  771. uint32 Length;
  772. //The byte array with the data
  773. byte* Buff;
  774. };
  775. ////
  776. //Functions for the VTable for SnapArrayBufferObject
  777. Js::RecyclableObject* DoObjectInflation_SnapArrayBufferInfo(const SnapObject* snpObject, InflateMap* inflator);
  778. //DoAddtlValueInstantiation is a nop
  779. void EmitAddtlInfo_SnapArrayBufferInfo(const SnapObject* snpObject, FileWriter* writer);
  780. void ParseAddtlInfo_SnapArrayBufferInfo(SnapObject* snpObject, FileReader* reader, SlabAllocator& alloc);
  781. #if ENABLE_SNAPSHOT_COMPARE
  782. void AssertSnapEquiv_SnapArrayBufferInfo(const SnapObject* sobj1, const SnapObject* sobj2, TTDCompareMap& compareMap);
  783. #endif
  784. //A struct that represents a typed array
  785. struct SnapTypedArrayInfo
  786. {
  787. //The byte offset that the data starts in in the buffer
  788. uint32 ByteOffset;
  789. //The length of the array (in terms of the underlying typed values)
  790. uint32 Length;
  791. //The array buffer that this typed array is a projection of -- need to fix this in cpp file too
  792. TTD_PTR_ID ArrayBufferAddr;
  793. };
  794. ////
  795. //Functions for the VTable for SnapTypedArrayObject
  796. Js::RecyclableObject* DoObjectInflation_SnapTypedArrayInfo(const SnapObject* snpObject, InflateMap* inflator);
  797. //DoAddtlValueInstantiation is a nop
  798. void EmitAddtlInfo_SnapTypedArrayInfo(const SnapObject* snpObject, FileWriter* writer);
  799. void ParseAddtlInfo_SnapTypedArrayInfo(SnapObject* snpObject, FileReader* reader, SlabAllocator& alloc);
  800. #if ENABLE_SNAPSHOT_COMPARE
  801. void AssertSnapEquiv_SnapTypedArrayInfo(const SnapObject* sobj1, const SnapObject* sobj2, TTDCompareMap& compareMap);
  802. #endif
  803. //////////////////
  804. //A struct that represents a set (or weakset) object
  805. struct SnapSetInfo
  806. {
  807. //The number of elements in the set
  808. uint32 SetSize;
  809. //The set values we want to store
  810. TTDVar* SetValueArray;
  811. };
  812. ////
  813. //Functions for the VTable for SnapSetObject
  814. Js::RecyclableObject* DoObjectInflation_SnapSetInfo(const SnapObject* snpObject, InflateMap* inflator);
  815. void DoAddtlValueInstantiation_SnapSetInfo(const SnapObject* snpObject, Js::RecyclableObject* obj, InflateMap* inflator);
  816. void EmitAddtlInfo_SnapSetInfo(const SnapObject* snpObject, FileWriter* writer);
  817. void ParseAddtlInfo_SnapSetInfo(SnapObject* snpObject, FileReader* reader, SlabAllocator& alloc);
  818. #if ENABLE_SNAPSHOT_COMPARE
  819. void AssertSnapEquiv_SnapSetInfo(const SnapObject* sobj1, const SnapObject* sobj2, TTDCompareMap& compareMap);
  820. #endif
  821. //////////////////
  822. //A struct that represents a map (or weakmap) object
  823. struct SnapMapInfo
  824. {
  825. //The number of elements in the set
  826. uint32 MapSize;
  827. //The keys/values we want to store (keys are at i, values at i + 1)
  828. TTDVar* MapKeyValueArray;
  829. };
  830. ////
  831. //Functions for the VTable for SnapMapObject
  832. Js::RecyclableObject* DoObjectInflation_SnapMapInfo(const SnapObject* snpObject, InflateMap* inflator);
  833. void DoAddtlValueInstantiation_SnapMapInfo(const SnapObject* snpObject, Js::RecyclableObject* obj, InflateMap* inflator);
  834. void EmitAddtlInfo_SnapMapInfo(const SnapObject* snpObject, FileWriter* writer);
  835. void ParseAddtlInfo_SnapMapInfo(SnapObject* snpObject, FileReader* reader, SlabAllocator& alloc);
  836. #if ENABLE_SNAPSHOT_COMPARE
  837. void AssertSnapEquiv_SnapMapInfo(const SnapObject* sobj1, const SnapObject* sobj2, TTDCompareMap& compareMap);
  838. #endif
  839. //////////////////
  840. //A struct that represents a map (or weakmap) object
  841. struct SnapProxyInfo
  842. {
  843. //The handler ptrid (or invalid if revoked)
  844. TTD_PTR_ID HandlerId;
  845. //The target ptrid (or invalid if revoked)
  846. TTD_PTR_ID TargetId;
  847. };
  848. ////
  849. //Functions for the VTable for SnapProxyObject
  850. Js::RecyclableObject* DoObjectInflation_SnapProxyInfo(const SnapObject* snpObject, InflateMap* inflator);
  851. void EmitAddtlInfo_SnapProxyInfo(const SnapObject* snpObject, FileWriter* writer);
  852. void ParseAddtlInfo_SnapProxyInfo(SnapObject* snpObject, FileReader* reader, SlabAllocator& alloc);
  853. #if ENABLE_SNAPSHOT_COMPARE
  854. void AssertSnapEquiv_SnapProxyInfo(const SnapObject* sobj1, const SnapObject* sobj2, TTDCompareMap& compareMap);
  855. #endif
  856. //////////////////
  857. struct SnapGeneratorFunctionInfo
  858. {
  859. TTD_PTR_ID scriptFunction; // pointer to GeneratorVirtualScriptFunction
  860. bool isAnonymousFunction;
  861. };
  862. struct SnapGeneratorVirtualScriptFunctionInfo : SnapScriptFunctionInfo
  863. {
  864. TTD_PTR_ID realFunction; //pointer to JavascriptGeneratorFunction
  865. };
  866. struct SnapAsyncFunctionInfo
  867. {
  868. };
  869. struct SnapGeneratorInfo
  870. {
  871. int generatorPrototype; // 0 == unknown, 1 == nullType, 2 == generatorPrototype
  872. Js::RegSlot frame_slotCount;
  873. TTDVar* frame_slotArray;
  874. uint32 state; // enum value of JavascriptGenerator.GeneratorState
  875. TTD_PTR_ID scriptFunction;
  876. uint32 arguments_callInfo_count;
  877. uint8 arguments_callInfo_flags;
  878. uint arguments_count;
  879. TTDVar* arguments_values;
  880. uint byteCodeReader_offset;
  881. };
  882. Js::RecyclableObject* DoObjectInflation_SnapGeneratorInfo(const SnapObject* snpObject, InflateMap* inflator);
  883. void DoAddtlValueInstantiation_SnapGeneratorInfo(const SnapObject* snpObject, Js::RecyclableObject* obj, InflateMap* inflator);
  884. void EmitAddtlInfo_SnapGeneratorInfo(const SnapObject* snpObject, FileWriter* writer);
  885. void ParseAddtlInfo_SnapGeneratorInfo(SnapObject* snpObject, FileReader* reader, SlabAllocator& alloc);
  886. #if ENABLE_SNAPSHOT_COMPARE
  887. void AssertSnapEquiv_SnapGeneratorInfo(const SnapObject* sobj1, const SnapObject* sobj2, TTDCompareMap& compareMap);
  888. #endif
  889. Js::RecyclableObject *DoObjectInflation_SnapGeneratorFunctionInfo(const SnapObject *snpObject, InflateMap *inflator);
  890. void DoAddtlValueInstantiation_SnapGeneratorFunctionInfo(const SnapObject *snpObject, Js::RecyclableObject *obj, InflateMap *inflator);
  891. void EmitAddtlInfo_SnapGeneratorFunctionInfo(const SnapObject *snpObject, FileWriter *writer);
  892. void ParseAddtlInfo_SnapGeneratorFunctionInfo(SnapObject *snpObject, FileReader *reader, SlabAllocator &alloc);
  893. #if ENABLE_SNAPSHOT_COMPARE
  894. void AssertSnapEquiv_SnapGeneratorFunctionInfo(const SnapObject *sobj1, const SnapObject *sobj2, TTDCompareMap &compareMap);
  895. #endif
  896. Js::RecyclableObject* DoObjectInflation_SnapGeneratorVirtualScriptFunctionInfo(const SnapObject *snpObject, InflateMap *inflator);
  897. void DoAddtlValueInstantiation_SnapGeneratorVirtualScriptFunctionInfo(const SnapObject *snpObject, Js::RecyclableObject *obj, InflateMap *inflator);
  898. void EmitAddtlInfo_SnapGeneratorVirtualScriptFunctionInfo(const SnapObject *snpObject, FileWriter *writer);
  899. void ParseAddtlInfo_SnapGeneratorVirtualScriptFunctionInfo(SnapObject *snpObject, FileReader *reader, SlabAllocator &alloc);
  900. #if ENABLE_SNAPSHOT_COMPARE
  901. void AssertSnapEquiv_SnapGeneratorVirtualScriptFunctionInfo(const SnapObject *sobj1, const SnapObject *sobj2, TTDCompareMap &compareMap);
  902. #endif
  903. Js::RecyclableObject *DoObjectInflation_SnapAsyncFunction(const SnapObject *snpObject, InflateMap *inflator);
  904. void DoAddtlValueInstantiation_SnapAsyncFunction(const SnapObject* snpObject, Js::RecyclableObject* obj, InflateMap* inflator);
  905. void EmitAddtlInfo_SnapAsyncFunction(const SnapObject* snpObject, FileWriter* writer);
  906. void ParseAddtlInfo_SnapAsyncFunction(SnapObject* snpObject, FileReader* reader, SlabAllocator& alloc);
  907. #if ENABLE_SNAPSHOT_COMPARE
  908. void AssertSnapEquiv_SnapAsyncFunction(const SnapObject* sobj1, const SnapObject* sobj2, TTDCompareMap& compareMap);
  909. #endif
  910. //////////
  911. struct SnapJavascriptPromiseAsyncSpawnExecutorFunctionInfo
  912. {
  913. TTD_PTR_ID generator;
  914. TTDVar target;
  915. };
  916. Js::RecyclableObject *DoObjectInflation_SnapJavascriptPromiseAsyncSpawnExecutorFunction(const SnapObject *snpObject, InflateMap *inflator);
  917. void DoAddtlValueInstantiation_SnapJavascriptPromiseAsyncSpawnExecutorFunction(const SnapObject* snpObject, Js::RecyclableObject* obj, InflateMap* inflator);
  918. void EmitAddtlInfo_SnapJavascriptPromiseAsyncSpawnExecutorFunction(const SnapObject* snpObject, FileWriter* writer);
  919. void ParseAddtlInfo_SnapJavascriptPromiseAsyncSpawnExecutorFunction(SnapObject* snpObject, FileReader* reader, SlabAllocator& alloc);
  920. #if ENABLE_SNAPSHOT_COMPARE
  921. void AssertSnapEquiv_SnapJavascriptPromiseAsyncSpawnExecutorFunction(const SnapObject* sobj1, const SnapObject* sobj2, TTDCompareMap& compareMap);
  922. #endif
  923. //////////
  924. struct SnapJavascriptPromiseAsyncSpawnStepArgumentExecutorFunctionInfo
  925. {
  926. TTD_PTR_ID generator;
  927. TTDVar reject;
  928. TTDVar resolve;
  929. bool isReject;
  930. TTDVar argument;
  931. uint32 entryPoint;
  932. };
  933. Js::RecyclableObject *DoObjectInflation_SnapJavascriptPromiseAsyncSpawnStepArgumentExecutorFunctionInfo(const SnapObject *snpObject, InflateMap *inflator);
  934. void DoAddtlValueInstantiation_SnapJavascriptPromiseAsyncSpawnStepArgumentExecutorFunctionInfo(const SnapObject* snpObject, Js::RecyclableObject* obj, InflateMap* inflator);
  935. void EmitAddtlInfo_SnapJavascriptPromiseAsyncSpawnStepArgumentExecutorFunctionInfo(const SnapObject* snpObject, FileWriter* writer);
  936. void ParseAddtlInfo_SnapJavascriptPromiseAsyncSpawnStepArgumentExecutorFunctionInfo(SnapObject* snpObject, FileReader* reader, SlabAllocator& alloc);
  937. #if ENABLE_SNAPSHOT_COMPARE
  938. void AssertSnapEquiv_SnapJavascriptPromiseAsyncSpawnStepArgumentExecutorFunctionInfo(const SnapObject* sobj1, const SnapObject* sobj2, TTDCompareMap& compareMap);
  939. #endif
  940. //////////
  941. }
  942. }
  943. #endif