diff options
-rw-r--r-- | tools/standalone_miri/debug.hpp | 2 | ||||
-rw-r--r-- | tools/standalone_miri/hir_sim.cpp | 15 | ||||
-rw-r--r-- | tools/standalone_miri/main.cpp | 112 | ||||
-rw-r--r-- | tools/standalone_miri/module_tree.cpp | 3 | ||||
-rw-r--r-- | tools/standalone_miri/module_tree.hpp | 1 | ||||
-rw-r--r-- | tools/standalone_miri/value.cpp | 31 |
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); } } |