%PDF- <> %âãÏÓ endobj 2 0 obj <> endobj 3 0 obj <>/ExtGState<>/ProcSet[/PDF/Text/ImageB/ImageC/ImageI] >>/Annots[ 28 0 R 29 0 R] /MediaBox[ 0 0 595.5 842.25] /Contents 4 0 R/Group<>/Tabs/S>> endobj ºaâÚÎΞ-ÌE1ÍØÄ÷{òò2ÿ ÛÖ^ÔÀá TÎ{¦?§®¥kuµùÕ5sLOšuY>endobj 2 0 obj<>endobj 2 0 obj<>endobj 2 0 obj<>endobj 2 0 obj<> endobj 2 0 obj<>endobj 2 0 obj<>es 3 0 R>> endobj 2 0 obj<> ox[ 0.000000 0.000000 609.600000 935.600000]/Fi endobj 3 0 obj<> endobj 7 1 obj<>/ProcSet[/PDF/Text/ImageB/ImageC/ImageI]>>/Subtype/Form>> stream
// Copyright 2020 the V8 project authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #ifndef V8_TOOLS_V8WINDBG_SRC_OBJECT_INSPECTION_H_ #define V8_TOOLS_V8WINDBG_SRC_OBJECT_INSPECTION_H_ #include <comutil.h> #include <wrl/implements.h> #include <sstream> #include <string> #include <vector> #include "tools/v8windbg/base/dbgext.h" #include "tools/v8windbg/src/v8-debug-helper-interop.h" #include "tools/v8windbg/src/v8windbg-extension.h" // The representation of the underlying V8 object that will be cached on the // DataModel representation. (Needs to implement IUnknown). class __declspec(uuid("6392E072-37BB-4220-A5FF-114098923A02")) IV8CachedObject : public IUnknown { public: virtual HRESULT __stdcall GetCachedV8HeapObject( V8HeapObject** pp_heap_object) = 0; }; class V8CachedObject : public WRL::RuntimeClass< WRL::RuntimeClassFlags<WRL::RuntimeClassType::ClassicCom>, IV8CachedObject> { public: V8CachedObject(Location location, std::string uncompressed_type_name, WRL::ComPtr<IDebugHostContext> context, bool is_compressed); V8CachedObject(V8HeapObject heap_object); ~V8CachedObject() override; static HRESULT Create(IModelObject* p_v8_object_instance, IV8CachedObject** result); IFACEMETHOD(GetCachedV8HeapObject)(V8HeapObject** pp_heap_object); private: // The properties and description of the object, if already read. V8HeapObject heap_object_; bool heap_object_initialized_ = false; // Data that is necessary for reading the object. Location location_; std::string uncompressed_type_name_; WRL::ComPtr<IDebugHostContext> context_; bool is_compressed_ = false; }; // A simple COM wrapper class to hold data required for IndexedFieldParent. // (Needs to implement IUnknown). class __declspec(uuid("6392E072-37BB-4220-A5FF-114098923A03")) IIndexedFieldData : public IUnknown { public: // Get a pointer to the Property object held by this IIndexedFieldData. The // pointer returned in this way is valid only while the containing // IIndexedFieldData is alive. virtual HRESULT __stdcall GetProperty(Property** property) = 0; }; class IndexedFieldData : public WRL::RuntimeClass< WRL::RuntimeClassFlags<WRL::RuntimeClassType::ClassicCom>, IIndexedFieldData> { public: IndexedFieldData(Property property); ~IndexedFieldData() override; // Get a pointer to the Property object held by this IndexedFieldData. The // pointer returned in this way is valid only while the containing // IndexedFieldData is alive. IFACEMETHOD(GetProperty)(Property** property); private: Property property_; }; // A parent model that provides indexing support for fields that contain arrays // of something more complicated than basic native types. class IndexedFieldParent : public WRL::RuntimeClass< WRL::RuntimeClassFlags<WRL::RuntimeClassType::ClassicCom>, IDataModelConcept, IIterableConcept, IIndexableConcept> { public: // IDataModelConcept IFACEMETHOD(InitializeObject) (IModelObject* model_object, IDebugHostTypeSignature* matching_type_signature, IDebugHostSymbolEnumerator* wildcard_matches); // IDataModelConcept IFACEMETHOD(GetName)(BSTR* model_name); // IIndexableConcept IFACEMETHOD(GetAt) (IModelObject* context_object, ULONG64 indexer_count, IModelObject** indexers, _COM_Errorptr_ IModelObject** object, IKeyStore** metadata); // IIndexableConcept IFACEMETHOD(GetDimensionality) (IModelObject* context_object, ULONG64* dimensionality); // IIndexableConcept IFACEMETHOD(SetAt) (IModelObject* context_object, ULONG64 indexer_count, IModelObject** indexers, IModelObject* value); // IIterableConcept IFACEMETHOD(GetDefaultIndexDimensionality) (IModelObject* context_object, ULONG64* dimensionality); // IIterableConcept IFACEMETHOD(GetIterator) (IModelObject* context_object, IModelIterator** iterator); }; // An iterator for the values within an array field. class IndexedFieldIterator : public WRL::RuntimeClass< WRL::RuntimeClassFlags<WRL::RuntimeClassType::ClassicCom>, IModelIterator> { public: IndexedFieldIterator(IModelObject* context_object); ~IndexedFieldIterator() override; IFACEMETHOD(Reset)(); IFACEMETHOD(GetNext) (IModelObject** object, ULONG64 dimensions, IModelObject** indexers, IKeyStore** metadata); private: size_t next_ = 0; WRL::ComPtr<IModelObject> context_object_; }; // Enumerates the names of fields on V8 objects. class V8ObjectKeyEnumerator : public WRL::RuntimeClass< WRL::RuntimeClassFlags<WRL::RuntimeClassType::ClassicCom>, IKeyEnumerator> { public: V8ObjectKeyEnumerator(WRL::ComPtr<IV8CachedObject>& v8_cached_object); ~V8ObjectKeyEnumerator() override; IFACEMETHOD(Reset)(); // This method will be called with a nullptr 'value' for each key if returned // from an IDynamicKeyProviderConcept. It will call GetKey on the // IDynamicKeyProviderConcept interface after each key returned. IFACEMETHOD(GetNext)(BSTR* key, IModelObject** value, IKeyStore** metadata); private: int index_ = 0; WRL::ComPtr<IV8CachedObject> sp_v8_cached_object_; }; // A parent model for V8 handle types such as v8::internal::Handle<*>. class V8LocalDataModel : public WRL::RuntimeClass< WRL::RuntimeClassFlags<WRL::RuntimeClassType::ClassicCom>, IDataModelConcept> { public: IFACEMETHOD(InitializeObject) (IModelObject* model_object, IDebugHostTypeSignature* matching_type_signature, IDebugHostSymbolEnumerator* wildcard_matches); IFACEMETHOD(GetName)(BSTR* model_name); }; // A parent model for V8 object types such as v8::internal::Object. class V8ObjectDataModel : public WRL::RuntimeClass< WRL::RuntimeClassFlags<WRL::RuntimeClassType::ClassicCom>, IDataModelConcept, IStringDisplayableConcept, IDynamicKeyProviderConcept> { public: HRESULT GetCachedObject(IModelObject* context_object, IV8CachedObject** result) { // Get the IModelObject for this parent object. As it is a dynamic provider, // there is only one parent directly on the object. WRL::ComPtr<IModelObject> sp_parent_model, sp_context_adjuster; RETURN_IF_FAIL(context_object->GetParentModel(0, &sp_parent_model, &sp_context_adjuster)); // See if the cached object is already present WRL::ComPtr<IUnknown> sp_context; HRESULT hr = context_object->GetContextForDataModel(sp_parent_model.Get(), &sp_context); WRL::ComPtr<IV8CachedObject> sp_v8_cached_object; if (SUCCEEDED(hr)) { RETURN_IF_FAIL(sp_context.As(&sp_v8_cached_object)); } else { RETURN_IF_FAIL( V8CachedObject::Create(context_object, &sp_v8_cached_object)); RETURN_IF_FAIL(sp_v8_cached_object.As(&sp_context)); RETURN_IF_FAIL(context_object->SetContextForDataModel( sp_parent_model.Get(), sp_context.Get())); } *result = sp_v8_cached_object.Detach(); return S_OK; } IFACEMETHOD(InitializeObject) (IModelObject* model_object, IDebugHostTypeSignature* matching_type_signature, IDebugHostSymbolEnumerator* wildcard_matches); IFACEMETHOD(GetName)(BSTR* model_name); IFACEMETHOD(ToDisplayString) (IModelObject* context_object, IKeyStore* metadata, BSTR* display_string); // IDynamicKeyProviderConcept IFACEMETHOD(GetKey) (IModelObject* context_object, PCWSTR key, IModelObject** key_value, IKeyStore** metadata, bool* has_key); IFACEMETHOD(SetKey) (IModelObject* context_object, PCWSTR key, IModelObject* key_value, IKeyStore* metadata); IFACEMETHOD(EnumerateKeys) (IModelObject* context_object, IKeyEnumerator** pp_enumerator); }; // The implemention of the "Value" getter for V8 handle types. class V8LocalValueProperty : public WRL::RuntimeClass< WRL::RuntimeClassFlags<WRL::RuntimeClassType::ClassicCom>, IModelPropertyAccessor> { public: IFACEMETHOD(GetValue) (PCWSTR pwsz_key, IModelObject* p_v8_object_instance, IModelObject** pp_value); IFACEMETHOD(SetValue) (PCWSTR /*pwsz_key*/, IModelObject* /*p_process_instance*/, IModelObject* /*p_value*/); }; // The implemention of the "NodeId" getter for v8::internal::compiler::Node // type. class V8InternalCompilerNodeIdProperty : public WRL::RuntimeClass< WRL::RuntimeClassFlags<WRL::RuntimeClassType::ClassicCom>, IModelPropertyAccessor> { public: IFACEMETHOD(GetValue) (PCWSTR pwsz_key, IModelObject* p_v8_object_instance, IModelObject** pp_value); IFACEMETHOD(SetValue) (PCWSTR /*pwsz_key*/, IModelObject* /*p_process_instance*/, IModelObject* /*p_value*/); }; // The implemention of the "bitset_name" getter for v8::internal::compiler::Type // type. class V8InternalCompilerBitsetNameProperty : public WRL::RuntimeClass< WRL::RuntimeClassFlags<WRL::RuntimeClassType::ClassicCom>, IModelPropertyAccessor> { public: IFACEMETHOD(GetValue) (PCWSTR pwsz_key, IModelObject* p_v8_compiler_type_instance, IModelObject** pp_value); IFACEMETHOD(SetValue) (PCWSTR /*pwsz_key*/, IModelObject* /*p_process_instance*/, IModelObject* /*p_value*/); }; // A way that someone can directly inspect a tagged value, even if that value // isn't in memory (from a register, or the user's imagination, etc.). class InspectV8ObjectMethod : public WRL::RuntimeClass< WRL::RuntimeClassFlags<WRL::RuntimeClassType::ClassicCom>, IModelMethod> { public: IFACEMETHOD(Call) (IModelObject* p_context_object, ULONG64 arg_count, _In_reads_(arg_count) IModelObject** pp_arguments, IModelObject** pp_result, IKeyStore** pp_metadata); }; HRESULT GetModelForProperty(const Property& prop, WRL::ComPtr<IDebugHostContext>& sp_ctx, IModelObject** result); #endif // V8_TOOLS_V8WINDBG_SRC_OBJECT_INSPECTION_H_