summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--tools/standalone_miri/main.cpp94
-rw-r--r--tools/standalone_miri/module_tree.cpp6
-rw-r--r--tools/standalone_miri/value.cpp208
-rw-r--r--tools/standalone_miri/value.hpp190
4 files changed, 280 insertions, 218 deletions
diff --git a/tools/standalone_miri/main.cpp b/tools/standalone_miri/main.cpp
index 1ab5b955..cd521501 100644
--- a/tools/standalone_miri/main.cpp
+++ b/tools/standalone_miri/main.cpp
@@ -153,7 +153,7 @@ public:
virtual bool multiply(const PrimitiveValue& v) = 0;
virtual bool divide(const PrimitiveValue& v) = 0;
virtual bool modulo(const PrimitiveValue& v) = 0;
- virtual void write_to_value(ValueCommon& tgt, size_t ofs) const = 0;
+ virtual void write_to_value(ValueCommonWrite& tgt, size_t ofs) const = 0;
template<typename T>
const T& check(const char* opname) const
@@ -212,14 +212,14 @@ struct PrimitiveUInt:
struct PrimitiveU64: public PrimitiveUInt<uint64_t>
{
PrimitiveU64(uint64_t v): PrimitiveUInt(v) {}
- void write_to_value(ValueCommon& tgt, size_t ofs) const override {
+ void write_to_value(ValueCommonWrite& tgt, size_t ofs) const override {
tgt.write_u64(ofs, this->v);
}
};
struct PrimitiveU32: public PrimitiveUInt<uint32_t>
{
PrimitiveU32(uint32_t v): PrimitiveUInt(v) {}
- void write_to_value(ValueCommon& tgt, size_t ofs) const override {
+ void write_to_value(ValueCommonWrite& tgt, size_t ofs) const override {
tgt.write_u32(ofs, this->v);
}
};
@@ -273,14 +273,14 @@ struct PrimitiveSInt:
struct PrimitiveI64: public PrimitiveSInt<int64_t>
{
PrimitiveI64(int64_t v): PrimitiveSInt(v) {}
- void write_to_value(ValueCommon& tgt, size_t ofs) const override {
+ void write_to_value(ValueCommonWrite& tgt, size_t ofs) const override {
tgt.write_i64(ofs, this->v);
}
};
struct PrimitiveI32: public PrimitiveSInt<int32_t>
{
PrimitiveI32(int32_t v): PrimitiveSInt(v) {}
- void write_to_value(ValueCommon& tgt, size_t ofs) const override {
+ void write_to_value(ValueCommonWrite& tgt, size_t ofs) const override {
tgt.write_i32(ofs, this->v);
}
};
@@ -458,11 +458,8 @@ struct MirHelpers
size_t ofs = val.read_usize(0);
// There MUST be a relocation at this point with a valid allocation.
- auto& val_alloc = val.m_alloc ? val.m_alloc : val.m_value->allocation;
- LOG_ASSERT(val_alloc, "Deref of a value with no allocation (hence no relocations)");
- LOG_ASSERT(val_alloc.is_alloc(), "Deref of a value with a non-data allocation");
- LOG_TRACE("Deref " << val_alloc.alloc() << " + " << ofs << " to give value of type " << ty);
- auto alloc = val_alloc.alloc().get_relocation(val.m_offset);
+ auto alloc = val.get_relocation(val.m_offset);
+ LOG_TRACE("Deref " << alloc << " + " << ofs << " to give value of type " << ty);
// NOTE: No alloc can happen when dereferencing a zero-sized pointer
if( alloc.is_alloc() )
{
@@ -595,7 +592,7 @@ struct MirHelpers
Value val = Value(ty);
val.write_usize(0, 0);
val.write_usize(POINTER_SIZE, ce.size());
- val.allocation.alloc().relocations.push_back(Relocation { 0, AllocationPtr::new_string(&ce) });
+ val.allocation->relocations.push_back(Relocation { 0, RelocationPtr::new_string(&ce) });
LOG_DEBUG(c << " = " << val);
//return Value::new_dataptr(ce.data());
return val;
@@ -612,7 +609,7 @@ struct MirHelpers
ty.wrappers.push_back(TypeWrapper { TypeWrapper::Ty::Borrow, 0 });
Value val = Value(ty);
val.write_usize(0, 0);
- val.allocation.alloc().relocations.push_back(Relocation { 0, s->val.allocation });
+ val.allocation->relocations.push_back(Relocation { 0, RelocationPtr::new_alloc(s->val.allocation) });
return val;
}
LOG_ERROR("Constant::ItemAddr - " << ce << " - not found");
@@ -676,6 +673,7 @@ InterpreterThread::~InterpreterThread()
}
void InterpreterThread::start(const ::HIR::Path& p, ::std::vector<Value> args)
{
+ assert( this->m_stack.empty() );
Value v;
if( this->call_path(v, p, ::std::move(args)) )
{
@@ -720,7 +718,7 @@ bool InterpreterThread::step_one(Value& out_thread_result)
{
src_base_value.m_value->create_allocation();
}
- alloc = AllocationPtr(src_base_value.m_value->allocation);
+ alloc = RelocationPtr::new_alloc( src_base_value.m_value->allocation );
}
if( alloc.is_alloc() )
LOG_DEBUG("- alloc=" << alloc << " (" << alloc.alloc() << ")");
@@ -740,7 +738,7 @@ bool InterpreterThread::step_one(Value& out_thread_result)
new_val.write_value(POINTER_SIZE, *src_base_value.m_metadata);
}
// - Add the relocation after writing the value (writing clears the relocations)
- new_val.allocation.alloc().relocations.push_back(Relocation { 0, ::std::move(alloc) });
+ new_val.allocation->relocations.push_back(Relocation { 0, ::std::move(alloc) });
} break;
TU_ARM(se.src, Cast, re) {
// Determine the type of cast, is it a reinterpret or is it a value transform?
@@ -1073,8 +1071,8 @@ bool InterpreterThread::step_one(Value& out_thread_result)
const auto& alloc_l = v_l.m_value ? v_l.m_value->allocation : v_l.m_alloc;
const auto& alloc_r = v_r.m_value ? v_r.m_value->allocation : v_r.m_alloc;
- auto reloc_l = alloc_l ? v_l.get_relocation(v_l.m_offset) : AllocationPtr();
- auto reloc_r = alloc_r ? v_r.get_relocation(v_r.m_offset) : AllocationPtr();
+ auto reloc_l = alloc_l ? v_l.get_relocation(v_l.m_offset) : RelocationPtr();
+ auto reloc_r = alloc_r ? v_r.get_relocation(v_r.m_offset) : RelocationPtr();
if( reloc_l != reloc_r )
{
@@ -1109,8 +1107,8 @@ bool InterpreterThread::step_one(Value& out_thread_result)
// Compare fat metadata.
if( res == 0 && v_l.m_size > POINTER_SIZE )
{
- reloc_l = alloc_l ? alloc_l.alloc().get_relocation(POINTER_SIZE) : AllocationPtr();
- reloc_r = alloc_r ? alloc_r.alloc().get_relocation(POINTER_SIZE) : AllocationPtr();
+ reloc_l = v_l.get_relocation(POINTER_SIZE);
+ reloc_r = v_r.get_relocation(POINTER_SIZE);
if( res == 0 && reloc_l != reloc_r )
{
@@ -1427,7 +1425,7 @@ bool InterpreterThread::step_one(Value& out_thread_result)
{
v.m_value->create_allocation();
}
- alloc = AllocationPtr(v.m_value->allocation);
+ alloc = RelocationPtr::new_alloc( v.m_value->allocation );
}
size_t ofs = v.m_offset;
assert(ty.get_meta_type() == RawType::Unreachable);
@@ -1436,7 +1434,7 @@ bool InterpreterThread::step_one(Value& out_thread_result)
auto ptr_val = Value(ptr_ty);
ptr_val.write_usize(0, ofs);
- ptr_val.allocation.alloc().relocations.push_back(Relocation { 0, ::std::move(alloc) });
+ ptr_val.allocation->relocations.push_back(Relocation { 0, ::std::move(alloc) });
if( !drop_value(ptr_val, ty, /*shallow=*/se.kind == ::MIR::eDropKind::SHALLOW) )
{
@@ -1549,7 +1547,7 @@ bool InterpreterThread::step_one(Value& out_thread_result)
}
else
{
- AllocationPtr fcn_alloc_ptr;
+ RelocationPtr fcn_alloc_ptr;
const ::HIR::Path* fcn_p;
if( te.fcn.is_Path() ) {
fcn_p = &te.fcn.as_Path();
@@ -1561,12 +1559,10 @@ bool InterpreterThread::step_one(Value& out_thread_result)
// TODO: Assert type
// TODO: Assert offset/content.
assert(v.read_usize(0) == 0);
- auto& alloc_ptr = v.m_alloc ? v.m_alloc : v.m_value->allocation;
- LOG_ASSERT(alloc_ptr, "Calling value that can't be a pointer (no allocation)");
- fcn_alloc_ptr = alloc_ptr.alloc().get_relocation(v.m_offset);
+ fcn_alloc_ptr = v.get_relocation(v.m_offset);
if( !fcn_alloc_ptr )
LOG_FATAL("Calling value with no relocation - " << v);
- LOG_ASSERT(fcn_alloc_ptr.get_ty() == AllocationPtr::Ty::Function, "Calling value that isn't a function pointer");
+ LOG_ASSERT(fcn_alloc_ptr.get_ty() == RelocationPtr::Ty::Function, "Calling value that isn't a function pointer");
fcn_p = &fcn_alloc_ptr.fcn();
}
@@ -1717,12 +1713,12 @@ bool InterpreterThread::call_extern(Value& rv, const ::std::string& link_name, c
rv = Value(rty);
rv.write_usize(0, 0);
// TODO: Use the alignment when making an allocation?
- rv.allocation.alloc().relocations.push_back({ 0, Allocation::new_alloc(size) });
+ rv.allocation->relocations.push_back({ 0, RelocationPtr::new_alloc(Allocation::new_alloc(size)) });
}
else if( link_name == "__rust_reallocate" )
{
LOG_ASSERT(args.at(0).allocation, "__rust_reallocate first argument doesn't have an allocation");
- auto alloc_ptr = args.at(0).allocation.alloc().get_relocation(0);
+ auto alloc_ptr = args.at(0).get_relocation(0);
auto ptr_ofs = args.at(0).read_usize(0);
LOG_ASSERT(ptr_ofs == 0, "__rust_reallocate with offset pointer");
auto oldsize = args.at(1).read_usize(0);
@@ -1742,7 +1738,7 @@ bool InterpreterThread::call_extern(Value& rv, const ::std::string& link_name, c
else if( link_name == "__rust_deallocate" )
{
LOG_ASSERT(args.at(0).allocation, "__rust_deallocate first argument doesn't have an allocation");
- auto alloc_ptr = args.at(0).allocation.alloc().get_relocation(0);
+ auto alloc_ptr = args.at(0).get_relocation(0);
auto ptr_ofs = args.at(0).read_usize(0);
LOG_ASSERT(ptr_ofs == 0, "__rust_deallocate with offset pointer");
LOG_DEBUG("__rust_deallocate(ptr=" << alloc_ptr << ")");
@@ -1948,8 +1944,7 @@ bool InterpreterThread::call_extern(Value& rv, const ::std::string& link_name, c
// - `void *memchr(const void *s, int c, size_t n);`
else if( link_name == "memchr" )
{
- LOG_ASSERT(args.at(0).allocation.is_alloc(), "");
- auto ptr_alloc = args.at(0).allocation.alloc().get_relocation(0);
+ auto ptr_alloc = args.at(0).get_relocation(0);
auto c = args.at(1).read_i32(0);
auto n = args.at(2).read_usize(0);
const void* ptr = args.at(0).read_pointer_const(0, n);
@@ -1961,7 +1956,7 @@ bool InterpreterThread::call_extern(Value& rv, const ::std::string& link_name, c
if( ret )
{
rv.write_usize(0, args.at(0).read_usize(0) + ( static_cast<const uint8_t*>(ret) - static_cast<const uint8_t*>(ptr) ));
- rv.allocation.alloc().relocations.push_back({ 0, ptr_alloc });
+ rv.allocation->relocations.push_back({ 0, ptr_alloc });
}
else
{
@@ -1982,7 +1977,7 @@ bool InterpreterThread::call_extern(Value& rv, const ::std::string& link_name, c
if( ret )
{
rv.write_usize(0, args.at(0).read_usize(0) + ( static_cast<const uint8_t*>(ret) - static_cast<const uint8_t*>(ptr) ));
- rv.allocation.alloc().relocations.push_back({ 0, ptr_alloc });
+ rv.allocation->relocations.push_back({ 0, ptr_alloc });
}
else
{
@@ -2027,9 +2022,7 @@ bool InterpreterThread::call_intrinsic(Value& rv, const ::std::string& name, con
LOG_ASSERT(ptr_val.size() == POINTER_SIZE, "atomic_store of a value that isn't a pointer-sized value");
// There MUST be a relocation at this point with a valid allocation.
- LOG_ASSERT(ptr_val.allocation, "Deref of a value with no allocation (hence no relocations)");
- LOG_TRACE("Deref " << ptr_val.allocation.alloc());
- auto alloc = ptr_val.allocation.alloc().get_relocation(0);
+ auto alloc = ptr_val.get_relocation(0);
LOG_ASSERT(alloc, "Deref of a value with no relocation");
// TODO: Atomic side of this?
@@ -2042,9 +2035,7 @@ bool InterpreterThread::call_intrinsic(Value& rv, const ::std::string& name, con
LOG_ASSERT(ptr_val.size() == POINTER_SIZE, "atomic_store of a value that isn't a pointer-sized value");
// There MUST be a relocation at this point with a valid allocation.
- LOG_ASSERT(ptr_val.allocation, "Deref of a value with no allocation (hence no relocations)");
- LOG_TRACE("Deref " << ptr_val.allocation.alloc());
- auto alloc = ptr_val.allocation.alloc().get_relocation(0);
+ auto alloc = ptr_val.get_relocation(0);
LOG_ASSERT(alloc, "Deref of a value with no relocation");
// TODO: Atomic lock the allocation.
@@ -2057,7 +2048,7 @@ bool InterpreterThread::call_intrinsic(Value& rv, const ::std::string& name, con
{
const auto& ty_T = ty_params.tys.at(0);
auto ptr_ofs = args.at(0).read_usize(0);
- auto ptr_alloc = args.at(0).allocation.alloc().get_relocation(0);
+ auto ptr_alloc = args.at(0).get_relocation(0);
auto v = args.at(1).read_value(0, ty_T.get_size());
// TODO: Atomic lock the allocation.
@@ -2078,7 +2069,7 @@ bool InterpreterThread::call_intrinsic(Value& rv, const ::std::string& name, con
{
const auto& ty_T = ty_params.tys.at(0);
auto ptr_ofs = args.at(0).read_usize(0);
- auto ptr_alloc = args.at(0).allocation.alloc().get_relocation(0);
+ auto ptr_alloc = args.at(0).get_relocation(0);
auto v = args.at(1).read_value(0, ty_T.get_size());
// TODO: Atomic lock the allocation.
@@ -2146,7 +2137,7 @@ bool InterpreterThread::call_intrinsic(Value& rv, const ::std::string& name, con
rv = ::std::move(args.at(0));
rv.write_usize(0, new_ofs);
if( ptr_alloc ) {
- rv.allocation.alloc().relocations.push_back({ 0, ptr_alloc });
+ rv.allocation->relocations.push_back({ 0, ptr_alloc });
}
}
// effectively ptr::write
@@ -2160,12 +2151,13 @@ bool InterpreterThread::call_intrinsic(Value& rv, const ::std::string& name, con
// There MUST be a relocation at this point with a valid allocation.
LOG_ASSERT(ptr_val.allocation, "Deref of a value with no allocation (hence no relocations)");
LOG_TRACE("Deref " << ptr_val << " and store " << data_val);
- auto alloc = ptr_val.allocation.alloc().get_relocation(0);
- LOG_ASSERT(alloc, "Deref of a value with no relocation");
+
+ auto ptr_alloc = ptr_val.get_relocation(0);
+ LOG_ASSERT(ptr_alloc, "Deref of a value with no relocation");
size_t ofs = ptr_val.read_usize(0);
- alloc.alloc().write_value(ofs, ::std::move(data_val));
- LOG_DEBUG(alloc.alloc());
+ ptr_alloc.alloc().write_value(ofs, ::std::move(data_val));
+ LOG_DEBUG(ptr_alloc.alloc());
}
else if( name == "uninit" )
{
@@ -2330,9 +2322,9 @@ bool InterpreterThread::call_intrinsic(Value& rv, const ::std::string& name, con
else if( name == "copy_nonoverlapping" )
{
auto src_ofs = args.at(0).read_usize(0);
- auto src_alloc = args.at(0).allocation.alloc().get_relocation(0);
+ auto src_alloc = args.at(0).get_relocation(0);
auto dst_ofs = args.at(1).read_usize(0);
- auto dst_alloc = args.at(1).allocation.alloc().get_relocation(0);
+ auto dst_alloc = args.at(1).get_relocation(0);
size_t ent_count = args.at(2).read_usize(0);
size_t ent_size = ty_params.tys.at(0).get_size();
auto byte_count = ent_count * ent_size;
@@ -2343,21 +2335,21 @@ bool InterpreterThread::call_intrinsic(Value& rv, const ::std::string& name, con
switch(src_alloc.get_ty())
{
- case AllocationPtr::Ty::Allocation: {
+ case RelocationPtr::Ty::Allocation: {
auto v = src_alloc.alloc().read_value(src_ofs, byte_count);
LOG_DEBUG("v = " << v);
dst_alloc.alloc().write_value(dst_ofs, ::std::move(v));
} break;
- case AllocationPtr::Ty::StdString:
+ case RelocationPtr::Ty::StdString:
LOG_ASSERT(src_ofs <= src_alloc.str().size(), "");
LOG_ASSERT(byte_count <= src_alloc.str().size(), "");
LOG_ASSERT(src_ofs + byte_count <= src_alloc.str().size(), "");
dst_alloc.alloc().write_bytes(dst_ofs, src_alloc.str().data() + src_ofs, byte_count);
break;
- case AllocationPtr::Ty::Function:
+ case RelocationPtr::Ty::Function:
LOG_FATAL("Attempt to copy* a function");
break;
- case AllocationPtr::Ty::FfiPointer:
+ case RelocationPtr::Ty::FfiPointer:
LOG_BUG("Trying to copy from a FFI pointer");
break;
}
diff --git a/tools/standalone_miri/module_tree.cpp b/tools/standalone_miri/module_tree.cpp
index ad41b33a..6a7a0b5f 100644
--- a/tools/standalone_miri/module_tree.cpp
+++ b/tools/standalone_miri/module_tree.cpp
@@ -151,13 +151,13 @@ bool Parser::parse_one()
auto a = Allocation::new_alloc( reloc_str.size() );
//a.alloc().set_tag();
- a.alloc().write_bytes(0, reloc_str.data(), reloc_str.size());
- s.val.allocation.alloc().relocations.push_back({ ofs, ::std::move(a) });
+ a->write_bytes(0, reloc_str.data(), reloc_str.size());
+ s.val.allocation->relocations.push_back({ ofs, RelocationPtr::new_alloc(::std::move(a)) });
}
else if( lex.next() == "::" || lex.next() == "<" )
{
auto reloc_path = parse_path();
- s.val.allocation.alloc().relocations.push_back({ ofs, AllocationPtr::new_fcn(reloc_path) });
+ s.val.allocation->relocations.push_back({ ofs, RelocationPtr::new_fcn(reloc_path) });
}
else
{
diff --git a/tools/standalone_miri/value.cpp b/tools/standalone_miri/value.cpp
index cdace6e2..d8eeee01 100644
--- a/tools/standalone_miri/value.cpp
+++ b/tools/standalone_miri/value.cpp
@@ -9,49 +9,79 @@
#include <algorithm>
#include "debug.hpp"
-AllocationPtr Allocation::new_alloc(size_t size)
+AllocationHandle Allocation::new_alloc(size_t size)
{
Allocation* rv = new Allocation();
rv->refcount = 1;
rv->data.resize( (size + 8-1) / 8 ); // QWORDS
rv->mask.resize( (size + 8-1) / 8 ); // bitmap bytes
//LOG_DEBUG(rv << " ALLOC");
- return AllocationPtr(rv);
+ return AllocationHandle(rv);
}
-AllocationPtr AllocationPtr::new_fcn(::HIR::Path p)
+AllocationHandle::AllocationHandle(const AllocationHandle& x):
+ m_ptr(x.m_ptr)
{
- AllocationPtr rv;
+ if( m_ptr )
+ {
+ assert(m_ptr->refcount != 0);
+ assert(m_ptr->refcount != SIZE_MAX);
+ m_ptr->refcount += 1;
+ //LOG_DEBUG(m_ptr << " REF++ " << m_ptr->refcount);
+ }
+}
+AllocationHandle::~AllocationHandle()
+{
+ if( m_ptr )
+ {
+ m_ptr->refcount -= 1;
+ //LOG_DEBUG(m_ptr << " REF-- " << m_ptr->refcount);
+ if(m_ptr->refcount == 0)
+ {
+ delete m_ptr;
+ }
+ }
+}
+
+RelocationPtr RelocationPtr::new_alloc(AllocationHandle alloc)
+{
+ RelocationPtr rv;
+ auto* ptr = alloc.m_ptr;
+ alloc.m_ptr = nullptr;
+ rv.m_ptr = reinterpret_cast<void*>( reinterpret_cast<uintptr_t>(ptr) + static_cast<uintptr_t>(Ty::Allocation) );
+ return rv;
+}
+RelocationPtr RelocationPtr::new_fcn(::HIR::Path p)
+{
+ RelocationPtr rv;
auto* ptr = new ::HIR::Path(::std::move(p));
rv.m_ptr = reinterpret_cast<void*>( reinterpret_cast<uintptr_t>(ptr) + static_cast<uintptr_t>(Ty::Function) );
return rv;
}
-AllocationPtr AllocationPtr::new_string(const ::std::string* ptr)
+RelocationPtr RelocationPtr::new_string(const ::std::string* ptr)
{
- AllocationPtr rv;
+ RelocationPtr rv;
rv.m_ptr = reinterpret_cast<void*>( reinterpret_cast<uintptr_t>(ptr) + static_cast<uintptr_t>(Ty::StdString) );
return rv;
}
-AllocationPtr AllocationPtr::new_ffi(FFIPointer info)
+RelocationPtr RelocationPtr::new_ffi(FFIPointer info)
{
- AllocationPtr rv;
+ RelocationPtr rv;
auto* ptr = new FFIPointer(info);
rv.m_ptr = reinterpret_cast<void*>( reinterpret_cast<uintptr_t>(ptr) + static_cast<uintptr_t>(Ty::FfiPointer) );
return rv;
}
-AllocationPtr::AllocationPtr(const AllocationPtr& x):
+RelocationPtr::RelocationPtr(const RelocationPtr& x):
m_ptr(nullptr)
{
if( x )
{
switch(x.get_ty())
{
- case Ty::Allocation:
- m_ptr = x.m_ptr;
- assert(alloc().refcount != 0);
- assert(alloc().refcount != SIZE_MAX);
- alloc().refcount += 1;
- //LOG_DEBUG(&alloc() << " REF++ " << alloc().refcount);
- break;
+ case Ty::Allocation: {
+ auto tmp = AllocationHandle( reinterpret_cast<Allocation*>(x.get_ptr()) );
+ *this = RelocationPtr::new_alloc(tmp);
+ tmp.m_ptr = nullptr;
+ } break;
case Ty::Function: {
auto ptr_i = reinterpret_cast<uintptr_t>(new ::HIR::Path(x.fcn()));
assert( (ptr_i & 3) == 0 );
@@ -75,21 +105,15 @@ AllocationPtr::AllocationPtr(const AllocationPtr& x):
m_ptr = nullptr;
}
}
-AllocationPtr::~AllocationPtr()
+RelocationPtr::~RelocationPtr()
{
if( *this )
{
switch(get_ty())
{
- case Ty::Allocation: {
- auto* ptr = &alloc();
- ptr->refcount -= 1;
- //LOG_DEBUG(&alloc() << " REF-- " << ptr->refcount);
- if(ptr->refcount == 0)
- {
- delete ptr;
- }
- } break;
+ case Ty::Allocation:
+ (void)AllocationHandle( reinterpret_cast<Allocation*>(get_ptr()) );
+ break;
case Ty::Function: {
auto* ptr = const_cast<::HIR::Path*>(&fcn());
delete ptr;
@@ -104,7 +128,7 @@ AllocationPtr::~AllocationPtr()
}
}
}
-size_t AllocationPtr::get_size() const
+size_t RelocationPtr::get_size() const
{
if( !*this )
return 0;
@@ -123,22 +147,22 @@ size_t AllocationPtr::get_size() const
throw "Unreachable";
}
-::std::ostream& operator<<(::std::ostream& os, const AllocationPtr& x)
+::std::ostream& operator<<(::std::ostream& os, const RelocationPtr& x)
{
if( x )
{
switch(x.get_ty())
{
- case AllocationPtr::Ty::Allocation:
+ case RelocationPtr::Ty::Allocation:
os << &x.alloc();
break;
- case AllocationPtr::Ty::Function:
+ case RelocationPtr::Ty::Function:
os << x.fcn();
break;
- case AllocationPtr::Ty::StdString:
+ case RelocationPtr::Ty::StdString:
os << "\"" << x.str() << "\"";
break;
- case AllocationPtr::Ty::FfiPointer:
+ case RelocationPtr::Ty::FfiPointer:
os << "FFI " << x.ffi().source_function << " " << x.ffi().ptr_value;
break;
}
@@ -150,17 +174,17 @@ size_t AllocationPtr::get_size() const
return os;
}
-uint64_t ValueCommon::read_usize(size_t ofs) const
+uint64_t ValueCommonRead::read_usize(size_t ofs) const
{
uint64_t v = 0;
this->read_bytes(ofs, &v, POINTER_SIZE);
return v;
}
-void ValueCommon::write_usize(size_t ofs, uint64_t v)
+void ValueCommonWrite::write_usize(size_t ofs, uint64_t v)
{
this->write_bytes(ofs, &v, POINTER_SIZE);
}
-void* ValueCommon::read_pointer_unsafe(size_t rd_ofs, size_t req_valid, size_t& out_size, bool& out_is_mut) const
+void* ValueCommonRead::read_pointer_unsafe(size_t rd_ofs, size_t req_valid, size_t& out_size, bool& out_is_mut) const
{
auto ofs = read_usize(rd_ofs);
auto reloc = get_relocation(rd_ofs);
@@ -180,7 +204,7 @@ void* ValueCommon::read_pointer_unsafe(size_t rd_ofs, size_t req_valid, size_t&
{
switch(reloc.get_ty())
{
- case AllocationPtr::Ty::Allocation: {
+ case RelocationPtr::Ty::Allocation: {
auto& a = reloc.alloc();
if( ofs > a.size() )
LOG_FATAL("Out-of-bounds pointer");
@@ -191,7 +215,7 @@ void* ValueCommon::read_pointer_unsafe(size_t rd_ofs, size_t req_valid, size_t&
out_is_mut = true;
return a.data_ptr() + ofs;
}
- case AllocationPtr::Ty::StdString: {
+ case RelocationPtr::Ty::StdString: {
const auto& s = reloc.str();
if( ofs > s.size() )
LOG_FATAL("Out-of-bounds pointer");
@@ -201,9 +225,9 @@ void* ValueCommon::read_pointer_unsafe(size_t rd_ofs, size_t req_valid, size_t&
out_is_mut = false;
return const_cast<void*>( static_cast<const void*>(s.data() + ofs) );
}
- case AllocationPtr::Ty::Function:
+ case RelocationPtr::Ty::Function:
LOG_FATAL("read_pointer w/ function");
- case AllocationPtr::Ty::FfiPointer:
+ case RelocationPtr::Ty::FfiPointer:
if( req_valid )
LOG_FATAL("Can't request valid data from a FFI pointer");
// TODO: Have an idea of mutability and available size from FFI
@@ -214,7 +238,7 @@ void* ValueCommon::read_pointer_unsafe(size_t rd_ofs, size_t req_valid, size_t&
throw "";
}
}
-ValueRef ValueCommon::read_pointer_valref_mut(size_t rd_ofs, size_t size)
+ValueRef ValueCommonRead::read_pointer_valref_mut(size_t rd_ofs, size_t size)
{
auto ofs = read_usize(rd_ofs);
auto reloc = get_relocation(rd_ofs);
@@ -290,7 +314,7 @@ Value Allocation::read_value(size_t ofs, size_t size) const
{
if( ofs <= r.slot_ofs && r.slot_ofs < ofs + size )
{
- rv.allocation.alloc().relocations.push_back({ r.slot_ofs - ofs, r.backing_alloc });
+ rv.allocation->relocations.push_back({ r.slot_ofs - ofs, r.backing_alloc });
}
}
@@ -303,7 +327,7 @@ Value Allocation::read_value(size_t ofs, size_t size) const
bool v = (this->mask[j/8] & test_mask) != 0;
if( v )
{
- rv.allocation.alloc().mask[i/8] |= set_mask;
+ rv.allocation->mask[i/8] |= set_mask;
}
}
}
@@ -365,8 +389,8 @@ void Allocation::write_value(size_t ofs, Value v)
// LOG_ERROR("Writing to read-only allocation " << this);
if( v.allocation )
{
- size_t v_size = v.allocation.alloc().size();
- const auto& src_alloc = v.allocation.alloc();
+ size_t v_size = v.allocation->size();
+ const auto& src_alloc = *v.allocation;
// Take a copy of the source mask
auto s_mask = src_alloc.mask;
@@ -575,18 +599,18 @@ Value Value::new_fnptr(const ::HIR::Path& fn_path)
{
Value rv( ::HIR::TypeRef(::HIR::CoreType { RawType::Function }) );
assert(rv.allocation);
- rv.allocation.alloc().relocations.push_back(Relocation { 0, AllocationPtr::new_fcn(fn_path) });
- rv.allocation.alloc().data.at(0) = 0;
- rv.allocation.alloc().mask.at(0) = 0xFF; // TODO: Get pointer size and make that much valid instead of 8 bytes
+ rv.allocation->relocations.push_back(Relocation { 0, RelocationPtr::new_fcn(fn_path) });
+ rv.allocation->data.at(0) = 0;
+ rv.allocation->mask.at(0) = 0xFF; // TODO: Get pointer size and make that much valid instead of 8 bytes
return rv;
}
Value Value::new_ffiptr(FFIPointer ffi)
{
Value rv( ::HIR::TypeRef(::HIR::CoreType { RawType::USize }) );
rv.create_allocation();
- rv.allocation.alloc().relocations.push_back(Relocation { 0, AllocationPtr::new_ffi(ffi) });
- rv.allocation.alloc().data.at(0) = 0;
- rv.allocation.alloc().mask.at(0) = 0xFF; // TODO: Get pointer size and make that much valid instead of 8 bytes
+ rv.allocation->relocations.push_back(Relocation { 0, RelocationPtr::new_ffi(ffi) });
+ rv.allocation->data.at(0) = 0;
+ rv.allocation->mask.at(0) = 0xFF; // TODO: Get pointer size and make that much valid instead of 8 bytes
return rv;
}
@@ -595,10 +619,10 @@ void Value::create_allocation()
assert(!this->allocation);
this->allocation = Allocation::new_alloc(this->direct_data.size);
if( this->direct_data.size > 0 )
- this->allocation.alloc().mask[0] = this->direct_data.mask[0];
+ this->allocation->mask[0] = this->direct_data.mask[0];
if( this->direct_data.size > 8 )
- this->allocation.alloc().mask[1] = this->direct_data.mask[1];
- ::std::memcpy(this->allocation.alloc().data.data(), this->direct_data.data, this->direct_data.size);
+ this->allocation->mask[1] = this->direct_data.mask[1];
+ ::std::memcpy(this->allocation->data.data(), this->direct_data.data, this->direct_data.size);
}
void Value::check_bytes_valid(size_t ofs, size_t size) const
{
@@ -606,7 +630,7 @@ void Value::check_bytes_valid(size_t ofs, size_t size) const
return ;
if( this->allocation )
{
- this->allocation.alloc().check_bytes_valid(ofs, size);
+ this->allocation->check_bytes_valid(ofs, size);
}
else
{
@@ -635,7 +659,7 @@ void Value::mark_bytes_valid(size_t ofs, size_t size)
{
if( this->allocation )
{
- this->allocation.alloc().mark_bytes_valid(ofs, size);
+ this->allocation->mark_bytes_valid(ofs, size);
}
else
{
@@ -652,7 +676,7 @@ Value Value::read_value(size_t ofs, size_t size) const
//TRACE_FUNCTION_R(ofs << ", " << size << ") - " << *this, rv);
if( this->allocation )
{
- rv = this->allocation.alloc().read_value(ofs, size);
+ rv = this->allocation->read_value(ofs, size);
}
else
{
@@ -670,7 +694,7 @@ void Value::read_bytes(size_t ofs, void* dst, size_t count) const
return ;
if( this->allocation )
{
- this->allocation.alloc().read_bytes(ofs, dst, count);
+ this->allocation->read_bytes(ofs, dst, count);
}
else
{
@@ -698,7 +722,7 @@ void Value::write_bytes(size_t ofs, const void* src, size_t count)
return ;
if( this->allocation )
{
- this->allocation.alloc().write_bytes(ofs, src, count);
+ this->allocation->write_bytes(ofs, src, count);
}
else
{
@@ -719,14 +743,14 @@ void Value::write_value(size_t ofs, Value v)
{
if( this->allocation )
{
- this->allocation.alloc().write_value(ofs, ::std::move(v));
+ this->allocation->write_value(ofs, ::std::move(v));
}
else
{
- if( v.allocation && !v.allocation.alloc().relocations.empty() )
+ if( v.allocation && !v.allocation->relocations.empty() )
{
this->create_allocation();
- this->allocation.alloc().write_value(ofs, ::std::move(v));
+ this->allocation->write_value(ofs, ::std::move(v));
}
else
{
@@ -749,7 +773,7 @@ void Value::write_value(size_t ofs, Value v)
{
if( v.allocation )
{
- os << v.allocation.alloc();
+ os << *v.allocation;
}
else
{
@@ -776,13 +800,13 @@ extern ::std::ostream& operator<<(::std::ostream& os, const ValueRef& v)
{
if( v.m_size == 0 )
return os;
- if( v.m_alloc || v.m_value->allocation )
+ if( v.m_alloc )
{
- const auto& alloc_ptr = v.m_alloc ? v.m_alloc : v.m_value->allocation;
+ const auto& alloc_ptr = v.m_alloc;;
// TODO: What if alloc_ptr isn't a data allocation?
switch(alloc_ptr.get_ty())
{
- case AllocationPtr::Ty::Allocation: {
+ case RelocationPtr::Ty::Allocation: {
const auto& alloc = alloc_ptr.alloc();
auto flags = os.flags();
@@ -813,10 +837,10 @@ extern ::std::ostream& operator<<(::std::ostream& os, const ValueRef& v)
}
os << " }";
} break;
- case AllocationPtr::Ty::Function:
+ case RelocationPtr::Ty::Function:
LOG_TODO("ValueRef to " << alloc_ptr);
break;
- case AllocationPtr::Ty::StdString: {
+ case RelocationPtr::Ty::StdString: {
const auto& s = alloc_ptr.str();
assert(v.m_offset < s.size());
assert(v.m_size < s.size());
@@ -829,12 +853,44 @@ extern ::std::ostream& operator<<(::std::ostream& os, const ValueRef& v)
}
os.setf(flags);
} break;
- case AllocationPtr::Ty::FfiPointer:
+ case RelocationPtr::Ty::FfiPointer:
LOG_TODO("ValueRef to " << alloc_ptr);
break;
}
}
- else
+ else if( v.m_value && v.m_value->allocation )
+ {
+ const auto& alloc = *v.m_value->allocation;
+
+ auto flags = os.flags();
+ os << ::std::hex;
+ for(size_t i = v.m_offset; i < ::std::min(alloc.size(), v.m_offset + v.m_size); i++)
+ {
+ if( i != 0 )
+ os << " ";
+
+ if( alloc.mask[i/8] & (1 << i%8) )
+ {
+ os << ::std::setw(2) << ::std::setfill('0') << (int)alloc.data_ptr()[i];
+ }
+ else
+ {
+ os << "--";
+ }
+ }
+ os.setf(flags);
+
+ os << " {";
+ for(const auto& r : alloc.relocations)
+ {
+ if( v.m_offset <= r.slot_ofs && r.slot_ofs < v.m_offset + v.m_size )
+ {
+ os << " @" << (r.slot_ofs - v.m_offset) << "=" << r.backing_alloc;
+ }
+ }
+ os << " }";
+ }
+ else if( v.m_value )
{
const auto& direct = v.m_value->direct_data;
@@ -855,6 +911,10 @@ extern ::std::ostream& operator<<(::std::ostream& os, const ValueRef& v)
}
os.setf(flags);
}
+ else
+ {
+ // TODO: no value?
+ }
return os;
}
@@ -868,9 +928,9 @@ Value ValueRef::read_value(size_t ofs, size_t size) const
if( m_alloc ) {
switch(m_alloc.get_ty())
{
- case AllocationPtr::Ty::Allocation:
+ case RelocationPtr::Ty::Allocation:
return m_alloc.alloc().read_value(m_offset + ofs, size);
- case AllocationPtr::Ty::StdString: {
+ case RelocationPtr::Ty::StdString: {
auto rv = Value::with_size(size, false);
//ASSERT_BUG(ofs <= m_alloc.str().size(), "");
//ASSERT_BUG(size <= m_alloc.str().size(), "");
@@ -893,9 +953,3 @@ bool ValueRef::compare(const void* other, size_t other_len) const
check_bytes_valid(0, other_len);
return ::std::memcmp(data_ptr(), other, other_len) == 0;
}
-uint64_t ValueRef::read_usize(size_t ofs) const
-{
- uint64_t v = 0;
- this->read_bytes(ofs, &v, POINTER_SIZE);
- return v;
-}
diff --git a/tools/standalone_miri/value.hpp b/tools/standalone_miri/value.hpp
index aa41b838..4da2eee6 100644
--- a/tools/standalone_miri/value.hpp
+++ b/tools/standalone_miri/value.hpp
@@ -23,12 +23,46 @@ struct FFIPointer
void* ptr_value;
};
-class AllocationPtr
+class AllocationHandle
{
friend class Allocation;
- void* m_ptr;
+ friend class RelocationPtr;
+ Allocation* m_ptr;
+
+private:
+ AllocationHandle(Allocation* p):
+ m_ptr(p)
+ {
+ }
public:
+ AllocationHandle(): m_ptr(nullptr) {}
+ AllocationHandle(AllocationHandle&& x): m_ptr(x.m_ptr) {
+ x.m_ptr = nullptr;
+ }
+ AllocationHandle(const AllocationHandle& x);
+ ~AllocationHandle();
+
+ AllocationHandle& operator=(const AllocationHandle& x) = delete;
+ AllocationHandle& operator=(AllocationHandle&& x) {
+ this->~AllocationHandle();
+ this->m_ptr = x.m_ptr;
+ x.m_ptr = nullptr;
+ return *this;
+ }
+ operator bool() const { return m_ptr != 0; }
+ const Allocation& operator*() const { assert(m_ptr); return *m_ptr; }
+ Allocation& operator*() { assert(m_ptr); return *m_ptr; }
+ const Allocation* operator->() const { assert(m_ptr); return m_ptr; }
+ Allocation* operator->() { assert(m_ptr); return m_ptr; }
+};
+
+// TODO: Split into RelocationPtr and AllocationHandle
+class RelocationPtr
+{
+ void* m_ptr;
+
+public:
enum class Ty
{
Allocation,
@@ -37,26 +71,20 @@ public:
FfiPointer,
};
-private:
- AllocationPtr(Allocation* p):
- m_ptr(p)
- {
- }
-public:
- AllocationPtr(): m_ptr(nullptr) {}
- AllocationPtr(AllocationPtr&& x): m_ptr(x.m_ptr) {
+ RelocationPtr(): m_ptr(nullptr) {}
+ RelocationPtr(RelocationPtr&& x): m_ptr(x.m_ptr) {
x.m_ptr = nullptr;
}
- AllocationPtr(const AllocationPtr& x);
- ~AllocationPtr();
- static AllocationPtr new_fcn(::HIR::Path p);
- //static AllocationPtr new_rawdata(const void* buf, size_t len);
- static AllocationPtr new_string(const ::std::string* s); // NOTE: The string must have a stable pointer
- static AllocationPtr new_ffi(FFIPointer info);
-
- AllocationPtr& operator=(const AllocationPtr& x) = delete;
- AllocationPtr& operator=(AllocationPtr&& x) {
- this->~AllocationPtr();
+ RelocationPtr(const RelocationPtr& x);
+ ~RelocationPtr();
+ static RelocationPtr new_alloc(AllocationHandle h);
+ static RelocationPtr new_fcn(::HIR::Path p);
+ static RelocationPtr new_string(const ::std::string* s); // NOTE: The string must have a stable pointer
+ static RelocationPtr new_ffi(FFIPointer info);
+
+ RelocationPtr& operator=(const RelocationPtr& x) = delete;
+ RelocationPtr& operator=(RelocationPtr&& x) {
+ this->~RelocationPtr();
this->m_ptr = x.m_ptr;
x.m_ptr = nullptr;
return *this;
@@ -98,7 +126,7 @@ public:
return static_cast<Ty>( reinterpret_cast<uintptr_t>(m_ptr) & 3 );
}
- friend ::std::ostream& operator<<(::std::ostream& os, const AllocationPtr& x);
+ friend ::std::ostream& operator<<(::std::ostream& os, const RelocationPtr& x);
private:
void* get_ptr() const {
return reinterpret_cast<void*>( reinterpret_cast<uintptr_t>(m_ptr) & ~3 );
@@ -109,27 +137,14 @@ struct Relocation
// Offset within parent allocation where this relocation is performed.
// TODO: Size?
size_t slot_ofs;
- AllocationPtr backing_alloc;
+ RelocationPtr backing_alloc;
};
-struct ValueCommon
+// TODO: Split write and read
+struct ValueCommonRead
{
- virtual AllocationPtr get_relocation(size_t ofs) const = 0;
+ virtual RelocationPtr get_relocation(size_t ofs) const = 0;
virtual void read_bytes(size_t ofs, void* dst, size_t count) const = 0;
- virtual void write_bytes(size_t ofs, const void* src, size_t count) = 0;
-
- void write_u8 (size_t ofs, uint8_t v) { write_bytes(ofs, &v, 1); }
- void write_u16(size_t ofs, uint16_t v) { write_bytes(ofs, &v, 2); }
- void write_u32(size_t ofs, uint32_t v) { write_bytes(ofs, &v, 4); }
- void write_u64(size_t ofs, uint64_t v) { write_bytes(ofs, &v, 8); }
- void write_i8 (size_t ofs, int8_t v) { write_u8 (ofs, static_cast<uint8_t >(v)); }
- void write_i16(size_t ofs, int16_t v) { write_u16(ofs, static_cast<uint16_t>(v)); }
- void write_i32(size_t ofs, int32_t v) { write_u32(ofs, static_cast<uint32_t>(v)); }
- void write_i64(size_t ofs, int64_t v) { write_u64(ofs, static_cast<uint64_t>(v)); }
- void write_f32(size_t ofs, float v) { write_bytes(ofs, &v, 4); }
- void write_f64(size_t ofs, double v) { write_bytes(ofs, &v, 8); }
- void write_usize(size_t ofs, uint64_t v);
- void write_isize(size_t ofs, int64_t v) { write_usize(ofs, static_cast<uint64_t>(v)); }
uint8_t read_u8(size_t ofs) const { uint8_t rv; read_bytes(ofs, &rv, 1); return rv; }
uint16_t read_u16(size_t ofs) const { uint16_t rv; read_bytes(ofs, &rv, 2); return rv; }
@@ -164,16 +179,34 @@ struct ValueCommon
/// Read a pointer and return a ValueRef to it (mutable data)
ValueRef read_pointer_valref_mut(size_t rd_ofs, size_t size);
};
+struct ValueCommonWrite:
+ public ValueCommonRead
+{
+ virtual void write_bytes(size_t ofs, const void* src, size_t count) = 0;
+
+ void write_u8 (size_t ofs, uint8_t v) { write_bytes(ofs, &v, 1); }
+ void write_u16(size_t ofs, uint16_t v) { write_bytes(ofs, &v, 2); }
+ void write_u32(size_t ofs, uint32_t v) { write_bytes(ofs, &v, 4); }
+ void write_u64(size_t ofs, uint64_t v) { write_bytes(ofs, &v, 8); }
+ void write_i8 (size_t ofs, int8_t v) { write_u8 (ofs, static_cast<uint8_t >(v)); }
+ void write_i16(size_t ofs, int16_t v) { write_u16(ofs, static_cast<uint16_t>(v)); }
+ void write_i32(size_t ofs, int32_t v) { write_u32(ofs, static_cast<uint32_t>(v)); }
+ void write_i64(size_t ofs, int64_t v) { write_u64(ofs, static_cast<uint64_t>(v)); }
+ void write_f32(size_t ofs, float v) { write_bytes(ofs, &v, 4); }
+ void write_f64(size_t ofs, double v) { write_bytes(ofs, &v, 8); }
+ void write_usize(size_t ofs, uint64_t v);
+ void write_isize(size_t ofs, int64_t v) { write_usize(ofs, static_cast<uint64_t>(v)); }
+};
class Allocation:
- public ValueCommon
+ public ValueCommonWrite
{
- friend class AllocationPtr;
+ friend class AllocationHandle;
size_t refcount;
// TODO: Read-only flag?
bool is_freed = false;
public:
- static AllocationPtr new_alloc(size_t size);
+ static AllocationHandle 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()); }
@@ -183,12 +216,12 @@ public:
::std::vector<uint8_t> mask;
::std::vector<Relocation> relocations;
- AllocationPtr get_relocation(size_t ofs) const override {
+ RelocationPtr get_relocation(size_t ofs) const override {
for(const auto& r : relocations) {
if(r.slot_ofs == ofs)
return r.backing_alloc;
}
- return AllocationPtr();
+ return RelocationPtr();
}
void mark_as_freed() {
is_freed = true;
@@ -211,10 +244,10 @@ public:
extern ::std::ostream& operator<<(::std::ostream& os, const Allocation& x);
struct Value:
- public ValueCommon
+ public ValueCommonWrite
{
// If NULL, data is direct
- AllocationPtr allocation;
+ AllocationHandle allocation;
struct {
uint8_t data[2*sizeof(size_t)-3]; // 16-3 = 13, fits in 16 bits of mask
uint8_t mask[2];
@@ -228,15 +261,15 @@ struct Value:
static Value new_ffiptr(FFIPointer ffi);
void create_allocation();
- size_t size() const { return allocation ? allocation.alloc().size() : direct_data.size; }
- const uint8_t* data_ptr() const { return allocation ? allocation.alloc().data_ptr() : direct_data.data; }
- uint8_t* data_ptr() { return allocation ? allocation.alloc().data_ptr() : direct_data.data; }
+ size_t size() const { return allocation ? allocation->size() : direct_data.size; }
+ const uint8_t* data_ptr() const { return allocation ? allocation->data_ptr() : direct_data.data; }
+ uint8_t* data_ptr() { return allocation ? allocation->data_ptr() : direct_data.data; }
- AllocationPtr get_relocation(size_t ofs) const override {
- if( this->allocation && this->allocation.is_alloc() )
- return this->allocation.alloc().get_relocation(ofs);
+ RelocationPtr get_relocation(size_t ofs) const override {
+ if( this->allocation && this->allocation )
+ return this->allocation->get_relocation(ofs);
else
- return AllocationPtr();
+ return RelocationPtr();
}
void check_bytes_valid(size_t ofs, size_t size) const;
@@ -251,17 +284,17 @@ struct Value:
extern ::std::ostream& operator<<(::std::ostream& os, const Value& v);
// A read-only reference to a value (to write, you have to go through it)
-struct ValueRef
- //:public ValueCommon
+struct ValueRef:
+ public ValueCommonRead
{
- // Either an AllocationPtr, or a Value pointer
- AllocationPtr m_alloc;
+ // Either an AllocationHandle, or a Value pointer
+ RelocationPtr m_alloc;
Value* m_value;
size_t m_offset; // Offset within the value
size_t m_size; // Size in bytes of the referenced value
::std::shared_ptr<Value> m_metadata;
- ValueRef(AllocationPtr ptr, size_t ofs, size_t size):
+ ValueRef(RelocationPtr ptr, size_t ofs, size_t size):
m_alloc(ptr),
m_value(nullptr),
m_offset(ofs),
@@ -271,12 +304,12 @@ struct ValueRef
{
switch(m_alloc.get_ty())
{
- case AllocationPtr::Ty::Allocation:
+ case RelocationPtr::Ty::Allocation:
assert(ofs < m_alloc.alloc().size());
assert(size <= m_alloc.alloc().size());
assert(ofs+size <= m_alloc.alloc().size());
break;
- case AllocationPtr::Ty::StdString:
+ case RelocationPtr::Ty::StdString:
assert(ofs < m_alloc.str().size());
assert(size <= m_alloc.str().size());
assert(ofs+size <= m_alloc.str().size());
@@ -297,24 +330,21 @@ struct ValueRef
{
}
- AllocationPtr get_relocation(size_t ofs) const {
+ RelocationPtr get_relocation(size_t ofs) const override {
if(m_alloc)
{
if( m_alloc.is_alloc() )
return m_alloc.alloc().get_relocation(ofs);
else
- return AllocationPtr();
+ return RelocationPtr();
}
- else if( m_value && m_value->allocation )
+ else if( m_value )
{
- if( m_value->allocation.is_alloc() )
- return m_value->allocation.alloc().get_relocation(ofs);
- else
- return AllocationPtr();
+ return m_value->get_relocation(ofs);
}
else
{
- return AllocationPtr();
+ return RelocationPtr();
}
}
Value read_value(size_t ofs, size_t size) const;
@@ -322,10 +352,10 @@ struct ValueRef
if( m_alloc ) {
switch(m_alloc.get_ty())
{
- case AllocationPtr::Ty::Allocation:
+ case RelocationPtr::Ty::Allocation:
return m_alloc.alloc().data_ptr() + m_offset;
break;
- case AllocationPtr::Ty::StdString:
+ case RelocationPtr::Ty::StdString:
return reinterpret_cast<const uint8_t*>(m_alloc.str().data() + m_offset);
default:
throw "TODO";
@@ -347,10 +377,10 @@ struct ValueRef
if( m_alloc ) {
switch(m_alloc.get_ty())
{
- case AllocationPtr::Ty::Allocation:
+ case RelocationPtr::Ty::Allocation:
m_alloc.alloc().read_bytes(m_offset + ofs, dst, size);
break;
- case AllocationPtr::Ty::StdString:
+ case RelocationPtr::Ty::StdString:
assert(m_offset+ofs <= m_alloc.str().size() && size <= m_alloc.str().size() && m_offset+ofs+size <= m_alloc.str().size());
::std::memcpy(dst, m_alloc.str().data() + m_offset + ofs, size);
break;
@@ -372,10 +402,10 @@ struct ValueRef
if( m_alloc ) {
switch(m_alloc.get_ty())
{
- case AllocationPtr::Ty::Allocation:
+ case RelocationPtr::Ty::Allocation:
m_alloc.alloc().check_bytes_valid(m_offset + ofs, size);
break;
- case AllocationPtr::Ty::StdString:
+ case RelocationPtr::Ty::StdString:
assert(m_offset+ofs <= m_alloc.str().size() && size <= m_alloc.str().size() && m_offset+ofs+size <= m_alloc.str().size());
break;
default:
@@ -389,19 +419,5 @@ struct ValueRef
}
bool compare(const void* other, size_t other_len) const;
-
- // TODO: Figure out how to make this use `ValueCommon` when it can't write.
- uint8_t read_u8(size_t ofs) const { uint8_t rv; read_bytes(ofs, &rv, 1); return rv; }
- uint16_t read_u16(size_t ofs) const { uint16_t rv; read_bytes(ofs, &rv, 2); return rv; }
- uint32_t read_u32(size_t ofs) const { uint32_t rv; read_bytes(ofs, &rv, 4); return rv; }
- uint64_t read_u64(size_t ofs) const { uint64_t rv; read_bytes(ofs, &rv, 8); return rv; }
- int8_t read_i8(size_t ofs) const { return static_cast<int8_t>(read_u8(ofs)); }
- int16_t read_i16(size_t ofs) const { return static_cast<int16_t>(read_u16(ofs)); }
- int32_t read_i32(size_t ofs) const { return static_cast<int32_t>(read_u32(ofs)); }
- int64_t read_i64(size_t ofs) const { return static_cast<int64_t>(read_u64(ofs)); }
- float read_f32(size_t ofs) const { float rv; read_bytes(ofs, &rv, 4); return rv; }
- double read_f64(size_t ofs) const { double rv; read_bytes(ofs, &rv, 8); return rv; }
- uint64_t read_usize(size_t ofs) const;
- int64_t read_isize(size_t ofs) const { return static_cast<int64_t>(read_usize(ofs)); }
};
extern ::std::ostream& operator<<(::std::ostream& os, const ValueRef& v);