diff options
author | John Hodge <tpg@mutabah.net> | 2018-05-13 09:27:13 +0800 |
---|---|---|
committer | John Hodge <tpg@mutabah.net> | 2018-05-13 09:27:13 +0800 |
commit | ac6f3ffba823e539c4c9afd93b7edf7122f463cc (patch) | |
tree | 418ebc63c6d5a28560bb396f1992505e80182515 /tools/standalone_miri | |
parent | 9f8469d5145ea51f2d4b2b9d1eb32d1029cfbeb5 (diff) | |
download | mrust-ac6f3ffba823e539c4c9afd93b7edf7122f463cc.tar.gz |
Standalone MIRI - Better vtable handling, fix to offset with null pointers
Diffstat (limited to 'tools/standalone_miri')
-rw-r--r-- | tools/standalone_miri/hir_sim.cpp | 30 | ||||
-rw-r--r-- | tools/standalone_miri/hir_sim.hpp | 6 | ||||
-rw-r--r-- | tools/standalone_miri/main.cpp | 31 | ||||
-rw-r--r-- | tools/standalone_miri/module_tree.cpp | 56 |
4 files changed, 65 insertions, 58 deletions
diff --git a/tools/standalone_miri/hir_sim.cpp b/tools/standalone_miri/hir_sim.cpp index 604f65a4..f3b4d400 100644 --- a/tools/standalone_miri/hir_sim.cpp +++ b/tools/standalone_miri/hir_sim.cpp @@ -166,32 +166,34 @@ const HIR::TypeRef* HIR::TypeRef::get_usized_type(size_t& running_inner_size) co return nullptr; } } -const HIR::TypeRef* HIR::TypeRef::get_meta_type() const +HIR::TypeRef HIR::TypeRef::get_meta_type() const { - static ::HIR::TypeRef static_usize = ::HIR::TypeRef(RawType::USize); if( this->wrappers.empty() ) { switch(this->inner_type) { case RawType::Composite: if( this->composite_type->dst_meta == RawType::Unreachable ) - return nullptr; - return &this->composite_type->dst_meta; - case RawType::TraitObject: - LOG_TODO("get_meta_type on TraitObject - " << *this); + return TypeRef(RawType::Unreachable); + return this->composite_type->dst_meta; + case RawType::TraitObject: { + auto rv = ::HIR::TypeRef( this->composite_type ); + rv.wrappers.push_back(TypeWrapper { TypeWrapper::Ty::Pointer, static_cast<size_t>(BorrowType::Shared) }); + return rv; + } case RawType::Str: - return &static_usize; + return TypeRef(RawType::USize); default: - return nullptr; + return TypeRef(RawType::Unreachable); } } else if( this->wrappers[0].type == TypeWrapper::Ty::Slice ) { - return &static_usize; + return TypeRef(RawType::USize); } else { - return nullptr; + return TypeRef(RawType::Unreachable); } } @@ -305,7 +307,11 @@ namespace HIR { os << "function_?"; break; case RawType::TraitObject: - os << "traitobject_?"; + os << "dyn "; + if( x.composite_type ) + os << x.composite_type->my_path; + else + os << "?"; break; case RawType::Bool: os << "bool"; break; case RawType::Char: os << "char"; break; @@ -385,4 +391,4 @@ namespace HIR { } return os; } -}
\ No newline at end of file +} diff --git a/tools/standalone_miri/hir_sim.hpp b/tools/standalone_miri/hir_sim.hpp index 7154de13..1dc9bcc4 100644 --- a/tools/standalone_miri/hir_sim.hpp +++ b/tools/standalone_miri/hir_sim.hpp @@ -23,7 +23,7 @@ struct DataType; enum class RawType { Unreachable, - Function, + Function, // TODO: Needs a way of indicating the signature? Unit, Bool, @@ -39,7 +39,7 @@ enum class RawType Char, Str, Composite, // Struct, Enum, Union, tuple, ... - TraitObject, // Data pointer is `*const ()`, metadata type stored in `composite_type` + TraitObject, // Data pointer is `*const ()`, vtable type stored in `composite_type` }; struct TypeWrapper { @@ -120,7 +120,7 @@ namespace HIR { size_t get_size(size_t ofs=0) const; bool has_slice_meta() const; // The attached metadata is a count const TypeRef* get_usized_type(size_t& running_inner_size) const; - const TypeRef* get_meta_type() const; + TypeRef get_meta_type() const; TypeRef get_inner() const; TypeRef wrap(TypeWrapper::Ty ty, size_t size) const; TypeRef get_field(size_t idx, size_t& ofs) const; diff --git a/tools/standalone_miri/main.cpp b/tools/standalone_miri/main.cpp index e5ef9c15..16cfd972 100644 --- a/tools/standalone_miri/main.cpp +++ b/tools/standalone_miri/main.cpp @@ -503,7 +503,7 @@ Value MIRI_Invoke(ModuleTree& modtree, ThreadState& thread, ::HIR::Path path, :: ty = composite_ty.get_field(e.field_index, inner_ofs); LOG_DEBUG("Field - " << composite_ty << "#" << e.field_index << " = @" << inner_ofs << " " << ty); base_val.m_offset += inner_ofs; - if( !ty.get_meta_type() ) + if( ty.get_meta_type() == HIR::TypeRef(RawType::Unreachable) ) { LOG_ASSERT(base_val.m_size >= ty.get_size(), "Field didn't fit in the value - " << ty.get_size() << " required, but " << base_val.m_size << " avail"); base_val.m_size = ty.get_size(); @@ -542,12 +542,12 @@ Value MIRI_Invoke(ModuleTree& modtree, ThreadState& thread, ::HIR::Path path, :: } size_t size; - const auto* meta_ty = ty.get_meta_type(); + const auto meta_ty = ty.get_meta_type(); ::std::shared_ptr<Value> meta_val; // If the type has metadata, store it. - if( meta_ty ) + if( meta_ty != RawType::Unreachable ) { - auto meta_size = meta_ty->get_size(); + auto meta_size = meta_ty.get_size(); LOG_ASSERT(val.m_size == POINTER_SIZE + meta_size, "Deref of " << ty << ", but pointer isn't correct size"); meta_val = ::std::make_shared<Value>( val.read_value(POINTER_SIZE, meta_size) ); @@ -768,14 +768,14 @@ Value MIRI_Invoke(ModuleTree& modtree, ThreadState& thread, ::HIR::Path path, :: else LOG_DEBUG("- alloc=" << alloc); size_t ofs = src_base_value.m_offset; - const auto* meta = src_ty.get_meta_type(); + const auto meta = src_ty.get_meta_type(); bool is_slice_like = src_ty.has_slice_meta(); src_ty.wrappers.insert(src_ty.wrappers.begin(), TypeWrapper { TypeWrapper::Ty::Borrow, static_cast<size_t>(re.type) }); new_val = Value(src_ty); // ^ Pointer value new_val.write_usize(0, ofs); - if( meta ) + if( meta != RawType::Unreachable ) { LOG_ASSERT(src_base_value.m_metadata, "Borrow of an unsized value, but no metadata avaliable"); new_val.write_value(POINTER_SIZE, *src_base_value.m_metadata); @@ -1460,7 +1460,7 @@ Value MIRI_Invoke(ModuleTree& modtree, ThreadState& thread, ::HIR::Path path, :: alloc = AllocationPtr(v.m_value->allocation); } size_t ofs = v.m_offset; - assert(!ty.get_meta_type()); + assert(ty.get_meta_type() == RawType::Unreachable); auto ptr_ty = ty.wrap(TypeWrapper::Ty::Borrow, 2); @@ -1954,20 +1954,21 @@ Value MIRI_Invoke_Intrinsic(ModuleTree& modtree, ThreadState& thread, const ::st } else if( name == "offset" ) { - auto ptr_val = ::std::move(args.at(0)); + auto ptr_alloc = args.at(0).get_relocation(0); + auto ptr_ofs = args.at(0).read_usize(0); auto& ofs_val = args.at(1); - auto r = ptr_val.allocation.alloc().get_relocation(0); - auto orig_ofs = ptr_val.read_usize(0); auto delta_counts = ofs_val.read_usize(0); - auto new_ofs = orig_ofs + delta_counts * ty_params.tys.at(0).get_size(); + auto new_ofs = ptr_ofs + delta_counts * ty_params.tys.at(0).get_size(); if(POINTER_SIZE != 8) { new_ofs &= 0xFFFFFFFF; } - ptr_val.write_usize(0, new_ofs); - ptr_val.allocation.alloc().relocations.push_back({ 0, r }); - rv = ::std::move(ptr_val); + rv = ::std::move(args.at(0)); + rv.write_usize(0, new_ofs); + if( ptr_alloc ) { + rv.allocation.alloc().relocations.push_back({ 0, ptr_alloc }); + } } // effectively ptr::write else if( name == "move_val_init" ) @@ -2008,7 +2009,7 @@ Value MIRI_Invoke_Intrinsic(ModuleTree& modtree, ThreadState& thread, const ::st size_t fixed_size = 0; if( const auto* ity = ty.get_usized_type(fixed_size) ) { - const auto& meta_ty = *ty.get_meta_type(); + 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() ) diff --git a/tools/standalone_miri/module_tree.cpp b/tools/standalone_miri/module_tree.cpp index a75cfa8f..fdc8f587 100644 --- a/tools/standalone_miri/module_tree.cpp +++ b/tools/standalone_miri/module_tree.cpp @@ -32,6 +32,8 @@ struct Parser RawType parse_core_type(); ::HIR::TypeRef parse_type(); ::HIR::GenericPath parse_tuple(); + + const DataType* get_composite(::HIR::GenericPath gp); }; void ModuleTree::load_file(const ::std::string& path) @@ -1130,19 +1132,8 @@ RawType Parser::parse_core_type() // Tuples! Should point to a composite ::HIR::GenericPath gp = parse_tuple(); - // Look up this type, then create a TypeRef referring to the type in the datastore - // - May need to create an unpopulated type? - auto it = tree.data_types.find(gp); - if( it == tree.data_types.end() ) - { - // 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; - } // Good. - return ::HIR::TypeRef(it->second.get()); + return ::HIR::TypeRef( this->get_composite(::std::move(gp)) ); } else if( lex.consume_if('[') ) { @@ -1155,7 +1146,6 @@ RawType Parser::parse_core_type() } else { - // TODO: How to handle arrays? rv.wrappers.insert( rv.wrappers.begin(), { TypeWrapper::Ty::Slice, 0 }); } lex.check_consume(']'); @@ -1196,19 +1186,7 @@ RawType Parser::parse_core_type() else if( lex.next() == "::" ) { auto path = parse_genericpath(); - // Look up this type, then create a TypeRef referring to the type in the datastore - // - May need to create an unpopulated type? - auto it = tree.data_types.find(path); - if( it == tree.data_types.end() ) - { - // 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; - } - // Good. - return ::HIR::TypeRef(it->second.get()); + return ::HIR::TypeRef( this->get_composite(::std::move(path))); } else if( lex.next() == "extern" || lex.next() == "fn" || lex.next() == "unsafe" ) { @@ -1282,8 +1260,17 @@ RawType Parser::parse_core_type() markers.push_back(parse_genericpath()); } lex.consume_if(')'); - return ::HIR::TypeRef(RawType::TraitObject); - // TODO: Generate the vtable path and locate that struct + + auto rv = ::HIR::TypeRef(RawType::TraitObject); + if( base_trait != ::HIR::GenericPath() ) + { + // Generate vtable path + auto vtable_path = base_trait; + vtable_path.m_simplepath.ents.back() += "#vtable"; + // - TODO: Associated types? + rv.composite_type = this->get_composite( ::std::move(vtable_path) ); + } + return rv; } else if( lex.next() == TokenClass::Ident ) { @@ -1295,6 +1282,19 @@ RawType Parser::parse_core_type() throw "ERROR"; } } +const DataType* Parser::get_composite(::HIR::GenericPath gp) +{ + auto it = tree.data_types.find(gp); + if( it == tree.data_types.end() ) + { + // 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; + } + return it->second.get(); +} ::HIR::SimplePath ModuleTree::find_lang_item(const char* name) const { |