Skip to content

run fullMIR tests in appveyor #401

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Jul 16, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions appveyor.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@ environment:
global:
PROJECT_NAME: miri
matrix:
- TARGET: i686-pc-windows-msvc
MSYS2_BITS: 32
- TARGET: x86_64-pc-windows-msvc
MSYS2_BITS: 64
- TARGET: i686-pc-windows-msvc
MSYS2_BITS: 32

# branches to build
branches:
Expand Down Expand Up @@ -35,6 +35,8 @@ test_script:
- set RUST_BACKTRACE=1
- cargo build --release
- cargo test --release
- set MIRI_SYSROOT=C:\Users\appveyor\.xargo\HOST
- cargo test --release

notifications:
- provider: Email
Expand Down
51 changes: 46 additions & 5 deletions src/fn_call.rs
Original file line number Diff line number Diff line change
Expand Up @@ -607,7 +607,7 @@ impl<'a, 'mir, 'tcx: 'mir + 'a> EvalContextExt<'tcx> for EvalContext<'a, 'mir, '
}

"_tlv_atexit" => {
return err!(Unimplemented("can't interpret with full mir for osx target".to_owned()));
return err!(Unimplemented("Thread-local store is not fully supported on macOS".to_owned()));
},

// Stub out all the other pthread calls to just return 0
Expand All @@ -623,12 +623,53 @@ impl<'a, 'mir, 'tcx: 'mir + 'a> EvalContextExt<'tcx> for EvalContext<'a, 'mir, '
}

// Windows API subs
"AddVectoredExceptionHandler" |
"SetThreadStackGuarantee" => {
let usize = self.tcx.types.usize;
"AddVectoredExceptionHandler" => {
// any non zero value works for the stdlib. This is just used for stackoverflows anyway
self.write_scalar(dest, Scalar::from_u128(1), usize)?;
self.write_scalar(dest, Scalar::from_u128(1), dest_ty)?;
},
"GetModuleHandleW" |
"GetProcAddress" |
"InitializeCriticalSection" |
"EnterCriticalSection" |
"TryEnterCriticalSection" |
"LeaveCriticalSection" |
"DeleteCriticalSection" |
"SetLastError" => {
// pretend these do not exist/nothing happened, by returning zero
self.write_scalar(dest, Scalar::from_u128(0), dest_ty)?;
},
"GetLastError" => {
// this is c::ERROR_CALL_NOT_IMPLEMENTED
self.write_scalar(dest, Scalar::from_u128(120), dest_ty)?;
},

// Windows TLS
"TlsAlloc" => {
// This just creates a key; Windows does not natively support TLS dtors.

// Figure out how large a TLS key actually is. This is c::DWORD.
let key_size = self.layout_of(dest_ty)?.size;

// Create key and return it
let key = self.memory.create_tls_key(None) as u128;
if key_size.bits() < 128 && key >= (1u128 << key_size.bits() as u128) {
return err!(OutOfTls);
}
self.write_scalar(dest, Scalar::from_u128(key), dest_ty)?;
}
"TlsGetValue" => {
let key = self.value_to_scalar(args[0])?.to_bytes()?;
let ptr = self.memory.load_tls(key)?;
self.write_ptr(dest, ptr, dest_ty)?;
}
"TlsSetValue" => {
let key = self.value_to_scalar(args[0])?.to_bytes()?;
let new_ptr = self.into_ptr(args[1].value)?;
self.memory.store_tls(key, new_ptr)?;

// Return success (1)
self.write_scalar(dest, Scalar::from_u128(1), dest_ty)?;
}

// We can't execute anything else
_ => {
Expand Down
20 changes: 18 additions & 2 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,12 @@ pub fn create_ecx<'a, 'mir: 'a, 'tcx: 'mir>(
main_id: DefId,
start_wrapper: Option<DefId>,
) -> EvalResult<'tcx, (EvalContext<'a, 'mir, 'tcx, Evaluator<'tcx>>, Option<Pointer>)> {
let mut ecx = EvalContext::new(tcx.at(syntax::codemap::DUMMY_SP), ty::ParamEnv::reveal_all(), Default::default(), Default::default());
let mut ecx = EvalContext::new(
tcx.at(syntax::codemap::DUMMY_SP),
ty::ParamEnv::reveal_all(),
Default::default(),
MemoryData::new()
);

let main_instance = ty::Instance::mono(ecx.tcx.tcx, main_id);
let main_mir = ecx.load_mir(main_instance.def)?;
Expand Down Expand Up @@ -338,7 +343,7 @@ pub struct TlsEntry<'tcx> {
dtor: Option<ty::Instance<'tcx>>,
}

#[derive(Clone, Default, PartialEq, Eq)]
#[derive(Clone, PartialEq, Eq)]
pub struct MemoryData<'tcx> {
/// The Key to use for the next thread-local allocation.
next_thread_local: TlsKey,
Expand All @@ -355,6 +360,17 @@ pub struct MemoryData<'tcx> {
statics: HashMap<GlobalId<'tcx>, AllocId>,
}

impl<'tcx> MemoryData<'tcx> {
fn new() -> Self {
MemoryData {
next_thread_local: 1, // start with 1 as we must not use 0 on Windows
thread_local: BTreeMap::new(),
locks: HashMap::new(),
statics: HashMap::new(),
}
}
}

impl<'tcx> Hash for MemoryData<'tcx> {
fn hash<H: Hasher>(&self, state: &mut H) {
let MemoryData {
Expand Down
1 change: 1 addition & 0 deletions src/tls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,7 @@ impl<'a, 'mir, 'tcx: 'mir + 'a> EvalContextExt<'tcx> for EvalContext<'a, 'mir, '
None => self.memory.fetch_tls_dtor(None)?,
};
}
// FIXME: On a windows target, call `unsafe extern "system" fn on_tls_callback`.
Ok(())
}
}