1// Copyright 2020 the V8 project authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef V8_TOOLS_V8WINDBG_SRC_V8WINDBG_EXTENSION_H_
6#define V8_TOOLS_V8WINDBG_SRC_V8WINDBG_EXTENSION_H_
7
8#include <memory>
9#include <unordered_map>
10#include <vector>
11
12#include "tools/v8windbg/base/utilities.h"
13
14// Responsible for initializing and uninitializing the extension. Also provides
15// various convenience functions.
16class Extension {
17 public:
18  Extension();
19  HRESULT Initialize();
20  ~Extension();
21  WRL::ComPtr<IDebugHostModule> GetV8Module(
22      WRL::ComPtr<IDebugHostContext>& sp_ctx);
23  WRL::ComPtr<IDebugHostType> GetTypeFromV8Module(
24      WRL::ComPtr<IDebugHostContext>& sp_ctx, const char16_t* type_name);
25  WRL::ComPtr<IDebugHostType> GetV8ObjectType(
26      WRL::ComPtr<IDebugHostContext>& sp_ctx);
27  void TryRegisterType(WRL::ComPtr<IDebugHostType>& sp_type,
28                       std::u16string type_name);
29  bool DoesTypeDeriveFromObject(const WRL::ComPtr<IDebugHostType>& sp_type);
30  static Extension* Current() { return current_extension_.get(); }
31  static void SetExtension(std::unique_ptr<Extension> new_extension) {
32    current_extension_ = std::move(new_extension);
33  }
34
35  // Returns the parent model for instances of v8::internal::Object and similar
36  // classes, which contain as their first and only field a tagged V8 value.
37  IModelObject* GetObjectDataModel() { return sp_object_data_model_.Get(); }
38
39  // Returns the parent model that provides indexing support for fields that
40  // contain arrays of something more complicated than basic native types.
41  IModelObject* GetIndexedFieldDataModel() {
42    return sp_indexed_field_model_.Get();
43  }
44
45 private:
46  HRESULT OverrideLocalsGetter(IModelObject* parent, const wchar_t* key_name,
47                               bool is_parameters);
48
49  template <class PropertyClass>
50  HRESULT RegisterAndAddPropertyForClass(
51      const wchar_t* class_name, const wchar_t* property_name,
52      WRL::ComPtr<IModelObject> sp_data_model);
53
54  // A property that has been overridden by this extension. The original value
55  // must be put back in place during ~Extension.
56  struct PropertyOverride {
57    PropertyOverride();
58    PropertyOverride(IModelObject* parent, std::u16string key_name,
59                     IModelObject* original_value,
60                     IKeyStore* original_metadata);
61    ~PropertyOverride();
62    PropertyOverride(const PropertyOverride&);
63    PropertyOverride& operator=(const PropertyOverride&);
64    WRL::ComPtr<IModelObject> parent;
65    std::u16string key_name;
66    WRL::ComPtr<IModelObject> original_value;
67    WRL::ComPtr<IKeyStore> original_metadata;
68  };
69
70  struct RegistrationType {
71    RegistrationType();
72    RegistrationType(IDebugHostTypeSignature* sp_signature,
73                     IModelObject* sp_data_model);
74    ~RegistrationType();
75    RegistrationType(const RegistrationType&);
76    RegistrationType& operator=(const RegistrationType&);
77
78    WRL::ComPtr<IDebugHostTypeSignature> sp_signature;
79    WRL::ComPtr<IModelObject> sp_data_model;
80  };
81
82  static std::unique_ptr<Extension> current_extension_;
83
84  WRL::ComPtr<IModelObject> sp_object_data_model_;
85  WRL::ComPtr<IModelObject> sp_local_data_model_;
86  WRL::ComPtr<IModelObject> sp_compiler_node_data_model_;
87  WRL::ComPtr<IModelObject> sp_compiler_type_data_model_;
88  WRL::ComPtr<IModelObject> sp_indexed_field_model_;
89
90  WRL::ComPtr<IDebugHostModule> sp_v8_module_;
91  std::unordered_map<std::u16string, WRL::ComPtr<IDebugHostType>>
92      cached_v8_module_types_;
93  std::vector<RegistrationType> registered_types_;
94  std::vector<PropertyOverride> overridden_properties_;
95  WRL::ComPtr<IDebugHostContext> sp_v8_module_ctx_;
96  ULONG v8_module_proc_id_;
97};
98#endif  // V8_TOOLS_V8WINDBG_SRC_V8WINDBG_EXTENSION_H_
99