TTSnapObjects.cpp 106 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134
  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. #include "RuntimeDebugPch.h"
  6. #if ENABLE_TTD
  7. namespace TTD
  8. {
  9. namespace NSSnapObjects
  10. {
  11. void ExtractCompoundObject(NSSnapObjects::SnapObject* sobj, Js::RecyclableObject* obj, bool isWellKnown, const TTDIdentifierDictionary<TTD_PTR_ID, NSSnapType::SnapType*>& idToTypeMap, SlabAllocator& alloc)
  12. {
  13. TTDAssert(!obj->CanHaveInterceptors(), "We are not prepared for custom external objects yet");
  14. sobj->ObjectPtrId = TTD_CONVERT_VAR_TO_PTR_ID(obj);
  15. sobj->SnapObjectTag = obj->GetSnapTag_TTD();
  16. TTD_WELLKNOWN_TOKEN lookupToken = isWellKnown ? obj->GetScriptContext()->TTDWellKnownInfo->ResolvePathForKnownObject(obj) : TTD_INVALID_WELLKNOWN_TOKEN;
  17. sobj->OptWellKnownToken = alloc.CopyRawNullTerminatedStringInto(lookupToken);
  18. Js::Type* objType = obj->GetType();
  19. sobj->SnapType = idToTypeMap.LookupKnownItem(TTD_CONVERT_TYPEINFO_TO_PTR_ID(objType));
  20. #if ENABLE_OBJECT_SOURCE_TRACKING
  21. InitializeDiagnosticOriginInformation(sobj->DiagOriginInfo);
  22. #endif
  23. if(Js::StaticType::Is(objType->GetTypeId()))
  24. {
  25. NSSnapObjects::StdPropertyExtract_StaticType(sobj, obj);
  26. }
  27. else
  28. {
  29. NSSnapObjects::StdPropertyExtract_DynamicType(sobj, static_cast<Js::DynamicObject*>(obj), alloc);
  30. }
  31. obj->ExtractSnapObjectDataInto(sobj, alloc);
  32. }
  33. void StdPropertyExtract_StaticType(SnapObject* snpObject, Js::RecyclableObject* obj)
  34. {
  35. snpObject->IsCrossSite = FALSE;
  36. snpObject->VarArrayCount = 0;
  37. snpObject->VarArray = nullptr;
  38. snpObject->OptIndexedObjectArray = TTD_INVALID_PTR_ID;
  39. snpObject->OptDependsOnInfo = nullptr;
  40. //AddtlSnapObjectInfo must be set later in type specific extract code
  41. }
  42. void StdPropertyExtract_DynamicType(SnapObject* snpObject, Js::DynamicObject* dynObj, SlabAllocator& alloc)
  43. {
  44. NSSnapType::SnapType* sType = snpObject->SnapType;
  45. snpObject->IsCrossSite = dynObj->IsCrossSiteObject();
  46. #if ENABLE_OBJECT_SOURCE_TRACKING
  47. CopyDiagnosticOriginInformation(snpObject->DiagOriginInfo, dynObj->TTDDiagOriginInfo);
  48. #endif
  49. if(sType->TypeHandlerInfo->MaxPropertyIndex == 0)
  50. {
  51. snpObject->VarArrayCount = 0;
  52. snpObject->VarArray = nullptr;
  53. }
  54. else
  55. {
  56. NSSnapType::SnapHandler* sHandler = sType->TypeHandlerInfo;
  57. static_assert(sizeof(TTDVar) == sizeof(Js::Var), "These need to be the same size (and have same bit layout) for this to work!");
  58. snpObject->VarArrayCount = sHandler->MaxPropertyIndex;
  59. snpObject->VarArray = alloc.SlabAllocateArray<TTDVar>(snpObject->VarArrayCount);
  60. TTDVar* cpyBase = snpObject->VarArray;
  61. if(sHandler->InlineSlotCapacity != 0)
  62. {
  63. Js::Var const* inlineSlots = dynObj->GetInlineSlots_TTD();
  64. //copy all the properties (if they all fit into the inline slots) otherwise just copy all the inline slot values
  65. uint32 inlineSlotCount = min(sHandler->MaxPropertyIndex, sHandler->InlineSlotCapacity);
  66. js_memcpy_s(cpyBase, inlineSlotCount * sizeof(TTDVar), inlineSlots, inlineSlotCount * sizeof(Js::Var));
  67. }
  68. if(sHandler->MaxPropertyIndex > sHandler->InlineSlotCapacity)
  69. {
  70. cpyBase = cpyBase + sHandler->InlineSlotCapacity;
  71. Js::Var const* auxSlots = dynObj->GetAuxSlots_TTD();
  72. //there are some values in aux slots (in addition to the inline slots) so copy them as well
  73. uint32 auxSlotCount = (sHandler->MaxPropertyIndex - sHandler->InlineSlotCapacity);
  74. js_memcpy_s(cpyBase, auxSlotCount * sizeof(TTDVar), auxSlots, auxSlotCount * sizeof(Js::Var));
  75. }
  76. }
  77. Js::ArrayObject* parray = dynObj->GetObjectArray();
  78. snpObject->OptIndexedObjectArray = (parray == nullptr) ? TTD_INVALID_PTR_ID : TTD_CONVERT_VAR_TO_PTR_ID(parray);
  79. snpObject->OptDependsOnInfo = nullptr;
  80. //AddtlSnapObjectInfo must be set later in type specific extract code
  81. }
  82. Js::DynamicObject* ReuseObjectCheckAndReset(const SnapObject* snpObject, InflateMap* inflator)
  83. {
  84. Js::RecyclableObject* robj = inflator->FindReusableObjectIfExists(snpObject->ObjectPtrId);
  85. if(robj == nullptr || Js::DynamicObject::FromVar(robj)->GetTypeId() != snpObject->SnapType->JsTypeId || Js::DynamicObject::FromVar(robj)->IsCrossSiteObject() != snpObject->IsCrossSite)
  86. {
  87. return nullptr;
  88. }
  89. TTDAssert(Js::DynamicType::Is(robj->GetTypeId()), "You should only do this for dynamic objects!!!");
  90. Js::DynamicObject* dynObj = Js::DynamicObject::FromVar(robj);
  91. return ObjectPropertyReset_General(snpObject, dynObj, inflator);
  92. }
  93. bool DoesObjectBlockScriptContextReuse(const SnapObject* snpObject, Js::DynamicObject* dynObj, InflateMap* inflator)
  94. {
  95. TTDAssert(snpObject->OptWellKnownToken != TTD_INVALID_WELLKNOWN_TOKEN, "Only well known objects can block re-use so check that before calling this.");
  96. JsUtil::BaseHashSet<Js::PropertyId, HeapAllocator>& propertyReset = inflator->GetPropertyResetSet();
  97. propertyReset.Clear();
  98. ////
  99. for(int32 i = 0; i < dynObj->GetPropertyCount(); i++)
  100. {
  101. Js::PropertyId pid = dynObj->GetPropertyId((Js::PropertyIndex)i);
  102. if(pid != Js::Constants::NoProperty)
  103. {
  104. propertyReset.AddNew(pid);
  105. }
  106. }
  107. const NSSnapType::SnapHandler* handler = snpObject->SnapType->TypeHandlerInfo;
  108. for(uint32 i = 0; i < handler->MaxPropertyIndex; ++i)
  109. {
  110. BOOL willOverwriteLater = (handler->PropertyInfoArray[i].DataKind != NSSnapType::SnapEntryDataKindTag::Clear);
  111. BOOL isInternal = Js::IsInternalPropertyId(handler->PropertyInfoArray[i].PropertyRecordId);
  112. if(willOverwriteLater | isInternal)
  113. {
  114. Js::PropertyId pid = handler->PropertyInfoArray[i].PropertyRecordId;
  115. propertyReset.Remove(pid);
  116. }
  117. }
  118. if(propertyReset.Count() != 0)
  119. {
  120. for(auto iter = propertyReset.GetIterator(); iter.IsValid(); iter.MoveNext())
  121. {
  122. Js::PropertyId pid = iter.CurrentValue();
  123. TTDAssert(pid != Js::Constants::NoProperty, "This shouldn't happen!!!");
  124. //We don't like trying to reset these
  125. if(Js::IsInternalPropertyId(pid))
  126. {
  127. propertyReset.Clear();
  128. return true;
  129. }
  130. //someone added a property that is not simple to remove so let's just be safe an recreate contexts
  131. if(!dynObj->IsConfigurable(pid))
  132. {
  133. propertyReset.Clear();
  134. return true;
  135. }
  136. }
  137. }
  138. propertyReset.Clear();
  139. ////
  140. return false;
  141. }
  142. Js::DynamicObject* ObjectPropertyReset_WellKnown(const SnapObject* snpObject, Js::DynamicObject* dynObj, InflateMap* inflator)
  143. {
  144. TTDAssert(snpObject->OptWellKnownToken != TTD_INVALID_WELLKNOWN_TOKEN, "Should only call this on well known objects.");
  145. JsUtil::BaseHashSet<Js::PropertyId, HeapAllocator>& propertyReset = inflator->GetPropertyResetSet();
  146. propertyReset.Clear();
  147. ////
  148. for(int32 i = 0; i < dynObj->GetPropertyCount(); i++)
  149. {
  150. Js::PropertyId pid = dynObj->GetPropertyId((Js::PropertyIndex)i);
  151. if(pid != Js::Constants::NoProperty)
  152. {
  153. propertyReset.AddNew(pid);
  154. }
  155. }
  156. const NSSnapType::SnapHandler* handler = snpObject->SnapType->TypeHandlerInfo;
  157. for(uint32 i = 0; i < handler->MaxPropertyIndex; ++i)
  158. {
  159. BOOL willOverwriteLater = (handler->PropertyInfoArray[i].DataKind != NSSnapType::SnapEntryDataKindTag::Clear);
  160. BOOL isInternal = Js::IsInternalPropertyId(handler->PropertyInfoArray[i].PropertyRecordId);
  161. if(willOverwriteLater | isInternal)
  162. {
  163. Js::PropertyId pid = handler->PropertyInfoArray[i].PropertyRecordId;
  164. propertyReset.Remove(pid);
  165. }
  166. }
  167. Js::Var undefined = dynObj->GetScriptContext()->GetLibrary()->GetUndefined();
  168. if(propertyReset.Count() != 0)
  169. {
  170. for(auto iter = propertyReset.GetIterator(); iter.IsValid(); iter.MoveNext())
  171. {
  172. BOOL ok = FALSE;
  173. Js::PropertyId pid = iter.CurrentValue();
  174. TTDAssert(pid != Js::Constants::NoProperty && !Js::IsInternalPropertyId(pid), "This shouldn't happen!!!");
  175. if(!dynObj->IsConfigurable(pid))
  176. {
  177. ok = dynObj->SetProperty(pid, undefined, Js::PropertyOperationFlags::PropertyOperation_Force, nullptr);
  178. }
  179. else
  180. {
  181. ok = dynObj->DeleteProperty(pid, Js::PropertyOperationFlags::PropertyOperation_Force);
  182. }
  183. TTDAssert(ok, "This property is stuck!!!");
  184. }
  185. }
  186. propertyReset.Clear();
  187. ////
  188. //always reset the index array as this is unusual and annoying to iterate over a bunch
  189. Js::ArrayObject* parray = dynObj->GetObjectArray();
  190. if(parray != nullptr)
  191. {
  192. Js::JavascriptArray* newArray = dynObj->GetLibrary()->CreateArray();
  193. dynObj->SetObjectArray(newArray);
  194. }
  195. return dynObj;
  196. }
  197. Js::DynamicObject* ObjectPropertyReset_General(const SnapObject* snpObject, Js::DynamicObject* dynObj, InflateMap* inflator)
  198. {
  199. TTDAssert(snpObject->OptWellKnownToken == TTD_INVALID_WELLKNOWN_TOKEN, "Should only call this on generic objects that we can fall back to re-allocating if we want.");
  200. if(!dynObj->GetDynamicType()->GetTypeHandler()->IsResetableForTTD(snpObject->SnapType->TypeHandlerInfo->MaxPropertyIndex))
  201. {
  202. return nullptr;
  203. }
  204. //always reset the index array as this is unusual and annoying to iterate over a bunch
  205. Js::ArrayObject* parray = dynObj->GetObjectArray();
  206. if(parray != nullptr)
  207. {
  208. Js::JavascriptArray* newArray = dynObj->GetLibrary()->CreateArray();
  209. dynObj->SetObjectArray(newArray);
  210. }
  211. return dynObj;
  212. }
  213. //
  214. //TODO: I still don't love this (and the reset above) as I feel it hits too much other execution machinery and can fail in odd cases.
  215. // For the current time it is ok but we may want to look into adding specialized methods for resetting/restoring.
  216. //
  217. void StdPropertyRestore(const SnapObject* snpObject, Js::DynamicObject* obj, InflateMap* inflator)
  218. {
  219. //Many protos are set at creation, don't mess with them if they are already correct
  220. if(snpObject->SnapType->PrototypeVar != nullptr)
  221. {
  222. Js::RecyclableObject* protoObj = Js::RecyclableObject::FromVar(inflator->InflateTTDVar(snpObject->SnapType->PrototypeVar));
  223. if(obj->GetType()->GetPrototype() != protoObj)
  224. {
  225. obj->SetPrototype(protoObj);
  226. }
  227. }
  228. //set all the standard properties
  229. const NSSnapType::SnapHandler* handler = snpObject->SnapType->TypeHandlerInfo;
  230. #if ENABLE_OBJECT_SOURCE_TRACKING
  231. CopyDiagnosticOriginInformation(obj->TTDDiagOriginInfo, snpObject->DiagOriginInfo);
  232. #endif
  233. //
  234. //We assume that placing properties back in the same order we read them out produces correct results.
  235. //This is not true for enumeration -- but we handle this by explicit logging
  236. //There may also be sensitivity in other cases -- e.g. activation objects with arguments objects that use slot index values directly.
  237. // Things look good in this case but future changes may require care and/or adding special case handling.
  238. //
  239. for(uint32 i = 0; i < handler->MaxPropertyIndex; ++i)
  240. {
  241. //We have an empty (or uninteresting) slot for so there is nothing to restore
  242. if(handler->PropertyInfoArray[i].DataKind == NSSnapType::SnapEntryDataKindTag::Clear)
  243. {
  244. continue;
  245. }
  246. TTDAssert(!Js::JavascriptProxy::Is(obj), "I didn't think proxies could have real properties directly on them.");
  247. Js::PropertyId pid = handler->PropertyInfoArray[i].PropertyRecordId;
  248. if(handler->PropertyInfoArray[i].DataKind == NSSnapType::SnapEntryDataKindTag::Uninitialized)
  249. {
  250. TTDAssert(!obj->HasOwnProperty(pid), "Shouldn't have this defined, or we should have cleared it, and nothing more to do.");
  251. BOOL success = obj->EnsureProperty(pid);
  252. TTDAssert(success, "Failed to set property during restore!!!");
  253. }
  254. else
  255. {
  256. TTDVar ttdVal = snpObject->VarArray[i];
  257. Js::Var pVal = (ttdVal != nullptr) ? inflator->InflateTTDVar(ttdVal) : nullptr;
  258. if(handler->PropertyInfoArray[i].DataKind == NSSnapType::SnapEntryDataKindTag::Data)
  259. {
  260. BOOL success = FALSE;
  261. if(!obj->HasOwnProperty(pid))
  262. {
  263. //easy case just set the property
  264. success = obj->SetPropertyWithAttributes(pid, pVal, PropertyDynamicTypeDefaults, nullptr);
  265. }
  266. else
  267. {
  268. //get the value to see if it is alreay ok
  269. Js::Var currentValue = nullptr;
  270. Js::JavascriptOperators::GetOwnProperty(obj, pid, &currentValue, obj->GetScriptContext());
  271. if(currentValue == pVal)
  272. {
  273. //the right value is already there -- easy
  274. success = TRUE;
  275. }
  276. else
  277. {
  278. //Ok so now we force set the property
  279. success = obj->SetPropertyWithAttributes(pid, pVal, PropertyDynamicTypeDefaults, nullptr);
  280. }
  281. }
  282. TTDAssert(success, "Failed to set property during restore!!!");
  283. }
  284. else
  285. {
  286. NSSnapType::SnapEntryDataKindTag ttag = handler->PropertyInfoArray[i].DataKind;
  287. if(ttag == NSSnapType::SnapEntryDataKindTag::Getter)
  288. {
  289. obj->SetAccessors(pid, pVal, nullptr);
  290. }
  291. else if(ttag == NSSnapType::SnapEntryDataKindTag::Setter)
  292. {
  293. obj->SetAccessors(pid, nullptr, pVal);
  294. }
  295. else
  296. {
  297. TTDAssert(false, "Don't know how to restore this accesstag!!");
  298. }
  299. }
  300. }
  301. Js::PropertyAttributes pAttrib = (Js::PropertyAttributes)handler->PropertyInfoArray[i].AttributeInfo;
  302. if(obj->IsWritable(pid) && (pAttrib & PropertyWritable) == PropertyNone)
  303. {
  304. obj->SetWritable(pid, FALSE);
  305. }
  306. if(obj->IsEnumerable(pid) && (pAttrib & PropertyEnumerable) == PropertyNone)
  307. {
  308. obj->SetEnumerable(pid, FALSE);
  309. }
  310. if(obj->IsConfigurable(pid) && (pAttrib & PropertyConfigurable) == PropertyNone)
  311. {
  312. obj->SetConfigurable(pid, FALSE);
  313. }
  314. }
  315. if(snpObject->OptIndexedObjectArray != TTD_INVALID_PTR_ID)
  316. {
  317. Js::Var objArray = inflator->LookupObject(snpObject->OptIndexedObjectArray);
  318. obj->SetObjectArray(Js::JavascriptArray::FromAnyArray(objArray));
  319. }
  320. //finally set the extensible flag
  321. if(handler->IsExtensibleFlag != Js::DynamicTypeHandler::IsExtensibleFlag)
  322. {
  323. //this automatically updates the type if needed
  324. obj->GetDynamicType()->GetTypeHandler()->PreventExtensions(obj);
  325. }
  326. else
  327. {
  328. if(!obj->GetIsExtensible())
  329. {
  330. TTDAssert(!(obj->GetDynamicType()->GetIsShared() || obj->GetDynamicType()->GetTypeHandler()->GetIsShared()), "We are just changing the flag so if it is shared this might unexpectedly change another type!");
  331. obj->GetDynamicType()->GetTypeHandler()->SetExtensible_TTD();
  332. }
  333. }
  334. if(snpObject->SnapType->HasNoEnumerableProperties != obj->GetDynamicType()->GetHasNoEnumerableProperties())
  335. {
  336. TTDAssert(!obj->GetDynamicType()->GetIsShared(), "This is shared so we are mucking something up.");
  337. obj->GetDynamicType()->SetHasNoEnumerableProperties(snpObject->SnapType->HasNoEnumerableProperties);
  338. }
  339. }
  340. void EmitObject(const SnapObject* snpObject, FileWriter* writer, NSTokens::Separator separator, const SnapObjectVTable* vtable, ThreadContext* threadContext)
  341. {
  342. writer->WriteRecordStart(separator);
  343. writer->AdjustIndent(1);
  344. writer->WriteAddr(NSTokens::Key::objectId, snpObject->ObjectPtrId);
  345. writer->WriteTag<SnapObjectType>(NSTokens::Key::objectType, snpObject->SnapObjectTag, NSTokens::Separator::CommaSeparator);
  346. writer->WriteBool(NSTokens::Key::isWellKnownToken, snpObject->OptWellKnownToken != TTD_INVALID_WELLKNOWN_TOKEN, NSTokens::Separator::CommaSeparator);
  347. if(snpObject->OptWellKnownToken != TTD_INVALID_WELLKNOWN_TOKEN)
  348. {
  349. writer->WriteWellKnownToken(NSTokens::Key::wellKnownToken, snpObject->OptWellKnownToken, NSTokens::Separator::CommaSeparator);
  350. }
  351. writer->WriteAddr(NSTokens::Key::typeId, snpObject->SnapType->TypePtrId, NSTokens::Separator::CommaSeparator);
  352. writer->WriteBool(NSTokens::Key::isCrossSite, !!snpObject->IsCrossSite, NSTokens::Separator::CommaSeparator);
  353. #if ENABLE_OBJECT_SOURCE_TRACKING
  354. writer->WriteKey(NSTokens::Key::originInfo, NSTokens::Separator::CommaSeparator);
  355. EmitDiagnosticOriginInformation(snpObject->DiagOriginInfo, writer, NSTokens::Separator::NoSeparator);
  356. #endif
  357. writer->WriteBool(NSTokens::Key::isDepOn, snpObject->OptDependsOnInfo != nullptr, NSTokens::Separator::CommaSeparator);
  358. if(snpObject->OptDependsOnInfo != nullptr)
  359. {
  360. writer->WriteLengthValue(snpObject->OptDependsOnInfo->DepOnCount, NSTokens::Separator::CommaSeparator);
  361. writer->WriteSequenceStart_DefaultKey(NSTokens::Separator::CommaSeparator);
  362. for(uint32 i = 0; i < snpObject->OptDependsOnInfo->DepOnCount; ++i)
  363. {
  364. writer->WriteNakedAddr(snpObject->OptDependsOnInfo->DepOnPtrArray[i], i != 0 ? NSTokens::Separator::CommaSeparator : NSTokens::Separator::NoSeparator);
  365. }
  366. writer->WriteSequenceEnd();
  367. }
  368. if(Js::DynamicType::Is(snpObject->SnapType->JsTypeId))
  369. {
  370. const NSSnapType::SnapHandler* handler = snpObject->SnapType->TypeHandlerInfo;
  371. writer->WriteAddr(NSTokens::Key::objectId, snpObject->OptIndexedObjectArray, NSTokens::Separator::CommaSeparator);
  372. if(handler->MaxPropertyIndex == 0)
  373. {
  374. writer->WriteLengthValue(snpObject->VarArrayCount, NSTokens::Separator::CommaSeparator);
  375. }
  376. else
  377. {
  378. writer->WriteLengthValue(handler->MaxPropertyIndex, NSTokens::Separator::CommaAndBigSpaceSeparator);
  379. writer->WriteSequenceStart_DefaultKey(NSTokens::Separator::CommaSeparator);
  380. writer->AdjustIndent(1);
  381. for(uint32 i = 0; i < handler->MaxPropertyIndex; ++i)
  382. {
  383. NSTokens::Separator varSep = i != 0 ? NSTokens::Separator::CommaAndBigSpaceSeparator : NSTokens::Separator::BigSpaceSeparator;
  384. if(handler->PropertyInfoArray[i].DataKind == NSSnapType::SnapEntryDataKindTag::Clear)
  385. {
  386. writer->WriteNakedNull(varSep);
  387. }
  388. else
  389. {
  390. #if ENABLE_TTD_INTERNAL_DIAGNOSTICS
  391. writer->WriteRecordStart(varSep);
  392. writer->WriteUInt32(NSTokens::Key::pid, (uint32)handler->PropertyInfoArray[i].PropertyRecordId, NSTokens::Separator::NoSeparator);
  393. writer->WriteKey(NSTokens::Key::entry, NSTokens::Separator::CommaSeparator);
  394. varSep = NSTokens::Separator::NoSeparator;
  395. #endif
  396. NSSnapValues::EmitTTDVar(snpObject->VarArray[i], writer, varSep);
  397. #if ENABLE_TTD_INTERNAL_DIAGNOSTICS
  398. writer->WriteRecordEnd();
  399. #endif
  400. }
  401. }
  402. writer->AdjustIndent(-1);
  403. writer->WriteSequenceEnd(NSTokens::Separator::BigSpaceSeparator);
  404. }
  405. }
  406. fPtr_EmitAddtlInfo addtlInfoEmit = vtable[(uint32)snpObject->SnapObjectTag].EmitAddtlInfoFunc;
  407. if(addtlInfoEmit != nullptr)
  408. {
  409. addtlInfoEmit(snpObject, writer);
  410. }
  411. writer->AdjustIndent(-1);
  412. writer->WriteRecordEnd(NSTokens::Separator::BigSpaceSeparator);
  413. }
  414. void ParseObject(SnapObject* snpObject, bool readSeparator, FileReader* reader, SlabAllocator& alloc, const SnapObjectVTable* vtable, const TTDIdentifierDictionary<TTD_PTR_ID, NSSnapType::SnapType*>& ptrIdToTypeMap)
  415. {
  416. reader->ReadRecordStart(readSeparator);
  417. snpObject->ObjectPtrId = reader->ReadAddr(NSTokens::Key::objectId);
  418. snpObject->SnapObjectTag = reader->ReadTag<SnapObjectType>(NSTokens::Key::objectType, true);
  419. bool hasWellKnownToken = reader->ReadBool(NSTokens::Key::isWellKnownToken, true);
  420. snpObject->OptWellKnownToken = TTD_INVALID_WELLKNOWN_TOKEN;
  421. if(hasWellKnownToken)
  422. {
  423. snpObject->OptWellKnownToken = reader->ReadWellKnownToken(NSTokens::Key::wellKnownToken, alloc, true);
  424. }
  425. snpObject->SnapType = ptrIdToTypeMap.LookupKnownItem(reader->ReadAddr(NSTokens::Key::typeId, true));
  426. snpObject->IsCrossSite = reader->ReadBool(NSTokens::Key::isCrossSite, true);
  427. #if ENABLE_OBJECT_SOURCE_TRACKING
  428. reader->ReadKey(NSTokens::Key::originInfo, true);
  429. ParseDiagnosticOriginInformation(snpObject->DiagOriginInfo, false, reader);
  430. #endif
  431. snpObject->OptDependsOnInfo = nullptr;
  432. bool isDepOn = reader->ReadBool(NSTokens::Key::isDepOn, true);
  433. if(isDepOn)
  434. {
  435. snpObject->OptDependsOnInfo = alloc.SlabAllocateStruct<DependsOnInfo>();
  436. snpObject->OptDependsOnInfo->DepOnCount = reader->ReadLengthValue(true);
  437. snpObject->OptDependsOnInfo->DepOnPtrArray = alloc.SlabAllocateArray<TTD_PTR_ID>(snpObject->OptDependsOnInfo->DepOnCount);
  438. reader->ReadSequenceStart_WDefaultKey(true);
  439. for(uint32 i = 0; i < snpObject->OptDependsOnInfo->DepOnCount; ++i)
  440. {
  441. snpObject->OptDependsOnInfo->DepOnPtrArray[i] = reader->ReadNakedAddr(i != 0);
  442. }
  443. reader->ReadSequenceEnd();
  444. }
  445. if(Js::DynamicType::Is(snpObject->SnapType->JsTypeId))
  446. {
  447. const NSSnapType::SnapHandler* handler = snpObject->SnapType->TypeHandlerInfo;
  448. snpObject->OptIndexedObjectArray = reader->ReadAddr(NSTokens::Key::objectId, true);
  449. snpObject->VarArrayCount = reader->ReadLengthValue(true);
  450. if(handler->MaxPropertyIndex == 0)
  451. {
  452. snpObject->VarArray = nullptr;
  453. }
  454. else
  455. {
  456. snpObject->VarArray = alloc.SlabAllocateArray<TTDVar>(snpObject->VarArrayCount);
  457. reader->ReadSequenceStart_WDefaultKey(true);
  458. for(uint32 i = 0; i < handler->MaxPropertyIndex; ++i)
  459. {
  460. bool readVarSeparator = i != 0;
  461. if(handler->PropertyInfoArray[i].DataKind == NSSnapType::SnapEntryDataKindTag::Clear)
  462. {
  463. reader->ReadNakedNull(readVarSeparator);
  464. }
  465. else
  466. {
  467. #if ENABLE_TTD_INTERNAL_DIAGNOSTICS
  468. reader->ReadRecordStart(readVarSeparator);
  469. reader->ReadUInt32(NSTokens::Key::pid);
  470. reader->ReadKey(NSTokens::Key::entry, true);
  471. readVarSeparator = false;
  472. #endif
  473. snpObject->VarArray[i] = NSSnapValues::ParseTTDVar(readVarSeparator, reader);
  474. #if ENABLE_TTD_INTERNAL_DIAGNOSTICS
  475. reader->ReadRecordEnd();
  476. #endif
  477. }
  478. }
  479. reader->ReadSequenceEnd();
  480. }
  481. }
  482. fPtr_ParseAddtlInfo addtlInfoParse = vtable[(uint32)snpObject->SnapObjectTag].ParseAddtlInfoFunc;
  483. if(addtlInfoParse != nullptr)
  484. {
  485. addtlInfoParse(snpObject, reader, alloc);
  486. }
  487. reader->ReadRecordEnd();
  488. }
  489. #if ENABLE_SNAPSHOT_COMPARE
  490. void AssertSnapEquiv(const SnapObject* sobj1, const SnapObject* sobj2, TTDCompareMap& compareMap)
  491. {
  492. compareMap.DiagnosticAssert(sobj1->SnapObjectTag == sobj2->SnapObjectTag);
  493. compareMap.DiagnosticAssert(TTD_DIAGNOSTIC_COMPARE_WELLKNOWN_TOKENS(sobj1->OptWellKnownToken, sobj2->OptWellKnownToken));
  494. NSSnapType::AssertSnapEquiv(sobj1->SnapType, sobj2->SnapType, compareMap);
  495. //Depends on info is a function of the rest of the properties so we don't need to explicitly check it.
  496. //But for sanity assert same counts.
  497. compareMap.DiagnosticAssert((sobj1->OptDependsOnInfo == nullptr && sobj2->OptDependsOnInfo == nullptr) || (sobj1->OptDependsOnInfo->DepOnCount == sobj2->OptDependsOnInfo->DepOnCount));
  498. //we allow the replay in debug mode to be cross site even if orig was not (that is ok) but if record was x-site then replay must be as well
  499. if(compareMap.StrictCrossSite)
  500. {
  501. compareMap.DiagnosticAssert(sobj1->IsCrossSite == sobj2->IsCrossSite);
  502. }
  503. else
  504. {
  505. compareMap.DiagnosticAssert(!sobj1->IsCrossSite || sobj2->IsCrossSite);
  506. }
  507. #if ENABLE_OBJECT_SOURCE_TRACKING
  508. compareMap.DiagnosticAssert(sobj1->DiagOriginInfo.SourceLine == sobj2->DiagOriginInfo.SourceLine);
  509. compareMap.DiagnosticAssert(sobj1->DiagOriginInfo.EventTime == sobj2->DiagOriginInfo.EventTime);
  510. compareMap.DiagnosticAssert(sobj1->DiagOriginInfo.TimeHash == sobj2->DiagOriginInfo.TimeHash);
  511. #endif
  512. compareMap.DiagnosticAssert(Js::DynamicType::Is(sobj1->SnapType->JsTypeId) == Js::DynamicType::Is(sobj2->SnapType->JsTypeId));
  513. if(Js::DynamicType::Is(sobj1->SnapType->JsTypeId))
  514. {
  515. compareMap.CheckConsistentAndAddPtrIdMapping_Special(sobj1->OptIndexedObjectArray, sobj2->OptIndexedObjectArray, _u("indexedObjectArray"));
  516. const NSSnapType::SnapHandler* handler1 = sobj1->SnapType->TypeHandlerInfo;
  517. JsUtil::BaseDictionary<int64, int32, HeapAllocator> sobj1PidMap(&HeapAllocator::Instance);
  518. for(uint32 i = 0; i < handler1->MaxPropertyIndex; ++i)
  519. {
  520. const NSSnapType::SnapHandlerPropertyEntry spe = handler1->PropertyInfoArray[i];
  521. if(spe.DataKind != NSSnapType::SnapEntryDataKindTag::Clear)
  522. {
  523. int64 locationTag = ComputeLocationTagForAssertCompare(spe);
  524. sobj1PidMap.AddNew(locationTag, (int32)i);
  525. }
  526. }
  527. const NSSnapType::SnapHandler* handler2 = sobj2->SnapType->TypeHandlerInfo;
  528. for(uint32 i = 0; i < handler2->MaxPropertyIndex; ++i)
  529. {
  530. const NSSnapType::SnapHandlerPropertyEntry spe = handler2->PropertyInfoArray[i];
  531. if(spe.DataKind != NSSnapType::SnapEntryDataKindTag::Clear && spe.DataKind != NSSnapType::SnapEntryDataKindTag::Uninitialized)
  532. {
  533. int64 locationTag = ComputeLocationTagForAssertCompare(spe);
  534. int32 idx1 = sobj1PidMap.LookupWithKey(locationTag, -1);
  535. compareMap.DiagnosticAssert(idx1 != -1);
  536. TTDVar var1 = sobj1->VarArray[idx1];
  537. TTDVar var2 = sobj2->VarArray[i];
  538. if(spe.DataKind == NSSnapType::SnapEntryDataKindTag::Data)
  539. {
  540. NSSnapValues::AssertSnapEquivTTDVar_Property(var1, var2, compareMap, spe.PropertyRecordId);
  541. }
  542. else if(spe.DataKind == NSSnapType::SnapEntryDataKindTag::Getter)
  543. {
  544. NSSnapValues::AssertSnapEquivTTDVar_PropertyGetter(var1, var2, compareMap, spe.PropertyRecordId);
  545. }
  546. else
  547. {
  548. TTDAssert(spe.DataKind == NSSnapType::SnapEntryDataKindTag::Setter, "What other tags are there???");
  549. NSSnapValues::AssertSnapEquivTTDVar_PropertySetter(var1, var2, compareMap, spe.PropertyRecordId);
  550. }
  551. }
  552. }
  553. }
  554. fPtr_AssertSnapEquivAddtlInfo equivCheck = compareMap.SnapObjCmpVTable[(int32)sobj1->SnapObjectTag];
  555. if(equivCheck != nullptr)
  556. {
  557. equivCheck(sobj1, sobj2, compareMap);
  558. }
  559. }
  560. #endif
  561. Js::RecyclableObject* DoObjectInflation_SnapDynamicObject(const SnapObject* snpObject, InflateMap* inflator)
  562. {
  563. Js::DynamicObject* rcObj = ReuseObjectCheckAndReset(snpObject, inflator);
  564. if(rcObj != nullptr)
  565. {
  566. return rcObj;
  567. }
  568. else
  569. {
  570. Js::ScriptContext* ctx = inflator->LookupScriptContext(snpObject->SnapType->ScriptContextLogId);
  571. return ctx->GetLibrary()->CreateObject();
  572. }
  573. }
  574. Js::RecyclableObject* DoObjectInflation_SnapExternalObject(const SnapObject* snpObject, InflateMap* inflator)
  575. {
  576. Js::DynamicObject* rcObj = ReuseObjectCheckAndReset(snpObject, inflator);
  577. if(rcObj != nullptr)
  578. {
  579. return rcObj;
  580. }
  581. else
  582. {
  583. Js::ScriptContext* ctx = inflator->LookupScriptContext(snpObject->SnapType->ScriptContextLogId);
  584. Js::Var res = nullptr;
  585. ctx->GetThreadContext()->TTDContext->TTDExternalObjectFunctions.pfCreateExternalObject(ctx, &res);
  586. return Js::RecyclableObject::FromVar(res);
  587. }
  588. }
  589. //////////////////
  590. Js::RecyclableObject* DoObjectInflation_SnapScriptFunctionInfo(const SnapObject* snpObject, InflateMap* inflator)
  591. {
  592. Js::ScriptContext* ctx = inflator->LookupScriptContext(snpObject->SnapType->ScriptContextLogId);
  593. SnapScriptFunctionInfo* snapFuncInfo = SnapObjectGetAddtlInfoAs<SnapScriptFunctionInfo*, SnapObjectType::SnapScriptFunctionObject>(snpObject);
  594. Js::FunctionBody* fbody = inflator->LookupFunctionBody(snapFuncInfo->BodyRefId);
  595. Js::ScriptFunction* func = nullptr;
  596. if(!fbody->GetInlineCachesOnFunctionObject())
  597. {
  598. func = ctx->GetLibrary()->CreateScriptFunction(fbody);
  599. }
  600. else
  601. {
  602. Js::ScriptFunctionWithInlineCache* ifunc = ctx->GetLibrary()->CreateScriptFunctionWithInlineCache(fbody);
  603. ifunc->CreateInlineCache();
  604. func = ifunc;
  605. }
  606. func->SetHasSuperReference(snapFuncInfo->HasSuperReference);
  607. return func;
  608. }
  609. void DoAddtlValueInstantiation_SnapScriptFunctionInfo(const SnapObject* snpObject, Js::RecyclableObject* obj, InflateMap* inflator)
  610. {
  611. Js::ScriptFunction* fobj = Js::ScriptFunction::FromVar(obj);
  612. SnapScriptFunctionInfo* snapFuncInfo = SnapObjectGetAddtlInfoAs<SnapScriptFunctionInfo*, SnapObjectType::SnapScriptFunctionObject>(snpObject);
  613. if(snapFuncInfo->CachedScopeObjId != TTD_INVALID_PTR_ID)
  614. {
  615. fobj->SetCachedScope(Js::ActivationObjectEx::FromVar(inflator->LookupObject(snapFuncInfo->CachedScopeObjId)));
  616. }
  617. if(snapFuncInfo->HomeObjId != TTD_INVALID_PTR_ID)
  618. {
  619. fobj->SetHomeObj(inflator->LookupObject(snapFuncInfo->HomeObjId));
  620. }
  621. if(snapFuncInfo->ScopeId != TTD_INVALID_PTR_ID)
  622. {
  623. Js::FrameDisplay* environment = inflator->LookupEnvironment(snapFuncInfo->ScopeId);
  624. fobj->SetEnvironment(environment);
  625. }
  626. if(snapFuncInfo->ComputedNameInfo != nullptr)
  627. {
  628. Js::Var cNameVar = inflator->InflateTTDVar(snapFuncInfo->ComputedNameInfo);
  629. fobj->SetComputedNameVar(cNameVar);
  630. }
  631. }
  632. void EmitAddtlInfo_SnapScriptFunctionInfo(const SnapObject* snpObject, FileWriter* writer)
  633. {
  634. SnapScriptFunctionInfo* snapFuncInfo = SnapObjectGetAddtlInfoAs<SnapScriptFunctionInfo*, SnapObjectType::SnapScriptFunctionObject>(snpObject);
  635. writer->WriteAddr(NSTokens::Key::functionBodyId, snapFuncInfo->BodyRefId, NSTokens::Separator::CommaAndBigSpaceSeparator);
  636. writer->WriteString(NSTokens::Key::name, snapFuncInfo->DebugFunctionName, NSTokens::Separator::CommaSeparator);
  637. writer->WriteAddr(NSTokens::Key::cachedScopeObjId, snapFuncInfo->CachedScopeObjId, NSTokens::Separator::CommaSeparator);
  638. writer->WriteAddr(NSTokens::Key::scopeId, snapFuncInfo->ScopeId, NSTokens::Separator::CommaSeparator);
  639. writer->WriteAddr(NSTokens::Key::ptrIdVal, snapFuncInfo->HomeObjId, NSTokens::Separator::CommaSeparator);
  640. writer->WriteKey(NSTokens::Key::nameInfo, NSTokens::Separator::CommaSeparator);
  641. NSSnapValues::EmitTTDVar(snapFuncInfo->ComputedNameInfo, writer, NSTokens::Separator::NoSeparator);
  642. writer->WriteBool(NSTokens::Key::boolVal, snapFuncInfo->HasSuperReference, NSTokens::Separator::CommaSeparator);
  643. }
  644. void ParseAddtlInfo_SnapScriptFunctionInfo(SnapObject* snpObject, FileReader* reader, SlabAllocator& alloc)
  645. {
  646. SnapScriptFunctionInfo* snapFuncInfo = alloc.SlabAllocateStruct<SnapScriptFunctionInfo>();
  647. snapFuncInfo->BodyRefId = reader->ReadAddr(NSTokens::Key::functionBodyId, true);
  648. reader->ReadString(NSTokens::Key::name, alloc, snapFuncInfo->DebugFunctionName, true);
  649. snapFuncInfo->CachedScopeObjId = reader->ReadAddr(NSTokens::Key::cachedScopeObjId, true);
  650. snapFuncInfo->ScopeId = reader->ReadAddr(NSTokens::Key::scopeId, true);
  651. snapFuncInfo->HomeObjId = reader->ReadAddr(NSTokens::Key::ptrIdVal, true);
  652. reader->ReadKey(NSTokens::Key::nameInfo, true);
  653. snapFuncInfo->ComputedNameInfo = NSSnapValues::ParseTTDVar(false, reader);
  654. snapFuncInfo->HasSuperReference = reader->ReadBool(NSTokens::Key::boolVal, true);
  655. SnapObjectSetAddtlInfoAs<SnapScriptFunctionInfo*, SnapObjectType::SnapScriptFunctionObject>(snpObject, snapFuncInfo);
  656. }
  657. #if ENABLE_SNAPSHOT_COMPARE
  658. void AssertSnapEquiv_SnapScriptFunctionInfo(const SnapObject* sobj1, const SnapObject* sobj2, TTDCompareMap& compareMap)
  659. {
  660. const SnapScriptFunctionInfo* snapFuncInfo1 = SnapObjectGetAddtlInfoAs<SnapScriptFunctionInfo*, SnapObjectType::SnapScriptFunctionObject>(sobj1);
  661. const SnapScriptFunctionInfo* snapFuncInfo2 = SnapObjectGetAddtlInfoAs<SnapScriptFunctionInfo*, SnapObjectType::SnapScriptFunctionObject>(sobj2);
  662. compareMap.DiagnosticAssert(TTStringEQForDiagnostics(snapFuncInfo1->DebugFunctionName, snapFuncInfo2->DebugFunctionName));
  663. compareMap.CheckConsistentAndAddPtrIdMapping_FunctionBody(snapFuncInfo1->BodyRefId, snapFuncInfo2->BodyRefId);
  664. compareMap.CheckConsistentAndAddPtrIdMapping_Special(snapFuncInfo1->ScopeId, snapFuncInfo2->ScopeId, _u("scopes"));
  665. compareMap.CheckConsistentAndAddPtrIdMapping_Special(snapFuncInfo1->CachedScopeObjId, snapFuncInfo2->CachedScopeObjId, _u("cachedScopeObj"));
  666. compareMap.CheckConsistentAndAddPtrIdMapping_Special(snapFuncInfo1->HomeObjId, snapFuncInfo2->HomeObjId, _u("homeObject"));
  667. NSSnapValues::AssertSnapEquivTTDVar_Special(snapFuncInfo1->ComputedNameInfo, snapFuncInfo2->ComputedNameInfo, compareMap, _u("computedName"));
  668. compareMap.DiagnosticAssert(snapFuncInfo1->HasSuperReference == snapFuncInfo2->HasSuperReference);
  669. }
  670. #endif
  671. Js::RecyclableObject* DoObjectInflation_SnapExternalFunctionInfo(const SnapObject* snpObject, InflateMap* inflator)
  672. {
  673. Js::ScriptContext* ctx = inflator->LookupScriptContext(snpObject->SnapType->ScriptContextLogId);
  674. TTDVar snapVar = SnapObjectGetAddtlInfoAs<TTDVar, SnapObjectType::SnapExternalFunctionObject>(snpObject);
  675. Js::Var fname = (snapVar != nullptr) ? inflator->InflateTTDVar(snapVar) : nullptr;
  676. return ctx->GetLibrary()->CreateExternalFunction_TTD(fname);
  677. }
  678. void EmitAddtlInfo_SnapExternalFunctionInfo(const SnapObject* snpObject, FileWriter* writer)
  679. {
  680. TTDVar snapName = SnapObjectGetAddtlInfoAs<TTDVar, SnapObjectType::SnapExternalFunctionObject>(snpObject);
  681. writer->WriteKey(NSTokens::Key::name, NSTokens::Separator::CommaSeparator);
  682. NSSnapValues::EmitTTDVar(snapName, writer, NSTokens::Separator::NoSeparator);
  683. }
  684. void ParseAddtlInfo_SnapExternalFunctionInfo(SnapObject* snpObject, FileReader* reader, SlabAllocator& alloc)
  685. {
  686. reader->ReadKey(NSTokens::Key::name, true);
  687. TTDVar snapName = NSSnapValues::ParseTTDVar(false, reader);
  688. SnapObjectSetAddtlInfoAs<TTDVar, SnapObjectType::SnapExternalFunctionObject>(snpObject, snapName);
  689. }
  690. #if ENABLE_SNAPSHOT_COMPARE
  691. void AssertSnapEquiv_SnapExternalFunctionInfo(const SnapObject* sobj1, const SnapObject* sobj2, TTDCompareMap& compareMap)
  692. {
  693. TTDVar snapName1 = SnapObjectGetAddtlInfoAs<TTDVar, SnapObjectType::SnapExternalFunctionObject>(sobj1);
  694. TTDVar snapName2 = SnapObjectGetAddtlInfoAs<TTDVar, SnapObjectType::SnapExternalFunctionObject>(sobj2);
  695. NSSnapValues::AssertSnapEquivTTDVar_Special(snapName1, snapName2, compareMap, _u("externalFunctionName"));
  696. }
  697. #endif
  698. Js::RecyclableObject* DoObjectInflation_SnapRevokerFunctionInfo(const SnapObject* snpObject, InflateMap* inflator)
  699. {
  700. Js::ScriptContext* ctx = inflator->LookupScriptContext(snpObject->SnapType->ScriptContextLogId);
  701. TTD_PTR_ID* proxyId = SnapObjectGetAddtlInfoAs<TTD_PTR_ID*, SnapObjectType::SnapRuntimeRevokerFunctionObject>(snpObject);
  702. Js::RecyclableObject* proxyObj = nullptr;
  703. if(*proxyId == TTD_INVALID_PTR_ID)
  704. {
  705. proxyObj = ctx->GetLibrary()->GetNull();
  706. }
  707. else
  708. {
  709. proxyObj = inflator->LookupObject(*proxyId);
  710. }
  711. return ctx->GetLibrary()->CreateRevokeFunction_TTD(proxyObj);
  712. }
  713. void EmitAddtlInfo_SnapRevokerFunctionInfo(const SnapObject* snpObject, FileWriter* writer)
  714. {
  715. TTD_PTR_ID* revokeTrgt = SnapObjectGetAddtlInfoAs<TTD_PTR_ID*, SnapObjectType::SnapRuntimeRevokerFunctionObject>(snpObject);
  716. writer->WriteAddr(NSTokens::Key::objectId, *revokeTrgt, NSTokens::Separator::CommaSeparator);
  717. }
  718. void ParseAddtlInfo_SnapRevokerFunctionInfo(SnapObject* snpObject, FileReader* reader, SlabAllocator& alloc)
  719. {
  720. TTD_PTR_ID* revokerId = alloc.SlabAllocateStruct<TTD_PTR_ID>();
  721. *revokerId = reader->ReadAddr(NSTokens::Key::objectId, true);
  722. SnapObjectSetAddtlInfoAs<TTD_PTR_ID*, SnapObjectType::SnapRuntimeRevokerFunctionObject>(snpObject, revokerId);
  723. }
  724. #if ENABLE_SNAPSHOT_COMPARE
  725. void AssertSnapEquiv_SnapRevokerFunctionInfo(const SnapObject* sobj1, const SnapObject* sobj2, TTDCompareMap& compareMap)
  726. {
  727. TTD_PTR_ID* revokeTrgt1 = SnapObjectGetAddtlInfoAs<TTD_PTR_ID*, SnapObjectType::SnapRuntimeRevokerFunctionObject>(sobj1);
  728. TTD_PTR_ID* revokeTrgt2 = SnapObjectGetAddtlInfoAs<TTD_PTR_ID*, SnapObjectType::SnapRuntimeRevokerFunctionObject>(sobj2);
  729. compareMap.CheckConsistentAndAddPtrIdMapping_Special(*revokeTrgt1, *revokeTrgt2, _u("revokeTarget"));
  730. }
  731. #endif
  732. Js::RecyclableObject* DoObjectInflation_SnapBoundFunctionInfo(const SnapObject* snpObject, InflateMap* inflator)
  733. {
  734. //Bound functions are not too common and have special internal state so it seems easiest to always re-create them.
  735. //We can re-evaluate this choice later if needed.
  736. Js::ScriptContext* ctx = inflator->LookupScriptContext(snpObject->SnapType->ScriptContextLogId);
  737. SnapBoundFunctionInfo* snapBoundInfo = SnapObjectGetAddtlInfoAs<SnapBoundFunctionInfo*, SnapObjectType::SnapBoundFunctionObject>(snpObject);
  738. Js::RecyclableObject* bFunction = inflator->LookupObject(snapBoundInfo->TargetFunction);
  739. Js::RecyclableObject* bThis = (snapBoundInfo->BoundThis != TTD_INVALID_PTR_ID) ? inflator->LookupObject(snapBoundInfo->BoundThis) : nullptr;
  740. Field(Js::Var)* bArgs = nullptr;
  741. if(snapBoundInfo->ArgCount != 0)
  742. {
  743. bArgs = RecyclerNewArray(ctx->GetRecycler(), Field(Js::Var), snapBoundInfo->ArgCount);
  744. for(uint i = 0; i < snapBoundInfo->ArgCount; i++)
  745. {
  746. bArgs[i] = inflator->InflateTTDVar(snapBoundInfo->ArgArray[i]);
  747. }
  748. }
  749. return ctx->GetLibrary()->CreateBoundFunction_TTD(bFunction, bThis, snapBoundInfo->ArgCount, (Js::Var*)bArgs);
  750. }
  751. void EmitAddtlInfo_SnapBoundFunctionInfo(const SnapObject* snpObject, FileWriter* writer)
  752. {
  753. SnapBoundFunctionInfo* snapBoundInfo = SnapObjectGetAddtlInfoAs<SnapBoundFunctionInfo*, SnapObjectType::SnapBoundFunctionObject>(snpObject);
  754. writer->WriteAddr(NSTokens::Key::boundFunction, snapBoundInfo->TargetFunction, NSTokens::Separator::CommaAndBigSpaceSeparator);
  755. writer->WriteAddr(NSTokens::Key::boundThis, snapBoundInfo->BoundThis, NSTokens::Separator::CommaSeparator);
  756. writer->WriteLengthValue(snapBoundInfo->ArgCount, NSTokens::Separator::CommaSeparator);
  757. writer->WriteKey(NSTokens::Key::boundArgs, NSTokens::Separator::CommaAndBigSpaceSeparator);
  758. writer->WriteSequenceStart();
  759. for(uint32 i = 0; i < snapBoundInfo->ArgCount; ++i)
  760. {
  761. NSSnapValues::EmitTTDVar(snapBoundInfo->ArgArray[i], writer, i != 0 ? NSTokens::Separator::CommaSeparator : NSTokens::Separator::NoSeparator);
  762. }
  763. writer->WriteSequenceEnd();
  764. }
  765. void ParseAddtlInfo_SnapBoundFunctionInfo(SnapObject* snpObject, FileReader* reader, SlabAllocator& alloc)
  766. {
  767. SnapBoundFunctionInfo* snapBoundInfo = alloc.SlabAllocateStruct<SnapBoundFunctionInfo>();
  768. snapBoundInfo->TargetFunction = reader->ReadAddr(NSTokens::Key::boundFunction, true);
  769. snapBoundInfo->BoundThis = reader->ReadAddr(NSTokens::Key::boundThis, true);
  770. snapBoundInfo->ArgCount = reader->ReadLengthValue(true);
  771. if(snapBoundInfo->ArgCount == 0)
  772. {
  773. snapBoundInfo->ArgArray = nullptr;
  774. }
  775. else
  776. {
  777. snapBoundInfo->ArgArray = alloc.SlabAllocateArray<TTDVar>(snapBoundInfo->ArgCount);
  778. }
  779. reader->ReadKey(NSTokens::Key::boundArgs, true);
  780. reader->ReadSequenceStart();
  781. for(uint32 i = 0; i < snapBoundInfo->ArgCount; ++i)
  782. {
  783. snapBoundInfo->ArgArray[i] = NSSnapValues::ParseTTDVar(i != 0, reader);
  784. }
  785. reader->ReadSequenceEnd();
  786. SnapObjectSetAddtlInfoAs<SnapBoundFunctionInfo*, SnapObjectType::SnapBoundFunctionObject>(snpObject, snapBoundInfo);
  787. }
  788. #if ENABLE_SNAPSHOT_COMPARE
  789. void AssertSnapEquiv_SnapBoundFunctionInfo(const SnapObject* sobj1, const SnapObject* sobj2, TTDCompareMap& compareMap)
  790. {
  791. SnapBoundFunctionInfo* snapBoundInfo1 = SnapObjectGetAddtlInfoAs<SnapBoundFunctionInfo*, SnapObjectType::SnapBoundFunctionObject>(sobj1);
  792. SnapBoundFunctionInfo* snapBoundInfo2 = SnapObjectGetAddtlInfoAs<SnapBoundFunctionInfo*, SnapObjectType::SnapBoundFunctionObject>(sobj2);
  793. compareMap.CheckConsistentAndAddPtrIdMapping_Special(snapBoundInfo1->TargetFunction, snapBoundInfo2->TargetFunction, _u("targetFunction"));
  794. compareMap.CheckConsistentAndAddPtrIdMapping_Special(snapBoundInfo1->BoundThis, snapBoundInfo2->BoundThis, _u("boundThis"));
  795. compareMap.DiagnosticAssert(snapBoundInfo1->ArgCount == snapBoundInfo2->ArgCount);
  796. for(uint32 i = 0; i < snapBoundInfo1->ArgCount; ++i)
  797. {
  798. NSSnapValues::AssertSnapEquivTTDVar_SpecialArray(snapBoundInfo1->ArgArray[i], snapBoundInfo2->ArgArray[i], compareMap, _u("boundArgs"), i);
  799. }
  800. }
  801. #endif
  802. //////////////////
  803. Js::RecyclableObject* DoObjectInflation_SnapActivationInfo(const SnapObject* snpObject, InflateMap* inflator)
  804. {
  805. Js::ScriptContext* ctx = inflator->LookupScriptContext(snpObject->SnapType->ScriptContextLogId);
  806. return ctx->GetLibrary()->CreateActivationObject();
  807. }
  808. Js::RecyclableObject* DoObjectInflation_SnapBlockActivationObject(const SnapObject* snpObject, InflateMap* inflator)
  809. {
  810. Js::ScriptContext* ctx = inflator->LookupScriptContext(snpObject->SnapType->ScriptContextLogId);
  811. return ctx->GetLibrary()->CreateBlockActivationObject();
  812. }
  813. Js::RecyclableObject* DoObjectInflation_SnapPseudoActivationObject(const SnapObject* snpObject, InflateMap* inflator)
  814. {
  815. Js::ScriptContext* ctx = inflator->LookupScriptContext(snpObject->SnapType->ScriptContextLogId);
  816. return ctx->GetLibrary()->CreatePseudoActivationObject();
  817. }
  818. Js::RecyclableObject* DoObjectInflation_SnapConsoleScopeActivationObject(const SnapObject* snpObject, InflateMap* inflator)
  819. {
  820. Js::ScriptContext* ctx = inflator->LookupScriptContext(snpObject->SnapType->ScriptContextLogId);
  821. return ctx->GetLibrary()->CreateConsoleScopeActivationObject();
  822. }
  823. //////////////////
  824. Js::RecyclableObject* DoObjectInflation_SnapHeapArgumentsInfo(const SnapObject* snpObject, InflateMap* inflator)
  825. {
  826. Js::ScriptContext* ctx = inflator->LookupScriptContext(snpObject->SnapType->ScriptContextLogId);
  827. SnapHeapArgumentsInfo* argsInfo = SnapObjectGetAddtlInfoAs<SnapHeapArgumentsInfo*, SnapObjectType::SnapHeapArgumentsObject>(snpObject);
  828. Js::RecyclableObject* activationObj = nullptr;
  829. if(argsInfo->IsFrameNullPtr)
  830. {
  831. activationObj = nullptr;
  832. }
  833. else
  834. {
  835. TTDAssert(argsInfo->FrameObject != TTD_INVALID_PTR_ID, "That won't work!");
  836. activationObj = inflator->LookupObject(argsInfo->FrameObject);
  837. }
  838. return ctx->GetLibrary()->CreateHeapArguments_TTD(argsInfo->NumOfArguments, argsInfo->FormalCount, static_cast<Js::ActivationObject*>(activationObj), argsInfo->DeletedArgFlags);
  839. }
  840. Js::RecyclableObject* DoObjectInflation_SnapES5HeapArgumentsInfo(const SnapObject* snpObject, InflateMap* inflator)
  841. {
  842. Js::ScriptContext* ctx = inflator->LookupScriptContext(snpObject->SnapType->ScriptContextLogId);
  843. SnapHeapArgumentsInfo* argsInfo = SnapObjectGetAddtlInfoAs<SnapHeapArgumentsInfo*, SnapObjectType::SnapES5HeapArgumentsObject>(snpObject);
  844. Js::RecyclableObject* activationObj = nullptr;
  845. if(argsInfo->IsFrameNullPtr)
  846. {
  847. activationObj = nullptr;
  848. }
  849. else
  850. {
  851. TTDAssert(argsInfo->FrameObject != TTD_INVALID_PTR_ID, "That won't work!");
  852. activationObj = inflator->LookupObject(argsInfo->FrameObject);
  853. }
  854. return ctx->GetLibrary()->CreateES5HeapArguments_TTD(argsInfo->NumOfArguments, argsInfo->FormalCount, static_cast<Js::ActivationObject*>(activationObj), argsInfo->DeletedArgFlags);
  855. }
  856. //////////////////
  857. ////
  858. //Promise Info
  859. Js::RecyclableObject* DoObjectInflation_SnapPromiseInfo(const SnapObject* snpObject, InflateMap* inflator)
  860. {
  861. const SnapPromiseInfo* promiseInfo = SnapObjectGetAddtlInfoAs<SnapPromiseInfo*, SnapObjectType::SnapPromiseObject>(snpObject);
  862. Js::ScriptContext* ctx = inflator->LookupScriptContext(snpObject->SnapType->ScriptContextLogId);
  863. Js::Var result = (promiseInfo->Result != nullptr) ? inflator->InflateTTDVar(promiseInfo->Result) : nullptr;
  864. JsUtil::List<Js::JavascriptPromiseReaction*, HeapAllocator> resolveReactions(&HeapAllocator::Instance);
  865. for(uint32 i = 0; i < promiseInfo->ResolveReactionCount; ++i)
  866. {
  867. Js::JavascriptPromiseReaction* reaction = NSSnapValues::InflatePromiseReactionInfo(promiseInfo->ResolveReactions + i, ctx, inflator);
  868. resolveReactions.Add(reaction);
  869. }
  870. JsUtil::List<Js::JavascriptPromiseReaction*, HeapAllocator> rejectReactions(&HeapAllocator::Instance);
  871. for(uint32 i = 0; i < promiseInfo->RejectReactionCount; ++i)
  872. {
  873. Js::JavascriptPromiseReaction* reaction = NSSnapValues::InflatePromiseReactionInfo(promiseInfo->RejectReactions + i, ctx, inflator);
  874. rejectReactions.Add(reaction);
  875. }
  876. Js::RecyclableObject* res = ctx->GetLibrary()->CreatePromise_TTD(promiseInfo->Status, result, resolveReactions, rejectReactions);
  877. return res;
  878. }
  879. void EmitAddtlInfo_SnapPromiseInfo(const SnapObject* snpObject, FileWriter* writer)
  880. {
  881. SnapPromiseInfo* promiseInfo = SnapObjectGetAddtlInfoAs<SnapPromiseInfo*, SnapObjectType::SnapPromiseObject>(snpObject);
  882. writer->WriteUInt32(NSTokens::Key::u32Val, promiseInfo->Status, NSTokens::Separator::CommaSeparator);
  883. writer->WriteKey(NSTokens::Key::resultValue, NSTokens::Separator::CommaSeparator);
  884. NSSnapValues::EmitTTDVar(promiseInfo->Result, writer, NSTokens::Separator::NoSeparator);
  885. writer->WriteLengthValue(promiseInfo->ResolveReactionCount, NSTokens::Separator::CommaSeparator);
  886. writer->WriteSequenceStart_DefaultKey(NSTokens::Separator::CommaSeparator);
  887. for(uint32 i = 0; i < promiseInfo->ResolveReactionCount; ++i)
  888. {
  889. NSTokens::Separator sep = (i != 0) ? NSTokens::Separator::CommaSeparator : NSTokens::Separator::NoSeparator;
  890. NSSnapValues::EmitPromiseReactionInfo(promiseInfo->ResolveReactions + i, writer, sep);
  891. }
  892. writer->WriteSequenceEnd();
  893. writer->WriteLengthValue(promiseInfo->RejectReactionCount, NSTokens::Separator::CommaSeparator);
  894. writer->WriteSequenceStart_DefaultKey(NSTokens::Separator::CommaSeparator);
  895. for(uint32 i = 0; i < promiseInfo->RejectReactionCount; ++i)
  896. {
  897. NSTokens::Separator sep = (i != 0) ? NSTokens::Separator::CommaSeparator : NSTokens::Separator::NoSeparator;
  898. NSSnapValues::EmitPromiseReactionInfo(promiseInfo->RejectReactions + i, writer, sep);
  899. }
  900. writer->WriteSequenceEnd();
  901. }
  902. void ParseAddtlInfo_SnapPromiseInfo(SnapObject* snpObject, FileReader* reader, SlabAllocator& alloc)
  903. {
  904. SnapPromiseInfo* promiseInfo = alloc.SlabAllocateStruct<SnapPromiseInfo>();
  905. promiseInfo->Status = reader->ReadUInt32(NSTokens::Key::u32Val, true);
  906. reader->ReadKey(NSTokens::Key::resultValue, true);
  907. promiseInfo->Result = NSSnapValues::ParseTTDVar(false, reader);
  908. promiseInfo->ResolveReactionCount = reader->ReadLengthValue(true);
  909. promiseInfo->ResolveReactions = nullptr;
  910. reader->ReadSequenceStart_WDefaultKey(true);
  911. if(promiseInfo->ResolveReactionCount != 0)
  912. {
  913. promiseInfo->ResolveReactions = alloc.SlabAllocateArray<NSSnapValues::SnapPromiseReactionInfo>(promiseInfo->ResolveReactionCount);
  914. for(uint32 i = 0; i < promiseInfo->ResolveReactionCount; ++i)
  915. {
  916. NSSnapValues::ParsePromiseReactionInfo(promiseInfo->ResolveReactions + i, i != 0, reader, alloc);
  917. }
  918. }
  919. reader->ReadSequenceEnd();
  920. promiseInfo->RejectReactionCount = reader->ReadLengthValue(true);
  921. promiseInfo->RejectReactions = nullptr;
  922. reader->ReadSequenceStart_WDefaultKey(true);
  923. if(promiseInfo->RejectReactionCount != 0)
  924. {
  925. promiseInfo->RejectReactions = alloc.SlabAllocateArray<NSSnapValues::SnapPromiseReactionInfo>(promiseInfo->RejectReactionCount);
  926. for(uint32 i = 0; i < promiseInfo->RejectReactionCount; ++i)
  927. {
  928. NSSnapValues::ParsePromiseReactionInfo(promiseInfo->RejectReactions + i, i != 0, reader, alloc);
  929. }
  930. }
  931. reader->ReadSequenceEnd();
  932. SnapObjectSetAddtlInfoAs<SnapPromiseInfo*, SnapObjectType::SnapPromiseObject>(snpObject, promiseInfo);
  933. }
  934. #if ENABLE_SNAPSHOT_COMPARE
  935. void AssertSnapEquiv_SnapPromiseInfo(const SnapObject* sobj1, const SnapObject* sobj2, TTDCompareMap& compareMap)
  936. {
  937. const SnapPromiseInfo* promiseInfo1 = SnapObjectGetAddtlInfoAs<SnapPromiseInfo*, SnapObjectType::SnapPromiseObject>(sobj1);
  938. const SnapPromiseInfo* promiseInfo2 = SnapObjectGetAddtlInfoAs<SnapPromiseInfo*, SnapObjectType::SnapPromiseObject>(sobj2);
  939. NSSnapValues::AssertSnapEquivTTDVar_Special(promiseInfo1->Result, promiseInfo2->Result, compareMap, _u("result"));
  940. compareMap.DiagnosticAssert(promiseInfo1->ResolveReactionCount == promiseInfo2->ResolveReactionCount);
  941. for(uint32 i = 0; i < promiseInfo1->ResolveReactionCount; ++i)
  942. {
  943. NSSnapValues::AssertSnapEquiv(promiseInfo1->ResolveReactions + i, promiseInfo2->ResolveReactions + i, compareMap);
  944. }
  945. compareMap.DiagnosticAssert(promiseInfo1->RejectReactionCount == promiseInfo2->RejectReactionCount);
  946. for(uint32 i = 0; i < promiseInfo1->RejectReactionCount; ++i)
  947. {
  948. NSSnapValues::AssertSnapEquiv(promiseInfo1->RejectReactions + i, promiseInfo2->RejectReactions + i, compareMap);
  949. }
  950. }
  951. #endif
  952. ////
  953. //PromiseResolveOrRejectFunction Info
  954. Js::RecyclableObject* DoObjectInflation_SnapPromiseResolveOrRejectFunctionInfo(const SnapObject* snpObject, InflateMap* inflator)
  955. {
  956. const SnapPromiseResolveOrRejectFunctionInfo* rrfInfo = SnapObjectGetAddtlInfoAs<SnapPromiseResolveOrRejectFunctionInfo*, SnapObjectType::SnapPromiseResolveOrRejectFunctionObject>(snpObject);
  957. Js::ScriptContext* ctx = inflator->LookupScriptContext(snpObject->SnapType->ScriptContextLogId);
  958. Js::RecyclableObject* promise = inflator->LookupObject(rrfInfo->PromiseId);
  959. if(!inflator->IsPromiseInfoDefined<Js::JavascriptPromiseResolveOrRejectFunctionAlreadyResolvedWrapper>(rrfInfo->AlreadyResolvedWrapperId))
  960. {
  961. Js::JavascriptPromiseResolveOrRejectFunctionAlreadyResolvedWrapper* wrapper = ctx->GetLibrary()->CreateAlreadyDefinedWrapper_TTD(rrfInfo->AlreadyResolvedValue);
  962. inflator->AddInflatedPromiseInfo<Js::JavascriptPromiseResolveOrRejectFunctionAlreadyResolvedWrapper>(rrfInfo->AlreadyResolvedWrapperId, wrapper);
  963. }
  964. Js::JavascriptPromiseResolveOrRejectFunctionAlreadyResolvedWrapper* alreadyResolved = inflator->LookupInflatedPromiseInfo<Js::JavascriptPromiseResolveOrRejectFunctionAlreadyResolvedWrapper>(rrfInfo->AlreadyResolvedWrapperId);
  965. return ctx->GetLibrary()->CreatePromiseResolveOrRejectFunction_TTD(promise, rrfInfo->IsReject, alreadyResolved);
  966. }
  967. void EmitAddtlInfo_SnapPromiseResolveOrRejectFunctionInfo(const SnapObject* snpObject, FileWriter* writer)
  968. {
  969. SnapPromiseResolveOrRejectFunctionInfo* rrfInfo = SnapObjectGetAddtlInfoAs<SnapPromiseResolveOrRejectFunctionInfo*, SnapObjectType::SnapPromiseResolveOrRejectFunctionObject>(snpObject);
  970. writer->WriteAddr(NSTokens::Key::ptrIdVal, rrfInfo->PromiseId, NSTokens::Separator::CommaSeparator);
  971. writer->WriteBool(NSTokens::Key::boolVal, rrfInfo->IsReject, NSTokens::Separator::CommaSeparator);
  972. writer->WriteAddr(NSTokens::Key::ptrIdVal, rrfInfo->AlreadyResolvedWrapperId, NSTokens::Separator::CommaSeparator);
  973. writer->WriteBool(NSTokens::Key::boolVal, rrfInfo->AlreadyResolvedValue, NSTokens::Separator::CommaSeparator);
  974. }
  975. void ParseAddtlInfo_SnapPromiseResolveOrRejectFunctionInfo(SnapObject* snpObject, FileReader* reader, SlabAllocator& alloc)
  976. {
  977. SnapPromiseResolveOrRejectFunctionInfo* rrfInfo = alloc.SlabAllocateStruct<SnapPromiseResolveOrRejectFunctionInfo>();
  978. rrfInfo->PromiseId = reader->ReadAddr(NSTokens::Key::ptrIdVal, true);
  979. rrfInfo->IsReject = reader->ReadBool(NSTokens::Key::boolVal, true);
  980. rrfInfo->AlreadyResolvedWrapperId = reader->ReadAddr(NSTokens::Key::ptrIdVal, true);
  981. rrfInfo->AlreadyResolvedValue = reader->ReadBool(NSTokens::Key::boolVal, true);
  982. SnapObjectSetAddtlInfoAs<SnapPromiseResolveOrRejectFunctionInfo*, SnapObjectType::SnapPromiseResolveOrRejectFunctionObject>(snpObject, rrfInfo);
  983. }
  984. #if ENABLE_SNAPSHOT_COMPARE
  985. void AssertSnapEquiv_SnapPromiseResolveOrRejectFunctionInfo(const SnapObject* sobj1, const SnapObject* sobj2, TTDCompareMap& compareMap)
  986. {
  987. SnapPromiseResolveOrRejectFunctionInfo* rrfInfo1 = SnapObjectGetAddtlInfoAs<SnapPromiseResolveOrRejectFunctionInfo*, SnapObjectType::SnapPromiseResolveOrRejectFunctionObject>(sobj1);
  988. SnapPromiseResolveOrRejectFunctionInfo* rrfInfo2 = SnapObjectGetAddtlInfoAs<SnapPromiseResolveOrRejectFunctionInfo*, SnapObjectType::SnapPromiseResolveOrRejectFunctionObject>(sobj2);
  989. compareMap.CheckConsistentAndAddPtrIdMapping_Special(rrfInfo1->PromiseId, rrfInfo2->PromiseId, _u("promise"));
  990. compareMap.DiagnosticAssert(rrfInfo1->IsReject == rrfInfo2->IsReject);
  991. compareMap.DiagnosticAssert(rrfInfo1->AlreadyResolvedValue == rrfInfo2->AlreadyResolvedValue);
  992. compareMap.CheckConsistentAndAddPtrIdMapping_NoEnqueue(rrfInfo1->AlreadyResolvedWrapperId, rrfInfo2->AlreadyResolvedWrapperId);
  993. }
  994. #endif
  995. ////
  996. //ReactionTaskFunction Info
  997. Js::RecyclableObject* DoObjectInflation_SnapPromiseReactionTaskFunctionInfo(const SnapObject* snpObject, InflateMap* inflator)
  998. {
  999. const SnapPromiseReactionTaskFunctionInfo* rInfo = SnapObjectGetAddtlInfoAs<SnapPromiseReactionTaskFunctionInfo*, SnapObjectType::SnapPromiseReactionTaskFunctionObject>(snpObject);
  1000. Js::ScriptContext* ctx = inflator->LookupScriptContext(snpObject->SnapType->ScriptContextLogId);
  1001. Js::JavascriptPromiseReaction* reaction = NSSnapValues::InflatePromiseReactionInfo(&rInfo->Reaction, ctx, inflator);
  1002. Js::Var argument = inflator->InflateTTDVar(rInfo->Argument);
  1003. return ctx->GetLibrary()->CreatePromiseReactionTaskFunction_TTD(reaction, argument);
  1004. }
  1005. void EmitAddtlInfo_SnapPromiseReactionTaskFunctionInfo(const SnapObject* snpObject, FileWriter* writer)
  1006. {
  1007. SnapPromiseReactionTaskFunctionInfo* rInfo = SnapObjectGetAddtlInfoAs<SnapPromiseReactionTaskFunctionInfo*, SnapObjectType::SnapPromiseReactionTaskFunctionObject>(snpObject);
  1008. writer->WriteKey(NSTokens::Key::entry, NSTokens::Separator::CommaSeparator);
  1009. NSSnapValues::EmitTTDVar(rInfo->Argument, writer, NSTokens::Separator::NoSeparator);
  1010. writer->WriteKey(NSTokens::Key::reaction, NSTokens::Separator::CommaSeparator);
  1011. NSSnapValues::EmitPromiseReactionInfo(&rInfo->Reaction, writer, NSTokens::Separator::NoSeparator);
  1012. }
  1013. void ParseAddtlInfo_SnapPromiseReactionTaskFunctionInfo(SnapObject* snpObject, FileReader* reader, SlabAllocator& alloc)
  1014. {
  1015. SnapPromiseReactionTaskFunctionInfo* rInfo = alloc.SlabAllocateStruct<SnapPromiseReactionTaskFunctionInfo>();
  1016. reader->ReadKey(NSTokens::Key::entry, true);
  1017. rInfo->Argument = NSSnapValues::ParseTTDVar(false, reader);
  1018. reader->ReadKey(NSTokens::Key::reaction, true);
  1019. NSSnapValues::ParsePromiseReactionInfo(&rInfo->Reaction, false, reader, alloc);
  1020. SnapObjectSetAddtlInfoAs<SnapPromiseReactionTaskFunctionInfo*, SnapObjectType::SnapPromiseReactionTaskFunctionObject>(snpObject, rInfo);
  1021. }
  1022. #if ENABLE_SNAPSHOT_COMPARE
  1023. void AssertSnapEquiv_SnapPromiseReactionTaskFunctionInfo(const SnapObject* sobj1, const SnapObject* sobj2, TTDCompareMap& compareMap)
  1024. {
  1025. SnapPromiseReactionTaskFunctionInfo* rInfo1 = SnapObjectGetAddtlInfoAs<SnapPromiseReactionTaskFunctionInfo*, SnapObjectType::SnapPromiseReactionTaskFunctionObject>(sobj1);
  1026. SnapPromiseReactionTaskFunctionInfo* rInfo2 = SnapObjectGetAddtlInfoAs<SnapPromiseReactionTaskFunctionInfo*, SnapObjectType::SnapPromiseReactionTaskFunctionObject>(sobj2);
  1027. NSSnapValues::AssertSnapEquivTTDVar_Special(rInfo1->Argument, rInfo2->Argument, compareMap, _u("argument"));
  1028. NSSnapValues::AssertSnapEquiv(&(rInfo1->Reaction), &(rInfo2->Reaction), compareMap);
  1029. }
  1030. #endif
  1031. ////
  1032. //AllResolveElementFunctionObject Info
  1033. Js::RecyclableObject* DoObjectInflation_SnapPromiseAllResolveElementFunctionInfo(const SnapObject* snpObject, InflateMap* inflator)
  1034. {
  1035. const SnapPromiseAllResolveElementFunctionInfo* aInfo = SnapObjectGetAddtlInfoAs<SnapPromiseAllResolveElementFunctionInfo*, SnapObjectType::SnapPromiseAllResolveElementFunctionObject>(snpObject);
  1036. Js::ScriptContext* ctx = inflator->LookupScriptContext(snpObject->SnapType->ScriptContextLogId);
  1037. Js::JavascriptPromiseCapability* capabilities = InflatePromiseCapabilityInfo(&aInfo->Capabilities, ctx, inflator);
  1038. if(!inflator->IsPromiseInfoDefined<Js::JavascriptPromiseAllResolveElementFunctionRemainingElementsWrapper>(aInfo->RemainingElementsWrapperId))
  1039. {
  1040. Js::JavascriptPromiseAllResolveElementFunctionRemainingElementsWrapper* remainingWrapper = ctx->GetLibrary()->CreateRemainingElementsWrapper_TTD(ctx, aInfo->RemainingElementsValue);
  1041. inflator->AddInflatedPromiseInfo(aInfo->RemainingElementsWrapperId, remainingWrapper);
  1042. }
  1043. Js::JavascriptPromiseAllResolveElementFunctionRemainingElementsWrapper* wrapper = inflator->LookupInflatedPromiseInfo<Js::JavascriptPromiseAllResolveElementFunctionRemainingElementsWrapper>(aInfo->RemainingElementsWrapperId);
  1044. Js::RecyclableObject* values = inflator->LookupObject(aInfo->Values);
  1045. return ctx->GetLibrary()->CreatePromiseAllResolveElementFunction_TTD(capabilities, aInfo->Index, wrapper, values, aInfo->AlreadyCalled);
  1046. }
  1047. void EmitAddtlInfo_SnapPromiseAllResolveElementFunctionInfo(const SnapObject* snpObject, FileWriter* writer)
  1048. {
  1049. SnapPromiseAllResolveElementFunctionInfo* aInfo = SnapObjectGetAddtlInfoAs<SnapPromiseAllResolveElementFunctionInfo*, SnapObjectType::SnapPromiseAllResolveElementFunctionObject>(snpObject);
  1050. writer->WriteKey(NSTokens::Key::entry, NSTokens::Separator::CommaSeparator);
  1051. NSSnapValues::EmitPromiseCapabilityInfo(&aInfo->Capabilities, writer, NSTokens::Separator::NoSeparator);
  1052. writer->WriteUInt32(NSTokens::Key::u32Val, aInfo->Index, NSTokens::Separator::CommaSeparator);
  1053. writer->WriteAddr(NSTokens::Key::ptrIdVal, aInfo->RemainingElementsWrapperId, NSTokens::Separator::CommaSeparator);
  1054. writer->WriteUInt32(NSTokens::Key::u32Val, aInfo->RemainingElementsValue, NSTokens::Separator::CommaSeparator);
  1055. writer->WriteAddr(NSTokens::Key::ptrIdVal, aInfo->Values, NSTokens::Separator::CommaSeparator);
  1056. writer->WriteBool(NSTokens::Key::boolVal, aInfo->AlreadyCalled, NSTokens::Separator::CommaSeparator);
  1057. }
  1058. void ParseAddtlInfo_SnapPromiseAllResolveElementFunctionInfo(SnapObject* snpObject, FileReader* reader, SlabAllocator& alloc)
  1059. {
  1060. SnapPromiseAllResolveElementFunctionInfo* aInfo = alloc.SlabAllocateStruct<SnapPromiseAllResolveElementFunctionInfo>();
  1061. reader->ReadKey(NSTokens::Key::entry, true);
  1062. NSSnapValues::ParsePromiseCapabilityInfo(&aInfo->Capabilities, false, reader, alloc);
  1063. aInfo->Index = reader->ReadUInt32(NSTokens::Key::u32Val, true);
  1064. aInfo->RemainingElementsWrapperId = reader->ReadAddr(NSTokens::Key::ptrIdVal, true);
  1065. aInfo->RemainingElementsValue = reader->ReadUInt32(NSTokens::Key::u32Val, true);
  1066. aInfo->Values = reader->ReadAddr(NSTokens::Key::ptrIdVal, true);
  1067. aInfo->AlreadyCalled = reader->ReadBool(NSTokens::Key::boolVal, true);
  1068. SnapObjectSetAddtlInfoAs<SnapPromiseAllResolveElementFunctionInfo*, SnapObjectType::SnapPromiseAllResolveElementFunctionObject>(snpObject, aInfo);
  1069. }
  1070. #if ENABLE_SNAPSHOT_COMPARE
  1071. void AssertSnapEquiv_SnapPromiseAllResolveElementFunctionInfo(const SnapObject* sobj1, const SnapObject* sobj2, TTDCompareMap& compareMap)
  1072. {
  1073. SnapPromiseAllResolveElementFunctionInfo* aInfo1 = SnapObjectGetAddtlInfoAs<SnapPromiseAllResolveElementFunctionInfo*, SnapObjectType::SnapPromiseAllResolveElementFunctionObject>(sobj1);
  1074. SnapPromiseAllResolveElementFunctionInfo* aInfo2 = SnapObjectGetAddtlInfoAs<SnapPromiseAllResolveElementFunctionInfo*, SnapObjectType::SnapPromiseAllResolveElementFunctionObject>(sobj2);
  1075. NSSnapValues::AssertSnapEquiv(&aInfo1->Capabilities, &aInfo2->Capabilities, compareMap);
  1076. compareMap.DiagnosticAssert(aInfo1->Index == aInfo2->Index);
  1077. compareMap.DiagnosticAssert(aInfo1->RemainingElementsValue == aInfo2->RemainingElementsValue);
  1078. compareMap.DiagnosticAssert(aInfo1->AlreadyCalled == aInfo2->AlreadyCalled);
  1079. compareMap.CheckConsistentAndAddPtrIdMapping_Special(aInfo1->Values, aInfo2->Values, _u("values"));
  1080. compareMap.CheckConsistentAndAddPtrIdMapping_NoEnqueue(aInfo1->RemainingElementsWrapperId, aInfo2->RemainingElementsWrapperId);
  1081. }
  1082. #endif
  1083. //////////////////
  1084. Js::RecyclableObject* DoObjectInflation_SnapBoxedValue(const SnapObject* snpObject, InflateMap* inflator)
  1085. {
  1086. //Boxed values are not too common and have special internal state so it seems easiest to always re-create them.
  1087. //We can re-evaluate this choice later if needed.
  1088. Js::ScriptContext* ctx = inflator->LookupScriptContext(snpObject->SnapType->ScriptContextLogId);
  1089. return ctx->GetLibrary()->CreateDefaultBoxedObject_TTD(snpObject->SnapType->JsTypeId);
  1090. }
  1091. void DoAddtlValueInstantiation_SnapBoxedValue(const SnapObject* snpObject, Js::RecyclableObject* obj, InflateMap* inflator)
  1092. {
  1093. Js::ScriptContext* ctx = inflator->LookupScriptContext(snpObject->SnapType->ScriptContextLogId);
  1094. TTDVar snapBoxedVar = SnapObjectGetAddtlInfoAs<TTDVar, SnapObjectType::SnapBoxedValueObject>(snpObject);
  1095. Js::Var jsvar = (snapBoxedVar != nullptr) ? inflator->InflateTTDVar(snapBoxedVar) : nullptr;
  1096. ctx->GetLibrary()->SetBoxedObjectValue_TTD(obj, jsvar);
  1097. }
  1098. void EmitAddtlInfo_SnapBoxedValue(const SnapObject* snpObject, FileWriter* writer)
  1099. {
  1100. TTDVar snapBoxedVar = SnapObjectGetAddtlInfoAs<TTDVar, SnapObjectType::SnapBoxedValueObject>(snpObject);
  1101. writer->WriteKey(NSTokens::Key::boxedInfo, NSTokens::Separator::CommaAndBigSpaceSeparator);
  1102. NSSnapValues::EmitTTDVar(snapBoxedVar, writer, NSTokens::Separator::NoSeparator);
  1103. }
  1104. void ParseAddtlInfo_SnapBoxedValue(SnapObject* snpObject, FileReader* reader, SlabAllocator& alloc)
  1105. {
  1106. reader->ReadKey(NSTokens::Key::boxedInfo, true);
  1107. TTDVar snapVar = NSSnapValues::ParseTTDVar(false, reader);
  1108. SnapObjectSetAddtlInfoAs<TTDVar, SnapObjectType::SnapBoxedValueObject>(snpObject, snapVar);
  1109. }
  1110. #if ENABLE_SNAPSHOT_COMPARE
  1111. void AssertSnapEquiv_SnapBoxedValue(const SnapObject* sobj1, const SnapObject* sobj2, TTDCompareMap& compareMap)
  1112. {
  1113. TTDVar snapBoxedVar1 = SnapObjectGetAddtlInfoAs<TTDVar, SnapObjectType::SnapBoxedValueObject>(sobj1);
  1114. TTDVar snapBoxedVar2 = SnapObjectGetAddtlInfoAs<TTDVar, SnapObjectType::SnapBoxedValueObject>(sobj2);
  1115. NSSnapValues::AssertSnapEquivTTDVar_Special(snapBoxedVar1, snapBoxedVar2, compareMap, _u("boxedVar"));
  1116. }
  1117. #endif
  1118. Js::RecyclableObject* DoObjectInflation_SnapDate(const SnapObject* snpObject, InflateMap* inflator)
  1119. {
  1120. //Dates are not too common and have some mutable state so it seems easiest to always re-create them.
  1121. //We can re-evaluate this choice later if needed.
  1122. Js::ScriptContext* ctx = inflator->LookupScriptContext(snpObject->SnapType->ScriptContextLogId);
  1123. double* dateInfo = SnapObjectGetAddtlInfoAs<double*, SnapObjectType::SnapDateObject>(snpObject);
  1124. return ctx->GetLibrary()->CreateDate_TTD(*dateInfo);
  1125. }
  1126. void EmitAddtlInfo_SnapDate(const SnapObject* snpObject, FileWriter* writer)
  1127. {
  1128. double* dateInfo = SnapObjectGetAddtlInfoAs<double*, SnapObjectType::SnapDateObject>(snpObject);
  1129. writer->WriteDouble(NSTokens::Key::doubleVal, *dateInfo, NSTokens::Separator::CommaAndBigSpaceSeparator);
  1130. }
  1131. void ParseAddtlInfo_SnapDate(SnapObject* snpObject, FileReader* reader, SlabAllocator& alloc)
  1132. {
  1133. double* dateInfo = alloc.SlabAllocateStruct<double>();
  1134. *dateInfo = reader->ReadDouble(NSTokens::Key::doubleVal, true);
  1135. SnapObjectSetAddtlInfoAs<double*, SnapObjectType::SnapDateObject>(snpObject, dateInfo);
  1136. }
  1137. #if ENABLE_SNAPSHOT_COMPARE
  1138. void AssertSnapEquiv_SnapDate(const SnapObject* sobj1, const SnapObject* sobj2, TTDCompareMap& compareMap)
  1139. {
  1140. const double* dateInfo1 = SnapObjectGetAddtlInfoAs<double*, SnapObjectType::SnapDateObject>(sobj1);
  1141. const double* dateInfo2 = SnapObjectGetAddtlInfoAs<double*, SnapObjectType::SnapDateObject>(sobj2);
  1142. compareMap.DiagnosticAssert(NSSnapValues::CheckSnapEquivTTDDouble(*dateInfo1, *dateInfo2));
  1143. }
  1144. #endif
  1145. Js::RecyclableObject* DoObjectInflation_SnapRegexInfo(const SnapObject* snpObject, InflateMap* inflator)
  1146. {
  1147. //Regexes are not too common and have some mutable state so it seems easiest to always re-create them.
  1148. //We can re-evaluate this choice later if needed.
  1149. Js::ScriptContext* ctx = inflator->LookupScriptContext(snpObject->SnapType->ScriptContextLogId);
  1150. SnapRegexInfo* regexInfo = SnapObjectGetAddtlInfoAs<SnapRegexInfo*, SnapObjectType::SnapRegexObject>(snpObject);
  1151. Js::Var lastVar = (regexInfo->LastIndexVar != nullptr) ? inflator->InflateTTDVar(regexInfo->LastIndexVar) : nullptr;
  1152. return ctx->GetLibrary()->CreateRegex_TTD(regexInfo->RegexStr.Contents, regexInfo->RegexStr.Length, regexInfo->Flags, regexInfo->LastIndexOrFlag, lastVar);
  1153. }
  1154. void EmitAddtlInfo_SnapRegexInfo(const SnapObject* snpObject, FileWriter* writer)
  1155. {
  1156. SnapRegexInfo* regexInfo = SnapObjectGetAddtlInfoAs<SnapRegexInfo*, SnapObjectType::SnapRegexObject>(snpObject);
  1157. writer->WriteString(NSTokens::Key::stringVal, regexInfo->RegexStr, NSTokens::Separator::CommaAndBigSpaceSeparator);
  1158. writer->WriteTag<UnifiedRegex::RegexFlags>(NSTokens::Key::attributeFlags, regexInfo->Flags, NSTokens::Separator::CommaSeparator);
  1159. writer->WriteUInt32(NSTokens::Key::u32Val, regexInfo->LastIndexOrFlag, NSTokens::Separator::CommaSeparator);
  1160. writer->WriteKey(NSTokens::Key::ttdVarTag, NSTokens::Separator::CommaSeparator);
  1161. NSSnapValues::EmitTTDVar(regexInfo->LastIndexVar, writer, NSTokens::Separator::NoSeparator);
  1162. }
  1163. void ParseAddtlInfo_SnapRegexInfo(SnapObject* snpObject, FileReader* reader, SlabAllocator& alloc)
  1164. {
  1165. SnapRegexInfo* regexInfo = alloc.SlabAllocateStruct<SnapRegexInfo>();
  1166. reader->ReadString(NSTokens::Key::stringVal, alloc, regexInfo->RegexStr, true);
  1167. regexInfo->Flags = reader->ReadTag<UnifiedRegex::RegexFlags>(NSTokens::Key::attributeFlags, true);
  1168. regexInfo->LastIndexOrFlag = reader->ReadUInt32(NSTokens::Key::u32Val, true);
  1169. reader->ReadKey(NSTokens::Key::ttdVarTag, true);
  1170. regexInfo->LastIndexVar = NSSnapValues::ParseTTDVar(false, reader);
  1171. SnapObjectSetAddtlInfoAs<SnapRegexInfo*, SnapObjectType::SnapRegexObject>(snpObject, regexInfo);
  1172. }
  1173. #if ENABLE_SNAPSHOT_COMPARE
  1174. void AssertSnapEquiv_SnapRegexInfo(const SnapObject* sobj1, const SnapObject* sobj2, TTDCompareMap& compareMap)
  1175. {
  1176. const SnapRegexInfo* regexInfo1 = SnapObjectGetAddtlInfoAs<SnapRegexInfo*, SnapObjectType::SnapRegexObject>(sobj1);
  1177. const SnapRegexInfo* regexInfo2 = SnapObjectGetAddtlInfoAs<SnapRegexInfo*, SnapObjectType::SnapRegexObject>(sobj2);
  1178. compareMap.DiagnosticAssert(TTStringEQForDiagnostics(regexInfo1->RegexStr, regexInfo2->RegexStr));
  1179. compareMap.DiagnosticAssert(regexInfo1->Flags == regexInfo2->Flags);
  1180. compareMap.DiagnosticAssert(regexInfo1->LastIndexOrFlag == regexInfo2->LastIndexOrFlag);
  1181. }
  1182. #endif
  1183. Js::RecyclableObject* DoObjectInflation_SnapError(const SnapObject* snpObject, InflateMap* inflator)
  1184. {
  1185. Js::ScriptContext* ctx = inflator->LookupScriptContext(snpObject->SnapType->ScriptContextLogId);
  1186. //
  1187. //TODO: This is not great we just create a generic error
  1188. //
  1189. return ctx->GetLibrary()->CreateError_TTD();
  1190. }
  1191. //////////////////
  1192. int32 SnapArrayInfo_InflateValue(int32 value, InflateMap* inflator) { return value; }
  1193. void SnapArrayInfo_EmitValue(int32 value, FileWriter* writer) { writer->WriteInt32(NSTokens::Key::i32Val, value, NSTokens::Separator::CommaSeparator); }
  1194. void SnapArrayInfo_ParseValue(int32* into, FileReader* reader, SlabAllocator& alloc) { *into = reader->ReadInt32(NSTokens::Key::i32Val, true); }
  1195. double SnapArrayInfo_InflateValue(double value, InflateMap* inflator) { return value; }
  1196. void SnapArrayInfo_EmitValue(double value, FileWriter* writer) { writer->WriteDouble(NSTokens::Key::doubleVal, value, NSTokens::Separator::CommaSeparator); }
  1197. void SnapArrayInfo_ParseValue(double* into, FileReader* reader, SlabAllocator& alloc) { *into = reader->ReadDouble(NSTokens::Key::doubleVal, true); }
  1198. Js::Var SnapArrayInfo_InflateValue(TTDVar value, InflateMap* inflator)
  1199. {
  1200. return inflator->InflateTTDVar(value);
  1201. }
  1202. void SnapArrayInfo_EmitValue(TTDVar value, FileWriter* writer)
  1203. {
  1204. writer->WriteKey(NSTokens::Key::ptrIdVal, NSTokens::Separator::CommaSeparator);
  1205. NSSnapValues::EmitTTDVar(value, writer, NSTokens::Separator::NoSeparator);
  1206. }
  1207. void SnapArrayInfo_ParseValue(TTDVar* into, FileReader* reader, SlabAllocator& alloc)
  1208. {
  1209. reader->ReadKey(NSTokens::Key::ptrIdVal, true);
  1210. *into = NSSnapValues::ParseTTDVar(false, reader);
  1211. }
  1212. #if ENABLE_SNAPSHOT_COMPARE
  1213. void SnapArrayInfo_EquivValue(int32 val1, int32 val2, TTDCompareMap& compareMap, int32 i)
  1214. {
  1215. compareMap.DiagnosticAssert(val1 == val2);
  1216. }
  1217. void SnapArrayInfo_EquivValue(double val1, double val2, TTDCompareMap& compareMap, int32 i)
  1218. {
  1219. compareMap.DiagnosticAssert(val1 == val2);
  1220. }
  1221. void SnapArrayInfo_EquivValue(TTDVar val1, TTDVar val2, TTDCompareMap& compareMap, int32 i)
  1222. {
  1223. NSSnapValues::AssertSnapEquivTTDVar_Array(val1, val2, compareMap, i);
  1224. }
  1225. #endif
  1226. //////////////////
  1227. Js::RecyclableObject* DoObjectInflation_SnapES5ArrayInfo(const SnapObject* snpObject, InflateMap* inflator)
  1228. {
  1229. Js::ScriptContext* ctx = inflator->LookupScriptContext(snpObject->SnapType->ScriptContextLogId);
  1230. return ctx->GetLibrary()->CreateES5Array_TTD();
  1231. }
  1232. void DoAddtlValueInstantiation_SnapES5ArrayInfo(const SnapObject* snpObject, Js::RecyclableObject* obj, InflateMap* inflator)
  1233. {
  1234. SnapES5ArrayInfo* es5Info = SnapObjectGetAddtlInfoAs<SnapES5ArrayInfo*, SnapObjectType::SnapES5ArrayObject>(snpObject);
  1235. Js::JavascriptArray* arrayObj = static_cast<Js::JavascriptArray*>(obj);
  1236. DoAddtlValueInstantiation_SnapArrayInfoCore<TTDVar, Js::Var>(es5Info->BasicArrayData, arrayObj, inflator);
  1237. for(uint32 i = 0; i < es5Info->GetterSetterCount; ++i)
  1238. {
  1239. const SnapES5ArrayGetterSetterEntry* entry = es5Info->GetterSetterEntries + i;
  1240. Js::Var getter = nullptr;
  1241. if(entry->Getter != nullptr)
  1242. {
  1243. getter = inflator->InflateTTDVar(entry->Getter);
  1244. }
  1245. Js::Var setter = nullptr;
  1246. if(entry->Setter != nullptr)
  1247. {
  1248. setter = inflator->InflateTTDVar(entry->Setter);
  1249. }
  1250. if(getter != nullptr || setter != nullptr)
  1251. {
  1252. arrayObj->SetItemAccessors(entry->Index, getter, setter);
  1253. }
  1254. arrayObj->SetItemAttributes(entry->Index, entry->Attributes);
  1255. }
  1256. //do length writable as needed
  1257. Js::JavascriptLibrary::SetLengthWritableES5Array_TTD(arrayObj, es5Info->IsLengthWritable);
  1258. }
  1259. void EmitAddtlInfo_SnapES5ArrayInfo(const SnapObject* snpObject, FileWriter* writer)
  1260. {
  1261. SnapES5ArrayInfo* es5Info = SnapObjectGetAddtlInfoAs<SnapES5ArrayInfo*, SnapObjectType::SnapES5ArrayObject>(snpObject);
  1262. writer->WriteLengthValue(es5Info->GetterSetterCount, NSTokens::Separator::CommaSeparator);
  1263. writer->WriteBool(NSTokens::Key::boolVal, es5Info->IsLengthWritable, NSTokens::Separator::CommaSeparator);
  1264. writer->WriteSequenceStart_DefaultKey(NSTokens::Separator::CommaSeparator);
  1265. for(uint32 i = 0; i < es5Info->GetterSetterCount; ++i)
  1266. {
  1267. NSTokens::Separator sep = (i != 0) ? NSTokens::Separator::CommaSeparator : NSTokens::Separator::NoSeparator;
  1268. const SnapES5ArrayGetterSetterEntry* entry = es5Info->GetterSetterEntries + i;
  1269. writer->WriteRecordStart(sep);
  1270. writer->WriteUInt32(NSTokens::Key::index, entry->Index);
  1271. writer->WriteUInt32(NSTokens::Key::attributeFlags, entry->Attributes, NSTokens::Separator::CommaSeparator);
  1272. writer->WriteKey(NSTokens::Key::getterEntry, NSTokens::Separator::CommaSeparator);
  1273. NSSnapValues::EmitTTDVar(entry->Getter, writer, NSTokens::Separator::NoSeparator);
  1274. writer->WriteKey(NSTokens::Key::setterEntry, NSTokens::Separator::CommaSeparator);
  1275. NSSnapValues::EmitTTDVar(entry->Setter, writer, NSTokens::Separator::NoSeparator);
  1276. writer->WriteRecordEnd();
  1277. }
  1278. writer->WriteSequenceEnd();
  1279. EmitAddtlInfo_SnapArrayInfoCore<TTDVar>(es5Info->BasicArrayData, writer);
  1280. }
  1281. void ParseAddtlInfo_SnapES5ArrayInfo(SnapObject* snpObject, FileReader* reader, SlabAllocator& alloc)
  1282. {
  1283. SnapES5ArrayInfo* es5Info = alloc.SlabAllocateStruct<SnapES5ArrayInfo>();
  1284. es5Info->GetterSetterCount = reader->ReadLengthValue(true);
  1285. es5Info->IsLengthWritable = reader->ReadBool(NSTokens::Key::boolVal, true);
  1286. if(es5Info->GetterSetterCount == 0)
  1287. {
  1288. es5Info->GetterSetterEntries = nullptr;
  1289. }
  1290. else
  1291. {
  1292. es5Info->GetterSetterEntries = alloc.SlabAllocateArray<SnapES5ArrayGetterSetterEntry>(es5Info->GetterSetterCount);
  1293. }
  1294. reader->ReadSequenceStart_WDefaultKey(true);
  1295. for(uint32 i = 0; i < es5Info->GetterSetterCount; ++i)
  1296. {
  1297. SnapES5ArrayGetterSetterEntry* entry = es5Info->GetterSetterEntries + i;
  1298. reader->ReadRecordStart(i != 0);
  1299. entry->Index = reader->ReadUInt32(NSTokens::Key::index);
  1300. entry->Attributes = (Js::PropertyAttributes)reader->ReadUInt32(NSTokens::Key::attributeFlags, true);
  1301. reader->ReadKey(NSTokens::Key::getterEntry, true);
  1302. entry->Getter = NSSnapValues::ParseTTDVar(false, reader);
  1303. reader->ReadKey(NSTokens::Key::setterEntry, true);
  1304. entry->Setter = NSSnapValues::ParseTTDVar(false, reader);
  1305. reader->ReadRecordEnd();
  1306. }
  1307. reader->ReadSequenceEnd();
  1308. es5Info->BasicArrayData = ParseAddtlInfo_SnapArrayInfoCore<TTDVar>(reader, alloc);
  1309. SnapObjectSetAddtlInfoAs<SnapES5ArrayInfo*, SnapObjectType::SnapES5ArrayObject>(snpObject, es5Info);
  1310. }
  1311. #if ENABLE_SNAPSHOT_COMPARE
  1312. void AssertSnapEquiv_SnapES5ArrayInfo(const SnapObject* sobj1, const SnapObject* sobj2, TTDCompareMap& compareMap)
  1313. {
  1314. SnapES5ArrayInfo* es5Info1 = SnapObjectGetAddtlInfoAs<SnapES5ArrayInfo*, SnapObjectType::SnapES5ArrayObject>(sobj1);
  1315. SnapES5ArrayInfo* es5Info2 = SnapObjectGetAddtlInfoAs<SnapES5ArrayInfo*, SnapObjectType::SnapES5ArrayObject>(sobj2);
  1316. compareMap.DiagnosticAssert(es5Info1->GetterSetterCount == es5Info2->GetterSetterCount);
  1317. compareMap.DiagnosticAssert(es5Info1->IsLengthWritable == es5Info2->IsLengthWritable);
  1318. for(uint32 i = 0; i < es5Info1->GetterSetterCount; ++i)
  1319. {
  1320. const SnapES5ArrayGetterSetterEntry* entry1 = es5Info1->GetterSetterEntries + i;
  1321. const SnapES5ArrayGetterSetterEntry* entry2 = es5Info2->GetterSetterEntries + i;
  1322. compareMap.DiagnosticAssert(entry1->Index == entry2->Index);
  1323. compareMap.DiagnosticAssert(entry1->Attributes == entry2->Attributes);
  1324. NSSnapValues::AssertSnapEquivTTDVar_SpecialArray(entry1->Getter, entry2->Getter, compareMap, _u("es5Getter"), entry1->Index);
  1325. NSSnapValues::AssertSnapEquivTTDVar_SpecialArray(entry1->Setter, entry2->Setter, compareMap, _u("es5Setter"), entry1->Index);
  1326. }
  1327. compareMap.DiagnosticAssert(es5Info1->BasicArrayData->Length == es5Info2->BasicArrayData->Length);
  1328. AssertSnapEquiv_SnapArrayInfoCore<TTDVar>(es5Info1->BasicArrayData->Data, es5Info2->BasicArrayData->Data, compareMap);
  1329. }
  1330. #endif
  1331. //////////////////
  1332. Js::RecyclableObject* DoObjectInflation_SnapArrayBufferInfo(const SnapObject* snpObject, InflateMap* inflator)
  1333. {
  1334. //ArrayBuffers can change on us so seems easiest to always re-create them.
  1335. //We can re-evaluate this choice later if needed.
  1336. Js::ScriptContext* ctx = inflator->LookupScriptContext(snpObject->SnapType->ScriptContextLogId);
  1337. SnapArrayBufferInfo* buffInfo = SnapObjectGetAddtlInfoAs<SnapArrayBufferInfo*, SnapObjectType::SnapArrayBufferObject>(snpObject);
  1338. Js::ArrayBuffer* abuff = ctx->GetLibrary()->CreateArrayBuffer(buffInfo->Length);
  1339. TTDAssert(abuff->GetByteLength() == buffInfo->Length, "Something is wrong with our sizes.");
  1340. js_memcpy_s(abuff->GetBuffer(), abuff->GetByteLength(), buffInfo->Buff, buffInfo->Length);
  1341. return abuff;
  1342. }
  1343. void EmitAddtlInfo_SnapArrayBufferInfo(const SnapObject* snpObject, FileWriter* writer)
  1344. {
  1345. SnapArrayBufferInfo* buffInfo = SnapObjectGetAddtlInfoAs<SnapArrayBufferInfo*, SnapObjectType::SnapArrayBufferObject>(snpObject);
  1346. writer->WriteLengthValue(buffInfo->Length, NSTokens::Separator::CommaAndBigSpaceSeparator);
  1347. if(buffInfo->Length > 0)
  1348. {
  1349. writer->WriteSequenceStart_DefaultKey(NSTokens::Separator::CommaSeparator);
  1350. for(uint32 i = 0; i < buffInfo->Length; ++i)
  1351. {
  1352. writer->WriteNakedByte(buffInfo->Buff[i], i != 0 ? NSTokens::Separator::CommaSeparator : NSTokens::Separator::NoSeparator);
  1353. }
  1354. writer->WriteSequenceEnd();
  1355. }
  1356. }
  1357. void ParseAddtlInfo_SnapArrayBufferInfo(SnapObject* snpObject, FileReader* reader, SlabAllocator& alloc)
  1358. {
  1359. SnapArrayBufferInfo* buffInfo = alloc.SlabAllocateStruct<SnapArrayBufferInfo>();
  1360. buffInfo->Length = reader->ReadLengthValue(true);
  1361. if(buffInfo->Length == 0)
  1362. {
  1363. buffInfo->Buff = nullptr;
  1364. }
  1365. else
  1366. {
  1367. buffInfo->Buff = alloc.SlabAllocateArray<byte>(buffInfo->Length);
  1368. reader->ReadSequenceStart_WDefaultKey(true);
  1369. for(uint32 i = 0; i < buffInfo->Length; ++i)
  1370. {
  1371. buffInfo->Buff[i] = reader->ReadNakedByte(i != 0);
  1372. }
  1373. reader->ReadSequenceEnd();
  1374. }
  1375. SnapObjectSetAddtlInfoAs<SnapArrayBufferInfo*, SnapObjectType::SnapArrayBufferObject>(snpObject, buffInfo);
  1376. }
  1377. #if ENABLE_SNAPSHOT_COMPARE
  1378. void AssertSnapEquiv_SnapArrayBufferInfo(const SnapObject* sobj1, const SnapObject* sobj2, TTDCompareMap& compareMap)
  1379. {
  1380. const SnapArrayBufferInfo* buffInfo1 = SnapObjectGetAddtlInfoAs<SnapArrayBufferInfo*, SnapObjectType::SnapArrayBufferObject>(sobj1);
  1381. const SnapArrayBufferInfo* buffInfo2 = SnapObjectGetAddtlInfoAs<SnapArrayBufferInfo*, SnapObjectType::SnapArrayBufferObject>(sobj2);
  1382. compareMap.DiagnosticAssert(buffInfo1->Length == buffInfo2->Length);
  1383. //
  1384. //Pending buffers cannot be accessed by the program until they are off the pending lists.
  1385. //So we do not force the updates in closer sync than this and they may not be updated in sync so (as long as they are pending) in both.
  1386. //
  1387. if(compareMap.H1PendingAsyncModBufferSet.Contains(sobj1->ObjectPtrId) || compareMap.H2PendingAsyncModBufferSet.Contains(sobj2->ObjectPtrId))
  1388. {
  1389. compareMap.DiagnosticAssert(compareMap.H1PendingAsyncModBufferSet.Contains(sobj1->ObjectPtrId) && compareMap.H2PendingAsyncModBufferSet.Contains(sobj2->ObjectPtrId));
  1390. }
  1391. else
  1392. {
  1393. for(uint32 i = 0; i < buffInfo1->Length; ++i)
  1394. {
  1395. compareMap.DiagnosticAssert(buffInfo1->Buff[i] == buffInfo2->Buff[i]);
  1396. }
  1397. }
  1398. }
  1399. #endif
  1400. Js::RecyclableObject* DoObjectInflation_SnapTypedArrayInfo(const SnapObject* snpObject, InflateMap* inflator)
  1401. {
  1402. //I am lazy and always re-create typed arrays.
  1403. //We can re-evaluate this choice later if needed.
  1404. Js::ScriptContext* ctx = inflator->LookupScriptContext(snpObject->SnapType->ScriptContextLogId);
  1405. SnapTypedArrayInfo* typedArrayInfo = SnapObjectGetAddtlInfoAs<SnapTypedArrayInfo*, SnapObjectType::SnapTypedArrayObject>(snpObject);
  1406. Js::JavascriptLibrary* jslib = ctx->GetLibrary();
  1407. Js::ArrayBuffer* arrayBuffer = Js::ArrayBuffer::FromVar(inflator->LookupObject(typedArrayInfo->ArrayBufferAddr));
  1408. Js::Var tab = nullptr;
  1409. switch(snpObject->SnapType->JsTypeId)
  1410. {
  1411. case Js::TypeIds_Int8Array:
  1412. tab = Js::Int8Array::Create(arrayBuffer, typedArrayInfo->ByteOffset, typedArrayInfo->Length, jslib);
  1413. break;
  1414. case Js::TypeIds_Uint8Array:
  1415. tab = Js::Uint8Array::Create(arrayBuffer, typedArrayInfo->ByteOffset, typedArrayInfo->Length, jslib);
  1416. break;
  1417. case Js::TypeIds_Uint8ClampedArray:
  1418. tab = Js::Uint8ClampedArray::Create(arrayBuffer, typedArrayInfo->ByteOffset, typedArrayInfo->Length, jslib);
  1419. break;
  1420. case Js::TypeIds_Int16Array:
  1421. tab = Js::Int16Array::Create(arrayBuffer, typedArrayInfo->ByteOffset, typedArrayInfo->Length, jslib);
  1422. break;
  1423. case Js::TypeIds_Uint16Array:
  1424. tab = Js::Uint16Array::Create(arrayBuffer, typedArrayInfo->ByteOffset, typedArrayInfo->Length, jslib);
  1425. break;
  1426. case Js::TypeIds_Int32Array:
  1427. tab = Js::Int32Array::Create(arrayBuffer, typedArrayInfo->ByteOffset, typedArrayInfo->Length, jslib);
  1428. break;
  1429. case Js::TypeIds_Uint32Array:
  1430. tab = Js::Uint32Array::Create(arrayBuffer, typedArrayInfo->ByteOffset, typedArrayInfo->Length, jslib);
  1431. break;
  1432. case Js::TypeIds_Float32Array:
  1433. tab = Js::Float32Array::Create(arrayBuffer, typedArrayInfo->ByteOffset, typedArrayInfo->Length, jslib);
  1434. break;
  1435. case Js::TypeIds_Float64Array:
  1436. tab = Js::Float64Array::Create(arrayBuffer, typedArrayInfo->ByteOffset, typedArrayInfo->Length, jslib);
  1437. break;
  1438. case Js::TypeIds_Int64Array:
  1439. tab = Js::Int64Array::Create(arrayBuffer, typedArrayInfo->ByteOffset, typedArrayInfo->Length, jslib);
  1440. break;
  1441. case Js::TypeIds_Uint64Array:
  1442. tab = Js::Uint64Array::Create(arrayBuffer, typedArrayInfo->ByteOffset, typedArrayInfo->Length, jslib);
  1443. break;
  1444. case Js::TypeIds_BoolArray:
  1445. tab = Js::BoolArray::Create(arrayBuffer, typedArrayInfo->ByteOffset, typedArrayInfo->Length, jslib);
  1446. break;
  1447. case Js::TypeIds_CharArray:
  1448. tab = Js::CharArray::Create(arrayBuffer, typedArrayInfo->ByteOffset, typedArrayInfo->Length, jslib);
  1449. break;
  1450. default:
  1451. TTDAssert(false, "Not a typed array!");
  1452. break;
  1453. }
  1454. return Js::RecyclableObject::FromVar(tab);
  1455. }
  1456. void EmitAddtlInfo_SnapTypedArrayInfo(const SnapObject* snpObject, FileWriter* writer)
  1457. {
  1458. SnapTypedArrayInfo* typedArrayInfo = SnapObjectGetAddtlInfoAs<SnapTypedArrayInfo*, SnapObjectType::SnapTypedArrayObject>(snpObject);
  1459. writer->WriteUInt32(NSTokens::Key::offset, typedArrayInfo->ByteOffset, NSTokens::Separator::CommaAndBigSpaceSeparator);
  1460. writer->WriteLengthValue(typedArrayInfo->Length, NSTokens::Separator::CommaSeparator);
  1461. writer->WriteAddr(NSTokens::Key::objectId, typedArrayInfo->ArrayBufferAddr, NSTokens::Separator::CommaSeparator);
  1462. }
  1463. void ParseAddtlInfo_SnapTypedArrayInfo(SnapObject* snpObject, FileReader* reader, SlabAllocator& alloc)
  1464. {
  1465. SnapTypedArrayInfo* typedArrayInfo = alloc.SlabAllocateStruct<SnapTypedArrayInfo>();
  1466. typedArrayInfo->ByteOffset = reader->ReadUInt32(NSTokens::Key::offset, true);
  1467. typedArrayInfo->Length = reader->ReadLengthValue(true);
  1468. typedArrayInfo->ArrayBufferAddr = reader->ReadAddr(NSTokens::Key::objectId, true);
  1469. SnapObjectSetAddtlInfoAs<SnapTypedArrayInfo*, SnapObjectType::SnapTypedArrayObject>(snpObject, typedArrayInfo);
  1470. }
  1471. #if ENABLE_SNAPSHOT_COMPARE
  1472. void AssertSnapEquiv_SnapTypedArrayInfo(const SnapObject* sobj1, const SnapObject* sobj2, TTDCompareMap& compareMap)
  1473. {
  1474. const SnapTypedArrayInfo* typedArrayInfo1 = SnapObjectGetAddtlInfoAs<SnapTypedArrayInfo*, SnapObjectType::SnapTypedArrayObject>(sobj1);
  1475. const SnapTypedArrayInfo* typedArrayInfo2 = SnapObjectGetAddtlInfoAs<SnapTypedArrayInfo*, SnapObjectType::SnapTypedArrayObject>(sobj2);
  1476. compareMap.DiagnosticAssert(typedArrayInfo1->ByteOffset == typedArrayInfo2->ByteOffset);
  1477. compareMap.DiagnosticAssert(typedArrayInfo1->Length == typedArrayInfo2->Length);
  1478. compareMap.CheckConsistentAndAddPtrIdMapping_Special(typedArrayInfo1->ArrayBufferAddr, typedArrayInfo2->ArrayBufferAddr, _u("arrayBuffer"));
  1479. }
  1480. #endif
  1481. //////////////////
  1482. Js::RecyclableObject* DoObjectInflation_SnapSetInfo(const SnapObject* snpObject, InflateMap* inflator)
  1483. {
  1484. Js::ScriptContext* ctx = inflator->LookupScriptContext(snpObject->SnapType->ScriptContextLogId);
  1485. if(snpObject->SnapType->JsTypeId == Js::TypeIds_Set)
  1486. {
  1487. return ctx->GetLibrary()->CreateSet_TTD();
  1488. }
  1489. else
  1490. {
  1491. return ctx->GetLibrary()->CreateWeakSet_TTD();
  1492. }
  1493. }
  1494. void DoAddtlValueInstantiation_SnapSetInfo(const SnapObject* snpObject, Js::RecyclableObject* obj, InflateMap* inflator)
  1495. {
  1496. SnapSetInfo* setInfo = SnapObjectGetAddtlInfoAs<SnapSetInfo*, SnapObjectType::SnapSetObject>(snpObject);
  1497. if(snpObject->SnapType->JsTypeId == Js::TypeIds_Set)
  1498. {
  1499. Js::JavascriptSet* sobj = (Js::JavascriptSet*)obj;
  1500. for(uint32 i = 0; i < setInfo->SetSize; ++i)
  1501. {
  1502. Js::Var val = inflator->InflateTTDVar(setInfo->SetValueArray[i]);
  1503. Js::JavascriptLibrary::AddSetElementInflate_TTD(sobj, val);
  1504. }
  1505. }
  1506. else
  1507. {
  1508. Js::JavascriptWeakSet* sobj = (Js::JavascriptWeakSet*)obj;
  1509. for(uint32 i = 0; i < setInfo->SetSize; ++i)
  1510. {
  1511. Js::Var val = inflator->InflateTTDVar(setInfo->SetValueArray[i]);
  1512. Js::JavascriptLibrary::AddWeakSetElementInflate_TTD(sobj, val);
  1513. }
  1514. }
  1515. }
  1516. void EmitAddtlInfo_SnapSetInfo(const SnapObject* snpObject, FileWriter* writer)
  1517. {
  1518. SnapSetInfo* setInfo = SnapObjectGetAddtlInfoAs<SnapSetInfo*, SnapObjectType::SnapSetObject>(snpObject);
  1519. writer->WriteLengthValue(setInfo->SetSize, NSTokens::Separator::CommaAndBigSpaceSeparator);
  1520. if(setInfo->SetSize > 0)
  1521. {
  1522. writer->WriteSequenceStart_DefaultKey(NSTokens::Separator::CommaSeparator);
  1523. for(uint32 i = 0; i < setInfo->SetSize; ++i)
  1524. {
  1525. NSSnapValues::EmitTTDVar(setInfo->SetValueArray[i], writer, i != 0 ? NSTokens::Separator::CommaSeparator : NSTokens::Separator::BigSpaceSeparator);
  1526. }
  1527. writer->WriteSequenceEnd();
  1528. }
  1529. }
  1530. void ParseAddtlInfo_SnapSetInfo(SnapObject* snpObject, FileReader* reader, SlabAllocator& alloc)
  1531. {
  1532. SnapSetInfo* setInfo = alloc.SlabAllocateStruct<SnapSetInfo>();
  1533. setInfo->SetSize = reader->ReadLengthValue(true);
  1534. if(setInfo->SetSize == 0)
  1535. {
  1536. setInfo->SetValueArray = nullptr;
  1537. }
  1538. else
  1539. {
  1540. setInfo->SetValueArray = alloc.SlabAllocateArray<TTDVar>(setInfo->SetSize);
  1541. reader->ReadSequenceStart_WDefaultKey(true);
  1542. for(uint32 i = 0; i < setInfo->SetSize; ++i)
  1543. {
  1544. setInfo->SetValueArray[i] = NSSnapValues::ParseTTDVar(i != 0, reader);
  1545. }
  1546. reader->ReadSequenceEnd();
  1547. }
  1548. SnapObjectSetAddtlInfoAs<SnapSetInfo*, SnapObjectType::SnapSetObject>(snpObject, setInfo);
  1549. }
  1550. #if ENABLE_SNAPSHOT_COMPARE
  1551. void AssertSnapEquiv_SnapSetInfo(const SnapObject* sobj1, const SnapObject* sobj2, TTDCompareMap& compareMap)
  1552. {
  1553. const SnapSetInfo* setInfo1 = SnapObjectGetAddtlInfoAs<SnapSetInfo*, SnapObjectType::SnapSetObject>(sobj1);
  1554. const SnapSetInfo* setInfo2 = SnapObjectGetAddtlInfoAs<SnapSetInfo*, SnapObjectType::SnapSetObject>(sobj2);
  1555. compareMap.DiagnosticAssert(setInfo1->SetSize == setInfo2->SetSize);
  1556. //Treat weak set contents as ignorable
  1557. if(sobj1->SnapType->JsTypeId == Js::TypeIds_Set)
  1558. {
  1559. for(uint32 i = 0; i < setInfo1->SetSize; ++i)
  1560. {
  1561. NSSnapValues::AssertSnapEquivTTDVar_SpecialArray(setInfo1->SetValueArray[i], setInfo2->SetValueArray[i], compareMap, _u("setValues"), i);
  1562. }
  1563. }
  1564. }
  1565. #endif
  1566. Js::RecyclableObject* DoObjectInflation_SnapMapInfo(const SnapObject* snpObject, InflateMap* inflator)
  1567. {
  1568. Js::ScriptContext* ctx = inflator->LookupScriptContext(snpObject->SnapType->ScriptContextLogId);
  1569. if(snpObject->SnapType->JsTypeId == Js::TypeIds_Map)
  1570. {
  1571. return ctx->GetLibrary()->CreateMap_TTD();
  1572. }
  1573. else
  1574. {
  1575. return ctx->GetLibrary()->CreateWeakMap_TTD();
  1576. }
  1577. }
  1578. void DoAddtlValueInstantiation_SnapMapInfo(const SnapObject* snpObject, Js::RecyclableObject* obj, InflateMap* inflator)
  1579. {
  1580. SnapMapInfo* mapInfo = SnapObjectGetAddtlInfoAs<SnapMapInfo*, SnapObjectType::SnapMapObject>(snpObject);
  1581. if(snpObject->SnapType->JsTypeId == Js::TypeIds_Map)
  1582. {
  1583. Js::JavascriptMap* mobj = (Js::JavascriptMap*)obj;
  1584. for(uint32 i = 0; i < mapInfo->MapSize; i+=2)
  1585. {
  1586. Js::Var key = inflator->InflateTTDVar(mapInfo->MapKeyValueArray[i]);
  1587. Js::Var data = inflator->InflateTTDVar(mapInfo->MapKeyValueArray[i + 1]);
  1588. Js::JavascriptLibrary::AddMapElementInflate_TTD(mobj, key, data);
  1589. }
  1590. }
  1591. else
  1592. {
  1593. Js::JavascriptWeakMap* mobj = (Js::JavascriptWeakMap*)obj;
  1594. for(uint32 i = 0; i < mapInfo->MapSize; i += 2)
  1595. {
  1596. Js::Var key = inflator->InflateTTDVar(mapInfo->MapKeyValueArray[i]);
  1597. Js::Var data = inflator->InflateTTDVar(mapInfo->MapKeyValueArray[i + 1]);
  1598. Js::JavascriptLibrary::AddWeakMapElementInflate_TTD(mobj, key, data);
  1599. }
  1600. }
  1601. }
  1602. void EmitAddtlInfo_SnapMapInfo(const SnapObject* snpObject, FileWriter* writer)
  1603. {
  1604. SnapMapInfo* mapInfo = SnapObjectGetAddtlInfoAs<SnapMapInfo*, SnapObjectType::SnapMapObject>(snpObject);
  1605. writer->WriteLengthValue(mapInfo->MapSize, NSTokens::Separator::CommaAndBigSpaceSeparator);
  1606. if(mapInfo->MapSize > 0)
  1607. {
  1608. writer->WriteSequenceStart_DefaultKey(NSTokens::Separator::CommaSeparator);
  1609. for(uint32 i = 0; i < mapInfo->MapSize; i+=2)
  1610. {
  1611. writer->WriteSequenceStart(i != 0 ? NSTokens::Separator::CommaAndBigSpaceSeparator : NSTokens::Separator::BigSpaceSeparator);
  1612. NSSnapValues::EmitTTDVar(mapInfo->MapKeyValueArray[i], writer, NSTokens::Separator::NoSeparator);
  1613. NSSnapValues::EmitTTDVar(mapInfo->MapKeyValueArray[i + 1], writer, NSTokens::Separator::CommaSeparator);
  1614. writer->WriteSequenceEnd();
  1615. }
  1616. writer->WriteSequenceEnd();
  1617. }
  1618. }
  1619. void ParseAddtlInfo_SnapMapInfo(SnapObject* snpObject, FileReader* reader, SlabAllocator& alloc)
  1620. {
  1621. SnapMapInfo* mapInfo = alloc.SlabAllocateStruct<SnapMapInfo>();
  1622. mapInfo->MapSize = reader->ReadLengthValue(true);
  1623. if(mapInfo->MapSize == 0)
  1624. {
  1625. mapInfo->MapKeyValueArray = nullptr;
  1626. }
  1627. else
  1628. {
  1629. mapInfo->MapKeyValueArray = alloc.SlabAllocateArray<TTDVar>(mapInfo->MapSize);
  1630. reader->ReadSequenceStart_WDefaultKey(true);
  1631. for(uint32 i = 0; i < mapInfo->MapSize; i+=2)
  1632. {
  1633. reader->ReadSequenceStart(i != 0);
  1634. mapInfo->MapKeyValueArray[i] = NSSnapValues::ParseTTDVar(false, reader);
  1635. mapInfo->MapKeyValueArray[i + 1] = NSSnapValues::ParseTTDVar(true, reader);
  1636. reader->ReadSequenceEnd();
  1637. }
  1638. reader->ReadSequenceEnd();
  1639. }
  1640. SnapObjectSetAddtlInfoAs<SnapMapInfo*, SnapObjectType::SnapMapObject>(snpObject, mapInfo);
  1641. }
  1642. #if ENABLE_SNAPSHOT_COMPARE
  1643. void AssertSnapEquiv_SnapMapInfo(const SnapObject* sobj1, const SnapObject* sobj2, TTDCompareMap& compareMap)
  1644. {
  1645. const SnapMapInfo* mapInfo1 = SnapObjectGetAddtlInfoAs<SnapMapInfo*, SnapObjectType::SnapMapObject>(sobj1);
  1646. const SnapMapInfo* mapInfo2 = SnapObjectGetAddtlInfoAs<SnapMapInfo*, SnapObjectType::SnapMapObject>(sobj2);
  1647. compareMap.DiagnosticAssert(mapInfo1->MapSize == mapInfo2->MapSize);
  1648. //Treat weak map contents as ignorable
  1649. if(sobj1->SnapType->JsTypeId == Js::TypeIds_Map)
  1650. {
  1651. for(uint32 i = 0; i < mapInfo1->MapSize; i += 2)
  1652. {
  1653. NSSnapValues::AssertSnapEquivTTDVar_SpecialArray(mapInfo1->MapKeyValueArray[i], mapInfo2->MapKeyValueArray[i], compareMap, _u("mapKeys"), i);
  1654. NSSnapValues::AssertSnapEquivTTDVar_SpecialArray(mapInfo1->MapKeyValueArray[i + 1], mapInfo2->MapKeyValueArray[i + 1], compareMap, _u("mapValues"), i);
  1655. }
  1656. }
  1657. }
  1658. #endif
  1659. //////////////////
  1660. Js::RecyclableObject* DoObjectInflation_SnapProxyInfo(const SnapObject* snpObject, InflateMap* inflator)
  1661. {
  1662. Js::ScriptContext* ctx = inflator->LookupScriptContext(snpObject->SnapType->ScriptContextLogId);
  1663. SnapProxyInfo* proxyInfo = SnapObjectGetAddtlInfoAs<SnapProxyInfo*, SnapObjectType::SnapProxyObject>(snpObject);
  1664. Js::RecyclableObject* handlerObj = (proxyInfo->HandlerId != TTD_INVALID_PTR_ID) ? inflator->LookupObject(proxyInfo->HandlerId) : nullptr;
  1665. Js::RecyclableObject* targetObj = (proxyInfo->TargetId != TTD_INVALID_PTR_ID) ? inflator->LookupObject(proxyInfo->TargetId) : nullptr;
  1666. return ctx->GetLibrary()->CreateProxy_TTD(handlerObj, targetObj);
  1667. }
  1668. void EmitAddtlInfo_SnapProxyInfo(const SnapObject* snpObject, FileWriter* writer)
  1669. {
  1670. SnapProxyInfo* proxyInfo = SnapObjectGetAddtlInfoAs<SnapProxyInfo*, SnapObjectType::SnapProxyObject>(snpObject);
  1671. writer->WriteAddr(NSTokens::Key::handlerId, proxyInfo->HandlerId, NSTokens::Separator::CommaSeparator);
  1672. writer->WriteAddr(NSTokens::Key::objectId, proxyInfo->TargetId, NSTokens::Separator::CommaSeparator);
  1673. }
  1674. void ParseAddtlInfo_SnapProxyInfo(SnapObject* snpObject, FileReader* reader, SlabAllocator& alloc)
  1675. {
  1676. SnapProxyInfo* proxyInfo = alloc.SlabAllocateStruct<SnapProxyInfo>();
  1677. proxyInfo->HandlerId = reader->ReadAddr(NSTokens::Key::handlerId, true);
  1678. proxyInfo->TargetId = reader->ReadAddr(NSTokens::Key::objectId, true);
  1679. SnapObjectSetAddtlInfoAs<SnapProxyInfo*, SnapObjectType::SnapProxyObject>(snpObject, proxyInfo);
  1680. }
  1681. #if ENABLE_SNAPSHOT_COMPARE
  1682. void AssertSnapEquiv_SnapProxyInfo(const SnapObject* sobj1, const SnapObject* sobj2, TTDCompareMap& compareMap)
  1683. {
  1684. const SnapProxyInfo* proxyInfo1 = SnapObjectGetAddtlInfoAs<SnapProxyInfo*, SnapObjectType::SnapProxyObject>(sobj1);
  1685. const SnapProxyInfo* proxyInfo2 = SnapObjectGetAddtlInfoAs<SnapProxyInfo*, SnapObjectType::SnapProxyObject>(sobj2);
  1686. compareMap.CheckConsistentAndAddPtrIdMapping_Special(proxyInfo1->HandlerId, proxyInfo2->HandlerId, _u("handlerId"));
  1687. compareMap.CheckConsistentAndAddPtrIdMapping_Special(proxyInfo1->TargetId, proxyInfo2->TargetId, _u("targetId"));
  1688. }
  1689. #endif
  1690. }
  1691. }
  1692. #endif