TTSnapObjects.h 53 KB

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