summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--tools/standalone_miri/debug.hpp2
-rw-r--r--tools/standalone_miri/hir_sim.cpp15
-rw-r--r--tools/standalone_miri/main.cpp112
-rw-r--r--tools/standalone_miri/module_tree.cpp3
-rw-r--r--tools/standalone_miri/module_tree.hpp1
-rw-r--r--tools/standalone_miri/value.cpp31
6 files changed, 123 insertions, 41 deletions
diff --git a/tools/standalone_miri/debug.hpp b/tools/standalone_miri/debug.hpp
index 3a420985..342ea6fe 100644
--- a/tools/standalone_miri/debug.hpp
+++ b/tools/standalone_miri/debug.hpp
@@ -29,6 +29,8 @@ public:
static bool enabled(const char* fcn_name);
static DebugSink get(const char* fcn_name, const char* file, unsigned line, DebugLevel lvl);
+ // TODO: Add a way to insert an annotation before/after an abort/warning/... that indicates what input location caused it.
+ //static void set_position();
static void inc_indent();
static void dec_indent();
diff --git a/tools/standalone_miri/hir_sim.cpp b/tools/standalone_miri/hir_sim.cpp
index d549fa1d..e1b7faf8 100644
--- a/tools/standalone_miri/hir_sim.cpp
+++ b/tools/standalone_miri/hir_sim.cpp
@@ -65,8 +65,16 @@ size_t HIR::TypeRef::get_size(size_t ofs) const
// Need to look up the metadata type for the actual type
if( this->inner_type == RawType::Composite )
{
- ::std::cerr << "TODO: Check metadata type for pointer " << *this << ", assuming none" << ::std::endl;
- return POINTER_SIZE;
+ if( this->composite_type->dst_meta == RawType::Unreachable )
+ {
+ return POINTER_SIZE;
+ }
+ // Special case: extern types (which appear when a type is only ever used by pointer)
+ if( this->composite_type->dst_meta == RawType::Unit )
+ {
+ return POINTER_SIZE;
+ }
+ LOG_TODO("Handle unsized struct " << *this);
}
else if( this->inner_type == RawType::Str )
return POINTER_SIZE*2;
@@ -220,7 +228,8 @@ namespace HIR {
os << "()";
break;
case RawType::Composite:
- os << "composite_" << x.composite_type;
+ os << x.composite_type->my_path;
+ //os << "composite_" << x.composite_type;
break;
case RawType::Unreachable:
os << "!";
diff --git a/tools/standalone_miri/main.cpp b/tools/standalone_miri/main.cpp
index 0d372991..427fe39d 100644
--- a/tools/standalone_miri/main.cpp
+++ b/tools/standalone_miri/main.cpp
@@ -415,9 +415,6 @@ Value MIRI_Invoke(ModuleTree& modtree, ::HIR::Path path, ::std::vector<Value> ar
// - Add the relocation after writing the value (writing clears the relocations)
new_val.allocation.alloc().relocations.push_back(Relocation { 0, ::std::move(alloc) });
} break;
- TU_ARM(se.src, SizedArray, re) {
- throw "TODO";
- } break;
TU_ARM(se.src, Cast, re) {
// Determine the type of cast, is it a reinterpret or is it a value transform?
// - Float <-> integer is a transform, anything else should be a reinterpret.
@@ -855,13 +852,13 @@ Value MIRI_Invoke(ModuleTree& modtree, ::HIR::Path path, ::std::vector<Value> ar
}
} break;
TU_ARM(se.src, DstMeta, re) {
- throw "TODO";
+ LOG_TODO(stmt);
} break;
TU_ARM(se.src, DstPtr, re) {
- throw "TODO";
+ LOG_TODO(stmt);
} break;
TU_ARM(se.src, MakeDst, re) {
- throw "TODO";
+ LOG_TODO(stmt);
} break;
TU_ARM(se.src, Tuple, re) {
::HIR::TypeRef dst_ty;
@@ -875,7 +872,34 @@ Value MIRI_Invoke(ModuleTree& modtree, ::HIR::Path path, ::std::vector<Value> ar
}
} break;
TU_ARM(se.src, Array, re) {
- throw "TODO";
+ ::HIR::TypeRef dst_ty;
+ state.get_value_and_type(se.dst, dst_ty);
+ new_val = Value(dst_ty);
+ // TODO: Assert that type is an array
+ auto inner_ty = dst_ty.get_inner();
+ size_t stride = inner_ty.get_size();
+
+ size_t ofs = 0;
+ for(const auto& v : re.vals)
+ {
+ new_val.write_value(ofs, state.param_to_value(v));
+ ofs += stride;
+ }
+ } break;
+ TU_ARM(se.src, SizedArray, re) {
+ ::HIR::TypeRef dst_ty;
+ state.get_value_and_type(se.dst, dst_ty);
+ new_val = Value(dst_ty);
+ // TODO: Assert that type is an array
+ auto inner_ty = dst_ty.get_inner();
+ size_t stride = inner_ty.get_size();
+
+ size_t ofs = 0;
+ for(size_t i = 0; i < re.count; i++)
+ {
+ new_val.write_value(ofs, state.param_to_value(re.val));
+ ofs += stride;
+ }
} break;
TU_ARM(se.src, Variant, re) {
// 1. Get the composite by path.
@@ -906,7 +930,18 @@ Value MIRI_Invoke(ModuleTree& modtree, ::HIR::Path path, ::std::vector<Value> ar
}
} break;
TU_ARM(se.src, Struct, re) {
- LOG_TODO(stmt);
+ const auto& data_ty = state.modtree.get_composite(re.path);
+
+ ::HIR::TypeRef dst_ty;
+ state.get_value_and_type(se.dst, dst_ty);
+ new_val = Value(dst_ty);
+ LOG_ASSERT(dst_ty.composite_type == &data_ty, "Destination type of RValue::Struct isn't the same as the input");
+
+ for(size_t i = 0; i < re.vals.size(); i++)
+ {
+ auto fld_ofs = data_ty.fields.at(i).first;
+ new_val.write_value(fld_ofs, state.param_to_value(re.vals[i]));
+ }
} break;
}
LOG_DEBUG("- " << new_val);
@@ -918,41 +953,60 @@ Value MIRI_Invoke(ModuleTree& modtree, ::HIR::Path path, ::std::vector<Value> ar
TU_ARM(stmt, Drop, se) {
if( se.flag_idx == ~0u || state.drop_flags.at(se.flag_idx) )
{
- ::HIR::TypeRef ty;
- auto v = state.get_value_and_type(se.slot, ty);
- // If an owned borrow, deref to inner
- // If an array, drop all inners
- if( !ty.wrappers.empty() )
- LOG_TODO(stmt << " - " << ty);
-
- // If a composite, check for drop glue and drop if present
- if( ty.wrappers.empty() )
- {
- if( ty.inner_type == RawType::Composite )
+ auto drop_value = [](ValueRef v, const ::HIR::TypeRef& ty) {
+ if( ty.wrappers.empty() )
{
- if( ty.composite_type->drop_glue != ::HIR::Path() )
+ if( ty.inner_type == RawType::Composite )
{
- LOG_TODO(stmt << " - " << ty);
+ if( ty.composite_type->drop_glue != ::HIR::Path() )
+ {
+ LOG_TODO("Drop - " << ty);
+ }
+ else
+ {
+ // No drop glue
+ }
+ }
+ else if( ty.inner_type == RawType::TraitObject )
+ {
+ LOG_TODO("Drop - " << ty);
}
else
{
- // No drop glue
+ // No destructor
}
}
- else if( ty.inner_type == RawType::TraitObject )
+ else if( ty.wrappers[0].type == TypeWrapper::Ty::Borrow )
{
- LOG_TODO(stmt << " - " << ty);
+ 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
+ }
}
+ // TODO: Arrays
else
{
- // No destructor
+ LOG_TODO("Drop - " << ty);
}
- }
+
+ };
+
+ ::HIR::TypeRef ty;
+ auto v = state.get_value_and_type(se.slot, ty);
+ drop_value(v, ty);
+ // TODO: Clear validity on the entire inner value.
}
} break;
- case ::MIR::Statement::TAG_SetDropFlag:
- LOG_TODO(stmt);
- break;
+ TU_ARM(stmt, SetDropFlag, se) {
+ bool val = (se.other == ~0 ? false : state.drop_flags.at(se.other)) != se.new_val;
+ LOG_DEBUG("- " << val);
+ state.drop_flags.at(se.idx) = val;
+ } break;
case ::MIR::Statement::TAG_ScopeEnd:
LOG_TODO(stmt);
break;
diff --git a/tools/standalone_miri/module_tree.cpp b/tools/standalone_miri/module_tree.cpp
index 2fc99bc4..905e6aaf 100644
--- a/tools/standalone_miri/module_tree.cpp
+++ b/tools/standalone_miri/module_tree.cpp
@@ -164,6 +164,7 @@ bool Parser::parse_one()
//::std::cout << "DEBUG: parse_one - type " << p << ::std::endl;
auto rv = DataType {};
+ rv.my_path = p;
lex.check_consume('{');
lex.check_consume("SIZE");
@@ -1127,6 +1128,7 @@ RawType Parser::parse_core_type()
{
// TODO: Later on need to check if the type is valid.
auto v = ::std::make_unique<DataType>(DataType {});
+ v->my_path = gp;
auto ir = tree.data_types.insert(::std::make_pair( ::std::move(gp), ::std::move(v)) );
it = ir.first;
}
@@ -1192,6 +1194,7 @@ RawType Parser::parse_core_type()
{
// TODO: Later on need to check if the type is valid.
auto v = ::std::make_unique<DataType>(DataType {});
+ v->my_path = path;
auto ir = tree.data_types.insert(::std::make_pair( ::std::move(path), ::std::move(v)) );
it = ir.first;
}
diff --git a/tools/standalone_miri/module_tree.hpp b/tools/standalone_miri/module_tree.hpp
index 20e37a51..ca24b06a 100644
--- a/tools/standalone_miri/module_tree.hpp
+++ b/tools/standalone_miri/module_tree.hpp
@@ -58,6 +58,7 @@ public:
// struct/union/enum
struct DataType
{
+ ::HIR::GenericPath my_path;
// TODO: Store the name of this type for logging?
// TODO: Metadata type! (indicates an unsized wrapper)
diff --git a/tools/standalone_miri/value.cpp b/tools/standalone_miri/value.cpp
index 522e40dd..45eb1474 100644
--- a/tools/standalone_miri/value.cpp
+++ b/tools/standalone_miri/value.cpp
@@ -176,16 +176,19 @@ Value Allocation::read_value(size_t ofs, size_t size) const
}
void Allocation::read_bytes(size_t ofs, void* dst, size_t count) const
{
+ if(count == 0)
+ return ;
+
if(ofs >= this->size() ) {
- ::std::cerr << "Value::write_bytes - Out of bounds read, " << ofs << " >= " << this->size() << ::std::endl;
+ LOG_ERROR("Out of bounds read, " << ofs << "+" << count << " > " << this->size());
throw "ERROR";
}
if(count > this->size() ) {
- ::std::cerr << "Value::write_bytes - Out of bounds read, count " << count << " > size " << this->size() << ::std::endl;
+ LOG_ERROR("Out of bounds read, " << ofs << "+" << count << " > " << this->size());
throw "ERROR";
}
if(ofs+count > this->size() ) {
- ::std::cerr << "Value::write_bytes - Out of bounds read, " << ofs << "+" << count << " > size " << this->size() << ::std::endl;
+ LOG_ERROR("Out of bounds read, " << ofs << "+" << count << " > " << this->size());
throw "ERROR";
}
check_bytes_valid(ofs, count);
@@ -259,16 +262,18 @@ void Allocation::write_value(size_t ofs, Value v)
}
void Allocation::write_bytes(size_t ofs, const void* src, size_t count)
{
+ if(count == 0)
+ return ;
if(ofs >= this->size() ) {
- ::std::cerr << "Value::write_bytes - Out of bounds write, " << ofs << " >= " << this->size() << ::std::endl;
+ LOG_ERROR("Out of bounds write, " << ofs << "+" << count << " > " << this->size());
throw "ERROR";
}
if(count > this->size() ) {
- ::std::cerr << "Value::write_bytes - Out of bounds write, count " << count << " > size " << this->size() << ::std::endl;
+ LOG_ERROR("Out of bounds write, " << ofs << "+" << count << " > " << this->size());
throw "ERROR";
}
if(ofs+count > this->size() ) {
- ::std::cerr << "Value::write_bytes - Out of bounds write, " << ofs << "+" << count << " > size " << this->size() << ::std::endl;
+ LOG_ERROR("Out of bounds write, " << ofs << "+" << count << " > " << this->size());
throw "ERROR";
}
@@ -465,6 +470,8 @@ Value Value::read_value(size_t ofs, size_t size) const
}
void Value::read_bytes(size_t ofs, void* dst, size_t count) const
{
+ if(count == 0)
+ return ;
if( this->allocation )
{
this->allocation.alloc().read_bytes(ofs, dst, count);
@@ -473,12 +480,18 @@ void Value::read_bytes(size_t ofs, void* dst, size_t count) const
{
check_bytes_valid(ofs, count);
- if(ofs >= this->direct_data.size )
+ if(ofs >= this->direct_data.size ) {
+ LOG_ERROR("Out of bounds read, " << ofs << "+" << count << " > " << this->size());
throw "ERROR";
- if(count > this->direct_data.size )
+ }
+ if(count > this->direct_data.size ) {
+ LOG_ERROR("Out of bounds read, " << ofs << "+" << count << " > " << this->size());
throw "ERROR";
- if(ofs+count > this->direct_data.size )
+ }
+ if(ofs+count > this->direct_data.size ) {
+ LOG_ERROR("Out of bounds read, " << ofs << "+" << count << " > " << this->size());
throw "ERROR";
+ }
::std::memcpy(dst, this->direct_data.data + ofs, count);
}
}