TTSnapObjects.h 53 KB

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