Migrate from winapi to windows-sys (#4346)

* Migrate from `winapi` to `windows-sys`

I believe that Microsoft itself is supporting the development of
`windows-sys` and it's also used by `cap-std` now so this switches
Wasmtime's dependencies on Windows APIs from the `winapi` crate to the
`windows-sys` crate. We still have `winapi` in our dependency graph but
that may get phased out over time.

* Make windows-sys a target-specific dependency
This commit is contained in:
Alex Crichton
2022-06-28 13:02:41 -05:00
committed by GitHub
parent 27b94a4173
commit df1502531d
15 changed files with 79 additions and 68 deletions

12
Cargo.lock generated
View File

@@ -3339,7 +3339,7 @@ dependencies = [
"wasmtime-runtime", "wasmtime-runtime",
"wasmtime-wasi", "wasmtime-wasi",
"wat", "wat",
"winapi", "windows-sys",
] ]
[[package]] [[package]]
@@ -3401,7 +3401,7 @@ dependencies = [
"sha2", "sha2",
"tempfile", "tempfile",
"toml", "toml",
"winapi", "windows-sys",
"zstd", "zstd",
] ]
@@ -3442,7 +3442,7 @@ dependencies = [
"wasmtime-wast", "wasmtime-wast",
"wast 42.0.0", "wast 42.0.0",
"wat", "wat",
"winapi", "windows-sys",
] ]
[[package]] [[package]]
@@ -3503,7 +3503,7 @@ dependencies = [
"cc", "cc",
"cfg-if", "cfg-if",
"rustix", "rustix",
"winapi", "windows-sys",
] ]
[[package]] [[package]]
@@ -3569,7 +3569,7 @@ dependencies = [
"wasmtime-environ", "wasmtime-environ",
"wasmtime-jit-debug", "wasmtime-jit-debug",
"wasmtime-runtime", "wasmtime-runtime",
"winapi", "windows-sys",
] ]
[[package]] [[package]]
@@ -3603,7 +3603,7 @@ dependencies = [
"wasmtime-environ", "wasmtime-environ",
"wasmtime-fiber", "wasmtime-fiber",
"wasmtime-jit-debug", "wasmtime-jit-debug",
"winapi", "windows-sys",
] ]
[[package]] [[package]]

View File

@@ -55,13 +55,15 @@ tracing-subscriber = "0.3.1"
wast = "42.0.0" wast = "42.0.0"
criterion = "0.3.4" criterion = "0.3.4"
num_cpus = "1.13.0" num_cpus = "1.13.0"
winapi = { version = "0.3.9", features = ['memoryapi'] }
memchr = "2.4" memchr = "2.4"
async-trait = "0.1" async-trait = "0.1"
wat = "1.0.43" wat = "1.0.43"
once_cell = "1.9.0" once_cell = "1.9.0"
rayon = "1.5.0" rayon = "1.5.0"
[target.'cfg(windows)'.dev-dependencies]
windows-sys = { version = "0.36.0", features = ["Win32_System_Memory"] }
[build-dependencies] [build-dependencies]
anyhow = "1.0.19" anyhow = "1.0.19"

View File

@@ -20,8 +20,11 @@ sha2 = "0.9.0"
toml = "0.5.5" toml = "0.5.5"
zstd = { version = "0.11.1", default-features = false } zstd = { version = "0.11.1", default-features = false }
[target.'cfg(target_os = "windows")'.dependencies] [target.'cfg(target_os = "windows")'.dependencies.windows-sys]
winapi = "0.3.7" version = "0.36.0"
features = [
"Win32_System_Threading",
]
[target.'cfg(not(target_os = "windows"))'.dependencies] [target.'cfg(not(target_os = "windows"))'.dependencies]
rustix = { version = "0.35.6", features = ["process"] } rustix = { version = "0.35.6", features = ["process"] }

View File

