summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--tools/standalone_miri/main.cpp4
-rw-r--r--tools/standalone_miri/mir.cpp11
-rw-r--r--tools/standalone_miri/miri.cpp38
-rw-r--r--tools/standalone_miri/module_tree.cpp4
-rw-r--r--tools/standalone_miri/value.cpp4
-rw-r--r--tools/standalone_miri/value.hpp68
6 files changed, 95 insertions, 34 deletions
diff --git a/tools/standalone_miri/main.cpp b/tools/standalone_miri/main.cpp
index deed08be..ed9b9267 100644
--- a/tools/standalone_miri/main.cpp
+++ b/tools/standalone_miri/main.cpp
@@ -74,11 +74,11 @@ int main(int argc, const char* argv[])
// Create argc/argv based on input arguments
auto argv_alloc = Allocation::new_alloc((1 + opts.args.size()) * POINTER_SIZE);
argv_alloc->write_usize(0 * POINTER_SIZE, 0);
- argv_alloc->relocations.push_back({ 0 * POINTER_SIZE, RelocationPtr::new_ffi(FFIPointer { "", (void*)(opts.infile.c_str()), opts.infile.size() + 1 }) });
+ argv_alloc->relocations.push_back({ 0 * POINTER_SIZE, RelocationPtr::new_ffi(FFIPointer::new_const_bytes(opts.infile.c_str(), opts.infile.size() + 1)) });
for(size_t i = 0; i < opts.args.size(); i ++)
{
argv_alloc->write_usize((1 + i) * POINTER_SIZE, 0);
- argv_alloc->relocations.push_back({ (1 + i) * POINTER_SIZE, RelocationPtr::new_ffi({ "", (void*)(opts.args[0]), ::std::strlen(opts.args[0]) + 1 }) });
+ argv_alloc->relocations.push_back({ (1 + i) * POINTER_SIZE, RelocationPtr::new_ffi(FFIPointer::new_const_bytes(opts.args[0], ::std::strlen(opts.args[0]) + 1)) });
}
// Construct argc/argv values
diff --git a/tools/standalone_miri/mir.cpp b/tools/standalone_miri/mir.cpp
index a0601823..f1b4841e 100644
--- a/tools/standalone_miri/mir.cpp
+++ b/tools/standalone_miri/mir.cpp
@@ -62,10 +62,10 @@ namespace MIR {
os << "\"" << e << "\"";
),
(Const,
- os << e.p;
+ os << *e.p;
),
(ItemAddr,
- os << "&" << e;
+ os << "&" << *e;
)
)
return os;
@@ -83,7 +83,7 @@ namespace MIR {
os << "Local(" << e << ")";
),
(Static,
- os << "Static(" << e << ")";
+ os << "Static(" << *e << ")";
),
(Field,
os << "Field(" << e.field_index << ", " << *e.val << ")";
@@ -296,5 +296,10 @@ namespace MIR {
)
return os;
}
+
+ EnumCachePtr::~EnumCachePtr()
+ {
+ assert(!this->p);
+ }
}
diff --git a/tools/standalone_miri/miri.cpp b/tools/standalone_miri/miri.cpp
index 8231f2c5..d5bcb024 100644
--- a/tools/standalone_miri/miri.cpp
+++ b/tools/standalone_miri/miri.cpp
@@ -273,7 +273,7 @@ struct MirHelpers
return ValueRef(this->frame.args.at(e.idx));
} break;
TU_ARM(lv, Static, e) {
- /*const*/ auto& s = this->thread.m_modtree.get_static(e);
+ /*const*/ auto& s = this->thread.m_modtree.get_static(*e);
ty = s.ty;
return ValueRef(s.val);
} break;
@@ -482,15 +482,15 @@ struct MirHelpers
// --> Accessor
TU_ARM(c, ItemAddr, ce) {
// Create a value with a special backing allocation of zero size that references the specified item.
- if( /*const auto* fn =*/ this->thread.m_modtree.get_function_opt(ce) ) {
+ if( /*const auto* fn =*/ this->thread.m_modtree.get_function_opt(*ce) ) {
ty = ::HIR::TypeRef(RawType::Function);
- return Value::new_fnptr(ce);
+ return Value::new_fnptr(*ce);
}
- if( const auto* s = this->thread.m_modtree.get_static_opt(ce) ) {
+ if( const auto* s = this->thread.m_modtree.get_static_opt(*ce) ) {
ty = s->ty.wrapped(TypeWrapper::Ty::Borrow, 0);
return Value::new_pointer(ty, 0, RelocationPtr::new_alloc(s->val.allocation));
}
- LOG_ERROR("Constant::ItemAddr - " << ce << " - not found");
+ LOG_ERROR("Constant::ItemAddr - " << *ce << " - not found");
} break;
}
throw "";
@@ -1031,19 +1031,20 @@ bool InterpreterThread::step_one(Value& out_thread_result)
LOG_ASSERT(ty_r.get_wrapper() == nullptr, "Bitwise operator with non-primitive - " << ty_r);
size_t max_bits = ty_r.get_size() * 8;
uint8_t shift;
- auto check_cast = [&](auto v){ LOG_ASSERT(0 <= v && v <= max_bits, "Shift out of range - " << v); return static_cast<uint8_t>(v); };
+ auto check_cast_u = [&](auto v){ LOG_ASSERT(0 <= v && v <= max_bits, "Shift out of range - " << v); return static_cast<uint8_t>(v); };
+ auto check_cast_s = [&](auto v){ LOG_ASSERT(v <= static_cast<int64_t>(max_bits), "Shift out of range - " << v); return static_cast<uint8_t>(v); };
switch(ty_r.inner_type)
{
- case RawType::U64: shift = check_cast(v_r.read_u64(0)); break;
- case RawType::U32: shift = check_cast(v_r.read_u32(0)); break;
- case RawType::U16: shift = check_cast(v_r.read_u16(0)); break;
- case RawType::U8 : shift = check_cast(v_r.read_u8 (0)); break;
- case RawType::I64: shift = check_cast(v_r.read_i64(0)); break;
- case RawType::I32: shift = check_cast(v_r.read_i32(0)); break;
- case RawType::I16: shift = check_cast(v_r.read_i16(0)); break;
- case RawType::I8 : shift = check_cast(v_r.read_i8 (0)); break;
- case RawType::USize: shift = check_cast(v_r.read_usize(0)); break;
- case RawType::ISize: shift = check_cast(v_r.read_isize(0)); break;
+ case RawType::U64: shift = check_cast_u(v_r.read_u64(0)); break;
+ case RawType::U32: shift = check_cast_u(v_r.read_u32(0)); break;
+ case RawType::U16: shift = check_cast_u(v_r.read_u16(0)); break;
+ case RawType::U8 : shift = check_cast_u(v_r.read_u8 (0)); break;
+ case RawType::I64: shift = check_cast_s(v_r.read_i64(0)); break;
+ case RawType::I32: shift = check_cast_s(v_r.read_i32(0)); break;
+ case RawType::I16: shift = check_cast_s(v_r.read_i16(0)); break;
+ case RawType::I8 : shift = check_cast_s(v_r.read_i8 (0)); break;
+ case RawType::USize: shift = check_cast_u(v_r.read_usize(0)); break;
+ case RawType::ISize: shift = check_cast_s(v_r.read_isize(0)); break;
default:
LOG_TODO("BinOp shift rhs unknown type - " << se.src << " w/ " << ty_r);
}
@@ -2213,9 +2214,8 @@ bool InterpreterThread::call_intrinsic(Value& rv, const ::std::string& name, con
LOG_FATAL("Attempt to copy* a function");
break;
case RelocationPtr::Ty::FfiPointer:
- LOG_ASSERT(src_ofs <= src_alloc.ffi().size, "");
- LOG_ASSERT(byte_count <= src_alloc.ffi().size, "");
- LOG_ASSERT(src_ofs + byte_count <= src_alloc.ffi().size, "");
+ LOG_ASSERT(src_alloc.ffi().layout, "");
+ LOG_ASSERT(src_alloc.ffi().layout->is_valid_read(src_ofs, byte_count), "");
dst_alloc.alloc().write_bytes(dst_ofs, reinterpret_cast<const char*>(src_alloc.ffi().ptr_value) + src_ofs, byte_count);
break;
}
diff --git a/tools/standalone_miri/module_tree.cpp b/tools/standalone_miri/module_tree.cpp
index eb6b6b9e..984662fe 100644
--- a/tools/standalone_miri/module_tree.cpp
+++ b/tools/standalone_miri/module_tree.cpp
@@ -379,7 +379,7 @@ bool Parser::parse_one()
else if( lex.next() == "::" || lex.next() == '<' )
{
auto path = p.parse_path();
- lv = ::MIR::LValue( ::std::move(path) );
+ lv = ::MIR::LValue( ::std::make_unique<HIR::Path>(::std::move(path)) );
}
else {
LOG_ERROR(lex << "Unexpected token in LValue - " << lex.next());
@@ -464,7 +464,7 @@ bool Parser::parse_one()
else if( p.lex.consume_if("ADDROF") ) {
auto path = p.parse_path();
- return ::MIR::Constant::make_ItemAddr({ ::std::move(path) });
+ return ::MIR::Constant::make_ItemAddr({ ::std::make_unique<HIR::Path>(::std::move(path)) });
}
else {
LOG_BUG(p.lex << "BUG? " << p.lex.next());
diff --git a/tools/standalone_miri/value.cpp b/tools/standalone_miri/value.cpp
index 849d3a64..9007eb5c 100644
--- a/tools/standalone_miri/value.cpp
+++ b/tools/standalone_miri/value.cpp
@@ -167,7 +167,7 @@ size_t RelocationPtr::get_size() const
os << "\"" << x.str() << "\"";
break;
case RelocationPtr::Ty::FfiPointer:
- os << "FFI " << x.ffi().source_function << " " << x.ffi().ptr_value;
+ os << "FFI " << x.ffi().tag_name << " " << x.ffi().ptr_value;
break;
}
}
@@ -237,7 +237,7 @@ void* ValueCommonRead::read_pointer_unsafe(size_t rd_ofs, size_t req_valid, size
//if( req_valid )
// LOG_FATAL("Can't request valid data from a FFI pointer");
// TODO: Have an idea of mutability and available size from FFI
- out_size = f.size - ofs;
+ out_size = f.get_size() - ofs;
out_is_mut = false;
return reinterpret_cast<char*>(reloc.ffi().ptr_value) + ofs;
}
diff --git a/tools/standalone_miri/value.hpp b/tools/standalone_miri/value.hpp
index b057b3c4..377361ce 100644
--- a/tools/standalone_miri/value.hpp
+++ b/tools/standalone_miri/value.hpp
@@ -21,11 +21,67 @@ class Allocation;
struct Value;
struct ValueRef;
+struct FfiLayout
+{
+ struct Range {
+ size_t len;
+ bool is_valid;
+ bool is_writable;
+ };
+ ::std::vector<Range> ranges;
+
+ size_t get_size() const {
+ size_t rv = 0;
+ for(const auto& r : ranges)
+ rv += r.len;
+ return rv;
+ }
+ bool is_valid_read(size_t o, size_t s) {
+ for(const auto& r : ranges)
+ {
+ if( o < r.len ) {
+ if( !r.is_valid )
+ return false;
+ if( o + s <= r.len )
+ {
+ s = 0;
+ break;
+ }
+ s -= (r.len - o);
+ o = 0;
+ }
+ else {
+ o -= r.len;
+ }
+ }
+ if( s > 0 )
+ {
+ return false;
+ }
+ return true;
+ }
+};
struct FFIPointer
{
- const char* source_function;
+ // FFI pointers require the following:
+ // - A tag indicating where they're valid/from
+ // - A data format (e.g. size of allocation, internal data format)
+ // - If the data format is unspecified (null) then it's a void pointer
+ // - An actual pointer
+
+ // Pointer value, returned by the FFI
void* ptr_value;
- size_t size;
+ // Tag name, used for validty checking by FFI hooks
+ const char* tag_name;
+ ::std::shared_ptr<FfiLayout> layout;
+
+ static FFIPointer new_const_bytes(const void* s, size_t size) {
+ return FFIPointer { const_cast<void*>(s), "", ::std::shared_ptr<FfiLayout>() };
+ };
+
+ size_t get_size() const {
+ return (layout ? layout->get_size() : 0);
+ }
};
class AllocationHandle
@@ -83,7 +139,7 @@ public:
RelocationPtr(const RelocationPtr& x);
~RelocationPtr();
static RelocationPtr new_alloc(AllocationHandle h);
- static RelocationPtr new_fcn(::HIR::Path p);
+ static RelocationPtr new_fcn(::HIR::Path p); // TODO: What if it's a FFI function? Could be encoded in here.
static RelocationPtr new_string(const ::std::string* s); // NOTE: The string must have a stable pointer
static RelocationPtr new_ffi(FFIPointer info);
@@ -331,9 +387,9 @@ struct ValueRef:
assert(ofs+size <= m_alloc.str().size());
break;
case RelocationPtr::Ty::FfiPointer:
- assert(ofs < m_alloc.ffi().size);
- assert(size <= m_alloc.ffi().size);
- assert(ofs+size <= m_alloc.ffi().size);
+ assert(ofs < m_alloc.ffi().get_size());
+ assert(size <= m_alloc.ffi().get_size());
+ assert(ofs+size <= m_alloc.ffi().get_size());
break;
default:
throw "TODO";