diff --git a/appveyor.yml b/appveyor.yml index 513d3d4193..10e8a513e0 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,19 +1,15 @@ +os: Visual Studio 2017 environment: matrix: - - TARGET: x86_64-pc-windows-gnu - BITS: 64 - MSYS2: 1 - TARGET: x86_64-pc-windows-msvc - BITS: 64 install: - appveyor DownloadFile https://win.rustup.rs/ -FileName rustup-init.exe - rustup-init.exe -yv --default-host %target% - set PATH=%PATH%;%USERPROFILE%\.cargo\bin - - if defined MSYS2 set PATH=C:\msys64\mingw%BITS%\bin;%PATH% - rustc -vV - cargo -vV - git submodule update --init --recursive build: false test_script: - - cargo build --verbose --all + - set RUST_BACKTRACE=1 - cargo test --verbose --all diff --git a/build.rs b/build.rs index 34f33e6db4..d5b74a2048 100644 --- a/build.rs +++ b/build.rs @@ -87,11 +87,13 @@ fn write_testsuite_tests(out: &mut File, dir_entry: DirEntry, testsuite: &str) - " .expect(\"instantiating \\\"spectest\\\"\");" )?; writeln!(out, " wast_context")?; - writeln!( - out, - " .run_file(&*isa, Path::new(\"{}\"))", - path.display() - )?; + write!(out, " .run_file(&*isa, Path::new(\"")?; + // Write out the string with escape_debug to prevent special characters such + // as backslash from being reinterpreted. + for c in path.display().to_string().chars() { + write!(out, "{}", c.escape_debug())?; + } + writeln!(out, "\"))")?; writeln!(out, " .expect(\"error running wast file\");",)?; writeln!(out, " }}")?; writeln!(out)?; diff --git a/lib/execute/Cargo.toml b/lib/execute/Cargo.toml index e3841a44cc..1e6e14042b 100644 --- a/lib/execute/Cargo.toml +++ b/lib/execute/Cargo.toml @@ -19,6 +19,7 @@ wasmtime-runtime = { path = "../runtime" } region = "1.0.0" failure = { version = "0.1.3", default-features = false } failure_derive = { version = "0.1.3", default-features = false } +target-lexicon = "0.2.0" [features] default = ["std"] diff --git a/lib/execute/src/instance_plus.rs b/lib/execute/src/instance_plus.rs index 8fc2686083..e22d58fe71 100644 --- a/lib/execute/src/instance_plus.rs +++ b/lib/execute/src/instance_plus.rs @@ -12,9 +12,10 @@ use std::slice; use std::string::String; use std::vec::Vec; use std::{mem, ptr}; +use target_tunables::target_tunables; use trampoline_park::TrampolinePark; use wasmtime_environ::{ - compile_module, Compilation, CompileError, DataInitializer, Module, ModuleEnvironment, Tunables, + compile_module, Compilation, CompileError, DataInitializer, Module, ModuleEnvironment, }; use wasmtime_runtime::{ wasmtime_call_trampoline, Export, Imports, Instance, InstantiationError, VMFunctionBody, @@ -42,9 +43,7 @@ impl InstancePlus { resolver: &mut Resolver, ) -> Result { let mut module = Module::new(); - - // TODO: Allow the tunables to be overridden. - let tunables = Tunables::default(); + let tunables = target_tunables(isa.triple()); let (lazy_function_body_inputs, lazy_data_initializers) = { let environ = ModuleEnvironment::new(isa, &mut module, tunables); diff --git a/lib/execute/src/lib.rs b/lib/execute/src/lib.rs index 4b440ba868..a2e7edc3d8 100644 --- a/lib/execute/src/lib.rs +++ b/lib/execute/src/lib.rs @@ -37,12 +37,14 @@ extern crate alloc; extern crate failure; #[macro_use] extern crate failure_derive; +extern crate target_lexicon; mod action; mod instance_plus; mod jit_code; mod link; mod resolver; +mod target_tunables; mod trampoline_park; pub use action::{ActionError, ActionOutcome, RuntimeValue}; @@ -50,6 +52,7 @@ pub use instance_plus::InstancePlus; pub use jit_code::JITCode; pub use link::link_module; pub use resolver::{NullResolver, Resolver}; +pub use target_tunables::target_tunables; #[cfg(not(feature = "std"))] mod std { diff --git a/lib/execute/src/link.rs b/lib/execute/src/link.rs index 4f69280259..7b1574986d 100644 --- a/lib/execute/src/link.rs +++ b/lib/execute/src/link.rs @@ -320,7 +320,10 @@ fn relocate( FloorF64 => wasmtime_f64_floor as usize, TruncF64 => wasmtime_f64_trunc as usize, NearestF64 => wasmtime_f64_nearest as usize, + #[cfg(not(target_os = "windows"))] Probestack => __rust_probestack as usize, + #[cfg(all(target_os = "windows", target_pointer_width = "64"))] + Probestack => __chkstk as usize, other => panic!("unexpected libcall: {}", other), } } @@ -357,5 +360,8 @@ fn relocate( /// A declaration for the stack probe function in Rust's standard library, for /// catching callstack overflow. extern "C" { + #[cfg(not(target_os = "windows"))] pub fn __rust_probestack(); + #[cfg(all(target_os = "windows", target_pointer_width = "64"))] + pub fn __chkstk(); } diff --git a/lib/execute/src/target_tunables.rs b/lib/execute/src/target_tunables.rs new file mode 100644 index 0000000000..2fd5b4848f --- /dev/null +++ b/lib/execute/src/target_tunables.rs @@ -0,0 +1,22 @@ +use std::cmp::min; +use target_lexicon::{OperatingSystem, Triple}; +use wasmtime_environ::Tunables; + +/// Return a `Tunables` instance tuned for the given target platform. +pub fn target_tunables(triple: &Triple) -> Tunables { + let mut result = Tunables::default(); + + match triple.operating_system { + OperatingSystem::Windows => { + // For now, use a smaller footprint on Windows so that we don't + // don't outstrip the paging file. + // TODO: Make this configurable. + result.static_memory_bound = min(result.static_memory_bound, 0x100); + result.static_memory_offset_guard_size = + min(result.static_memory_offset_guard_size, 0x10000); + } + _ => {} + } + + result +} diff --git a/lib/runtime/Cargo.toml b/lib/runtime/Cargo.toml index 43f506bb51..ea75df08a0 100644 --- a/lib/runtime/Cargo.toml +++ b/lib/runtime/Cargo.toml @@ -23,6 +23,9 @@ cast = { version = "0.2.2", default-features = false } failure = { version = "0.1.3", default-features = false } failure_derive = { version = "0.1.3", default-features = false } +[target.'cfg(target_os = "windows")'.dependencies] +winapi = { version = "0.3.6", features = ["winbase", "memoryapi"] } + [build-dependencies] cmake = "0.1.35" bindgen = "0.44.0" diff --git a/lib/runtime/signalhandlers/SignalHandlers.cpp b/lib/runtime/signalhandlers/SignalHandlers.cpp index 520cf4be02..f20d2c36af 100644 --- a/lib/runtime/signalhandlers/SignalHandlers.cpp +++ b/lib/runtime/signalhandlers/SignalHandlers.cpp @@ -453,7 +453,9 @@ WasmTrapHandler(LPEXCEPTION_POINTERS exception) EXCEPTION_RECORD* record = exception->ExceptionRecord; if (record->ExceptionCode != EXCEPTION_ACCESS_VIOLATION && - record->ExceptionCode != EXCEPTION_ILLEGAL_INSTRUCTION) + record->ExceptionCode != EXCEPTION_ILLEGAL_INSTRUCTION && + record->ExceptionCode != EXCEPTION_STACK_OVERFLOW && + record->ExceptionCode != EXCEPTION_INT_DIVIDE_BY_ZERO) { return EXCEPTION_CONTINUE_SEARCH; } diff --git a/lib/runtime/src/lib.rs b/lib/runtime/src/lib.rs index 6d3245896c..304b106c67 100644 --- a/lib/runtime/src/lib.rs +++ b/lib/runtime/src/lib.rs @@ -42,6 +42,8 @@ extern crate cast; extern crate failure; #[macro_use] extern crate failure_derive; +#[cfg(target_os = "windows")] +extern crate winapi; mod export; mod imports; diff --git a/lib/runtime/src/mmap.rs b/lib/runtime/src/mmap.rs index 03537fdbcb..749140c52b 100644 --- a/lib/runtime/src/mmap.rs +++ b/lib/runtime/src/mmap.rs @@ -130,7 +130,7 @@ impl Drop for Mmap { if !self.ptr.is_null() { use winapi::um::memoryapi::VirtualFree; use winapi::um::winnt::MEM_RELEASE; - let r = unsafe { VirtualFree(self.ptr, self.len, MEM_RELEASE) }; + let r = unsafe { VirtualFree(self.ptr as *mut libc::c_void, self.len, MEM_RELEASE) }; assert_eq!(r, 0); } } diff --git a/lib/wast/src/spectest.rs b/lib/wast/src/spectest.rs index 062ab7b0f3..4ea623b55a 100644 --- a/lib/wast/src/spectest.rs +++ b/lib/wast/src/spectest.rs @@ -7,7 +7,7 @@ use target_lexicon::HOST; use wasmtime_environ::{ translate_signature, Export, MemoryPlan, MemoryStyle, Module, TablePlan, TableStyle, }; -use wasmtime_execute::{ActionError, InstancePlus}; +use wasmtime_execute::{target_tunables, ActionError, InstancePlus}; use wasmtime_runtime::{Imports, VMFunctionBody}; extern "C" fn spectest_print() {} @@ -199,14 +199,17 @@ pub fn instantiate_spectest() -> Result { .exports .insert("table".to_owned(), Export::Table(table)); + let tunables = target_tunables(&HOST); let memory = module.memory_plans.push(MemoryPlan { memory: Memory { minimum: 1, maximum: Some(2), shared: false, }, - style: MemoryStyle::Static { bound: 65536 }, - offset_guard_size: 0x80000000, + style: MemoryStyle::Static { + bound: tunables.static_memory_bound, + }, + offset_guard_size: tunables.static_memory_offset_guard_size, }); module .exports diff --git a/lib/wast/src/wast.rs b/lib/wast/src/wast.rs index f82d1575ae..b044a8fcb9 100644 --- a/lib/wast/src/wast.rs +++ b/lib/wast/src/wast.rs @@ -253,7 +253,7 @@ impl WastContext { ) -> Result<(), WastFileError> { let mut parser = ScriptParser::from_str(str::from_utf8(wast).unwrap()).unwrap(); - while let Some(Command { kind, line }) = parser.next().unwrap() { + while let Some(Command { kind, line }) = parser.next().expect("parser") { match kind { CommandKind::Module { module, name } => { self.module(isa, name, module)