@@ -230,8 +230,7 @@ impl WorkerThread {
#[cfg(target_os = "windows")] #[cfg(target_os = "windows")]
fn lower_thread_priority() { fn lower_thread_priority() {
use winapi::um::processthreadsapi::{GetCurrentThread, SetThreadPriority}; use windows_sys::Win32::System::Threading::*;
use winapi::um::winbase::THREAD_MODE_BACKGROUND_BEGIN;
// https://docs.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-setthreadpriority // https://docs.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-setthreadpriority
// https://docs.microsoft.com/en-us/windows/win32/procthread/scheduling-priorities // https://docs.microsoft.com/en-us/windows/win32/procthread/scheduling-priorities

View File

@@ -19,11 +19,11 @@ cfg-if = "1.0"
[target.'cfg(unix)'.dependencies] [target.'cfg(unix)'.dependencies]
rustix = { version = "0.35.6", features = ["mm", "param"] } rustix = { version = "0.35.6", features = ["mm", "param"] }
[target.'cfg(windows)'.dependencies.winapi] [target.'cfg(windows)'.dependencies.windows-sys]
version = "0.3.9" version = "0.36.1"
features = [ features = [
"fibersapi", "Win32_System_Threading",
"winbase", "Win32_Foundation",
] ]
[build-dependencies] [build-dependencies]

View File

@@ -1,12 +1,10 @@
use crate::RunResult; use crate::RunResult;
use std::cell::Cell; use std::cell::Cell;
use std::ffi::c_void;
use std::io; use std::io;
use std::ptr; use std::ptr;
use winapi::shared::minwindef::*; use windows_sys::Win32::Foundation::*;
use winapi::shared::winerror::ERROR_NOT_SUPPORTED; use windows_sys::Win32::System::Threading::*;
use winapi::um::fibersapi::*;
use winapi::um::processthreadsapi::SetThreadStackGuarantee;
use winapi::um::winbase::*;
#[derive(Debug)] #[derive(Debug)]
pub struct FiberStack(usize); pub struct FiberStack(usize);
@@ -26,7 +24,7 @@ impl FiberStack {
} }
pub struct Fiber { pub struct Fiber {
fiber: LPVOID, fiber: *mut c_void,
state: Box<StartState>, state: Box<StartState>,
} }
@@ -35,18 +33,18 @@ pub struct Suspend {
} }
struct StartState { struct StartState {
parent: Cell<LPVOID>, parent: Cell<*mut c_void>,
initial_closure: Cell<*mut u8>, initial_closure: Cell<*mut u8>,
result_location: Cell<*const u8>, result_location: Cell<*const u8>,
} }
const FIBER_FLAG_FLOAT_SWITCH: DWORD = 1; const FIBER_FLAG_FLOAT_SWITCH: u32 = 1;
extern "C" { extern "C" {
fn wasmtime_fiber_get_current() -> LPVOID; fn wasmtime_fiber_get_current() -> *mut c_void;
} }
unsafe extern "system" fn fiber_start<F, A, B, C>(data: LPVOID) unsafe extern "system" fn fiber_start<F, A, B, C>(data: *mut c_void)
where where
F: FnOnce(A, &super::Suspend<A, B, C>) -> C, F: FnOnce(A, &super::Suspend<A, B, C>) -> C,
{ {

View File

@@ -29,8 +29,11 @@ rustc-demangle = "0.1.16"
cpp_demangle = "0.3.2" cpp_demangle = "0.3.2"
log = "0.4.8" log = "0.4.8"
[target.'cfg(target_os = "windows")'.dependencies] [target.'cfg(target_os = "windows")'.dependencies.windows-sys]
winapi = { version = "0.3.8", features = ["winnt", "impl-default"] } version = "0.36.0"
features = [
"Win32_System_Diagnostics_Debug",
]
[target.'cfg(target_os = "linux")'.dependencies] [target.'cfg(target_os = "linux")'.dependencies]
rustix = { version = "0.35.6", features = ["process"] } rustix = { version = "0.35.6", features = ["process"] }

View File

@@ -2,7 +2,7 @@
use anyhow::{bail, Result}; use anyhow::{bail, Result};
use std::mem; use std::mem;
use winapi::um::winnt; use windows_sys::Win32::System::Diagnostics::Debug::*;
/// Represents a registry of function unwind information for Windows x64 ABI. /// Represents a registry of function unwind information for Windows x64 ABI.
pub struct UnwindRegistration { pub struct UnwindRegistration {
@@ -16,9 +16,9 @@ impl UnwindRegistration {
unwind_len: usize, unwind_len: usize,
) -> Result<UnwindRegistration> { ) -> Result<UnwindRegistration> {
assert!(unwind_info as usize % 4 == 0); assert!(unwind_info as usize % 4 == 0);
let unit_len = mem::size_of::<winnt::RUNTIME_FUNCTION>(); let unit_len = mem::size_of::<IMAGE_RUNTIME_FUNCTION_ENTRY>();
assert!(unwind_len % unit_len == 0); assert!(unwind_len % unit_len == 0);
if winnt::RtlAddFunctionTable( if RtlAddFunctionTable(
unwind_info as *mut _, unwind_info as *mut _,
(unwind_len / unit_len) as u32, (unwind_len / unit_len) as u32,
base_address as u64, base_address as u64,
@@ -40,7 +40,7 @@ impl UnwindRegistration {
impl Drop for UnwindRegistration { impl Drop for UnwindRegistration {
fn drop(&mut self) { fn drop(&mut self) {
unsafe { unsafe {
winnt::RtlDeleteFunctionTable(self.functions as _); RtlDeleteFunctionTable(self.functions as _);
} }
} }
} }

View File

@@ -33,8 +33,15 @@ mach = "0.3.2"
[target.'cfg(unix)'.dependencies] [target.'cfg(unix)'.dependencies]
rustix = { version = "0.35.6", features = ["mm"] } rustix = { version = "0.35.6", features = ["mm"] }
[target.'cfg(target_os = "windows")'.dependencies] [target.'cfg(target_os = "windows")'.dependencies.windows-sys]
winapi = { version = "0.3.7", features = ["winbase", "memoryapi", "errhandlingapi", "handleapi"] } version = "0.36.0"
features = [
"Win32_System_Kernel",
"Win32_System_Memory",
"Win32_System_Diagnostics_Debug",
"Win32_Storage_FileSystem",
"Win32_Security",
]
[build-dependencies] [build-dependencies]
cc = "1.0" cc = "1.0"

View File

@@ -1,6 +1,5 @@
use anyhow::{bail, Result}; use anyhow::{bail, Result};
use winapi::um::memoryapi::{VirtualAlloc, VirtualFree}; use windows_sys::Win32::System::Memory::*;
use winapi::um::winnt::{MEM_COMMIT, MEM_DECOMMIT, PAGE_READWRITE};
pub fn commit(addr: *mut u8, len: usize) -> Result<()> { pub fn commit(addr: *mut u8, len: usize) -> Result<()> {
if len == 0 { if len == 0 {

View File

@@ -87,9 +87,10 @@ impl Mmap {
use std::fs::OpenOptions; use std::fs::OpenOptions;
use std::io; use std::io;
use std::os::windows::prelude::*; use std::os::windows::prelude::*;
use winapi::um::handleapi::*; use windows_sys::Win32::Foundation::*;
use winapi::um::memoryapi::*; use windows_sys::Win32::Storage::FileSystem::*;
use winapi::um::winnt::*; use windows_sys::Win32::System::Memory::*;
unsafe { unsafe {
// Open the file with read/execute access and only share for // Open the file with read/execute access and only share for
// read. This will enable us to perform the proper mmap below // read. This will enable us to perform the proper mmap below
@@ -111,14 +112,14 @@ impl Mmap {
// Create a file mapping that allows PAGE_EXECUTE_READ which // Create a file mapping that allows PAGE_EXECUTE_READ which
// we'll be using for mapped text sections in ELF images later. // we'll be using for mapped text sections in ELF images later.
let mapping = CreateFileMappingW( let mapping = CreateFileMappingW(
file.as_raw_handle().cast(), file.as_raw_handle() as isize,
ptr::null_mut(), ptr::null_mut(),
PAGE_EXECUTE_READ, PAGE_EXECUTE_READ,
0, 0,
0, 0,
ptr::null(), ptr::null(),
); );
if mapping.is_null() { if mapping == 0 {
return Err(io::Error::last_os_error()) return Err(io::Error::last_os_error())
.context("failed to create file mapping"); .context("failed to create file mapping");
} }
@@ -219,8 +220,7 @@ impl Mmap {
pub fn accessible_reserved(accessible_size: usize, mapping_size: usize) -> Result<Self> { pub fn accessible_reserved(accessible_size: usize, mapping_size: usize) -> Result<Self> {
use anyhow::bail; use anyhow::bail;
use std::io; use std::io;
use winapi::um::memoryapi::VirtualAlloc; use windows_sys::Win32::System::Memory::*;
use winapi::um::winnt::{MEM_COMMIT, MEM_RESERVE, PAGE_NOACCESS, PAGE_READWRITE};
if mapping_size == 0 { if mapping_size == 0 {
return Ok(Self::new()); return Ok(Self::new());
@@ -299,10 +299,10 @@ impl Mmap {
#[cfg(target_os = "windows")] #[cfg(target_os = "windows")]
pub fn make_accessible(&mut self, start: usize, len: usize) -> Result<()> { pub fn make_accessible(&mut self, start: usize, len: usize) -> Result<()> {
use anyhow::bail; use anyhow::bail;
use std::ffi::c_void;
use std::io; use std::io;
use winapi::ctypes::c_void; use windows_sys::Win32::System::Memory::*;
use winapi::um::memoryapi::VirtualAlloc;
use winapi::um::winnt::{MEM_COMMIT, PAGE_READWRITE};
let page_size = region::page::size(); let page_size = region::page::size();
assert_eq!(start & (page_size - 1), 0); assert_eq!(start & (page_size - 1), 0);
assert_eq!(len & (page_size - 1), 0); assert_eq!(len & (page_size - 1), 0);
@@ -383,8 +383,7 @@ impl Mmap {
#[cfg(windows)] #[cfg(windows)]
{ {
use std::io; use std::io;
use winapi::um::memoryapi::*; use windows_sys::Win32::System::Memory::*;
use winapi::um::winnt::*;
if self.file.is_some() { if self.file.is_some() {
let mut old = 0; let mut old = 0;
@@ -438,9 +437,9 @@ impl Drop for Mmap {
#[cfg(target_os = "windows")] #[cfg(target_os = "windows")]
fn drop(&mut self) { fn drop(&mut self) {
if self.len != 0 { if self.len != 0 {
use winapi::ctypes::c_void; use std::ffi::c_void;
use winapi::um::memoryapi::*; use windows_sys::Win32::System::Memory::*;
use winapi::um::winnt::MEM_RELEASE;
if self.file.is_none() { if self.file.is_none() {
let r = unsafe { VirtualFree(self.ptr as *mut c_void, 0, MEM_RELEASE) }; let r = unsafe { VirtualFree(self.ptr as *mut c_void, 0, MEM_RELEASE) };
assert_ne!(r, 0); assert_ne!(r, 0);

View File

@@ -1,13 +1,11 @@
use crate::traphandlers::{tls, wasmtime_longjmp}; use crate::traphandlers::{tls, wasmtime_longjmp};
use std::io; use std::io;
use winapi::um::errhandlingapi::*; use windows_sys::Win32::Foundation::*;
use winapi::um::minwinbase::*; use windows_sys::Win32::System::Diagnostics::Debug::*;
use winapi::um::winnt::*; use windows_sys::Win32::System::Kernel::*;
use winapi::vc::excpt::*;
/// Function which may handle custom signals while processing traps. /// Function which may handle custom signals while processing traps.
pub type SignalHandler<'a> = pub type SignalHandler<'a> = dyn Fn(*mut EXCEPTION_POINTERS) -> bool + Send + Sync + 'a;
dyn Fn(winapi::um::winnt::PEXCEPTION_POINTERS) -> bool + Send + Sync + 'a;
pub unsafe fn platform_init() { pub unsafe fn platform_init() {
// our trap handler needs to go first, so that we can recover from // our trap handler needs to go first, so that we can recover from
@@ -21,7 +19,7 @@ pub unsafe fn platform_init() {
} }
} }
unsafe extern "system" fn exception_handler(exception_info: PEXCEPTION_POINTERS) -> LONG { unsafe extern "system" fn exception_handler(exception_info: *mut EXCEPTION_POINTERS) -> i32 {
// Check the kind of exception, since we only handle a subset within // Check the kind of exception, since we only handle a subset within
// wasm code. If anything else happens we want to defer to whatever // wasm code. If anything else happens we want to defer to whatever
// the rest of the system wants to do for this exception. // the rest of the system wants to do for this exception.
@@ -31,7 +29,7 @@ unsafe extern "system" fn exception_handler(exception_info: PEXCEPTION_POINTERS)
&& record.ExceptionCode != EXCEPTION_INT_DIVIDE_BY_ZERO && record.ExceptionCode != EXCEPTION_INT_DIVIDE_BY_ZERO
&& record.ExceptionCode != EXCEPTION_INT_OVERFLOW && record.ExceptionCode != EXCEPTION_INT_OVERFLOW
{ {
return EXCEPTION_CONTINUE_SEARCH; return ExceptionContinueSearch;
} }
// FIXME: this is what the previous C++ did to make sure that TLS // FIXME: this is what the previous C++ did to make sure that TLS
@@ -43,7 +41,7 @@ unsafe extern "system" fn exception_handler(exception_info: PEXCEPTION_POINTERS)
// Rust. // Rust.
// //
// if (!NtCurrentTeb()->Reserved1[sThreadLocalArrayPointerIndex]) { // if (!NtCurrentTeb()->Reserved1[sThreadLocalArrayPointerIndex]) {
// return EXCEPTION_CONTINUE_SEARCH; // return ExceptionContinueSearch;
// } // }
// This is basically the same as the unix version above, only with a // This is basically the same as the unix version above, only with a
@@ -51,7 +49,7 @@ unsafe extern "system" fn exception_handler(exception_info: PEXCEPTION_POINTERS)
tls::with(|info| { tls::with(|info| {
let info = match info { let info = match info {
Some(info) => info, Some(info) => info,
None => return EXCEPTION_CONTINUE_SEARCH, None => return ExceptionContinueSearch,
}; };
cfg_if::cfg_if! { cfg_if::cfg_if! {
if #[cfg(target_arch = "x86_64")] { if #[cfg(target_arch = "x86_64")] {
@@ -64,9 +62,9 @@ unsafe extern "system" fn exception_handler(exception_info: PEXCEPTION_POINTERS)
} }
let jmp_buf = info.jmp_buf_if_trap(ip, |handler| handler(exception_info)); let jmp_buf = info.jmp_buf_if_trap(ip, |handler| handler(exception_info));
if jmp_buf.is_null() { if jmp_buf.is_null() {
EXCEPTION_CONTINUE_SEARCH ExceptionContinueSearch
} else if jmp_buf as usize == 1 { } else if jmp_buf as usize == 1 {
EXCEPTION_CONTINUE_EXECUTION ExceptionContinueExecution
} else { } else {
info.capture_backtrace(ip); info.capture_backtrace(ip);
wasmtime_longjmp(jmp_buf) wasmtime_longjmp(jmp_buf)

View File

@@ -39,8 +39,11 @@ object = { version = "0.28", default-features = false, features = ['read_core',
async-trait = { version = "0.1.51", optional = true } async-trait = { version = "0.1.51", optional = true }
once_cell = "1.12" once_cell = "1.12"
[target.'cfg(target_os = "windows")'.dependencies] [target.'cfg(target_os = "windows")'.dependencies.windows-sys]
winapi = "0.3.7" version = "0.36.0"
features = [
"Win32_System_Diagnostics_Debug",
]
[dev-dependencies] [dev-dependencies]
tempfile = "3.0" tempfile = "3.0"

View File

@@ -10,6 +10,7 @@
//! available on Windows. //! available on Windows.
use crate::{AsContextMut, Store}; use crate::{AsContextMut, Store};
use windows_sys::Win32::System::Diagnostics::Debug::EXCEPTION_POINTERS;
/// Extensions for the [`Store`] type only available on Windows. /// Extensions for the [`Store`] type only available on Windows.
pub trait StoreExt { pub trait StoreExt {
@@ -18,13 +19,13 @@ pub trait StoreExt {
/// TODO: needs more documentation. /// TODO: needs more documentation.
unsafe fn set_signal_handler<H>(&mut self, handler: H) unsafe fn set_signal_handler<H>(&mut self, handler: H)
where where
H: 'static + Fn(winapi::um::winnt::PEXCEPTION_POINTERS) -> bool + Send + Sync; H: 'static + Fn(*mut EXCEPTION_POINTERS) -> bool + Send + Sync;
} }
impl<T> StoreExt for Store<T> { impl<T> StoreExt for Store<T> {
unsafe fn set_signal_handler<H>(&mut self, handler: H) unsafe fn set_signal_handler<H>(&mut self, handler: H)
where where
H: 'static + Fn(winapi::um::winnt::PEXCEPTION_POINTERS) -> bool + Send + Sync, H: 'static + Fn(*mut EXCEPTION_POINTERS) -> bool + Send + Sync,
{ {
self.as_context_mut() self.as_context_mut()
.0 .0

View File

@@ -266,8 +266,7 @@ unsafe fn assert_faults(ptr: *mut u8) {
} }
#[cfg(windows)] #[cfg(windows)]
{ {
use winapi::um::memoryapi::*; use windows_sys::Win32::System::Memory::*;
use winapi::um::winnt::*;
let mut info = std::mem::MaybeUninit::uninit(); let mut info = std::mem::MaybeUninit::uninit();
let r = VirtualQuery( let r = VirtualQuery(