summaryrefslogtreecommitdiff
path: root/tools
diff options
context:
space:
mode:
authorJohn Hodge <tpg@mutabah.net>2018-05-19 13:29:22 +0800
committerJohn Hodge <tpg@mutabah.net>2018-05-19 13:29:22 +0800
commitd97d3a3e9fedb73c612fae542db28626a687ab22 (patch)
tree87f361feabd1afcee45af5fb24502ca477742884 /tools
parenta96b446e80f109138e2a639ec94222017af0b9b1 (diff)
downloadmrust-d97d3a3e9fedb73c612fae542db28626a687ab22.tar.gz
Standalone MIRI - Remove direct uses of TypeRef.wrappers
Diffstat (limited to 'tools')
-rw-r--r--tools/standalone_miri/hir_sim.cpp40
-rw-r--r--tools/standalone_miri/hir_sim.hpp30
-rw-r--r--tools/standalone_miri/main.cpp4
-rw-r--r--tools/standalone_miri/miri.cpp240
-rw-r--r--tools/standalone_miri/module_tree.cpp18
-rw-r--r--tools/standalone_miri/value.cpp37
6 files changed, 186 insertions, 183 deletions
diff --git a/tools/standalone_miri/hir_sim.cpp b/tools/standalone_miri/hir_sim.cpp
index 94f0d0e1..35f8f608 100644
--- a/tools/standalone_miri/hir_sim.cpp
+++ b/tools/standalone_miri/hir_sim.cpp
@@ -1,7 +1,12 @@
-//
-//
-//
+/*
+ * mrustc Standalone MIRI
+ * - by John Hodge (Mutabah)
+ *
+ * value.cpp
+ * - Copy of the various HIR types from the compiler
+ */
#include <iostream>
+#include <algorithm>
#include "hir_sim.hpp"
#include "module_tree.hpp"
@@ -140,7 +145,32 @@ HIR::TypeRef HIR::TypeRef::wrap(TypeWrapper::Ty ty, size_t size)&&
rv.wrappers.insert(rv.wrappers.begin(), { ty, size });
return rv;
}
-const HIR::TypeRef* HIR::TypeRef::get_usized_type(size_t& running_inner_size) const
+bool HIR::TypeRef::has_pointer() const
+{
+ // If ALL of the (potentially non) wrappers are Array, look deeper
+ // - Don't need to worry about unsized types here
+ if( ::std::all_of(this->wrappers.begin(), this->wrappers.end(), [](const auto& x){ return x.type == TypeWrapper::Ty::Array; }) )
+ {
+ // TODO: Function pointers should be _pointers_
+ if( this->inner_type == RawType::Function )
+ {
+ return true;
+ }
+ // Check the inner type
+ if( this->inner_type == RawType::Composite )
+ {
+ // Still not sure, check the inner for any pointers.
+ for(const auto& fld : this->composite_type->fields)
+ {
+ if( fld.second.has_pointer() )
+ return true;
+ }
+ }
+ return false;
+ }
+ return true;
+}
+const HIR::TypeRef* HIR::TypeRef::get_unsized_type(size_t& running_inner_size) const
{
if( this->wrappers.empty() )
{
@@ -153,7 +183,7 @@ const HIR::TypeRef* HIR::TypeRef::get_usized_type(size_t& running_inner_size) co
return nullptr;
running_inner_size = this->composite_type->fields.back().first;
size_t tmp;
- return this->composite_type->fields.back().second.get_usized_type(tmp);
+ return this->composite_type->fields.back().second.get_unsized_type(tmp);
case RawType::TraitObject:
case RawType::Str:
return this;
diff --git a/tools/standalone_miri/hir_sim.hpp b/tools/standalone_miri/hir_sim.hpp
index 9f5ba59c..7730ac48 100644
--- a/tools/standalone_miri/hir_sim.hpp
+++ b/tools/standalone_miri/hir_sim.hpp
@@ -118,15 +118,41 @@ namespace HIR {
}
size_t get_size(size_t ofs=0) const;
+
+ // Returns true if this (unsized) type is a wrapper around a slice
+ // - Fills `out_inner_size` with the size of the slice element
bool has_slice_meta(size_t& out_inner_size) const; // The attached metadata is a count of elements
- const TypeRef* get_usized_type(size_t& running_inner_size) const;
+ // Returns the base unsized type for this type (returning nullptr if there's no unsized field)
+ // - Fills `running_inner_size` with the offset to the unsized field
+ const TypeRef* get_unsized_type(size_t& running_inner_size) const;
+ // Returns the type of associated metadata for this (unsized) type (or `!` if not unsized)
TypeRef get_meta_type() const;
+ // Get the inner type (one level of wrapping removed)
TypeRef get_inner() const;
+
+ // Add a wrapper over this type (moving)
TypeRef wrap(TypeWrapper::Ty ty, size_t size)&&;
+ // Add a wrapper over this type (copying)
TypeRef wrapped(TypeWrapper::Ty ty, size_t size) const {
return TypeRef(*this).wrap(ty, size);
}
+ // Get the wrapper at the provided offset (0 = outermost)
+ const TypeWrapper* get_wrapper(size_t ofs=0) const {
+ //assert(ofs <= this->wrappers.size());
+ if( ofs < this->wrappers.size() ) {
+ return &this->wrappers[ofs];
+ }
+ else {
+ return nullptr;
+ }
+ }
+
+ // Returns true if the type contains any pointers
+ bool has_pointer() const;
+ // Get the type and offset of the specified field index
TypeRef get_field(size_t idx, size_t& ofs) const;
+ // Get the offset and type of a field (recursing using `other_idx`)
+ size_t get_field_ofs(size_t idx, const ::std::vector<size_t>& other_idx, TypeRef& ty) const;
bool operator==(const RawType& x) const {
if( this->wrappers.size() != 0 )
@@ -152,8 +178,6 @@ namespace HIR {
return false;
}
- size_t get_field_ofs(size_t idx, const ::std::vector<size_t>& other_idx, TypeRef& ty) const;
-
friend ::std::ostream& operator<<(::std::ostream& os, const TypeRef& x);
};
diff --git a/tools/standalone_miri/main.cpp b/tools/standalone_miri/main.cpp
index e3a8d22e..90b5eff3 100644
--- a/tools/standalone_miri/main.cpp
+++ b/tools/standalone_miri/main.cpp
@@ -62,9 +62,7 @@ int main(int argc, const char* argv[])
// Construct argc/argv values
auto val_argc = Value::new_isize(1 + opts.args.size());
- ::HIR::TypeRef argv_ty { RawType::I8 };
- argv_ty.wrappers.push_back(TypeWrapper { TypeWrapper::Ty::Pointer, 0 });
- argv_ty.wrappers.push_back(TypeWrapper { TypeWrapper::Ty::Pointer, 0 });
+ auto argv_ty = ::HIR::TypeRef(RawType::I8).wrap(TypeWrapper::Ty::Pointer, 0 ).wrap(TypeWrapper::Ty::Pointer, 0);
auto val_argv = Value::new_pointer(argv_ty, 0, RelocationPtr::new_alloc(argv_alloc));
// Catch various exceptions from the interpreter
diff --git a/tools/standalone_miri/miri.cpp b/tools/standalone_miri/miri.cpp
index c0e7d15c..63be419c 100644
--- a/tools/standalone_miri/miri.cpp
+++ b/tools/standalone_miri/miri.cpp
@@ -175,7 +175,7 @@ public:
static PrimitiveValueVirt from_value(const ::HIR::TypeRef& t, const ValueRef& v) {
PrimitiveValueVirt rv;
- LOG_ASSERT(t.wrappers.empty(), "PrimitiveValueVirt::from_value: " << t);
+ LOG_ASSERT(t.get_wrapper() == nullptr, "PrimitiveValueVirt::from_value: " << t);
switch(t.inner_type)
{
case RawType::U32:
@@ -281,15 +281,18 @@ struct MirHelpers
auto idx = get_value_ref(*e.idx).read_usize(0);
::HIR::TypeRef array_ty;
auto base_val = get_value_and_type(*e.val, array_ty);
- if( array_ty.wrappers.empty() )
+ const auto* wrapper = array_ty.get_wrapper();
+ if( !wrapper )
+ {
LOG_ERROR("Indexing non-array/slice - " << array_ty);
- if( array_ty.wrappers.front().type == TypeWrapper::Ty::Array )
+ }
+ else if( wrapper->type == TypeWrapper::Ty::Array )
{
ty = array_ty.get_inner();
base_val.m_offset += ty.get_size() * idx;
return base_val;
}
- else if( array_ty.wrappers.front().type == TypeWrapper::Ty::Slice )
+ else if( wrapper->type == TypeWrapper::Ty::Slice )
{
LOG_TODO("Slice index");
}
@@ -354,7 +357,7 @@ struct MirHelpers
size_t slice_inner_size;
if( ty.has_slice_meta(slice_inner_size) ) {
- size = (ty.wrappers.empty() ? ty.get_size() : 0) + meta_val->read_usize(0) * slice_inner_size;
+ size = (ty.get_wrapper() == nullptr ? ty.get_size() : 0) + meta_val->read_usize(0) * slice_inner_size;
}
//else if( ty == RawType::TraitObject) {
// // NOTE: Getting the size from the allocation is semi-valid, as you can't sub-slice trait objects
@@ -468,8 +471,7 @@ struct MirHelpers
LOG_TODO("Constant::Bytes");
} break;
TU_ARM(c, StaticString, ce) {
- ty = ::HIR::TypeRef(RawType::Str);
- ty.wrappers.push_back(TypeWrapper { TypeWrapper::Ty::Borrow, 0 });
+ ty = ::HIR::TypeRef(RawType::Str).wrap(TypeWrapper::Ty::Borrow, 0);
Value val = Value(ty);
val.write_ptr(0, 0, RelocationPtr::new_string(&ce));
val.write_usize(POINTER_SIZE, ce.size());
@@ -484,8 +486,7 @@ struct MirHelpers
return Value::new_fnptr(ce);
}
if( const auto* s = this->thread.m_modtree.get_static_opt(ce) ) {
- ty = s->ty;
- ty.wrappers.insert(ty.wrappers.begin(), TypeWrapper { TypeWrapper::Ty::Borrow, 0 });
+ ty = s->ty.wrapped(TypeWrapper::Ty::Borrow, 0);
return Value::new_pointer(ty, 0, RelocationPtr::new_alloc(s->val.allocation));
}
LOG_ERROR("Constant::ItemAddr - " << ce << " - not found");
@@ -602,10 +603,10 @@ bool InterpreterThread::step_one(Value& out_thread_result)
LOG_DEBUG("- alloc=" << alloc);
size_t ofs = src_base_value.m_offset;
const auto meta = src_ty.get_meta_type();
- src_ty.wrappers.insert(src_ty.wrappers.begin(), TypeWrapper { TypeWrapper::Ty::Borrow, static_cast<size_t>(re.type) });
+ auto dst_ty = src_ty.wrapped(TypeWrapper::Ty::Borrow, static_cast<size_t>(re.type));
// Create the pointer
- new_val = Value(src_ty);
+ new_val = Value(dst_ty);
new_val.write_ptr(0, ofs, ::std::move(alloc));
// - Add metadata if required
if( meta != RawType::Unreachable )
@@ -626,26 +627,24 @@ bool InterpreterThread::step_one(Value& out_thread_result)
// No-op cast
new_val = src_value.read_value(0, re.type.get_size());
}
- else if( !re.type.wrappers.empty() )
+ else if( const auto* dst_w = re.type.get_wrapper() )
{
// Destination can only be a raw pointer
- if( re.type.wrappers.at(0).type != TypeWrapper::Ty::Pointer ) {
- throw "ERROR";
+ if( dst_w->type != TypeWrapper::Ty::Pointer ) {
+ LOG_ERROR("Attempting to cast to a type other than a raw pointer - " << re.type);
}
- if( !src_ty.wrappers.empty() )
+ if( const auto* src_w = src_ty.get_wrapper() )
{
// Source can be either
- if( src_ty.wrappers.at(0).type != TypeWrapper::Ty::Pointer
- && src_ty.wrappers.at(0).type != TypeWrapper::Ty::Borrow ) {
- throw "ERROR";
+ if( src_w->type != TypeWrapper::Ty::Pointer && src_w->type != TypeWrapper::Ty::Borrow ) {
+ LOG_ERROR("Attempting to cast to a pointer from a non-pointer - " << src_ty);
}
- if( src_ty.get_size() > re.type.get_size() ) {
- // TODO: How to casting fat to thin?
- //LOG_TODO("Handle casting fat to thin, " << src_ty << " -> " << re.type);
- new_val = src_value.read_value(0, re.type.get_size());
+ if( src_ty.get_size() < re.type.get_size() )
+ {
+ LOG_ERROR("Casting to a fatter pointer, " << src_ty << " -> " << re.type);
}
- else
+ else
{
new_val = src_value.read_value(0, re.type.get_size());
}
@@ -660,18 +659,15 @@ bool InterpreterThread::step_one(Value& out_thread_result)
}
else
{
- ::std::cerr << "ERROR: Trying to pointer (" << re.type <<" ) from invalid type (" << src_ty << ")\n";
- throw "ERROR";
+ LOG_ERROR("Trying to cast to pointer (" << re.type <<" ) from invalid type (" << src_ty << ")\n");
}
new_val = src_value.read_value(0, re.type.get_size());
}
}
- else if( !src_ty.wrappers.empty() )
+ else if( const auto* src_w = src_ty.get_wrapper() )
{
- // TODO: top wrapper MUST be a pointer
- if( src_ty.wrappers.at(0).type != TypeWrapper::Ty::Pointer
- && src_ty.wrappers.at(0).type != TypeWrapper::Ty::Borrow ) {
- throw "ERROR";
+ if( src_w->type != TypeWrapper::Ty::Pointer && src_w->type != TypeWrapper::Ty::Borrow ) {
+ LOG_ERROR("Attempting to cast to a non-pointer - " << src_ty);
}
// TODO: MUST be a thin pointer?
@@ -802,7 +798,7 @@ bool InterpreterThread::step_one(Value& out_thread_result)
LOG_ASSERT(dt.variants[i].field_path.empty(), "");
}
::HIR::TypeRef tag_ty = dt.fields[0].second;
- LOG_ASSERT(tag_ty.wrappers.empty(), "");
+ LOG_ASSERT(tag_ty.get_wrapper() == nullptr, "");
switch(tag_ty.inner_type)
{
case RawType::USize:
@@ -954,7 +950,33 @@ bool InterpreterThread::step_one(Value& out_thread_result)
}
LOG_DEBUG("res=" << res << ", " << reloc_l << " ? " << reloc_r);
- if( ty_l.wrappers.empty() )
+ if( const auto* w = ty_l.get_wrapper() )
+ {
+ if( w->type == TypeWrapper::Ty::Pointer )
+ {
+ // TODO: Technically only EQ/NE are valid.
+
+ res = res != 0 ? res : Ops::do_compare(v_l.read_usize(0), v_r.read_usize(0));
+
+ // Compare fat metadata.
+ if( res == 0 && v_l.m_size > POINTER_SIZE )
+ {
+ reloc_l = v_l.get_relocation(POINTER_SIZE);
+ reloc_r = v_r.get_relocation(POINTER_SIZE);
+
+ if( res == 0 && reloc_l != reloc_r )
+ {
+ res = (reloc_l < reloc_r ? -1 : 1);
+ }
+ res = res != 0 ? res : Ops::do_compare(v_l.read_usize(POINTER_SIZE), v_r.read_usize(POINTER_SIZE));
+ }
+ }
+ else
+ {
+ LOG_TODO("BinOp comparisons - " << se.src << " w/ " << ty_l);
+ }
+ }
+ else
{
switch(ty_l.inner_type)
{
@@ -972,29 +994,6 @@ bool InterpreterThread::step_one(Value& out_thread_result)
LOG_TODO("BinOp comparisons - " << se.src << " w/ " << ty_l);
}
}
- else if( ty_l.wrappers.front().type == TypeWrapper::Ty::Pointer )
- {
- // TODO: Technically only EQ/NE are valid.
-
- res = res != 0 ? res : Ops::do_compare(v_l.read_usize(0), v_r.read_usize(0));
-
- // Compare fat metadata.
- if( res == 0 && v_l.m_size > POINTER_SIZE )
- {
- reloc_l = v_l.get_relocation(POINTER_SIZE);
- reloc_r = v_r.get_relocation(POINTER_SIZE);
-
- if( res == 0 && reloc_l != reloc_r )
- {
- res = (reloc_l < reloc_r ? -1 : 1);
- }
- res = res != 0 ? res : Ops::do_compare(v_l.read_usize(POINTER_SIZE), v_r.read_usize(POINTER_SIZE));
- }
- }
- else
- {
- LOG_TODO("BinOp comparisons - " << se.src << " w/ " << ty_l);
- }
bool res_bool;
switch(re.op)
{
@@ -1013,8 +1012,8 @@ bool InterpreterThread::step_one(Value& out_thread_result)
} break;
case ::MIR::eBinOp::BIT_SHL:
case ::MIR::eBinOp::BIT_SHR: {
- LOG_ASSERT(ty_l.wrappers.empty(), "Bitwise operator on non-primitive - " << ty_l);
- LOG_ASSERT(ty_r.wrappers.empty(), "Bitwise operator with non-primitive - " << ty_r);
+ LOG_ASSERT(ty_l.get_wrapper() == nullptr, "Bitwise operator on non-primitive - " << ty_l);
+ LOG_ASSERT(ty_r.get_wrapper() == nullptr, "Bitwise operator with non-primitive - " << ty_r);
size_t max_bits = ty_r.get_size() * 8;
uint8_t shift;
auto check_cast = [&](auto v){ LOG_ASSERT(0 <= v && v <= max_bits, "Shift out of range - " << v); return static_cast<uint8_t>(v); };
@@ -1051,7 +1050,7 @@ bool InterpreterThread::step_one(Value& out_thread_result)
case ::MIR::eBinOp::BIT_OR:
case ::MIR::eBinOp::BIT_XOR:
LOG_ASSERT(ty_l == ty_r, "BinOp type mismatch - " << ty_l << " != " << ty_r);
- LOG_ASSERT(ty_l.wrappers.empty(), "Bitwise operator on non-primitive - " << ty_l);
+ LOG_ASSERT(ty_l.get_wrapper() == nullptr, "Bitwise operator on non-primitive - " << ty_l);
new_val = Value(ty_l);
switch(ty_l.inner_type)
{
@@ -1104,7 +1103,7 @@ bool InterpreterThread::step_one(Value& out_thread_result)
TU_ARM(se.src, UniOp, re) {
::HIR::TypeRef ty;
auto v = state.get_value_and_type(re.val, ty);
- LOG_ASSERT(ty.wrappers.empty(), "UniOp on wrapped type - " << ty);
+ LOG_ASSERT(ty.get_wrapper() == nullptr, "UniOp on wrapped type - " << ty);
new_val = Value(ty);
switch(re.op)
{
@@ -1238,7 +1237,6 @@ bool InterpreterThread::step_one(Value& out_thread_result)
const auto& data_ty = this->m_modtree.get_composite(re.path);
auto dst_ty = ::HIR::TypeRef(&data_ty);
new_val = Value(dst_ty);
- LOG_DEBUG("Variant " << new_val);
// Three cases:
// - Unions (no tag)
// - Data enums (tag and data)
@@ -1250,7 +1248,6 @@ bool InterpreterThread::step_one(Value& out_thread_result)
new_val.write_value(fld.first, state.param_to_value(re.val));
}
- LOG_DEBUG("Variant " << new_val);
if( var.base_field != SIZE_MAX )
{
::HIR::TypeRef tag_ty;
@@ -1279,7 +1276,7 @@ bool InterpreterThread::step_one(Value& out_thread_result)
}
} break;
}
- LOG_DEBUG("- " << new_val);
+ LOG_DEBUG("- new_val=" << new_val);
state.write_lvalue(se.dst, ::std::move(new_val));
} break;
case ::MIR::Statement::TAG_Asm:
@@ -1352,8 +1349,8 @@ bool InterpreterThread::step_one(Value& out_thread_result)
TU_ARM(bb.terminator, Switch, te) {
::HIR::TypeRef ty;
auto v = state.get_value_and_type(te.val, ty);
- LOG_ASSERT(ty.wrappers.size() == 0, "" << ty);
- LOG_ASSERT(ty.inner_type == RawType::Composite, "" << ty);
+ LOG_ASSERT(ty.get_wrapper() == nullptr, "Matching on wrapped value - " << ty);
+ LOG_ASSERT(ty.inner_type == RawType::Composite, "Matching on non-coposite - " << ty);
// TODO: Convert the variant list into something that makes it easier to switch on.
size_t found_target = SIZE_MAX;
@@ -1578,8 +1575,7 @@ bool InterpreterThread::call_extern(Value& rv, const ::std::string& link_name, c
auto size = args.at(0).read_usize(0);
auto align = args.at(1).read_usize(0);
LOG_DEBUG("__rust_allocate(size=" << size << ", align=" << align << ")");
- ::HIR::TypeRef rty { RawType::Unit };
- rty.wrappers.push_back({ TypeWrapper::Ty::Pointer, 0 });
+ auto rty = ::HIR::TypeRef(RawType::Unit).wrap( TypeWrapper::Ty::Pointer, 0 );
// TODO: Use the alignment when making an allocation?
rv = Value::new_pointer(rty, 0, RelocationPtr::new_alloc(Allocation::new_alloc(size)));
@@ -2051,14 +2047,14 @@ bool InterpreterThread::call_intrinsic(Value& rv, const ::std::string& name, con
// Get unsized type somehow.
// - _HAS_ to be the last type, so that makes it easier
size_t fixed_size = 0;
- if( const auto* ity = ty.get_usized_type(fixed_size) )
+ if( const auto* ity = ty.get_unsized_type(fixed_size) )
{
const auto meta_ty = ty.get_meta_type();
LOG_DEBUG("size_of_val - " << ty << " ity=" << *ity << " meta_ty=" << meta_ty << " fixed_size=" << fixed_size);
size_t flex_size = 0;
- if( !ity->wrappers.empty() )
+ if( const auto* w = ity->get_wrapper() )
{
- LOG_ASSERT(ity->wrappers[0].type == TypeWrapper::Ty::Slice, "");
+ LOG_ASSERT(w->type == TypeWrapper::Ty::Slice, "size_of_val on wrapped type that isn't a slice - " << *ity);
size_t item_size = ity->get_inner().get_size();
size_t item_count = val.read_usize(POINTER_SIZE);
flex_size = item_count * item_size;
@@ -2088,40 +2084,7 @@ bool InterpreterThread::call_intrinsic(Value& rv, const ::std::string& name, con
{
auto& val = args.at(0);
const auto& ty = ty_params.tys.at(0);
- if( !ty.wrappers.empty() )
- {
- size_t item_count = 0;
- switch(ty.wrappers[0].type)
- {
- case TypeWrapper::Ty::Slice:
- case TypeWrapper::Ty::Array:
- item_count = (ty.wrappers[0].type == TypeWrapper::Ty::Slice ? val.read_usize(POINTER_SIZE) : ty.wrappers[0].size);
- break;
- case TypeWrapper::Ty::Pointer:
- break;
- case TypeWrapper::Ty::Borrow:
- // TODO: Only &move has a destructor
- break;
- }
- LOG_ASSERT(ty.wrappers[0].type == TypeWrapper::Ty::Slice, "drop_in_place should only exist for slices - " << ty);
- const auto& ity = ty.get_inner();
- size_t item_size = ity.get_size();
-
- auto ptr = val.read_value(0, POINTER_SIZE);
- for(size_t i = 0; i < item_count; i ++)
- {
- // TODO: Nested calls?
- if( !drop_value(ptr, ity) )
- {
- LOG_DEBUG("Handle multiple queued calls");
- }
- ptr.write_usize(0, ptr.read_usize(0) + item_size);
- }
- }
- else
- {
- return drop_value(val, ty);
- }
+ return drop_value(val, ty);
}
// ----------------------------------------------------------------
// Checked arithmatic
@@ -2249,12 +2212,55 @@ bool InterpreterThread::drop_value(Value ptr, const ::HIR::TypeRef& ty, bool is_
if( ofs != 0 || !alloc || !alloc.is_alloc() ) {
LOG_ERROR("Attempting to shallow drop with invalid pointer (no relocation or non-zero offset) - " << box_ptr_vr);
}
-
+
LOG_DEBUG("drop_value SHALLOW deallocate " << alloc);
alloc.alloc().mark_as_freed();
return true;
}
- if( ty.wrappers.empty() )
+ if( const auto* w = ty.get_wrapper() )
+ {
+ switch( w->type )
+ {
+ case TypeWrapper::Ty::Borrow:
+ if( w->size == static_cast<size_t>(::HIR::BorrowType::Move) )
+ {
+ LOG_TODO("Drop - " << ty << " - dereference and go to inner");
+ // TODO: Clear validity on the entire inner value.
+ //auto iptr = ptr.read_value(0, ty.get_size());
+ //drop_value(iptr, ty.get_inner());
+ }
+ else
+ {
+ // No destructor
+ }
+ break;
+ case TypeWrapper::Ty::Pointer:
+ // No destructor
+ break;
+ case TypeWrapper::Ty::Slice: {
+ // - Get thin pointer and count
+ auto ofs = ptr.read_usize(0);
+ auto ptr_reloc = ptr.get_relocation(0);
+ auto count = ptr.read_usize(POINTER_SIZE);
+
+ auto ity = ty.get_inner();
+ auto pty = ity.wrapped(TypeWrapper::Ty::Borrow, static_cast<size_t>(::HIR::BorrowType::Move));
+ for(uint64_t i = 0; i < count; i ++)
+ {
+ auto ptr = Value::new_pointer(pty, ofs, ptr_reloc);
+ if( !drop_value(ptr, ity) ) {
+ LOG_TODO("Handle closure looping when dropping a slice");
+ }
+ ofs += ity.get_size();
+ }
+ } break;
+ // TODO: Arrays?
+ default:
+ LOG_TODO("Drop - " << ty << " - array?");
+ break;
+ }
+ }
+ else
{
if( ty.inner_type == RawType::Composite )
{
@@ -2279,29 +2285,5 @@ bool InterpreterThread::drop_value(Value ptr, const ::HIR::TypeRef& ty, bool is_
// No destructor
}
}
- else
- {
- switch( ty.wrappers[0].type )
- {
- case TypeWrapper::Ty::Borrow:
- if( ty.wrappers[0].size == static_cast<size_t>(::HIR::BorrowType::Move) )
- {
- LOG_TODO("Drop - " << ty << " - dereference and go to inner");
- // TODO: Clear validity on the entire inner value.
- }
- else
- {
- // No destructor
- }
- break;
- case TypeWrapper::Ty::Pointer:
- // No destructor
- break;
- // TODO: Arrays
- default:
- LOG_TODO("Drop - " << ty << " - array?");
- break;
- }
- }
return true;
}
diff --git a/tools/standalone_miri/module_tree.cpp b/tools/standalone_miri/module_tree.cpp
index cb6f943d..db5fd495 100644
--- a/tools/standalone_miri/module_tree.cpp
+++ b/tools/standalone_miri/module_tree.cpp
@@ -266,7 +266,7 @@ bool Parser::parse_one()
//const auto* tag_ty = &rv.fields.at(base_idx).second;
//for(auto idx : other_idx)
//{
- // assert(tag_ty->wrappers.size() == 0);
+ // assert(tag_ty->get_wrapper() == nullptr);
// assert(tag_ty->inner_type == RawType::Composite);
// LOG_TODO(lex << "Calculate tag offset with nested tag - " << idx << " ty=" << *tag_ty);
//}
@@ -1130,14 +1130,14 @@ RawType Parser::parse_core_type()
{
size_t size = lex.next().integer();
lex.consume();
- rv.wrappers.insert( rv.wrappers.begin(), { TypeWrapper::Ty::Array, size });
+ lex.check_consume(']');
+ return ::std::move(rv).wrap( TypeWrapper::Ty::Array, size );
}
else
{
- rv.wrappers.insert( rv.wrappers.begin(), { TypeWrapper::Ty::Slice, 0 });
+ lex.check_consume(']');
+ return ::std::move(rv).wrap( TypeWrapper::Ty::Slice, 0 );
}
- lex.check_consume(']');
- return rv;
}
else if( lex.consume_if('!') )
{
@@ -1152,9 +1152,7 @@ RawType Parser::parse_core_type()
bt = ::HIR::BorrowType::Unique;
else
; // keep as shared
- auto rv = parse_type();
- rv.wrappers.insert( rv.wrappers.begin(), { TypeWrapper::Ty::Borrow, static_cast<size_t>(bt) });
- return rv;
+ return parse_type().wrap( TypeWrapper::Ty::Borrow, static_cast<size_t>(bt) );
}
else if( lex.consume_if('*') )
{
@@ -1167,9 +1165,7 @@ RawType Parser::parse_core_type()
; // keep as shared
else
throw "ERROR";
- auto rv = parse_type();
- rv.wrappers.insert( rv.wrappers.begin(), { TypeWrapper::Ty::Pointer, static_cast<size_t>(bt) });
- return rv;
+ return parse_type().wrap( TypeWrapper::Ty::Pointer, static_cast<size_t>(bt) );
}
else if( lex.next() == "::" )
{
diff --git a/tools/standalone_miri/value.cpp b/tools/standalone_miri/value.cpp
index c1098d1d..cf378077 100644
--- a/tools/standalone_miri/value.cpp
+++ b/tools/standalone_miri/value.cpp
@@ -545,38 +545,12 @@ Value::Value()
Value::Value(::HIR::TypeRef ty)
{
size_t size = ty.get_size();
-#if 1
+
// Support inline data if the data will fit within the inline region (which is the size of the metadata)
if( ty.get_size() <= sizeof(this->direct_data.data) )
{
- struct H
- {
- static bool has_pointer(const ::HIR::TypeRef& ty)
- {
- if( ty.wrappers.empty() || ::std::all_of(ty.wrappers.begin(), ty.wrappers.end(), [](const auto& x){ return x.type == TypeWrapper::Ty::Array; }) )
- {
- // TODO: Function pointers should be _pointers_
- if( ty.inner_type == RawType::Function )
- {
- return true;
- }
- // Check the inner type
- if( ty.inner_type != RawType::Composite )
- {
- return false;
- }
- // Still not sure, check the inner for any pointers.
- for(const auto& fld : ty.composite_type->fields)
- {
- if( H::has_pointer(fld.second) )
- return true;
- }
- return false;
- }
- return true;
- }
- };
- if( ! H::has_pointer(ty) )
+ // AND the type doesn't contain a pointer (of any kind)
+ if( ! ty.has_pointer() )
{
// Will fit in a inline allocation, nice.
//LOG_TRACE("No pointers in " << ty << ", storing inline");
@@ -586,7 +560,6 @@ Value::Value(::HIR::TypeRef ty)
return ;
}
}
-#endif
// Fallback: Make a new allocation
//LOG_TRACE(" Creating allocation for " << ty);
@@ -626,8 +599,8 @@ Value Value::new_ffiptr(FFIPointer ffi)
return rv;
}
Value Value::new_pointer(::HIR::TypeRef ty, uint64_t v, RelocationPtr r) {
- assert(!ty.wrappers.empty());
- assert(ty.wrappers[0].type == TypeWrapper::Ty::Borrow || ty.wrappers[0].type == TypeWrapper::Ty::Pointer);
+ assert(ty.get_wrapper());
+ assert(ty.get_wrapper()->type == TypeWrapper::Ty::Borrow || ty.get_wrapper()->type == TypeWrapper::Ty::Pointer);
Value rv(ty);
rv.write_usize(0, v);
rv.allocation->relocations.push_back(Relocation { 0, /*POINTER_SIZE,*/ ::std::move(r) });