summaryrefslogtreecommitdiff
path: root/tools/standalone_miri
diff options
context:
space:
mode:
authorJohn Hodge <tpg@mutabah.net>2018-05-13 09:27:13 +0800
committerJohn Hodge <tpg@mutabah.net>2018-05-13 09:27:13 +0800
commitac6f3ffba823e539c4c9afd93b7edf7122f463cc (patch)
tree418ebc63c6d5a28560bb396f1992505e80182515 /tools/standalone_miri
parent9f8469d5145ea51f2d4b2b9d1eb32d1029cfbeb5 (diff)
downloadmrust-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.cpp30
-rw-r--r--tools/standalone_miri/hir_sim.hpp6
-rw-r--r--tools/standalone_miri/main.cpp31
-rw-r--r--tools/standalone_miri/module_tree.cpp56
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
{