summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--tools/standalone_miri/hir_sim.cpp68
-rw-r--r--tools/standalone_miri/hir_sim.hpp32
-rw-r--r--tools/standalone_miri/miri.cpp35
-rw-r--r--tools/standalone_miri/module_tree.cpp11
-rw-r--r--tools/standalone_miri/module_tree.hpp20
5 files changed, 118 insertions, 48 deletions
diff --git a/tools/standalone_miri/hir_sim.cpp b/tools/standalone_miri/hir_sim.cpp
index dc03ca8a..135ea214 100644
--- a/tools/standalone_miri/hir_sim.cpp
+++ b/tools/standalone_miri/hir_sim.cpp
@@ -42,18 +42,18 @@ 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 )
{
- if( this->composite_type->dst_meta == RawType::Unreachable )
+ 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 )
+ if( this->composite_type().dst_meta == RawType::Unit )
{
return POINTER_SIZE;
}
// TODO: Ideally, this inner type wouldn't be unsized itself... but checking that would be interesting.
- return POINTER_SIZE + this->composite_type->dst_meta.get_size();
+ return POINTER_SIZE + this->composite_type().dst_meta.get_size();
}
else if( this->inner_type == RawType::Str )
return POINTER_SIZE*2;
@@ -77,8 +77,8 @@ size_t HIR::TypeRef::get_size(size_t ofs) const
return 0;
case RawType::Composite:
// NOTE: Don't care if the type has metadata
- LOG_ASSERT(this->composite_type->populated, "Getting size of non-defined type - " << *this);
- return this->composite_type->size;
+ LOG_ASSERT(this->composite_type().populated, "Getting size of non-defined type - " << *this);
+ return this->composite_type().size;
case RawType::Unreachable:
LOG_BUG("Attempting to get size of an unreachable type, " << *this);
case RawType::TraitObject:
@@ -126,8 +126,8 @@ size_t HIR::TypeRef::get_align(size_t ofs) const
return 1;
case RawType::Composite:
// NOTE: Don't care if the type has metadata
- LOG_ASSERT(this->composite_type->populated, "Getting alignment of non-defined type - " << *this);
- return this->composite_type->alignment;
+ LOG_ASSERT(this->composite_type().populated, "Getting alignment of non-defined type - " << *this);
+ return this->composite_type().alignment;
case RawType::TraitObject:
case RawType::Str:
return 1;
@@ -217,7 +217,7 @@ bool HIR::TypeRef::has_pointer() const
if( this->inner_type == RawType::Composite )
{
// Still not sure, check the inner for any pointers.
- for(const auto& fld : this->composite_type->fields)
+ for(const auto& fld : this->composite_type().fields)
{
if( fld.second.has_pointer() )
return true;
@@ -245,13 +245,13 @@ const HIR::TypeRef* HIR::TypeRef::get_unsized_type(size_t& running_inner_size) c
switch(this->inner_type)
{
case RawType::Composite:
- if(!this->composite_type->variants.empty())
+ if(!this->composite_type().variants.empty())
return nullptr;
- if(this->composite_type->fields.empty())
+ if(this->composite_type().fields.empty())
return nullptr;
- running_inner_size = this->composite_type->fields.back().first;
+ running_inner_size = this->composite_type().fields.back().first;
size_t tmp;
- return this->composite_type->fields.back().second.get_unsized_type(tmp);
+ return this->composite_type().fields.back().second.get_unsized_type(tmp);
case RawType::TraitObject:
case RawType::Str:
return this;
@@ -278,11 +278,12 @@ HIR::TypeRef HIR::TypeRef::get_meta_type() const
switch(this->inner_type)
{
case RawType::Composite:
- if( this->composite_type->dst_meta == RawType::Unreachable )
+ if( this->composite_type().dst_meta == RawType::Unreachable )
return TypeRef(RawType::Unreachable);
- return this->composite_type->dst_meta;
+ return this->composite_type().dst_meta;
case RawType::TraitObject:
- return ::HIR::TypeRef(this->composite_type).wrap( TypeWrapper::Ty::Pointer, static_cast<size_t>(BorrowType::Shared) );
+ LOG_ASSERT(this->ptr.composite_type, "get_meta_type - " << *this);
+ return ::HIR::TypeRef(this->ptr.composite_type).wrap( TypeWrapper::Ty::Pointer, static_cast<size_t>(BorrowType::Shared) );
case RawType::Str:
return TypeRef(RawType::USize);
default:
@@ -316,9 +317,9 @@ HIR::TypeRef HIR::TypeRef::get_field(size_t idx, size_t& ofs) const
{
if( this->inner_type == RawType::Composite )
{
- LOG_ASSERT(idx < this->composite_type->fields.size(), "Field " << idx << " out of bounds in type " << *this);
- ofs = this->composite_type->fields.at(idx).first;
- return this->composite_type->fields.at(idx).second;
+ LOG_ASSERT(idx < this->composite_type().fields.size(), "Field " << idx << " out of bounds in type " << *this);
+ ofs = this->composite_type().fields.at(idx).first;
+ return this->composite_type().fields.at(idx).second;
}
else
{
@@ -330,14 +331,14 @@ size_t HIR::TypeRef::get_field_ofs(size_t base_idx, const ::std::vector<size_t>&
{
assert(this->wrappers.size() == 0);
assert(this->inner_type == RawType::Composite);
- size_t ofs = this->composite_type->fields.at(base_idx).first;
- const auto* ty_p = &this->composite_type->fields.at(base_idx).second;
+ size_t ofs = this->composite_type().fields.at(base_idx).first;
+ const auto* ty_p = &this->composite_type().fields.at(base_idx).second;
for(auto idx : other_idx)
{
assert(ty_p->wrappers.size() == 0);
assert(ty_p->inner_type == RawType::Composite);
- ofs += ty_p->composite_type->fields.at(idx).first;
- ty_p = &ty_p->composite_type->fields.at(idx).second;
+ ofs += ty_p->composite_type().fields.at(idx).first;
+ ty_p = &ty_p->composite_type().fields.at(idx).second;
}
ty = *ty_p;
return ofs;
@@ -394,19 +395,30 @@ namespace HIR {
os << "()";
break;
case RawType::Composite:
- os << x.composite_type->my_path;
+ os << x.composite_type().my_path;
//os << "composite_" << x.composite_type;
break;
case RawType::Unreachable:
os << "!";
break;
- case RawType::Function:
- os << "function_?";
- break;
+ case RawType::Function: {
+ assert( x.ptr.function_type );
+ const auto& ft = *x.ptr.function_type;
+ if( ft.unsafe )
+ os << "unsafe ";
+ if( ft.abi != "Rust" )
+ os << "extern \"" << ft.abi << "\" ";
+ os << "fn( ";
+ for(const auto& a : ft.args)
+ os << a << ", ";
+ os << ")";
+ if( ft.ret != RawType::Unit )
+ os << "-> " << ft.ret;
+ } break;
case RawType::TraitObject:
os << "dyn ";
- if( x.composite_type )
- os << x.composite_type->my_path;
+ if( x.ptr.composite_type )
+ os << x.composite_type().my_path;
else
os << "?";
break;
diff --git a/tools/standalone_miri/hir_sim.hpp b/tools/standalone_miri/hir_sim.hpp
index 9483f1bb..81d3635a 100644
--- a/tools/standalone_miri/hir_sim.hpp
+++ b/tools/standalone_miri/hir_sim.hpp
@@ -28,6 +28,7 @@ enum Ordering
#endif
struct DataType;
+struct FunctionType;
enum class RawType
{
@@ -77,7 +78,6 @@ struct TypeWrapper
}
};
-
namespace HIR {
enum class BorrowType
@@ -97,24 +97,35 @@ namespace HIR {
// Top to bottom list of wrappers (first entry is the outermost wrapper)
::std::vector<TypeWrapper> wrappers;
RawType inner_type = RawType::Unit;
- const DataType* composite_type = nullptr;
+ union {
+ const DataType* composite_type;
+ const FunctionType* function_type;
+ } ptr;
TypeRef()
{
+ ptr.composite_type = nullptr;
}
explicit TypeRef(const DataType* dt):
- inner_type(RawType::Composite),
- composite_type(dt)
+ inner_type(RawType::Composite)
+ {
+ ptr.composite_type = dt;
+ }
+ explicit TypeRef(const FunctionType* fp):
+ inner_type(RawType::Function)
{
+ ptr.function_type = fp;
}
explicit TypeRef(RawType rt):
inner_type(rt)
{
+ ptr.composite_type = nullptr;
}
explicit TypeRef(CoreType ct):
inner_type(ct.raw_type)
{
+ ptr.composite_type = nullptr;
}
static TypeRef diverge() {
TypeRef rv;
@@ -165,6 +176,17 @@ namespace HIR {
// 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;
+ const DataType& composite_type() const {
+ assert(inner_type == RawType::Composite || inner_type == RawType::TraitObject);
+ assert(ptr.composite_type);
+ return *ptr.composite_type;
+ }
+ const FunctionType& function_type() const {
+ assert(inner_type == RawType::Function);
+ assert(ptr.function_type);
+ return *ptr.function_type;
+ }
+
bool operator==(const RawType& x) const {
if( this->wrappers.size() != 0 )
return false;
@@ -176,7 +198,7 @@ namespace HIR {
Ordering ord(const TypeRef& x) const {
__ORD(wrappers);
__ORD_C(int, inner_type);
- __ORD_C(uintptr_t, composite_type);
+ __ORD_C(uintptr_t, ptr.composite_type); // pointer comparison only
return OrdEqual;
}
bool operator==(const TypeRef& x) const {
diff --git a/tools/standalone_miri/miri.cpp b/tools/standalone_miri/miri.cpp
index 1a235880..ab7e2e22 100644
--- a/tools/standalone_miri/miri.cpp
+++ b/tools/standalone_miri/miri.cpp
@@ -909,7 +909,7 @@ bool InterpreterThread::step_one(Value& out_thread_result)
case RawType::Unit:
LOG_FATAL("Cast of unit");
case RawType::Composite: {
- const auto& dt = *src_ty.composite_type;
+ const auto& dt = src_ty.composite_type();
if( dt.variants.size() == 0 ) {
LOG_FATAL("Cast of composite - " << src_ty);
}
@@ -1418,10 +1418,18 @@ bool InterpreterThread::step_one(Value& out_thread_result)
state.get_value_and_type(se.dst, dst_ty);
new_val = Value(dst_ty);
- for(size_t i = 0; i < re.vals.size(); i++)
+ if( dst_ty.inner_type == RawType::Unit )
+ {
+ LOG_ASSERT(re.vals.size() == 0 , "");
+ }
+ else
{
- auto fld_ofs = dst_ty.composite_type->fields.at(i).first;
- new_val.write_value(fld_ofs, state.param_to_value(re.vals[i]));
+ LOG_ASSERT(dst_ty.inner_type == RawType::Composite, dst_ty);
+ for(size_t i = 0; i < re.vals.size(); i++)
+ {
+ auto fld_ofs = dst_ty.composite_type().fields.at(i).first;
+ new_val.write_value(fld_ofs, state.param_to_value(re.vals[i]));
+ }
}
} break;
TU_ARM(se.src, Array, re) {
@@ -1489,7 +1497,8 @@ bool InterpreterThread::step_one(Value& out_thread_result)
::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");
+ LOG_ASSERT(dst_ty.inner_type == RawType::Composite, dst_ty);
+ LOG_ASSERT(dst_ty.ptr.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++)
{
@@ -1579,9 +1588,9 @@ bool InterpreterThread::step_one(Value& out_thread_result)
// TODO: Convert the variant list into something that makes it easier to switch on.
size_t found_target = SIZE_MAX;
size_t default_target = SIZE_MAX;
- for(size_t i = 0; i < ty.composite_type->variants.size(); i ++)
+ for(size_t i = 0; i < ty.composite_type().variants.size(); i ++)
{
- const auto& var = ty.composite_type->variants[i];
+ const auto& var = ty.composite_type().variants[i];
if( var.tag_data.size() == 0 )
{
// Save as the default, error for multiple defaults
@@ -2589,10 +2598,10 @@ bool InterpreterThread::call_intrinsic(Value& rv, const RcString& name, const ::
size_t fallback = SIZE_MAX;
size_t found_index = SIZE_MAX;
- assert(ty.composite_type);
- for(size_t i = 0; i < ty.composite_type->variants.size(); i ++)
+ LOG_ASSERT(ty.inner_type == RawType::Composite, "discriminant_value " << ty);
+ for(size_t i = 0; i < ty.composite_type().variants.size(); i ++)
{
- const auto& var = ty.composite_type->variants[i];
+ const auto& var = ty.composite_type().variants[i];
if( var.tag_data.size() == 0 )
{
// Only seen in Option<NonNull>
@@ -3135,10 +3144,10 @@ bool InterpreterThread::drop_value(Value ptr, const ::HIR::TypeRef& ty, bool is_
m_stack.insert( m_stack.end() - 1, StackFrame::make_wrapper([this,pty,ity,ptr_reloc,count, i,ofs](Value& rv, Value drop_rv) mutable {
assert(i < count);
i ++;
+ ofs += ity.get_size();
if( i < count )
{
auto ptr = Value::new_pointer(pty, ofs, ptr_reloc);
- ofs += ity.get_size();
assert(!drop_value(ptr, ity));
return false;
}
@@ -3162,12 +3171,12 @@ bool InterpreterThread::drop_value(Value ptr, const ::HIR::TypeRef& ty, bool is_
{
if( ty.inner_type == RawType::Composite )
{
- if( ty.composite_type->drop_glue != ::HIR::Path() )
+ if( ty.composite_type().drop_glue != ::HIR::Path() )
{
LOG_DEBUG("Drop - " << ty);
Value tmp;
- return this->call_path(tmp, ty.composite_type->drop_glue, { ptr });
+ return this->call_path(tmp, ty.composite_type().drop_glue, { ptr });
}
else
{
diff --git a/tools/standalone_miri/module_tree.cpp b/tools/standalone_miri/module_tree.cpp
index 2d1eb838..91d82d85 100644
--- a/tools/standalone_miri/module_tree.cpp
+++ b/tools/standalone_miri/module_tree.cpp
@@ -1229,7 +1229,14 @@ RawType Parser::parse_core_type()
{
ret_ty = ::HIR::TypeRef::unit();
}
- return ::HIR::TypeRef(RawType::Function);
+ auto ft = FunctionType {
+ is_unsafe,
+ ::std::move(abi),
+ ::std::move(args),
+ ::std::move(ret_ty)
+ };
+ const auto* ft_p = &*tree.function_types.insert(::std::move(ft)).first;
+ return ::HIR::TypeRef(ft_p);
// TODO: Use abi/ret_ty/args as part of that
}
else if( lex.consume_if("dyn") )
@@ -1294,7 +1301,7 @@ RawType Parser::parse_core_type()
vtable_path.m_params.tys.push_back( ::std::move(atys[0].second) );
}
// - TODO: Associated types? (Need to ensure ordering is correct)
- rv.composite_type = this->get_composite( ::std::move(vtable_path) );
+ rv.ptr.composite_type = this->get_composite( ::std::move(vtable_path) );
}
else
{
diff --git a/tools/standalone_miri/module_tree.hpp b/tools/standalone_miri/module_tree.hpp
index 5da8439f..299aa51c 100644
--- a/tools/standalone_miri/module_tree.hpp
+++ b/tools/standalone_miri/module_tree.hpp
@@ -49,6 +49,8 @@ class ModuleTree
// Hack: Tuples are stored as `::""::<A,B,C,...>`
::std::map<::HIR::GenericPath, ::std::unique_ptr<DataType>> data_types;
+ ::std::set<FunctionType> function_types; // note: insertion doesn't invaliate pointers.
+
::std::map<::std::string, const Function*> ext_functions;
public:
ModuleTree();
@@ -95,3 +97,21 @@ struct DataType
};
::std::vector<VariantValue> variants;
};
+
+struct FunctionType
+{
+ bool unsafe;
+ ::std::string abi;
+ ::std::vector<HIR::TypeRef> args;
+ HIR::TypeRef ret;
+
+ bool operator<(const FunctionType& x) const {
+ #define _(f) if(f != x.f) return f < x.f
+ _(unsafe);
+ _(abi);
+ _(args);
+ _(ret);
+ #undef _
+ return false;
+ }
+};