summaryrefslogtreecommitdiff
path: root/tools/standalone_miri/main.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'tools/standalone_miri/main.cpp')
-rw-r--r--tools/standalone_miri/main.cpp94
1 files changed, 43 insertions, 51 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;
}