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