TTSnapObjects.h 47 KB

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