• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2019 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 // This file defines internal versions of the public API structs. These should
6 // all be tidy and simple classes which maintain proper ownership (unique_ptr)
7 // of each other. Each contains an instance of its corresponding public type,
8 // which can be filled out with GetPublicView.
9 
10 #ifndef V8_TOOLS_DEBUG_HELPER_DEBUG_HELPER_INTERNAL_H_
11 #define V8_TOOLS_DEBUG_HELPER_DEBUG_HELPER_INTERNAL_H_
12 
13 #include <memory>
14 #include <string>
15 #include <vector>
16 
17 #include "debug-helper.h"
18 #include "src/objects/instance-type.h"
19 
20 namespace d = v8::debug_helper;
21 
22 namespace v8 {
23 namespace internal {
24 namespace debug_helper_internal {
25 
26 // A value that was read from the debuggee's memory.
27 template <typename TValue>
28 struct Value {
29   d::MemoryAccessResult validity;
30   TValue value;
31 };
32 
33 // Internal version of API class v8::debug_helper::PropertyBase.
34 class PropertyBase {
35  public:
PropertyBase(std::string name,std::string type,std::string decompressed_type)36   PropertyBase(std::string name, std::string type,
37                std::string decompressed_type)
38       : name_(name), type_(type), decompressed_type_(decompressed_type) {}
SetFieldsOnPublicView(d::PropertyBase * public_view)39   void SetFieldsOnPublicView(d::PropertyBase* public_view) {
40     public_view->name = name_.c_str();
41     public_view->type = type_.c_str();
42     public_view->decompressed_type = decompressed_type_.c_str();
43   }
44 
45  private:
46   std::string name_;
47   std::string type_;
48   std::string decompressed_type_;
49 };
50 
51 // Internal version of API class v8::debug_helper::StructProperty.
52 class StructProperty : public PropertyBase {
53  public:
StructProperty(std::string name,std::string type,std::string decompressed_type,size_t offset,uint8_t num_bits,uint8_t shift_bits)54   StructProperty(std::string name, std::string type,
55                  std::string decompressed_type, size_t offset, uint8_t num_bits,
56                  uint8_t shift_bits)
57       : PropertyBase(std::move(name), std::move(type),
58                      std::move(decompressed_type)),
59         offset_(offset),
60         num_bits_(num_bits),
61         shift_bits_(shift_bits) {}
62 
GetPublicView()63   d::StructProperty* GetPublicView() {
64     PropertyBase::SetFieldsOnPublicView(&public_view_);
65     public_view_.offset = offset_;
66     public_view_.num_bits = num_bits_;
67     public_view_.shift_bits = shift_bits_;
68     return &public_view_;
69   }
70 
71  private:
72   size_t offset_;
73   uint8_t num_bits_;
74   uint8_t shift_bits_;
75 
76   d::StructProperty public_view_;
77 };
78 
79 // Internal version of API class v8::debug_helper::ObjectProperty.
80 class ObjectProperty : public PropertyBase {
81  public:
ObjectProperty(std::string name,std::string type,std::string decompressed_type,uintptr_t address,size_t num_values,size_t size,std::vector<std::unique_ptr<StructProperty>> struct_fields,d::PropertyKind kind)82   ObjectProperty(std::string name, std::string type,
83                  std::string decompressed_type, uintptr_t address,
84                  size_t num_values, size_t size,
85                  std::vector<std::unique_ptr<StructProperty>> struct_fields,
86                  d::PropertyKind kind)
87       : PropertyBase(std::move(name), std::move(type),
88                      std::move(decompressed_type)),
89         address_(address),
90         num_values_(num_values),
91         size_(size),
92         struct_fields_(std::move(struct_fields)),
93         kind_(kind) {}
94 
GetPublicView()95   d::ObjectProperty* GetPublicView() {
96     PropertyBase::SetFieldsOnPublicView(&public_view_);
97     public_view_.address = address_;
98     public_view_.num_values = num_values_;
99     public_view_.size = size_;
100     public_view_.num_struct_fields = struct_fields_.size();
101     struct_fields_raw_.clear();
102     for (const auto& property : struct_fields_) {
103       struct_fields_raw_.push_back(property->GetPublicView());
104     }
105     public_view_.struct_fields = struct_fields_raw_.data();
106     public_view_.kind = kind_;
107     return &public_view_;
108   }
109 
110  private:
111   uintptr_t address_;
112   size_t num_values_;
113   size_t size_;
114   std::vector<std::unique_ptr<StructProperty>> struct_fields_;
115   d::PropertyKind kind_;
116 
117   d::ObjectProperty public_view_;
118   std::vector<d::StructProperty*> struct_fields_raw_;
119 };
120 
121 class ObjectPropertiesResult;
122 struct ObjectPropertiesResultExtended : public d::ObjectPropertiesResult {
123   // Back reference for cleanup.
124   debug_helper_internal::ObjectPropertiesResult* base;
125 };
126 
127 // Internal version of API class v8::debug_helper::ObjectPropertiesResult.
128 class ObjectPropertiesResult {
129  public:
ObjectPropertiesResult(d::TypeCheckResult type_check_result,std::string brief,std::string type)130   ObjectPropertiesResult(d::TypeCheckResult type_check_result,
131                          std::string brief, std::string type)
132       : type_check_result_(type_check_result), brief_(brief), type_(type) {}
ObjectPropertiesResult(d::TypeCheckResult type_check_result,std::string brief,std::string type,std::vector<std::unique_ptr<ObjectProperty>> properties,std::vector<std::string> guessed_types)133   ObjectPropertiesResult(
134       d::TypeCheckResult type_check_result, std::string brief, std::string type,
135       std::vector<std::unique_ptr<ObjectProperty>> properties,
136       std::vector<std::string> guessed_types)
137       : ObjectPropertiesResult(type_check_result, brief, type) {
138     properties_ = std::move(properties);
139     guessed_types_ = std::move(guessed_types);
140   }
141 
Prepend(const char * prefix)142   void Prepend(const char* prefix) { brief_ = prefix + brief_; }
143 
GetPublicView()144   d::ObjectPropertiesResult* GetPublicView() {
145     public_view_.type_check_result = type_check_result_;
146     public_view_.brief = brief_.c_str();
147     public_view_.type = type_.c_str();
148     public_view_.num_properties = properties_.size();
149     properties_raw_.clear();
150     for (const auto& property : properties_) {
151       properties_raw_.push_back(property->GetPublicView());
152     }
153     public_view_.properties = properties_raw_.data();
154     public_view_.num_guessed_types = guessed_types_.size();
155     guessed_types_raw_.clear();
156     for (const auto& guess : guessed_types_) {
157       guessed_types_raw_.push_back(guess.c_str());
158     }
159     public_view_.guessed_types = guessed_types_raw_.data();
160     public_view_.base = this;
161     return &public_view_;
162   }
163 
164  private:
165   d::TypeCheckResult type_check_result_;
166   std::string brief_;
167   std::string type_;
168   std::vector<std::unique_ptr<ObjectProperty>> properties_;
169   std::vector<std::string> guessed_types_;
170 
171   ObjectPropertiesResultExtended public_view_;
172   std::vector<d::ObjectProperty*> properties_raw_;
173   std::vector<const char*> guessed_types_raw_;
174 };
175 
176 class StackFrameResult;
177 struct StackFrameResultExtended : public d::StackFrameResult {
178   // Back reference for cleanup.
179   debug_helper_internal::StackFrameResult* base;
180 };
181 
182 // Internal version of API class v8::debug_helper::StackFrameResult.
183 class StackFrameResult {
184  public:
StackFrameResult(std::vector<std::unique_ptr<ObjectProperty>> properties)185   StackFrameResult(std::vector<std::unique_ptr<ObjectProperty>> properties) {
186     properties_ = std::move(properties);
187   }
188 
GetPublicView()189   d::StackFrameResult* GetPublicView() {
190     public_view_.num_properties = properties_.size();
191     properties_raw_.clear();
192     for (const auto& property : properties_) {
193       properties_raw_.push_back(property->GetPublicView());
194     }
195     public_view_.properties = properties_raw_.data();
196     public_view_.base = this;
197     return &public_view_;
198   }
199 
200  private:
201   std::vector<std::unique_ptr<ObjectProperty>> properties_;
202 
203   StackFrameResultExtended public_view_;
204   std::vector<d::ObjectProperty*> properties_raw_;
205 };
206 
207 class TqObjectVisitor;
208 
209 // Base class representing a V8 object in the debuggee's address space.
210 // Subclasses for specific object types are generated by the Torque compiler.
211 class TqObject {
212  public:
TqObject(uintptr_t address)213   TqObject(uintptr_t address) : address_(address) {}
214   virtual ~TqObject() = default;
215   virtual std::vector<std::unique_ptr<ObjectProperty>> GetProperties(
216       d::MemoryAccessor accessor) const;
217   virtual const char* GetName() const;
218   virtual void Visit(TqObjectVisitor* visitor) const;
219   virtual bool IsSuperclassOf(const TqObject* other) const;
220 
221  protected:
222   uintptr_t address_;
223 };
224 
225 // A helpful template so that generated code can be sure that a string type name
226 // actually resolves to a type, by repeating the name as the template parameter
227 // and the value.
228 template <typename T>
CheckTypeName(const char * name)229 const char* CheckTypeName(const char* name) {
230   return name;
231 }
232 
233 // In ptr-compr builds, returns whether the address looks like a compressed
234 // pointer (zero-extended from 32 bits). Otherwise returns false because no
235 // pointers can be compressed.
236 bool IsPointerCompressed(uintptr_t address);
237 
238 // If the given address looks like a compressed pointer, returns a decompressed
239 // representation of it. Otherwise returns the address unmodified.
240 uintptr_t EnsureDecompressed(uintptr_t address,
241                              uintptr_t any_uncompressed_address);
242 
243 // Converts the MemoryAccessResult from attempting to read an array's length
244 // into the corresponding PropertyKind for the array.
245 d::PropertyKind GetArrayKind(d::MemoryAccessResult mem_result);
246 
247 // List of fully-qualified names for every Object subtype, generated based on
248 // Torque class definitions.
249 extern const d::ClassList kObjectClassList;
250 
251 }  // namespace debug_helper_internal
252 }  // namespace internal
253 }  // namespace v8
254 
255 #endif
256