TTSnapObjects.cpp 131 KB

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