ae8eb6c290
This change updates GetObjectProperties to list all of the bitfields within a class field, if that class field's type is a bitfield struct. The representation of bitfields in the GetObjectProperties response is very similar to the representation of struct fields, but with two extra bytes of data specifying the shift and size of the bitfield. Bug: v8:9376 Change-Id: I40a22169f3d01652a7f2db8cface43c2a1e30cfe Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1960835 Reviewed-by: Tobias Tebbi <tebbi@chromium.org> Commit-Queue: Seth Brenith <seth.brenith@microsoft.com> Cr-Commit-Position: refs/heads/master@{#65610}
213 lines
7.1 KiB
C++
213 lines
7.1 KiB
C++
// 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.
|
|
|
|
// 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.
|
|
|
|
#ifndef V8_TOOLS_DEBUG_HELPER_DEBUG_HELPER_INTERNAL_H_
|
|
#define V8_TOOLS_DEBUG_HELPER_DEBUG_HELPER_INTERNAL_H_
|
|
|
|
#include <memory>
|
|
#include <string>
|
|
#include <vector>
|
|
|
|
#include "debug-helper.h"
|
|
#include "src/objects/instance-type.h"
|
|
|
|
namespace d = v8::debug_helper;
|
|
|
|
namespace v8_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,
|
|
std::string decompressed_type)
|
|
: name_(name), type_(type), decompressed_type_(decompressed_type) {}
|
|
void SetFieldsOnPublicView(d::PropertyBase* public_view) {
|
|
public_view->name = name_.c_str();
|
|
public_view->type = type_.c_str();
|
|
public_view->decompressed_type = decompressed_type_.c_str();
|
|
}
|
|
|
|
private:
|
|
std::string name_;
|
|
std::string type_;
|
|
std::string decompressed_type_;
|
|
};
|
|
|
|
// Internal version of API class v8::debug_helper::StructProperty.
|
|
class StructProperty : public PropertyBase {
|
|
public:
|
|
StructProperty(std::string name, std::string type,
|
|
std::string decompressed_type, size_t offset, uint8_t num_bits,
|
|
uint8_t shift_bits)
|
|
: PropertyBase(std::move(name), std::move(type),
|
|
std::move(decompressed_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,
|
|
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)
|
|
: PropertyBase(std::move(name), std::move(type),
|
|
std::move(decompressed_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.
|
|
v8_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 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_;
|
|
};
|
|
|
|
// 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);
|
|
|
|
// List of fully-qualified names for every Object subtype, generated based on
|
|
// Torque class definitions.
|
|
extern const d::ClassList kObjectClassList;
|
|
|
|
} // namespace v8_debug_helper_internal
|
|
|
|
#endif
|