summaryrefslogtreecommitdiff
path: root/tools/standalone_miri/value.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'tools/standalone_miri/value.hpp')
-rw-r--r--tools/standalone_miri/value.hpp72
1 files changed, 69 insertions, 3 deletions
diff --git a/tools/standalone_miri/value.hpp b/tools/standalone_miri/value.hpp
index 65403a81..9f9e68f4 100644
--- a/tools/standalone_miri/value.hpp
+++ b/tools/standalone_miri/value.hpp
@@ -6,33 +6,95 @@
#include <vector>
#include <memory>
#include <cstdint>
+#include <cassert>
namespace HIR {
struct TypeRef;
+ struct Path;
}
class Allocation;
+
class AllocationPtr
{
friend class Allocation;
- Allocation* m_ptr;
+ void* m_ptr;
+public:
+
+ enum class Ty
+ {
+ Allocation,
+ Function, // m_ptr is a pointer to the function.
+ Unused1,
+ Unused2,
+ };
+
+private:
+ AllocationPtr(Allocation* p):
+ m_ptr(p)
+ {
+ }
public:
AllocationPtr(): m_ptr(nullptr) {}
+ AllocationPtr(AllocationPtr&& x): m_ptr(x.m_ptr) {
+ x.m_ptr = nullptr;
+ }
+ AllocationPtr(const AllocationPtr& x);
+ ~AllocationPtr();
+ static AllocationPtr new_fcn(::HIR::Path p);
+
+ AllocationPtr& operator=(AllocationPtr&& x) {
+ this->~AllocationPtr();
+ this->m_ptr = x.m_ptr;
+ x.m_ptr = nullptr;
+ return *this;
+ }
operator bool() const { return m_ptr != 0; }
- Allocation& operator*() { return *m_ptr; }
- Allocation* operator->() { return m_ptr; }
+ bool is_alloc() {
+ return *this && get_ty() == Ty::Allocation;
+ }
+ Allocation& alloc() {
+ assert(get_ty() == Ty::Allocation);
+ return *static_cast<Allocation*>(get_ptr());
+ }
+ const Allocation& alloc() const {
+ assert(get_ty() == Ty::Allocation);
+ return *static_cast<Allocation*>(get_ptr());
+ }
+ const ::HIR::Path& fcn() const {
+ assert(get_ty() == Ty::Function);
+ return *static_cast<const ::HIR::Path*>(get_ptr());
+ }
+
+ Ty get_ty() const {
+ return static_cast<Ty>( reinterpret_cast<uintptr_t>(m_ptr) & 3 );
+ }
+private:
+ void* get_ptr() const {
+ return reinterpret_cast<void*>( reinterpret_cast<uintptr_t>(m_ptr) & ~3 );
+ }
};
struct Relocation
{
+ // Offset within parent allocation where this relocation is performed.
+ // TODO: Size?
size_t slot_ofs;
AllocationPtr backing_alloc;
};
class Allocation
{
+ friend class AllocationPtr;
size_t refcount;
+ // TODO: Read-only flag?
public:
+ static AllocationPtr new_alloc(size_t size);
+
+ const uint8_t* data_ptr() const { return reinterpret_cast<const uint8_t*>(this->data.data()); }
+ uint8_t* data_ptr() { return reinterpret_cast< uint8_t*>(this->data.data()); }
+
::std::vector<uint64_t> data;
+ ::std::vector<uint8_t> mask;
::std::vector<Relocation> relocations;
};
@@ -54,6 +116,7 @@ struct Value
Value();
Value(::HIR::TypeRef ty);
+ static Value new_fnptr(const ::HIR::Path& fn_path);
void check_bytes_valid(size_t ofs, size_t size) const;
void mark_bytes_valid(size_t ofs, size_t size);
@@ -65,5 +128,8 @@ struct Value
void write_bytes(size_t ofs, const void* src, size_t count);
size_t as_usize() const;
+private:
+ const uint8_t* data_ptr() const { return allocation ? allocation.alloc().data_ptr() + meta.indirect_meta.offset : meta.direct_data.data; }
+ uint8_t* data_ptr() { return allocation ? allocation.alloc().data_ptr() + meta.indirect_meta.offset : meta.direct_data.data; }
};
extern ::std::ostream& operator<<(::std::ostream& os, const Value& v);