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