summaryrefslogtreecommitdiff
path: root/tools/standalone_miri/main.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'tools/standalone_miri/main.cpp')
-rw-r--r--tools/standalone_miri/main.cpp166
1 files changed, 129 insertions, 37 deletions
diff --git a/tools/standalone_miri/main.cpp b/tools/standalone_miri/main.cpp
index 3fc807c5..703a6fab 100644
--- a/tools/standalone_miri/main.cpp
+++ b/tools/standalone_miri/main.cpp
@@ -7,6 +7,10 @@
#include <algorithm>
#include <iomanip>
#include "debug.hpp"
+#ifdef _WIN32
+# define NOMINMAX
+# include <Windows.h>
+#endif
struct ProgramOptions
{
@@ -40,11 +44,24 @@ int main(int argc, const char* argv[])
val_argc.write_bytes(0, "\0\0\0", 4);
val_argv.write_bytes(0, "\0\0\0\0\0\0\0", argv_ty.get_size());
- ::std::vector<Value> args;
- args.push_back(::std::move(val_argc));
- args.push_back(::std::move(val_argv));
- auto rv = MIRI_Invoke( tree, tree.find_lang_item("start"), ::std::move(args) );
- ::std::cout << rv << ::std::endl;
+ try
+ {
+ ::std::vector<Value> args;
+ args.push_back(::std::move(val_argc));
+ args.push_back(::std::move(val_argv));
+ auto rv = MIRI_Invoke( tree, tree.find_lang_item("start"), ::std::move(args) );
+ ::std::cout << rv << ::std::endl;
+ }
+ catch(const DebugExceptionTodo& /*e*/)
+ {
+ ::std::cerr << "TODO Hit" << ::std::endl;
+ return 1;
+ }
+ catch(const DebugExceptionError& /*e*/)
+ {
+ ::std::cerr << "Error encountered" << ::std::endl;
+ throw;
+ }
return 0;
}
@@ -273,9 +290,20 @@ struct Ops {
Value MIRI_Invoke(ModuleTree& modtree, ::HIR::Path path, ::std::vector<Value> args)
{
- TRACE_FUNCTION_R(path, "");
+ Value ret;
+ TRACE_FUNCTION_R(path, path << " = " << ret);
+
+
+ // TODO: Support overriding certain functions
+ {
+ if( path == ::HIR::SimplePath { "std", { "sys", "imp", "c", "SetThreadStackGuarantee" } } )
+ {
+ ret = Value(::HIR::TypeRef{RawType::I32});
+ ret.write_i32(0, 120); // ERROR_CALL_NOT_IMPLEMENTED
+ return ret;
+ }
+ }
- LOG_DEBUG(path);
const auto& fcn = modtree.get_function(path);
for(size_t i = 0; i < args.size(); i ++)
{
@@ -285,22 +313,25 @@ Value MIRI_Invoke(ModuleTree& modtree, ::HIR::Path path, ::std::vector<Value> ar
if( fcn.external.link_name != "" )
{
// External function!
- return MIRI_Invoke_Extern(fcn.external.link_name, fcn.external.link_abi, ::std::move(args));
+ ret = MIRI_Invoke_Extern(fcn.external.link_name, fcn.external.link_abi, ::std::move(args));
+ return ret;
}
+ ret = Value(fcn.ret_ty == RawType::Unreachable ? ::HIR::TypeRef() : fcn.ret_ty);
+
struct State
{
ModuleTree& modtree;
const Function& fcn;
- Value ret;
+ Value& ret;
::std::vector<Value> args;
::std::vector<Value> locals;
::std::vector<bool> drop_flags;
- State(ModuleTree& modtree, const Function& fcn, ::std::vector<Value> args):
+ State(ModuleTree& modtree, const Function& fcn, Value& ret, ::std::vector<Value> args):
modtree(modtree),
fcn(fcn),
- ret(fcn.ret_ty == RawType::Unreachable ? ::HIR::TypeRef() : fcn.ret_ty),
+ ret(ret),
args(::std::move(args)),
drop_flags(fcn.m_mir.drop_flags)
{
@@ -552,7 +583,7 @@ Value MIRI_Invoke(ModuleTree& modtree, ::HIR::Path path, ::std::vector<Value> ar
}
throw "";
}
- } state { modtree, fcn, ::std::move(args) };
+ } state { modtree, fcn, ret, ::std::move(args) };
size_t bb_idx = 0;
for(;;)
@@ -764,18 +795,75 @@ Value MIRI_Invoke(ModuleTree& modtree, ::HIR::Path path, ::std::vector<Value> ar
// Can be an integer, or F32 (pointer is impossible atm)
switch(src_ty.inner_type)
{
- case RawType::Unreachable: throw "BUG";
- case RawType::Composite: throw "ERROR";
- case RawType::TraitObject: throw "ERROR";
+ case RawType::Unreachable:
+ LOG_BUG("Casting unreachable");
+ case RawType::TraitObject:
+ case RawType::Str:
+ LOG_FATAL("Cast of unsized type - " << src_ty);
case RawType::Function:
LOG_ASSERT(re.type.inner_type == RawType::USize, "");
new_val = src_value.read_value(0, re.type.get_size());
break;
- case RawType::Char: LOG_TODO("Cast char to integer (only u32)");
- case RawType::Str: throw "ERROR";
- case RawType::Unit: throw "ERROR";
- case RawType::Bool: throw "ERROR";
- case RawType::F64: throw "BUG";
+ case RawType::Char:
+ LOG_TODO("Cast char to integer (only u32)");
+ case RawType::Unit:
+ LOG_FATAL("Cast of unit");
+ case RawType::Composite: {
+ const auto& dt = *src_ty.composite_type;
+ if( dt.variants.size() == 0 ) {
+ LOG_FATAL("Cast of composite - " << src_ty);
+ }
+ // TODO: Check that all variants have the same tag offset
+ LOG_ASSERT(dt.fields.size() == 1, "");
+ LOG_ASSERT(dt.fields[0].first == 0, "");
+ for(size_t i = 0; i < dt.variants.size(); i ++ ) {
+ LOG_ASSERT(dt.variants[i].base_field == 0, "");
+ LOG_ASSERT(dt.variants[i].field_path.empty(), "");
+ }
+ ::HIR::TypeRef tag_ty = dt.fields[0].second;
+ LOG_ASSERT(tag_ty.wrappers.empty(), "");
+ switch(tag_ty.inner_type)
+ {
+ case RawType::USize:
+ dst_val = static_cast<uint64_t>( src_value.read_usize(0) );
+ if(0)
+ case RawType::ISize:
+ dst_val = static_cast<uint64_t>( src_value.read_isize(0) );
+ if(0)
+ case RawType::U8:
+ dst_val = static_cast<uint64_t>( src_value.read_u8 (0) );
+ if(0)
+ case RawType::I8:
+ dst_val = static_cast<uint64_t>( src_value.read_i8 (0) );
+ if(0)
+ case RawType::U16:
+ dst_val = static_cast<uint64_t>( src_value.read_u16(0) );
+ if(0)
+ case RawType::I16:
+ dst_val = static_cast<uint64_t>( src_value.read_i16(0) );
+ if(0)
+ case RawType::U32:
+ dst_val = static_cast<uint64_t>( src_value.read_u32(0) );
+ if(0)
+ case RawType::I32:
+ dst_val = static_cast<uint64_t>( src_value.read_i32(0) );
+ if(0)
+ case RawType::U64:
+ dst_val = static_cast<uint64_t>( src_value.read_u64(0) );
+ if(0)
+ case RawType::I64:
+ dst_val = static_cast<uint64_t>( src_value.read_i64(0) );
+ break;
+ default:
+ LOG_FATAL("Bad tag type in cast - " << tag_ty);
+ }
+ } if(0)
+ case RawType::Bool:
+ dst_val = static_cast<uint64_t>( src_value.read_u8 (0) );
+ if(0)
+ case RawType::F64:
+ dst_val = static_cast<uint64_t>( src_value.read_f64(0) );
+ if(0)
case RawType::F32:
dst_val = static_cast<uint64_t>( src_value.read_f32(0) );
if(0)
@@ -889,21 +977,16 @@ Value MIRI_Invoke(ModuleTree& modtree, ::HIR::Path path, ::std::vector<Value> ar
{
switch(ty_l.inner_type)
{
- case RawType::U64:
- res = res != 0 ? res : Ops::do_compare(v_l.read_u64(0), v_r.read_u64(0));
- break;
- case RawType::U32:
- res = res != 0 ? res : Ops::do_compare(v_l.read_u32(0), v_r.read_u32(0));
- break;
- case RawType::U16:
- res = res != 0 ? res : Ops::do_compare(v_l.read_u16(0), v_r.read_u16(0));
- break;
- case RawType::U8:
- res = res != 0 ? res : Ops::do_compare(v_l.read_u8(0), v_r.read_u8(0));
- break;
- case RawType::USize:
- res = res != 0 ? res : Ops::do_compare(v_l.read_usize(0), v_r.read_usize(0));
- break;
+ case RawType::U64: res = res != 0 ? res : Ops::do_compare(v_l.read_u64(0), v_r.read_u64(0)); break;
+ case RawType::U32: res = res != 0 ? res : Ops::do_compare(v_l.read_u32(0), v_r.read_u32(0)); break;
+ case RawType::U16: res = res != 0 ? res : Ops::do_compare(v_l.read_u16(0), v_r.read_u16(0)); break;
+ case RawType::U8 : res = res != 0 ? res : Ops::do_compare(v_l.read_u8 (0), v_r.read_u8 (0)); break;
+ case RawType::I64: res = res != 0 ? res : Ops::do_compare(v_l.read_i64(0), v_r.read_i64(0)); break;
+ case RawType::I32: res = res != 0 ? res : Ops::do_compare(v_l.read_i32(0), v_r.read_i32(0)); break;
+ case RawType::I16: res = res != 0 ? res : Ops::do_compare(v_l.read_i16(0), v_r.read_i16(0)); break;
+ case RawType::I8 : res = res != 0 ? res : Ops::do_compare(v_l.read_i8 (0), v_r.read_i8 (0)); break;
+ case RawType::USize: res = res != 0 ? res : Ops::do_compare(v_l.read_usize(0), v_r.read_usize(0)); break;
+ case RawType::ISize: res = res != 0 ? res : Ops::do_compare(v_l.read_isize(0), v_r.read_isize(0)); break;
default:
LOG_TODO("BinOp comparisons - " << se.src << " w/ " << ty_l);
}
@@ -1373,6 +1456,15 @@ Value MIRI_Invoke_Extern(const ::std::string& link_name, const ::std::string& ab
rv.write_usize(0, 1);
return rv;
}
+#ifdef _WIN32
+ else if( link_name == "GetModuleHandleW" )
+ {
+ const void* arg0 = (args.at(0).allocation ? args.at(0).allocation.alloc().data_ptr() : nullptr);
+ //extern void* GetModuleHandleW(const void* s);
+
+ return Value::new_ffiptr(FFIPointer { "GetModuleHandleW", GetModuleHandleW(static_cast<LPCWSTR>(arg0)) });
+ }
+#endif
// Allocators!
else if( link_name == "__rust_allocate" )
{
@@ -1596,8 +1688,8 @@ Value MIRI_Invoke_Intrinsic(const ModuleTree& modtree, const ::std::string& name
case AllocationPtr::Ty::Function:
LOG_FATAL("Attempt to copy* a function");
break;
- case AllocationPtr::Ty::Unused2:
- LOG_BUG("Unused tag");
+ case AllocationPtr::Ty::FfiPointer:
+ LOG_BUG("Trying to copy from a FFI pointer");
break;
}
}