DiagObjectModel.h 45 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051
  1. //-------------------------------------------------------------------------------------------------------
  2. // Copyright (C) Microsoft. All rights reserved.
  3. // Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
  4. //-------------------------------------------------------------------------------------------------------
  5. #pragma once
  6. namespace Js
  7. {
  8. class IDiagObjectAddress;
  9. class IDiagObjectModelDisplay;
  10. class RecyclableMethodsGroupWalker;
  11. class RecyclableObjectWalker;
  12. class RecyclableArrayWalker;
  13. // Concrete type for manipulating JS Vars
  14. struct ResolvedObject
  15. {
  16. ResolvedObject() : propId(Js::Constants::NoProperty), scriptContext(nullptr), address(nullptr),
  17. objectDisplay(nullptr), obj(nullptr), originalObj(nullptr), isConst(false), name(nullptr)
  18. {}
  19. PropertyId propId;
  20. ScriptContext *scriptContext;
  21. IDiagObjectAddress *address;
  22. IDiagObjectModelDisplay *objectDisplay;
  23. Var obj;
  24. Var originalObj;
  25. LPCWSTR name;
  26. TypeId typeId;
  27. bool isConst;
  28. WeakArenaReference<IDiagObjectModelDisplay>* GetObjectDisplay();
  29. IDiagObjectModelDisplay * CreateDisplay();
  30. bool IsInDeadZone() const;
  31. };
  32. // interfaces for manipulating DataTypes
  33. // Allow setting the value across different parent data types
  34. class IDiagObjectAddress
  35. {
  36. public:
  37. virtual BOOL Set(Var updateObject) = 0;
  38. virtual BOOL IsWritable() { return !IsInDeadZone(); }
  39. virtual Var GetValue(BOOL fUpdated) { return nullptr; }
  40. virtual BOOL IsInDeadZone() const { return FALSE; };
  41. };
  42. class IDiagObjectModelWalkerBase
  43. {
  44. public:
  45. // Get the child at i'th position.
  46. virtual BOOL Get(int i, ResolvedObject* pResolvedObject) = 0;
  47. // Returns number of children for the current diag object.
  48. virtual uint32 GetChildrenCount() = 0;
  49. virtual BOOL GetGroupObject(ResolvedObject* pResolvedObject) = 0;
  50. virtual IDiagObjectAddress *FindPropertyAddress(PropertyId propId, bool& isConst) { return nullptr;}
  51. };
  52. enum DiagObjectModelDisplayType
  53. {
  54. DiagObjectModelDisplayType_LocalsDisplay,
  55. DiagObjectModelDisplayType_RecyclableObjectDisplay,
  56. DiagObjectModelDisplayType_RecyclableCollectionObjectDisplay,
  57. DiagObjectModelDisplayType_RecyclableKeyValueDisplay,
  58. DiagObjectModelDisplayType_RecyclableSimdDisplay,
  59. };
  60. // Allow getting information across different data types
  61. class IDiagObjectModelDisplay
  62. {
  63. public:
  64. virtual LPCWSTR Name() = 0;
  65. virtual LPCWSTR Type() = 0;
  66. virtual LPCWSTR Value(int radix) = 0;
  67. virtual BOOL HasChildren() = 0;
  68. virtual BOOL Set(Var updateObject) = 0;
  69. virtual DBGPROP_ATTRIB_FLAGS GetTypeAttribute() = 0;
  70. virtual BOOL SetDefaultTypeAttribute(DBGPROP_ATTRIB_FLAGS attributes) { return FALSE; };
  71. virtual WeakArenaReference<IDiagObjectModelWalkerBase>* CreateWalker() = 0;
  72. virtual BOOL IsLocalsAsRoot() { return FALSE; }
  73. virtual Var GetVarValue(BOOL fUpdated) { return nullptr; }
  74. virtual IDiagObjectAddress * GetDiagAddress() { return nullptr; }
  75. virtual DiagObjectModelDisplayType GetType() = 0;
  76. virtual bool IsFake() { return (this->GetTypeAttribute() & DBGPROP_ATTRIB_VALUE_IS_FAKE) == DBGPROP_ATTRIB_VALUE_IS_FAKE; }
  77. virtual bool IsLiteralProperty() const = 0;
  78. virtual bool IsSymbolProperty() { return false; }
  79. virtual ~IDiagObjectModelDisplay() { /* Dummy */ }
  80. };
  81. //
  82. // There are three distinct types of classes defined in order to inspect a variable on watch/locals window.
  83. // If someone has to change or provide the support for custom types/objects (such as PixelArray etc) be displayed on the debugger, they need to aware
  84. // of few things which are mentioned below.
  85. // <...>Display (eg RecyclableArrayDisplay), mentions how current variable is given to debugger, and tells what walker (enumerator) to be chosen
  86. // in order to walk to children of the current variable.
  87. // <...>Walker (eg RecyclableArrayWalker), mentions logic of walk thru content of the current variable (the object generally acts like an enumerator). Let say for an array, it has logic to go thru each
  88. // indices and populate values.
  89. // <...>Address (eg RecyclableArrayAddress), associated with each child and will be used to updating that item. The object if this will be consumed by "<...>Walker"
  90. // object when it walks thru each children of the current variable.
  91. // In order to support the custom objects, above classes should be used (or derived) to get started.
  92. //
  93. enum DebuggerPropertyDisplayInfoFlags
  94. {
  95. DebuggerPropertyDisplayInfoFlags_None = 0x0,
  96. DebuggerPropertyDisplayInfoFlags_Const = 0x1,
  97. DebuggerPropertyDisplayInfoFlags_InDeadZone = 0x2,
  98. DebuggerPropertyDisplayInfoFlags_Unscope = 0x4,
  99. };
  100. struct DebuggerPropertyDisplayInfo
  101. {
  102. PropertyId propId;
  103. Var aVar;
  104. DWORD flags; // DebuggerPropertyDisplayInfoFlags.
  105. DebuggerPropertyDisplayInfo(PropertyId _propId, Var _aVar, DWORD _flags) : propId(_propId), aVar(_aVar), flags(_flags)
  106. {}
  107. bool IsUnscoped() const { return (flags & DebuggerPropertyDisplayInfoFlags_Unscope) != 0; }
  108. bool IsConst() const { return (flags & DebuggerPropertyDisplayInfoFlags_Const) != 0; }
  109. bool IsInDeadZone() const { return (flags & DebuggerPropertyDisplayInfoFlags_InDeadZone) != 0; }
  110. };
  111. enum UIGroupType
  112. {
  113. UIGroupType_None,
  114. UIGroupType_InnerScope, // variables under the innerscope (such as Block/Catch)
  115. UIGroupType_Scope,
  116. UIGroupType_Globals,
  117. UIGroupType_Param
  118. };
  119. enum FramesLocalType
  120. {
  121. LocalType_None = 0x0,
  122. LocalType_Reg = 0x1,
  123. LocalType_InSlot = 0x2,
  124. LocalType_InObject = 0x4,
  125. };
  126. enum FrameWalkerFlags
  127. {
  128. FW_None = 0x0,
  129. FW_MakeGroups = 0x1, // Make groups such as [Scope], [Globals] etc.
  130. FW_EnumWithScopeAlso = 0x2, // While walking include the with scope as well.
  131. FW_AllowLexicalThis = 0x4, // Do not filter out Js::PropertyIds::_lexicalThisSlotSymbol
  132. FW_AllowSuperReference = 0x8, // Allow walking of Js::PropertyIds::_superReferenceSymbol and Js::PropertyIds::_superCtorReferenceSymbol
  133. FW_DontAddGlobalsDirectly = 0x10, // Do not add global object directly.
  134. };
  135. class VariableWalkerBase : public IDiagObjectModelWalkerBase
  136. {
  137. public:
  138. DiagStackFrame* pFrame;
  139. Var instance;
  140. JsUtil::List<DebuggerPropertyDisplayInfo*, ArenaAllocator> *pMembersList;
  141. UIGroupType groupType;
  142. private:
  143. bool allowLexicalThis;
  144. bool allowSuperReference;
  145. public :
  146. VariableWalkerBase(DiagStackFrame* _pFrame, Var _instance, UIGroupType _groupType, bool allowLexicalThis, bool allowSuperReference = false)
  147. : pFrame(_pFrame), instance(_instance), pMembersList(nullptr), groupType(_groupType), allowLexicalThis(allowLexicalThis), allowSuperReference(allowSuperReference)
  148. {
  149. }
  150. // Defined virtual function, should be extended by type of variable scope.
  151. virtual void PopulateMembers() { };
  152. virtual IDiagObjectAddress * GetObjectAddress(int index) { return nullptr; }
  153. virtual Var GetVarObjectAt(int index);
  154. virtual bool IsConstAt(int index);
  155. /// IDiagObjectModelWalkerBase
  156. virtual BOOL Get(int i, ResolvedObject* pResolvedObject) override;
  157. virtual uint32 GetChildrenCount() override;
  158. virtual BOOL GetGroupObject(ResolvedObject* pResolvedObject) override sealed;
  159. virtual IDiagObjectAddress *FindPropertyAddress(PropertyId propId, bool& isConst) override;
  160. static BOOL GetExceptionObject(int &index, DiagStackFrame* frame, ResolvedObject* pResolvedObject);
  161. static bool HasExceptionObject(DiagStackFrame* frame);
  162. static BOOL GetReturnedValue(int &index, DiagStackFrame* frame, ResolvedObject* pResolvedObject);
  163. static int GetReturnedValueCount(DiagStackFrame* frame);
  164. static void GetReturnedValueResolvedObject(ReturnedValue * returnValue, DiagStackFrame* frame, ResolvedObject* pResolvedObject);
  165. #ifdef ENABLE_MUTATION_BREAKPOINT
  166. static BOOL GetBreakMutationBreakpointValue(int &index, DiagStackFrame* frame, ResolvedObject* pResolvedObject);
  167. static uint GetBreakMutationBreakpointsCount(DiagStackFrame* frame);
  168. #endif
  169. bool IsInGroup() const { return (groupType != UIGroupType::UIGroupType_None && groupType != UIGroupType::UIGroupType_Param && groupType != UIGroupType::UIGroupType_InnerScope); }
  170. bool IsWalkerForCurrentFrame() const { return groupType == UIGroupType::UIGroupType_None || groupType == UIGroupType_Param; }
  171. DebuggerScope * GetScopeWhenHaltAtFormals();
  172. static bool IsInParamScope(DebuggerScope* scope, DiagStackFrame* pFrame);
  173. int GetAdjustedByteCodeOffset() const;
  174. DebuggerPropertyDisplayInfo* AllocateNewPropertyDisplayInfo(PropertyId propertyId, Var value, bool isConst, bool isInDeadZone);
  175. protected:
  176. int GetMemberCount() { return pMembersList ? pMembersList->Count() : 0; }
  177. bool IsPropertyValid(PropertyId propertyId, RegSlot location, bool *isPropertyInDebuggerScope, bool* isConst, bool* isInDeadZone) const;
  178. private:
  179. static JavascriptString * ParseFunctionName(JavascriptString* displayName, ScriptContext* scriptContext);
  180. };
  181. class RegSlotVariablesWalker : public VariableWalkerBase
  182. {
  183. // This will be pointing to the inner debugger scope (block/catch)
  184. DebuggerScope* debuggerScope;
  185. public:
  186. RegSlotVariablesWalker(DiagStackFrame* _pFrame, DebuggerScope *_debuggerScope, UIGroupType _groupType, bool allowSuperReference = false)
  187. : VariableWalkerBase(_pFrame, nullptr, _groupType, /* allowLexicalThis */ false, allowSuperReference), debuggerScope(_debuggerScope)
  188. {
  189. }
  190. virtual void PopulateMembers() override;
  191. virtual IDiagObjectAddress * GetObjectAddress(int index) override;
  192. virtual Var GetVarObjectAt(int index) override;
  193. private:
  194. bool IsRegisterValid(PropertyId propertyId, RegSlot registerSlot) const;
  195. bool IsRegisterInScope(PropertyId propertyId, RegSlot registerSlot) const;
  196. Var GetVarObjectAndRegAt(int index, RegSlot* reg = nullptr);
  197. };
  198. class SlotArrayVariablesWalker : public VariableWalkerBase
  199. {
  200. public:
  201. SlotArrayVariablesWalker(DiagStackFrame* _pFrame, Var _instance, UIGroupType _groupType, bool allowLexicalThis, bool allowSuperReference = false) : VariableWalkerBase(_pFrame, _instance, _groupType, allowLexicalThis, allowSuperReference) {}
  202. virtual void PopulateMembers() override;
  203. virtual IDiagObjectAddress * GetObjectAddress(int index) override;
  204. ScopeSlots GetSlotArray() {
  205. Var *slotArray = (Var *) instance;
  206. Assert(slotArray != nullptr);
  207. return ScopeSlots(slotArray);
  208. }
  209. };
  210. class ObjectVariablesWalker : public VariableWalkerBase
  211. {
  212. public:
  213. ObjectVariablesWalker(DiagStackFrame* _pFrame, Var _instance, UIGroupType _groupType, bool allowLexicalThis, bool allowSuperReference = false) : VariableWalkerBase(_pFrame, _instance, _groupType, allowLexicalThis, allowSuperReference) {}
  214. virtual void PopulateMembers() override;
  215. virtual IDiagObjectAddress * GetObjectAddress(int index) override;
  216. protected:
  217. void AddObjectProperties(int count, Js::RecyclableObject* object);
  218. };
  219. class RootObjectVariablesWalker : public ObjectVariablesWalker
  220. {
  221. public:
  222. RootObjectVariablesWalker(DiagStackFrame* _pFrame, Var _instance, UIGroupType _groupType) : ObjectVariablesWalker(_pFrame, _instance, _groupType, /* allowLexicalThis */ false) {}
  223. virtual void PopulateMembers() override;
  224. };
  225. class DiagScopeVariablesWalker sealed : public VariableWalkerBase
  226. {
  227. public:
  228. // Represent catch/with scope objects, (ie. the representation for the diagnostics purposes.)
  229. JsUtil::List<IDiagObjectModelWalkerBase*, ArenaAllocator> *pDiagScopeObjects;
  230. uint32 diagScopeVarCount;
  231. bool scopeIsInitialized;
  232. bool enumWithScopeAlso;
  233. public:
  234. DiagScopeVariablesWalker(DiagStackFrame* _pFrame, Var _instance, bool _enumWithScopeAlso)
  235. : VariableWalkerBase(_pFrame, _instance, UIGroupType_InnerScope, /* allowLexicalThis */ false), pDiagScopeObjects(nullptr), diagScopeVarCount(0), scopeIsInitialized(false), enumWithScopeAlso(_enumWithScopeAlso)
  236. {}
  237. DiagScopeVariablesWalker(DiagStackFrame* _pFrame, Var _instance, IDiagObjectModelWalkerBase* innerWalker);
  238. virtual BOOL Get(int i, ResolvedObject* pResolvedObject) override;
  239. virtual uint32 GetChildrenCount() override;
  240. virtual IDiagObjectAddress *FindPropertyAddress(PropertyId propId, bool& isConst) override;
  241. };
  242. // Display of variable on the locals window
  243. // Also responsible for walking on the current frame and build up chain of scopes.
  244. class LocalsWalker sealed : public IDiagObjectModelWalkerBase
  245. {
  246. friend class RecyclableArgumentsArrayWalker;
  247. DiagStackFrame* pFrame;
  248. JsUtil::List<VariableWalkerBase *, ArenaAllocator> * pVarWalkers; // This includes, current frame, all scopes and globals for a current frame
  249. uint totalLocalsCount;
  250. DWORD frameWalkerFlags;
  251. // true, if user has not defined the 'arguments' in the script, this is used for displaying a fake arguments object and display in the locals window.
  252. bool hasUserNotDefinedArguments;
  253. public:
  254. LocalsWalker(DiagStackFrame* _frame, DWORD _frameWalkerFlags);
  255. virtual BOOL Get(int i, ResolvedObject* pResolvedObject) override;
  256. virtual uint32 GetChildrenCount() override;
  257. virtual uint32 GetLocalVariablesCount();
  258. BOOL GetLocal(int i, ResolvedObject* pResolvedObject);
  259. BOOL GetScopeObject(int i, ResolvedObject* pResolvedObject);
  260. BOOL GetGlobalsObject(ResolvedObject* pResolvedObject);
  261. virtual BOOL GetGroupObject(ResolvedObject* pResolvedObject) {return FALSE; }
  262. static DWORD GetCurrentFramesLocalsType(DiagStackFrame* frame);
  263. static DebuggerScope * GetScopeWhenHaltAtFormals(DiagStackFrame* frame);
  264. static int GetAdjustedByteCodeOffset(DiagStackFrame* frame);
  265. IDiagObjectAddress * FindPropertyAddress(PropertyId propId, bool& isConst) override;
  266. // enumerateGroups will be true for the when fetching from a variable from the expression evaluation.
  267. IDiagObjectAddress * FindPropertyAddress(PropertyId propId, bool enumerateGroups, bool& isConst);
  268. template <typename FnProcessResolvedObject>
  269. DynamicObject* CreateAndPopulateActivationObject(ScriptContext* scriptContext, FnProcessResolvedObject processResolvedObjectFn)
  270. {
  271. Assert(scriptContext);
  272. Js::DynamicObject* activeScopeObject = nullptr;
  273. uint32 count = this->GetChildrenCount();
  274. if (count > 0)
  275. {
  276. activeScopeObject = scriptContext->GetLibrary()->CreateActivationObject();
  277. for (uint32 i = 0; i < count; i++)
  278. {
  279. Js::ResolvedObject resolveObject;
  280. if (this->Get(i, &resolveObject) && resolveObject.propId != Js::Constants::NoProperty)
  281. {
  282. if (!activeScopeObject->HasOwnProperty(resolveObject.propId))
  283. {
  284. OUTPUT_TRACE(Js::ConsoleScopePhase, _u("Adding '%s' property to activeScopeObject\n"), resolveObject.scriptContext->GetPropertyName(resolveObject.propId)->GetBuffer());
  285. if (resolveObject.IsInDeadZone())
  286. {
  287. PropertyOperationFlags flags = static_cast<PropertyOperationFlags>(PropertyOperation_SpecialValue | PropertyOperation_AllowUndecl);
  288. PropertyAttributes attributes = resolveObject.isConst ? PropertyConstDefaults : PropertyLetDefaults;
  289. resolveObject.obj = scriptContext->GetLibrary()->GetUndeclBlockVar();
  290. activeScopeObject->SetPropertyWithAttributes(
  291. resolveObject.propId,
  292. resolveObject.obj,
  293. attributes, nullptr, flags);
  294. }
  295. else
  296. {
  297. activeScopeObject->SetPropertyWithAttributes(
  298. resolveObject.propId,
  299. JavascriptOperators::BoxStackInstance(resolveObject.obj, scriptContext), //The value escapes, box if necessary.
  300. resolveObject.isConst ? PropertyConstDefaults : PropertyDynamicTypeDefaults,
  301. nullptr);
  302. }
  303. processResolvedObjectFn(resolveObject);
  304. }
  305. }
  306. }
  307. }
  308. return activeScopeObject;
  309. }
  310. BOOL CreateArgumentsObject(ResolvedObject* pResolvedObject);
  311. bool HasUserNotDefinedArguments() const { return hasUserNotDefinedArguments; }
  312. private:
  313. bool ShouldMakeGroups() const { return frameWalkerFlags & FW_MakeGroups; }
  314. bool ShouldInsertFakeArguments();
  315. void ExpandArgumentsObject(IDiagObjectModelDisplay * argumentsDisplay);
  316. BOOL GetGroupObject(Js::UIGroupType uiGroupType, int i, ResolvedObject* pResolvedObject);
  317. };
  318. class LocalsDisplay : public IDiagObjectModelDisplay
  319. {
  320. DiagStackFrame* pFrame;
  321. public:
  322. LocalsDisplay(DiagStackFrame* _frame);
  323. virtual LPCWSTR Name() override;
  324. virtual LPCWSTR Type() override;
  325. virtual LPCWSTR Value(int radix) override;
  326. virtual BOOL HasChildren() override;
  327. virtual BOOL Set(Var updateObject) override;
  328. virtual DBGPROP_ATTRIB_FLAGS GetTypeAttribute() override;
  329. virtual WeakArenaReference<IDiagObjectModelWalkerBase>* CreateWalker() override;
  330. virtual BOOL IsLocalsAsRoot() { return TRUE; }
  331. virtual DiagObjectModelDisplayType GetType() { return DiagObjectModelDisplayType_LocalsDisplay; }
  332. virtual bool IsLiteralProperty() const { return false; }
  333. };
  334. //
  335. // The locals var's addresses.
  336. // A representation of an address when this Var is taken from the slot array.
  337. class LocalObjectAddressForSlot : public IDiagObjectAddress
  338. {
  339. ScopeSlots slotArray;
  340. int slotIndex;
  341. Var value;
  342. public:
  343. LocalObjectAddressForSlot(ScopeSlots _pSlotArray, int _slotIndex, Js::Var _value);
  344. virtual BOOL Set(Var updateObject) override;
  345. virtual Var GetValue(BOOL fUpdated);
  346. virtual BOOL IsInDeadZone() const;
  347. };
  348. // A representation of an address when this Var is taken from the direct regslot.
  349. class LocalObjectAddressForRegSlot : public IDiagObjectAddress
  350. {
  351. DiagStackFrame* pFrame;
  352. RegSlot regSlot;
  353. Var value;
  354. public:
  355. LocalObjectAddressForRegSlot(DiagStackFrame* _pFrame, RegSlot _regSlot, Js::Var _value);
  356. virtual BOOL Set(Var updateObject) override;
  357. virtual Var GetValue(BOOL fUpdated);
  358. BOOL IsInDeadZone() const;
  359. };
  360. class CatchScopeWalker sealed : public IDiagObjectModelWalkerBase
  361. {
  362. DiagStackFrame* pFrame;
  363. DebuggerScope * debuggerScope;
  364. public :
  365. CatchScopeWalker(DiagStackFrame* _pFrame, DebuggerScope* _debuggerScope)
  366. : pFrame(_pFrame), debuggerScope(_debuggerScope)
  367. {
  368. }
  369. /// IDiagObjectModelWalkerBase
  370. virtual BOOL Get(int i, ResolvedObject* pResolvedObject) override;
  371. virtual uint32 GetChildrenCount() override;
  372. virtual BOOL GetGroupObject(ResolvedObject* pResolvedObject) override { return FALSE; }
  373. virtual IDiagObjectAddress *FindPropertyAddress(PropertyId propId, bool& isConst) override;
  374. private:
  375. void FetchValueAndAddress(DebuggerScopeProperty &scopeProperty, _Out_opt_ Var *pValue, _Out_opt_ IDiagObjectAddress ** ppAddress);
  376. };
  377. // Concrete Classes for Objects
  378. class RecyclableObjectWalker : public IDiagObjectModelWalkerBase
  379. {
  380. protected:
  381. ScriptContext* scriptContext;
  382. Var instance;
  383. Var originalInstance; // Remember original instance for prototype walk, because evaluating getters in CallGetter() if __proto__ instance is passed does not work
  384. JsUtil::List<DebuggerPropertyDisplayInfo *, ArenaAllocator> * pMembersList;
  385. RecyclableArrayWalker * innerArrayObjectWalker; // Will be used for array indices on the object
  386. JsUtil::List<IDiagObjectModelWalkerBase *, ArenaAllocator> * fakeGroupObjectWalkerList; // such as [prototype], [Methods] etc.
  387. void InsertItem(Js::RecyclableObject *pOriginalObject, Js::RecyclableObject *pObject, PropertyId propertyId, bool isConst, bool isUnscoped, Js::RecyclableMethodsGroupWalker **ppMethodsGrouptWalker, bool shouldPinProperty = false);
  388. void InsertItem(PropertyId propertyId, bool isConst, bool isUnscoped, Var itemObj, Js::RecyclableMethodsGroupWalker **ppMethodsGrouptWalker, bool shouldPinProperty = false);
  389. void EnsureFakeGroupObjectWalkerList();
  390. public:
  391. RecyclableObjectWalker(ScriptContext* pContext, Var slot);
  392. RecyclableObjectWalker(ScriptContext* pContext, Var slot, Var originalInstance);
  393. virtual BOOL Get(int i, ResolvedObject* pResolvedObject) override;
  394. virtual uint32 GetChildrenCount() override;
  395. virtual BOOL GetGroupObject(ResolvedObject* pResolvedObject) { return FALSE; };
  396. virtual IDiagObjectAddress *FindPropertyAddress(PropertyId propertyId, bool& isConst) override;
  397. static Var GetObject(RecyclableObject* originalInstance, RecyclableObject* instance, PropertyId propertyId, ScriptContext* scriptContext);
  398. };
  399. class RecyclableObjectAddress : public IDiagObjectAddress
  400. {
  401. Var parentObj;
  402. Js::PropertyId propId;
  403. Js::Var value;
  404. BOOL isInDeadZone;
  405. public:
  406. RecyclableObjectAddress(Var parentObj, Js::PropertyId _propId, Js::Var _value, BOOL _isInDeadZone);
  407. virtual BOOL Set(Var updateObject) override;
  408. virtual BOOL IsWritable() override;
  409. virtual Var GetValue(BOOL fUpdated);
  410. BOOL IsInDeadZone() const;
  411. };
  412. class RecyclableObjectDisplay : public IDiagObjectModelDisplay
  413. {
  414. protected:
  415. ScriptContext* scriptContext;
  416. Var instance;
  417. Var originalInstance;
  418. LPCWSTR name;
  419. IDiagObjectAddress* pObjAddress;
  420. DBGPROP_ATTRIB_FLAGS defaultAttributes;
  421. PropertyId propertyId;
  422. public:
  423. RecyclableObjectDisplay(ResolvedObject* resolvedObject, DBGPROP_ATTRIB_FLAGS defaultAttributes = DBGPROP_ATTRIB_NO_ATTRIB);
  424. virtual LPCWSTR Name() override;
  425. virtual LPCWSTR Type() override;
  426. virtual LPCWSTR Value(int radix) override;
  427. virtual BOOL HasChildren() override;
  428. virtual BOOL Set(Var updateObject) override;
  429. virtual BOOL SetDefaultTypeAttribute(DBGPROP_ATTRIB_FLAGS attributes) override { defaultAttributes = attributes; return TRUE; };
  430. virtual DBGPROP_ATTRIB_FLAGS GetTypeAttribute() override;
  431. virtual WeakArenaReference<IDiagObjectModelWalkerBase>* CreateWalker() override;
  432. virtual Var GetVarValue(BOOL fUpdated) override;
  433. virtual IDiagObjectAddress * GetDiagAddress() override { return pObjAddress; }
  434. virtual DiagObjectModelDisplayType GetType() { return DiagObjectModelDisplayType_RecyclableObjectDisplay; }
  435. virtual bool IsLiteralProperty() const;
  436. virtual bool IsSymbolProperty() override;
  437. static BOOL GetPropertyWithScriptEnter(RecyclableObject* originalInstance, RecyclableObject* instance, PropertyId propertyId, Var* value, ScriptContext* scriptContext);
  438. StringBuilder<ArenaAllocator>* GetStringBuilder();
  439. PropertyId GetPropertyId() const;
  440. };
  441. // Concrete classes for Arrays
  442. class RecyclableArrayAddress : public IDiagObjectAddress
  443. {
  444. protected:
  445. Var parentArray;
  446. unsigned int index;
  447. public:
  448. RecyclableArrayAddress(Var parentArray, unsigned int index);
  449. virtual BOOL Set(Var updateObject) override;
  450. };
  451. class RecyclableArrayDisplay : public RecyclableObjectDisplay
  452. {
  453. protected:
  454. BOOL HasChildrenInternal(Js::JavascriptArray* arrayObj);
  455. public:
  456. RecyclableArrayDisplay(ResolvedObject* resolvedObject);
  457. virtual BOOL HasChildren() override;
  458. virtual WeakArenaReference<IDiagObjectModelWalkerBase>* CreateWalker() override;
  459. };
  460. class RecyclableArrayWalker : public RecyclableObjectWalker
  461. {
  462. protected:
  463. uint32 indexedItemCount;
  464. JsUtil::List<uint32, ArenaAllocator> * pAbsoluteIndexList;
  465. // Just populate the indexes only.
  466. bool fOnlyOwnProperties;
  467. uint32 GetItemCount(Js::JavascriptArray* arrayObj);
  468. // ES5Array will extend this.
  469. virtual uint32 GetNextDescriptor(uint32 currentDescriptor) { return Js::JavascriptArray::InvalidIndex; }
  470. LPCWSTR GetIndexName(uint32 index, StringBuilder<ArenaAllocator>* stringBuilder);
  471. Js::JavascriptArray* GetArrayObject();
  472. public:
  473. RecyclableArrayWalker(ScriptContext* pContext, Var slot, Var originalInstance);
  474. void SetOnlyWalkOwnProperties(bool set) { fOnlyOwnProperties = set; }
  475. virtual BOOL Get(int i, ResolvedObject* pResolvedObject) override;
  476. virtual uint32 GetChildrenCount() override;
  477. virtual BOOL FetchItemAtIndex(Js::JavascriptArray* arrayObj, uint32 index, Var *value);
  478. virtual Var FetchItemAt(Js::JavascriptArray* arrayObj, uint32 index);
  479. virtual BOOL GetResolvedObject(Js::JavascriptArray* arrayObj, int index, ResolvedObject* pResolvedObject, uint32 * pabsIndex) sealed;
  480. StringBuilder<ArenaAllocator>* GetBuilder();
  481. };
  482. // Concrete classes for Arguments object
  483. //
  484. class RecyclableArgumentsObjectDisplay : public RecyclableObjectDisplay
  485. {
  486. LocalsWalker *pLocalsWalker;
  487. public:
  488. RecyclableArgumentsObjectDisplay(ResolvedObject* resolvedObject, LocalsWalker *localsWalker);
  489. virtual BOOL HasChildren() override;
  490. virtual WeakArenaReference<IDiagObjectModelWalkerBase>* CreateWalker() override;
  491. };
  492. class RecyclableArgumentsObjectWalker : public RecyclableObjectWalker
  493. {
  494. LocalsWalker *pLocalsWalker;
  495. public:
  496. RecyclableArgumentsObjectWalker(ScriptContext* pContext, Var instance, LocalsWalker * localsWalker);
  497. virtual uint32 GetChildrenCount() override;
  498. };
  499. class RecyclableArgumentsArrayAddress : public IDiagObjectAddress
  500. {
  501. Var parentArray;
  502. unsigned int index;
  503. public:
  504. RecyclableArgumentsArrayAddress(Var parentArray, unsigned int index);
  505. virtual BOOL Set(Var updateObject) override;
  506. };
  507. class RecyclableArgumentsArrayWalker : public RecyclableArrayWalker
  508. {
  509. JsUtil::List<IDiagObjectAddress *, ArenaAllocator> * pFormalsList;
  510. public:
  511. RecyclableArgumentsArrayWalker(ScriptContext* pContext, Var slot, Var originalInstance);
  512. virtual BOOL Get(int i, ResolvedObject* pResolvedObject) override;
  513. virtual uint32 GetChildrenCount() override;
  514. void FetchFormalsAddress (LocalsWalker * localsWalker);
  515. };
  516. // Concrete classes for Typed array objects
  517. //
  518. class RecyclableTypedArrayAddress : public RecyclableArrayAddress
  519. {
  520. public:
  521. RecyclableTypedArrayAddress(Var parentArray, unsigned int index);
  522. virtual BOOL Set(Var updateObject) override;
  523. };
  524. class RecyclableTypedArrayDisplay : public RecyclableObjectDisplay
  525. {
  526. public:
  527. RecyclableTypedArrayDisplay(ResolvedObject* resolvedObject);
  528. virtual BOOL HasChildren() override;
  529. virtual WeakArenaReference<IDiagObjectModelWalkerBase>* CreateWalker() override;
  530. };
  531. class RecyclableTypedArrayWalker : public RecyclableArrayWalker
  532. {
  533. public:
  534. RecyclableTypedArrayWalker(ScriptContext* pContext, Var slot, Var originalInstance);
  535. virtual BOOL Get(int i, ResolvedObject* pResolvedObject) override;
  536. virtual uint32 GetChildrenCount() override;
  537. };
  538. // Concrete classes for Pixel array objects
  539. //
  540. class RecyclablePixelArrayAddress : public RecyclableArrayAddress
  541. {
  542. public:
  543. RecyclablePixelArrayAddress(Var parentArray, unsigned int index);
  544. virtual BOOL Set(Var updateObject) override;
  545. };
  546. class RecyclablePixelArrayDisplay : public RecyclableObjectDisplay
  547. {
  548. public:
  549. RecyclablePixelArrayDisplay(ResolvedObject* resolvedObject);
  550. virtual BOOL HasChildren() override;
  551. virtual WeakArenaReference<IDiagObjectModelWalkerBase>* CreateWalker() override;
  552. };
  553. class RecyclablePixelArrayWalker : public RecyclableArrayWalker
  554. {
  555. public:
  556. RecyclablePixelArrayWalker(ScriptContext* pContext, Var slot, Var originalInstance);
  557. virtual BOOL Get(int i, ResolvedObject* pResolvedObject) override;
  558. virtual uint32 GetChildrenCount() override;
  559. };
  560. // Concrete classes for ES5 array objects
  561. //
  562. class RecyclableES5ArrayAddress : public RecyclableArrayAddress
  563. {
  564. public:
  565. RecyclableES5ArrayAddress(Var parentArray, unsigned int index);
  566. virtual BOOL Set(Var updateObject) override;
  567. };
  568. class RecyclableES5ArrayDisplay : public RecyclableArrayDisplay
  569. {
  570. public:
  571. RecyclableES5ArrayDisplay(ResolvedObject* resolvedObject);
  572. virtual BOOL HasChildren() override;
  573. virtual WeakArenaReference<IDiagObjectModelWalkerBase>* CreateWalker() override;
  574. };
  575. class RecyclableES5ArrayWalker sealed : public RecyclableArrayWalker
  576. {
  577. public:
  578. RecyclableES5ArrayWalker(ScriptContext* pContext, Var slot, Var originalInstance);
  579. virtual uint32 GetNextDescriptor(uint32 currentDescriptor) override;
  580. virtual BOOL FetchItemAtIndex(Js::JavascriptArray* arrayObj, uint32 index, Var *value) override;
  581. virtual Var FetchItemAt(Js::JavascriptArray* arrayObj, uint32 index) override;
  582. };
  583. // Concrete classes for Proto group object
  584. //
  585. class RecyclableProtoObjectWalker : public RecyclableObjectWalker
  586. {
  587. public:
  588. RecyclableProtoObjectWalker(ScriptContext* pContext, Var slot, Var originalInstance);
  589. virtual BOOL GetGroupObject(ResolvedObject* pResolvedObject) override;
  590. virtual IDiagObjectAddress *FindPropertyAddress(PropertyId propId, bool& isConst) override;
  591. };
  592. class RecyclableProtoObjectAddress : public RecyclableObjectAddress
  593. {
  594. public:
  595. RecyclableProtoObjectAddress(Var _parentObj, Js::PropertyId _propId, Js::Var _value);
  596. };
  597. // Concrete classes for Map, Set, and WeakMap group objects
  598. //
  599. template <typename TData>
  600. struct RecyclableCollectionObjectWalkerPropertyData
  601. {
  602. RecyclableCollectionObjectWalkerPropertyData():key(nullptr), value(nullptr) { }
  603. RecyclableCollectionObjectWalkerPropertyData(Var key, Var value):key(key), value(value) { }
  604. Var key;
  605. Var value;
  606. };
  607. template<>
  608. struct RecyclableCollectionObjectWalkerPropertyData<JavascriptSet>
  609. {
  610. RecyclableCollectionObjectWalkerPropertyData():value(nullptr) { }
  611. RecyclableCollectionObjectWalkerPropertyData(Var value):value(value) { }
  612. Var value;
  613. };
  614. template<>
  615. struct RecyclableCollectionObjectWalkerPropertyData<JavascriptWeakSet>
  616. {
  617. RecyclableCollectionObjectWalkerPropertyData():value(nullptr) { }
  618. RecyclableCollectionObjectWalkerPropertyData(Var value):value(value) { }
  619. Var value;
  620. };
  621. template <typename TData>
  622. class RecyclableCollectionObjectWalker : public IDiagObjectModelWalkerBase
  623. {
  624. ScriptContext* scriptContext;
  625. Var instance;
  626. JsUtil::List<RecyclableCollectionObjectWalkerPropertyData<TData>, ArenaAllocator>* propertyList;
  627. const char16* Name();
  628. IDiagObjectModelDisplay* CreateTDataDisplay(ResolvedObject* resolvedObject, int i);
  629. void GetChildren();
  630. public:
  631. RecyclableCollectionObjectWalker(ScriptContext* scriptContext, Var instance):scriptContext(scriptContext), instance(instance), propertyList(nullptr) { }
  632. virtual BOOL GetGroupObject(ResolvedObject* pResolvedObject) override;
  633. virtual BOOL Get(int i, ResolvedObject* pResolvedObject) override;
  634. virtual uint32 GetChildrenCount() override;
  635. };
  636. typedef RecyclableCollectionObjectWalker<JavascriptMap> RecyclableMapObjectWalker;
  637. typedef RecyclableCollectionObjectWalker<JavascriptSet> RecyclableSetObjectWalker;
  638. typedef RecyclableCollectionObjectWalker<JavascriptWeakMap> RecyclableWeakMapObjectWalker;
  639. typedef RecyclableCollectionObjectWalker<JavascriptWeakSet> RecyclableWeakSetObjectWalker;
  640. template <typename TData>
  641. class RecyclableCollectionObjectDisplay : public IDiagObjectModelDisplay
  642. {
  643. ScriptContext* scriptContext;
  644. const char16* name;
  645. RecyclableCollectionObjectWalker<TData>* walker;
  646. public:
  647. RecyclableCollectionObjectDisplay(ScriptContext* scriptContext, const char16* name, RecyclableCollectionObjectWalker<TData>* walker) : scriptContext(scriptContext), name(name), walker(walker) { }
  648. virtual LPCWSTR Name() override { return name; }
  649. virtual LPCWSTR Type() override { return _u(""); }
  650. virtual LPCWSTR Value(int radix) override;
  651. virtual BOOL HasChildren() override { return walker->GetChildrenCount() > 0; }
  652. virtual BOOL Set(Var updateObject) override { return FALSE; }
  653. virtual BOOL SetDefaultTypeAttribute(DBGPROP_ATTRIB_FLAGS attributes) override { return FALSE; }
  654. virtual DBGPROP_ATTRIB_FLAGS GetTypeAttribute() override { return DBGPROP_ATTRIB_VALUE_READONLY | DBGPROP_ATTRIB_VALUE_IS_FAKE | (HasChildren() ? DBGPROP_ATTRIB_VALUE_IS_EXPANDABLE : 0); }
  655. virtual WeakArenaReference<IDiagObjectModelWalkerBase>* CreateWalker() override;
  656. virtual Var GetVarValue(BOOL fUpdated) override { return nullptr; }
  657. virtual IDiagObjectAddress * GetDiagAddress() override { return nullptr; }
  658. virtual DiagObjectModelDisplayType GetType() { return DiagObjectModelDisplayType_RecyclableCollectionObjectDisplay; }
  659. virtual bool IsLiteralProperty() const { return false; }
  660. };
  661. class RecyclableKeyValueDisplay : public IDiagObjectModelDisplay
  662. {
  663. ScriptContext* scriptContext;
  664. Var key;
  665. Var value;
  666. const char16* name;
  667. public:
  668. RecyclableKeyValueDisplay(ScriptContext* scriptContext, Var key, Var value, const char16* name) : scriptContext(scriptContext), key(key), value(value), name(name) { }
  669. virtual LPCWSTR Name() override { return name; }
  670. virtual LPCWSTR Type() override { return _u(""); }
  671. virtual LPCWSTR Value(int radix) override;
  672. virtual BOOL HasChildren() override { return TRUE; }
  673. virtual BOOL Set(Var updateObject) override { return FALSE; }
  674. virtual DBGPROP_ATTRIB_FLAGS GetTypeAttribute() override { return DBGPROP_ATTRIB_VALUE_IS_EXPANDABLE | DBGPROP_ATTRIB_VALUE_IS_FAKE | DBGPROP_ATTRIB_VALUE_READONLY; }
  675. virtual WeakArenaReference<IDiagObjectModelWalkerBase>* CreateWalker() override;
  676. virtual DiagObjectModelDisplayType GetType() { return DiagObjectModelDisplayType_RecyclableKeyValueDisplay; }
  677. virtual bool IsLiteralProperty() const { return false; }
  678. };
  679. class RecyclableKeyValueWalker : public IDiagObjectModelWalkerBase
  680. {
  681. ScriptContext* scriptContext;
  682. Var key;
  683. Var value;
  684. public:
  685. RecyclableKeyValueWalker(ScriptContext* scriptContext, Var key, Var value):scriptContext(scriptContext), key(key), value(value) { }
  686. virtual BOOL Get(int i, ResolvedObject* pResolvedObject) override;
  687. // Children count is 2 for 'key' and 'value'
  688. virtual uint32 GetChildrenCount() override { return 2; }
  689. virtual BOOL GetGroupObject(ResolvedObject* pResolvedObject) override { return FALSE; }
  690. };
  691. class RecyclableProxyObjectDisplay : public RecyclableObjectDisplay
  692. {
  693. public:
  694. RecyclableProxyObjectDisplay(ResolvedObject* resolvedObject);
  695. virtual BOOL HasChildren() override { return TRUE; }
  696. virtual WeakArenaReference<IDiagObjectModelWalkerBase>* CreateWalker() override;
  697. };
  698. class RecyclableProxyObjectWalker : public RecyclableObjectWalker
  699. {
  700. public:
  701. RecyclableProxyObjectWalker(ScriptContext* pContext, Var instance);
  702. virtual BOOL Get(int i, ResolvedObject* pResolvedObject) override;
  703. // Children count is 2 for '[target]' and '[handler]'
  704. virtual uint32 GetChildrenCount() override { return 2; }
  705. virtual BOOL GetGroupObject(ResolvedObject* pResolvedObject) override;
  706. };
  707. class RecyclablePromiseObjectDisplay : public RecyclableObjectDisplay
  708. {
  709. public:
  710. RecyclablePromiseObjectDisplay(ResolvedObject* resolvedObject);
  711. virtual BOOL HasChildren() override { return TRUE; }
  712. virtual WeakArenaReference<IDiagObjectModelWalkerBase>* CreateWalker() override;
  713. };
  714. class RecyclablePromiseObjectWalker : public RecyclableObjectWalker
  715. {
  716. public:
  717. RecyclablePromiseObjectWalker(ScriptContext* pContext, Var instance);
  718. virtual BOOL Get(int i, ResolvedObject* pResolvedObject) override;
  719. // Children count is 2 for '[status]' and '[value]'
  720. virtual uint32 GetChildrenCount() override { return 2; }
  721. virtual BOOL GetGroupObject(ResolvedObject* pResolvedObject) override;
  722. };
  723. // Concrete classes for Methods group object
  724. //
  725. class RecyclableMethodsGroupWalker : public RecyclableObjectWalker
  726. {
  727. public:
  728. RecyclableMethodsGroupWalker(ScriptContext* pContext, Var slot);
  729. void AddItem(Js::PropertyId propertyId, Var obj);
  730. virtual BOOL Get(int i, ResolvedObject* pResolvedObject) override;
  731. virtual uint32 GetChildrenCount() override;
  732. virtual BOOL GetGroupObject(ResolvedObject* pResolvedObject) override;
  733. void Sort();
  734. };
  735. class RecyclableMethodsGroupDisplay : public RecyclableObjectDisplay
  736. {
  737. public:
  738. RecyclableMethodsGroupWalker *methodGroupWalker;
  739. RecyclableMethodsGroupDisplay(RecyclableMethodsGroupWalker *_methodGroupWalker, ResolvedObject* resolvedObject);
  740. virtual LPCWSTR Type() override;
  741. virtual LPCWSTR Value(int radix) override;
  742. virtual BOOL HasChildren() override;
  743. virtual DBGPROP_ATTRIB_FLAGS GetTypeAttribute() override;
  744. virtual WeakArenaReference<IDiagObjectModelWalkerBase>* CreateWalker() override;
  745. };
  746. // Concrete classes for Scope group object
  747. //
  748. class ScopeVariablesGroupDisplay : public RecyclableObjectDisplay
  749. {
  750. public:
  751. VariableWalkerBase *scopeGroupWalker;
  752. ScopeVariablesGroupDisplay(VariableWalkerBase *walker, ResolvedObject* resolvedObject);
  753. virtual LPCWSTR Type() override;
  754. virtual LPCWSTR Value(int radix) override;
  755. virtual BOOL HasChildren() override;
  756. virtual DBGPROP_ATTRIB_FLAGS GetTypeAttribute() override;
  757. virtual WeakArenaReference<IDiagObjectModelWalkerBase>* CreateWalker() override;
  758. };
  759. // Concrete classes for Globals group object
  760. //
  761. class GlobalsScopeVariablesGroupDisplay sealed : public RecyclableObjectDisplay
  762. {
  763. public:
  764. VariableWalkerBase *globalsGroupWalker;
  765. GlobalsScopeVariablesGroupDisplay(VariableWalkerBase *walker, ResolvedObject* resolvedObject);
  766. virtual LPCWSTR Type() override;
  767. virtual LPCWSTR Value(int radix) override;
  768. virtual BOOL HasChildren() override;
  769. virtual DBGPROP_ATTRIB_FLAGS GetTypeAttribute() override;
  770. virtual WeakArenaReference<IDiagObjectModelWalkerBase>* CreateWalker() override;
  771. };
  772. #ifdef ENABLE_MUTATION_BREAKPOINT
  773. // For Pending Mutation breakpoint
  774. class PendingMutationBreakpointDisplay : public RecyclableObjectDisplay
  775. {
  776. MutationType mutationType;
  777. public:
  778. PendingMutationBreakpointDisplay(ResolvedObject* resolvedObject, MutationType mutationType);
  779. virtual LPCWSTR Value(int radix) override { return _u(""); }
  780. virtual BOOL HasChildren() override { return TRUE; }
  781. virtual WeakArenaReference<IDiagObjectModelWalkerBase>* CreateWalker() override;
  782. };
  783. class PendingMutationBreakpointWalker : public RecyclableObjectWalker
  784. {
  785. MutationType mutationType;
  786. public:
  787. PendingMutationBreakpointWalker(ScriptContext* pContext, Var instance, MutationType mutationType);
  788. virtual BOOL Get(int i, ResolvedObject* pResolvedObject) override;
  789. virtual uint32 GetChildrenCount() override;
  790. };
  791. #endif
  792. #ifdef ENABLE_SIMDJS
  793. // For SIMD walker
  794. template <typename simdType, uint elementCount>
  795. class RecyclableSimdObjectWalker : public RecyclableObjectWalker
  796. {
  797. public:
  798. RecyclableSimdObjectWalker(ScriptContext* pContext, Var instance) : RecyclableObjectWalker(pContext, instance) { }
  799. virtual BOOL Get(int i, ResolvedObject* pResolvedObject) override;
  800. virtual uint32 GetChildrenCount() override { return elementCount; }
  801. };
  802. // For SIMD concrete walker: specify SIMD type and total elementCount
  803. // elementCount can be 4, 8 or 16 for SIMD type like int32x4, int16x8, int8x16
  804. typedef RecyclableSimdObjectWalker<JavascriptSIMDFloat32x4, 4> RecyclableSimdFloat32x4ObjectWalker;
  805. typedef RecyclableSimdObjectWalker<JavascriptSIMDInt32x4, 4> RecyclableSimdInt32x4ObjectWalker;
  806. typedef RecyclableSimdObjectWalker<JavascriptSIMDInt8x16, 16> RecyclableSimdInt8x16ObjectWalker;
  807. typedef RecyclableSimdObjectWalker<JavascriptSIMDInt16x8, 8> RecyclableSimdInt16x8ObjectWalker;
  808. typedef RecyclableSimdObjectWalker<JavascriptSIMDBool32x4, 4> RecyclableSimdBool32x4ObjectWalker;
  809. typedef RecyclableSimdObjectWalker<JavascriptSIMDBool8x16, 16> RecyclableSimdBool8x16ObjectWalker;
  810. typedef RecyclableSimdObjectWalker<JavascriptSIMDBool16x8, 8> RecyclableSimdBool16x8ObjectWalker;
  811. typedef RecyclableSimdObjectWalker<JavascriptSIMDUint32x4, 4> RecyclableSimdUint32x4ObjectWalker;
  812. typedef RecyclableSimdObjectWalker<JavascriptSIMDUint8x16, 16> RecyclableSimdUint8x16ObjectWalker;
  813. typedef RecyclableSimdObjectWalker<JavascriptSIMDUint16x8, 8> RecyclableSimdUint16x8ObjectWalker;
  814. // For SIMD display
  815. template <typename simdType, typename simdWalker>
  816. class RecyclableSimdObjectDisplay : public RecyclableObjectDisplay
  817. {
  818. public:
  819. RecyclableSimdObjectDisplay(ResolvedObject* resolvedObject) : RecyclableObjectDisplay(resolvedObject) {};
  820. virtual LPCWSTR Type() override;
  821. virtual LPCWSTR Value(int radix) override;
  822. virtual BOOL HasChildren() override { return TRUE; }
  823. virtual WeakArenaReference<IDiagObjectModelWalkerBase>* CreateWalker() override;
  824. virtual DBGPROP_ATTRIB_FLAGS GetTypeAttribute() override { return DBGPROP_ATTRIB_VALUE_IS_EXPANDABLE | DBGPROP_ATTRIB_VALUE_IS_FAKE | DBGPROP_ATTRIB_VALUE_READONLY; }
  825. virtual DiagObjectModelDisplayType GetType() { return DiagObjectModelDisplayType_RecyclableSimdDisplay; }
  826. };
  827. // For SIMD concrete display: specify SIMD type and concrete simd walker
  828. typedef RecyclableSimdObjectDisplay<JavascriptSIMDFloat32x4, RecyclableSimdFloat32x4ObjectWalker> RecyclableSimdFloat32x4ObjectDisplay;
  829. typedef RecyclableSimdObjectDisplay<JavascriptSIMDInt32x4, RecyclableSimdInt32x4ObjectWalker> RecyclableSimdInt32x4ObjectDisplay;
  830. typedef RecyclableSimdObjectDisplay<JavascriptSIMDInt8x16, RecyclableSimdInt8x16ObjectWalker> RecyclableSimdInt8x16ObjectDisplay;
  831. typedef RecyclableSimdObjectDisplay<JavascriptSIMDInt16x8, RecyclableSimdInt16x8ObjectWalker> RecyclableSimdInt16x8ObjectDisplay;
  832. typedef RecyclableSimdObjectDisplay<JavascriptSIMDBool32x4, RecyclableSimdBool32x4ObjectWalker> RecyclableSimdBool32x4ObjectDisplay;
  833. typedef RecyclableSimdObjectDisplay<JavascriptSIMDBool8x16, RecyclableSimdBool8x16ObjectWalker> RecyclableSimdBool8x16ObjectDisplay;
  834. typedef RecyclableSimdObjectDisplay<JavascriptSIMDBool16x8, RecyclableSimdBool16x8ObjectWalker> RecyclableSimdBool16x8ObjectDisplay;
  835. typedef RecyclableSimdObjectDisplay<JavascriptSIMDUint32x4, RecyclableSimdUint32x4ObjectWalker> RecyclableSimdUint32x4ObjectDisplay;
  836. typedef RecyclableSimdObjectDisplay<JavascriptSIMDUint8x16, RecyclableSimdUint8x16ObjectWalker> RecyclableSimdUint8x16ObjectDisplay;
  837. typedef RecyclableSimdObjectDisplay<JavascriptSIMDUint16x8, RecyclableSimdUint16x8ObjectWalker> RecyclableSimdUint16x8ObjectDisplay;
  838. #endif // #ifdef ENABLE_SIMDJS
  839. }