11cb0ef41Sopenharmony_ci// Copyright 2020 the V8 project authors. All rights reserved. 21cb0ef41Sopenharmony_ci// Use of this source code is governed by a BSD-style license that can be 31cb0ef41Sopenharmony_ci// found in the LICENSE file. 41cb0ef41Sopenharmony_ci 51cb0ef41Sopenharmony_ci#ifndef V8_TOOLS_V8WINDBG_SRC_OBJECT_INSPECTION_H_ 61cb0ef41Sopenharmony_ci#define V8_TOOLS_V8WINDBG_SRC_OBJECT_INSPECTION_H_ 71cb0ef41Sopenharmony_ci 81cb0ef41Sopenharmony_ci#include <comutil.h> 91cb0ef41Sopenharmony_ci#include <wrl/implements.h> 101cb0ef41Sopenharmony_ci 111cb0ef41Sopenharmony_ci#include <sstream> 121cb0ef41Sopenharmony_ci#include <string> 131cb0ef41Sopenharmony_ci#include <vector> 141cb0ef41Sopenharmony_ci 151cb0ef41Sopenharmony_ci#include "tools/v8windbg/base/dbgext.h" 161cb0ef41Sopenharmony_ci#include "tools/v8windbg/src/v8-debug-helper-interop.h" 171cb0ef41Sopenharmony_ci#include "tools/v8windbg/src/v8windbg-extension.h" 181cb0ef41Sopenharmony_ci 191cb0ef41Sopenharmony_ci// The representation of the underlying V8 object that will be cached on the 201cb0ef41Sopenharmony_ci// DataModel representation. (Needs to implement IUnknown). 211cb0ef41Sopenharmony_ciclass __declspec(uuid("6392E072-37BB-4220-A5FF-114098923A02")) IV8CachedObject 221cb0ef41Sopenharmony_ci : public IUnknown { 231cb0ef41Sopenharmony_ci public: 241cb0ef41Sopenharmony_ci virtual HRESULT __stdcall GetCachedV8HeapObject( 251cb0ef41Sopenharmony_ci V8HeapObject** pp_heap_object) = 0; 261cb0ef41Sopenharmony_ci}; 271cb0ef41Sopenharmony_ci 281cb0ef41Sopenharmony_ciclass V8CachedObject 291cb0ef41Sopenharmony_ci : public WRL::RuntimeClass< 301cb0ef41Sopenharmony_ci WRL::RuntimeClassFlags<WRL::RuntimeClassType::ClassicCom>, 311cb0ef41Sopenharmony_ci IV8CachedObject> { 321cb0ef41Sopenharmony_ci public: 331cb0ef41Sopenharmony_ci V8CachedObject(Location location, std::string uncompressed_type_name, 341cb0ef41Sopenharmony_ci WRL::ComPtr<IDebugHostContext> context, bool is_compressed); 351cb0ef41Sopenharmony_ci V8CachedObject(V8HeapObject heap_object); 361cb0ef41Sopenharmony_ci ~V8CachedObject() override; 371cb0ef41Sopenharmony_ci 381cb0ef41Sopenharmony_ci static HRESULT Create(IModelObject* p_v8_object_instance, 391cb0ef41Sopenharmony_ci IV8CachedObject** result); 401cb0ef41Sopenharmony_ci 411cb0ef41Sopenharmony_ci IFACEMETHOD(GetCachedV8HeapObject)(V8HeapObject** pp_heap_object); 421cb0ef41Sopenharmony_ci 431cb0ef41Sopenharmony_ci private: 441cb0ef41Sopenharmony_ci // The properties and description of the object, if already read. 451cb0ef41Sopenharmony_ci V8HeapObject heap_object_; 461cb0ef41Sopenharmony_ci bool heap_object_initialized_ = false; 471cb0ef41Sopenharmony_ci 481cb0ef41Sopenharmony_ci // Data that is necessary for reading the object. 491cb0ef41Sopenharmony_ci Location location_; 501cb0ef41Sopenharmony_ci std::string uncompressed_type_name_; 511cb0ef41Sopenharmony_ci WRL::ComPtr<IDebugHostContext> context_; 521cb0ef41Sopenharmony_ci bool is_compressed_ = false; 531cb0ef41Sopenharmony_ci}; 541cb0ef41Sopenharmony_ci 551cb0ef41Sopenharmony_ci// A simple COM wrapper class to hold data required for IndexedFieldParent. 561cb0ef41Sopenharmony_ci// (Needs to implement IUnknown). 571cb0ef41Sopenharmony_ciclass __declspec(uuid("6392E072-37BB-4220-A5FF-114098923A03")) IIndexedFieldData 581cb0ef41Sopenharmony_ci : public IUnknown { 591cb0ef41Sopenharmony_ci public: 601cb0ef41Sopenharmony_ci // Get a pointer to the Property object held by this IIndexedFieldData. The 611cb0ef41Sopenharmony_ci // pointer returned in this way is valid only while the containing 621cb0ef41Sopenharmony_ci // IIndexedFieldData is alive. 631cb0ef41Sopenharmony_ci virtual HRESULT __stdcall GetProperty(Property** property) = 0; 641cb0ef41Sopenharmony_ci}; 651cb0ef41Sopenharmony_ci 661cb0ef41Sopenharmony_ciclass IndexedFieldData 671cb0ef41Sopenharmony_ci : public WRL::RuntimeClass< 681cb0ef41Sopenharmony_ci WRL::RuntimeClassFlags<WRL::RuntimeClassType::ClassicCom>, 691cb0ef41Sopenharmony_ci IIndexedFieldData> { 701cb0ef41Sopenharmony_ci public: 711cb0ef41Sopenharmony_ci IndexedFieldData(Property property); 721cb0ef41Sopenharmony_ci ~IndexedFieldData() override; 731cb0ef41Sopenharmony_ci 741cb0ef41Sopenharmony_ci // Get a pointer to the Property object held by this IndexedFieldData. The 751cb0ef41Sopenharmony_ci // pointer returned in this way is valid only while the containing 761cb0ef41Sopenharmony_ci // IndexedFieldData is alive. 771cb0ef41Sopenharmony_ci IFACEMETHOD(GetProperty)(Property** property); 781cb0ef41Sopenharmony_ci 791cb0ef41Sopenharmony_ci private: 801cb0ef41Sopenharmony_ci Property property_; 811cb0ef41Sopenharmony_ci}; 821cb0ef41Sopenharmony_ci 831cb0ef41Sopenharmony_ci// A parent model that provides indexing support for fields that contain arrays 841cb0ef41Sopenharmony_ci// of something more complicated than basic native types. 851cb0ef41Sopenharmony_ciclass IndexedFieldParent 861cb0ef41Sopenharmony_ci : public WRL::RuntimeClass< 871cb0ef41Sopenharmony_ci WRL::RuntimeClassFlags<WRL::RuntimeClassType::ClassicCom>, 881cb0ef41Sopenharmony_ci IDataModelConcept, IIterableConcept, IIndexableConcept> { 891cb0ef41Sopenharmony_ci public: 901cb0ef41Sopenharmony_ci // IDataModelConcept 911cb0ef41Sopenharmony_ci IFACEMETHOD(InitializeObject) 921cb0ef41Sopenharmony_ci (IModelObject* model_object, IDebugHostTypeSignature* matching_type_signature, 931cb0ef41Sopenharmony_ci IDebugHostSymbolEnumerator* wildcard_matches); 941cb0ef41Sopenharmony_ci 951cb0ef41Sopenharmony_ci // IDataModelConcept 961cb0ef41Sopenharmony_ci IFACEMETHOD(GetName)(BSTR* model_name); 971cb0ef41Sopenharmony_ci 981cb0ef41Sopenharmony_ci // IIndexableConcept 991cb0ef41Sopenharmony_ci IFACEMETHOD(GetAt) 1001cb0ef41Sopenharmony_ci (IModelObject* context_object, ULONG64 indexer_count, IModelObject** indexers, 1011cb0ef41Sopenharmony_ci _COM_Errorptr_ IModelObject** object, IKeyStore** metadata); 1021cb0ef41Sopenharmony_ci 1031cb0ef41Sopenharmony_ci // IIndexableConcept 1041cb0ef41Sopenharmony_ci IFACEMETHOD(GetDimensionality) 1051cb0ef41Sopenharmony_ci (IModelObject* context_object, ULONG64* dimensionality); 1061cb0ef41Sopenharmony_ci 1071cb0ef41Sopenharmony_ci // IIndexableConcept 1081cb0ef41Sopenharmony_ci IFACEMETHOD(SetAt) 1091cb0ef41Sopenharmony_ci (IModelObject* context_object, ULONG64 indexer_count, IModelObject** indexers, 1101cb0ef41Sopenharmony_ci IModelObject* value); 1111cb0ef41Sopenharmony_ci 1121cb0ef41Sopenharmony_ci // IIterableConcept 1131cb0ef41Sopenharmony_ci IFACEMETHOD(GetDefaultIndexDimensionality) 1141cb0ef41Sopenharmony_ci (IModelObject* context_object, ULONG64* dimensionality); 1151cb0ef41Sopenharmony_ci 1161cb0ef41Sopenharmony_ci // IIterableConcept 1171cb0ef41Sopenharmony_ci IFACEMETHOD(GetIterator) 1181cb0ef41Sopenharmony_ci (IModelObject* context_object, IModelIterator** iterator); 1191cb0ef41Sopenharmony_ci}; 1201cb0ef41Sopenharmony_ci 1211cb0ef41Sopenharmony_ci// An iterator for the values within an array field. 1221cb0ef41Sopenharmony_ciclass IndexedFieldIterator 1231cb0ef41Sopenharmony_ci : public WRL::RuntimeClass< 1241cb0ef41Sopenharmony_ci WRL::RuntimeClassFlags<WRL::RuntimeClassType::ClassicCom>, 1251cb0ef41Sopenharmony_ci IModelIterator> { 1261cb0ef41Sopenharmony_ci public: 1271cb0ef41Sopenharmony_ci IndexedFieldIterator(IModelObject* context_object); 1281cb0ef41Sopenharmony_ci ~IndexedFieldIterator() override; 1291cb0ef41Sopenharmony_ci 1301cb0ef41Sopenharmony_ci IFACEMETHOD(Reset)(); 1311cb0ef41Sopenharmony_ci 1321cb0ef41Sopenharmony_ci IFACEMETHOD(GetNext) 1331cb0ef41Sopenharmony_ci (IModelObject** object, ULONG64 dimensions, IModelObject** indexers, 1341cb0ef41Sopenharmony_ci IKeyStore** metadata); 1351cb0ef41Sopenharmony_ci 1361cb0ef41Sopenharmony_ci private: 1371cb0ef41Sopenharmony_ci size_t next_ = 0; 1381cb0ef41Sopenharmony_ci WRL::ComPtr<IModelObject> context_object_; 1391cb0ef41Sopenharmony_ci}; 1401cb0ef41Sopenharmony_ci 1411cb0ef41Sopenharmony_ci// Enumerates the names of fields on V8 objects. 1421cb0ef41Sopenharmony_ciclass V8ObjectKeyEnumerator 1431cb0ef41Sopenharmony_ci : public WRL::RuntimeClass< 1441cb0ef41Sopenharmony_ci WRL::RuntimeClassFlags<WRL::RuntimeClassType::ClassicCom>, 1451cb0ef41Sopenharmony_ci IKeyEnumerator> { 1461cb0ef41Sopenharmony_ci public: 1471cb0ef41Sopenharmony_ci V8ObjectKeyEnumerator(WRL::ComPtr<IV8CachedObject>& v8_cached_object); 1481cb0ef41Sopenharmony_ci ~V8ObjectKeyEnumerator() override; 1491cb0ef41Sopenharmony_ci 1501cb0ef41Sopenharmony_ci IFACEMETHOD(Reset)(); 1511cb0ef41Sopenharmony_ci 1521cb0ef41Sopenharmony_ci // This method will be called with a nullptr 'value' for each key if returned 1531cb0ef41Sopenharmony_ci // from an IDynamicKeyProviderConcept. It will call GetKey on the 1541cb0ef41Sopenharmony_ci // IDynamicKeyProviderConcept interface after each key returned. 1551cb0ef41Sopenharmony_ci IFACEMETHOD(GetNext)(BSTR* key, IModelObject** value, IKeyStore** metadata); 1561cb0ef41Sopenharmony_ci 1571cb0ef41Sopenharmony_ci private: 1581cb0ef41Sopenharmony_ci int index_ = 0; 1591cb0ef41Sopenharmony_ci WRL::ComPtr<IV8CachedObject> sp_v8_cached_object_; 1601cb0ef41Sopenharmony_ci}; 1611cb0ef41Sopenharmony_ci 1621cb0ef41Sopenharmony_ci// A parent model for V8 handle types such as v8::internal::Handle<*>. 1631cb0ef41Sopenharmony_ciclass V8LocalDataModel 1641cb0ef41Sopenharmony_ci : public WRL::RuntimeClass< 1651cb0ef41Sopenharmony_ci WRL::RuntimeClassFlags<WRL::RuntimeClassType::ClassicCom>, 1661cb0ef41Sopenharmony_ci IDataModelConcept> { 1671cb0ef41Sopenharmony_ci public: 1681cb0ef41Sopenharmony_ci IFACEMETHOD(InitializeObject) 1691cb0ef41Sopenharmony_ci (IModelObject* model_object, IDebugHostTypeSignature* matching_type_signature, 1701cb0ef41Sopenharmony_ci IDebugHostSymbolEnumerator* wildcard_matches); 1711cb0ef41Sopenharmony_ci 1721cb0ef41Sopenharmony_ci IFACEMETHOD(GetName)(BSTR* model_name); 1731cb0ef41Sopenharmony_ci}; 1741cb0ef41Sopenharmony_ci 1751cb0ef41Sopenharmony_ci// A parent model for V8 object types such as v8::internal::Object. 1761cb0ef41Sopenharmony_ciclass V8ObjectDataModel 1771cb0ef41Sopenharmony_ci : public WRL::RuntimeClass< 1781cb0ef41Sopenharmony_ci WRL::RuntimeClassFlags<WRL::RuntimeClassType::ClassicCom>, 1791cb0ef41Sopenharmony_ci IDataModelConcept, IStringDisplayableConcept, 1801cb0ef41Sopenharmony_ci IDynamicKeyProviderConcept> { 1811cb0ef41Sopenharmony_ci public: 1821cb0ef41Sopenharmony_ci HRESULT GetCachedObject(IModelObject* context_object, 1831cb0ef41Sopenharmony_ci IV8CachedObject** result) { 1841cb0ef41Sopenharmony_ci // Get the IModelObject for this parent object. As it is a dynamic provider, 1851cb0ef41Sopenharmony_ci // there is only one parent directly on the object. 1861cb0ef41Sopenharmony_ci WRL::ComPtr<IModelObject> sp_parent_model, sp_context_adjuster; 1871cb0ef41Sopenharmony_ci RETURN_IF_FAIL(context_object->GetParentModel(0, &sp_parent_model, 1881cb0ef41Sopenharmony_ci &sp_context_adjuster)); 1891cb0ef41Sopenharmony_ci 1901cb0ef41Sopenharmony_ci // See if the cached object is already present 1911cb0ef41Sopenharmony_ci WRL::ComPtr<IUnknown> sp_context; 1921cb0ef41Sopenharmony_ci HRESULT hr = context_object->GetContextForDataModel(sp_parent_model.Get(), 1931cb0ef41Sopenharmony_ci &sp_context); 1941cb0ef41Sopenharmony_ci 1951cb0ef41Sopenharmony_ci WRL::ComPtr<IV8CachedObject> sp_v8_cached_object; 1961cb0ef41Sopenharmony_ci 1971cb0ef41Sopenharmony_ci if (SUCCEEDED(hr)) { 1981cb0ef41Sopenharmony_ci RETURN_IF_FAIL(sp_context.As(&sp_v8_cached_object)); 1991cb0ef41Sopenharmony_ci } else { 2001cb0ef41Sopenharmony_ci RETURN_IF_FAIL( 2011cb0ef41Sopenharmony_ci V8CachedObject::Create(context_object, &sp_v8_cached_object)); 2021cb0ef41Sopenharmony_ci RETURN_IF_FAIL(sp_v8_cached_object.As(&sp_context)); 2031cb0ef41Sopenharmony_ci RETURN_IF_FAIL(context_object->SetContextForDataModel( 2041cb0ef41Sopenharmony_ci sp_parent_model.Get(), sp_context.Get())); 2051cb0ef41Sopenharmony_ci } 2061cb0ef41Sopenharmony_ci 2071cb0ef41Sopenharmony_ci *result = sp_v8_cached_object.Detach(); 2081cb0ef41Sopenharmony_ci return S_OK; 2091cb0ef41Sopenharmony_ci } 2101cb0ef41Sopenharmony_ci 2111cb0ef41Sopenharmony_ci IFACEMETHOD(InitializeObject) 2121cb0ef41Sopenharmony_ci (IModelObject* model_object, IDebugHostTypeSignature* matching_type_signature, 2131cb0ef41Sopenharmony_ci IDebugHostSymbolEnumerator* wildcard_matches); 2141cb0ef41Sopenharmony_ci 2151cb0ef41Sopenharmony_ci IFACEMETHOD(GetName)(BSTR* model_name); 2161cb0ef41Sopenharmony_ci 2171cb0ef41Sopenharmony_ci IFACEMETHOD(ToDisplayString) 2181cb0ef41Sopenharmony_ci (IModelObject* context_object, IKeyStore* metadata, BSTR* display_string); 2191cb0ef41Sopenharmony_ci 2201cb0ef41Sopenharmony_ci // IDynamicKeyProviderConcept 2211cb0ef41Sopenharmony_ci IFACEMETHOD(GetKey) 2221cb0ef41Sopenharmony_ci (IModelObject* context_object, PCWSTR key, IModelObject** key_value, 2231cb0ef41Sopenharmony_ci IKeyStore** metadata, bool* has_key); 2241cb0ef41Sopenharmony_ci 2251cb0ef41Sopenharmony_ci IFACEMETHOD(SetKey) 2261cb0ef41Sopenharmony_ci (IModelObject* context_object, PCWSTR key, IModelObject* key_value, 2271cb0ef41Sopenharmony_ci IKeyStore* metadata); 2281cb0ef41Sopenharmony_ci 2291cb0ef41Sopenharmony_ci IFACEMETHOD(EnumerateKeys) 2301cb0ef41Sopenharmony_ci (IModelObject* context_object, IKeyEnumerator** pp_enumerator); 2311cb0ef41Sopenharmony_ci}; 2321cb0ef41Sopenharmony_ci 2331cb0ef41Sopenharmony_ci// The implemention of the "Value" getter for V8 handle types. 2341cb0ef41Sopenharmony_ciclass V8LocalValueProperty 2351cb0ef41Sopenharmony_ci : public WRL::RuntimeClass< 2361cb0ef41Sopenharmony_ci WRL::RuntimeClassFlags<WRL::RuntimeClassType::ClassicCom>, 2371cb0ef41Sopenharmony_ci IModelPropertyAccessor> { 2381cb0ef41Sopenharmony_ci public: 2391cb0ef41Sopenharmony_ci IFACEMETHOD(GetValue) 2401cb0ef41Sopenharmony_ci (PCWSTR pwsz_key, IModelObject* p_v8_object_instance, 2411cb0ef41Sopenharmony_ci IModelObject** pp_value); 2421cb0ef41Sopenharmony_ci 2431cb0ef41Sopenharmony_ci IFACEMETHOD(SetValue) 2441cb0ef41Sopenharmony_ci (PCWSTR /*pwsz_key*/, IModelObject* /*p_process_instance*/, 2451cb0ef41Sopenharmony_ci IModelObject* /*p_value*/); 2461cb0ef41Sopenharmony_ci}; 2471cb0ef41Sopenharmony_ci 2481cb0ef41Sopenharmony_ci// The implemention of the "NodeId" getter for v8::internal::compiler::Node 2491cb0ef41Sopenharmony_ci// type. 2501cb0ef41Sopenharmony_ciclass V8InternalCompilerNodeIdProperty 2511cb0ef41Sopenharmony_ci : public WRL::RuntimeClass< 2521cb0ef41Sopenharmony_ci WRL::RuntimeClassFlags<WRL::RuntimeClassType::ClassicCom>, 2531cb0ef41Sopenharmony_ci IModelPropertyAccessor> { 2541cb0ef41Sopenharmony_ci public: 2551cb0ef41Sopenharmony_ci IFACEMETHOD(GetValue) 2561cb0ef41Sopenharmony_ci (PCWSTR pwsz_key, IModelObject* p_v8_object_instance, 2571cb0ef41Sopenharmony_ci IModelObject** pp_value); 2581cb0ef41Sopenharmony_ci 2591cb0ef41Sopenharmony_ci IFACEMETHOD(SetValue) 2601cb0ef41Sopenharmony_ci (PCWSTR /*pwsz_key*/, IModelObject* /*p_process_instance*/, 2611cb0ef41Sopenharmony_ci IModelObject* /*p_value*/); 2621cb0ef41Sopenharmony_ci}; 2631cb0ef41Sopenharmony_ci 2641cb0ef41Sopenharmony_ci// The implemention of the "bitset_name" getter for v8::internal::compiler::Type 2651cb0ef41Sopenharmony_ci// type. 2661cb0ef41Sopenharmony_ciclass V8InternalCompilerBitsetNameProperty 2671cb0ef41Sopenharmony_ci : public WRL::RuntimeClass< 2681cb0ef41Sopenharmony_ci WRL::RuntimeClassFlags<WRL::RuntimeClassType::ClassicCom>, 2691cb0ef41Sopenharmony_ci IModelPropertyAccessor> { 2701cb0ef41Sopenharmony_ci public: 2711cb0ef41Sopenharmony_ci IFACEMETHOD(GetValue) 2721cb0ef41Sopenharmony_ci (PCWSTR pwsz_key, IModelObject* p_v8_compiler_type_instance, 2731cb0ef41Sopenharmony_ci IModelObject** pp_value); 2741cb0ef41Sopenharmony_ci 2751cb0ef41Sopenharmony_ci IFACEMETHOD(SetValue) 2761cb0ef41Sopenharmony_ci (PCWSTR /*pwsz_key*/, IModelObject* /*p_process_instance*/, 2771cb0ef41Sopenharmony_ci IModelObject* /*p_value*/); 2781cb0ef41Sopenharmony_ci}; 2791cb0ef41Sopenharmony_ci 2801cb0ef41Sopenharmony_ci// A way that someone can directly inspect a tagged value, even if that value 2811cb0ef41Sopenharmony_ci// isn't in memory (from a register, or the user's imagination, etc.). 2821cb0ef41Sopenharmony_ciclass InspectV8ObjectMethod 2831cb0ef41Sopenharmony_ci : public WRL::RuntimeClass< 2841cb0ef41Sopenharmony_ci WRL::RuntimeClassFlags<WRL::RuntimeClassType::ClassicCom>, 2851cb0ef41Sopenharmony_ci IModelMethod> { 2861cb0ef41Sopenharmony_ci public: 2871cb0ef41Sopenharmony_ci IFACEMETHOD(Call) 2881cb0ef41Sopenharmony_ci (IModelObject* p_context_object, ULONG64 arg_count, 2891cb0ef41Sopenharmony_ci _In_reads_(arg_count) IModelObject** pp_arguments, IModelObject** pp_result, 2901cb0ef41Sopenharmony_ci IKeyStore** pp_metadata); 2911cb0ef41Sopenharmony_ci}; 2921cb0ef41Sopenharmony_ci 2931cb0ef41Sopenharmony_ciHRESULT GetModelForProperty(const Property& prop, 2941cb0ef41Sopenharmony_ci WRL::ComPtr<IDebugHostContext>& sp_ctx, 2951cb0ef41Sopenharmony_ci IModelObject** result); 2961cb0ef41Sopenharmony_ci 2971cb0ef41Sopenharmony_ci#endif // V8_TOOLS_V8WINDBG_SRC_OBJECT_INSPECTION_H_ 298