From 9a56680281069e8fdf1c3e615029105131cad82f Mon Sep 17 00:00:00 2001 From: Mackenzie Clark Date: Fri, 8 Feb 2019 13:51:29 -0800 Subject: [PATCH 01/14] fix windows linking and appveyor build (#166) --- .appveyor.yml | 137 ++----------------------- lib/clif-backend/src/resolver.rs | 12 ++- lib/clif-backend/src/signal/windows.rs | 4 + lib/emscripten/src/env/windows/mod.rs | 1 - lib/emscripten/src/io/windows.rs | 25 ++--- lib/emscripten/src/stdio.rs | 22 ++-- lib/emscripten/src/time.rs | 1 - 7 files changed, 53 insertions(+), 149 deletions(-) diff --git a/.appveyor.yml b/.appveyor.yml index a4b1fbe96..8bcc3b4c7 100644 --- a/.appveyor.yml +++ b/.appveyor.yml @@ -1,6 +1,3 @@ -# This appveyor build file is heavily inspired by uutils/coreutils -# https://raw.githubusercontent.com/uutils/coreutils/d0db7bbaa46dabf65b71e3e33b1ed7595aaacc56/.appveyor.yml - branches: except: - master @@ -9,143 +6,27 @@ version: "{build} ~ {branch}" os: Visual Studio 2017 -matrix: - allow_failures: - - CHANNEL: stable -# - ABI: gnu - environment: matrix: - # minimum version -# - CHANNEL: 1.31.0 -# ARCH: i686 -# ABI: msvc -# # "msvc" ABI -# - CHANNEL: stable -# ARCH: i686 -# ABI: msvc -# - CHANNEL: stable -# ARCH: x86_64 -# ABI: msvc - # - CHANNEL: beta - # ARCH: i686 - # ABI: msvc - # - CHANNEL: beta - # ARCH: x86_64 - # ABI: msvc -# - CHANNEL: nightly -# ARCH: i686 -# ABI: msvc -# - CHANNEL: nightly -# ARCH: x86_64 -# ABI: msvc -# # "gnu" ABI -# - CHANNEL: stable -# ARCH: i686 -# ABI: gnu -# - CHANNEL: stable -# ARCH: x86_64 -# ABI: gnu - # - CHANNEL: beta - # ARCH: i686 - # ABI: gnu - # - CHANNEL: beta - # ARCH: x86_64 - # ABI: gnu - # - CHANNEL: nightly - # ARCH: i686 - # ABI: gnu - # - CHANNEL: nightly - # ARCH: x86_64 - # ABI: gnu - # * specific gnu compilers -# - CHANNEL: stable -# ARCH: i686 -# ABI: gnu -# MINGW_URL: https://sourceforge.net/projects/mingw-w64/files/Toolchains%20targetting%20Win32/Personal%20Builds/mingw-builds/4.9.2/threads-win32/dwarf/i686-4.9.2-release-win32-dwarf-rt_v4-rev4.7z/download -# MINGW_ARCHIVE: i686-4.9.2-release-win32-dwarf-rt_v4-rev4.7z - CHANNEL: stable ARCH: x86_64 - ABI: gnu - MINGW_URL: https://sourceforge.net/projects/mingw-w64/files/Toolchains%20targetting%20Win64/Personal%20Builds/mingw-builds/7.3.0/threads-posix/seh/x86_64-7.3.0-release-posix-seh-rt_v5-rev0.7z/download#mingw-w64-x86_64-7.3.0-posix-seh.7z + ABI: msvc + TARGET: x86_64-pc-windows-msvc install: - - echo %PATH% - # force branch checkout (if knowable), then reset to the specific commit ## (can be needed for accurate code coverage info) - # * this allows later apps to see the branch name using standard `git branch` operations, yet always builds the correct specific commit - # * ref: [`@`](https://archive.is/RVpnF) - - if DEFINED APPVEYOR_REPO_BRANCH if /I "%APPVEYOR_REPO_SCM%"=="git" ( git checkout "%APPVEYOR_REPO_BRANCH%" & git reset --hard "%APPVEYOR_REPO_COMMIT%" ) - # ensure CWD is project main directory - - cd "%APPVEYOR_BUILD_FOLDER%" - # create a working area - - ps: if ( ! $env:CI_TEMP_DIR ) { $env:CI_TEMP_DIR = "${env:TEMP}\${env:APPVEYOR_JOB_ID}" ; mkdir -force $env:CI_TEMP_DIR | out-null } - - # rust installation - - set "TARGET=%ARCH%-pc-windows-%ABI%" - # * install `rust` via `rustup` - - appveyor DownloadFile "https://win.rustup.rs/" -FileName "%CI_TEMP_DIR%\rustup-init.exe" - - call "%CI_TEMP_DIR%\rustup-init.exe" -y --default-toolchain %CHANNEL% --default-host %TARGET% --no-modify-path >NUL - - set "PATH=%PATH%;%USERPROFILE%\.cargo\bin" - - ps: $env:TOOLCHAIN = $(rustup show active-toolchain) - - rename "C:\Program Files\Git\usr\bin\sh.exe" sh2.exe - # * set RUST_BACKTRACE for enhanced error messages - - set RUST_BACKTRACE=1 - # * show versions + - appveyor DownloadFile https://win.rustup.rs/ -FileName rustup-init.exe + - rustup-init.exe -yv --default-host %target% + - set PATH=%PATH%;%USERPROFILE%\.cargo\bin - rustc -vV - cargo -vV - # finalize FEATURES - - if /i "%CHANNEL%"=="nightly" set "FEATURES=nightly" - - # "gnu" ABI setup - # * use the system MinGW/MSYS if we can - - if /i "%ABI%"=="gnu" set MSYS_BINDIR=C:\msys64\usr\bin - - if /i "%ABI%"=="gnu" if /i "%ARCH%"=="i686" set "MSYS_BITS=32" - - if /i "%ABI%"=="gnu" if /i "%ARCH%"=="x86_64" set "MSYS_BITS=64" - - if defined MSYS_BITS set "MSYS_MINGWDIR=C:\msys64\mingw%MSYS_BITS%" - - if defined MSYS_MINGWDIR set "MSYS_BINDIR=C:\msys64\usr\bin" - ## * workaround for rust-lang/rust#47048 / rust-lang/rust#53454 ## !maint: remove when resolved - - if /i "%ABI%"=="gnu" if /i "%ARCH%"=="i686" if not DEFINED MINGW_URL set "MINGW_URL=https://downloads.sourceforge.net/project/mingw-w64/Toolchains targetting Win32/Personal Builds/mingw-builds/8.1.0/threads-posix/dwarf/i686-8.1.0-release-posix-dwarf-rt_v6-rev0.7z" - - if /i "%ABI%"=="gnu" if /i "%ARCH%"=="x86_64" if not DEFINED MINGW_URL set "MINGW_URL=https://downloads.sourceforge.net/project/mingw-w64/Toolchains targetting Win64/Personal Builds/mingw-builds/8.1.0/threads-posix/seh/x86_64-8.1.0-release-posix-seh-rt_v6-rev0.7z" - ## - # * specific MinGW, if specified - - ps: if ( ! $env:MINGW_ARCHIVE -and $env:MINGW_URL ) { $env:MINGW_ARCHIVE = $($([URI]$env:MINGW_URL).fragment).TrimStart('#') } - - ps: if ( ! $env:MINGW_ARCHIVE -and $env:MINGW_URL ) { $env:MINGW_ARCHIVE = $([URI]$env:MINGW_URL).segments[-1] } - - if defined MINGW_ARCHIVE curl --insecure -fsSL "%MINGW_URL%" -o "%CI_TEMP_DIR%\%MINGW_ARCHIVE%" - - if defined MINGW_ARCHIVE mkdir "%CI_TEMP_DIR%\MinGW" >NUL - - if defined MINGW_ARCHIVE 7z x -y "%CI_TEMP_DIR%\%MINGW_ARCHIVE%" -o"%CI_TEMP_DIR%\MinGW" >NUL - - if defined MINGW_ARCHIVE set "MSYS_MINGWDIR=%CI_TEMP_DIR%\MinGW\mingw%MSYS_BITS%" - - if defined MINGW_ARCHIVE set "MSYS_BINDIR=%MSYS_MINGWDIR%\bin" - # * MinGW/MSYS PATH setup - - if defined MSYS_MINGWDIR set PATH=%MSYS_MINGWDIR%\%ARCH%-w64-mingw32\bin;%MSYS_BINDIR%;%PATH% - ## * workaround for rust-lang/rust#47048 / rust-lang/rust#53454 ## !maint: remove when resolved - # ** ref: , - # ** egs: , - - if /i "%ABI%"=="gnu" rustup install %CHANNEL%-%ARCH%-pc-windows-msvc - - if /i "%ABI%"=="gnu" rustup default %CHANNEL%-%ARCH%-pc-windows-msvc - - if /i "%ABI%"=="gnu" rustup target add %TARGET% - - if /i "%ABI%"=="gnu" rustup show - - if /i "%ABI%"=="gnu" rustc -vV - - ps: $env:TOOLCHAIN = $(rustup show active-toolchain) - # ** copy libs from gcc toolchain to rust toolchain (more specifically, "crt2.o" and "dllcrt2.o" are needed) - - if defined MSYS_MINGWDIR copy /y "%MSYS_MINGWDIR%\%ARCH%-w64-mingw32\lib\*.o" "%USERPROFILE%\.rustup\toolchains\%TOOLCHAIN%\lib\rustlib\%TARGET%\lib" >NUL - ## - - if /i "%ABI%"=="gnu" where gcc - - if /i "%ABI%"=="gnu" gcc --version - - # "msvc" ABI setup - - if /i "%ABI%" == "msvc" if /i "%ARCH%" == "i686" call "%VS140COMNTOOLS%\..\..\VC\vcvarsall.bat" - - if /i "%ABI%" == "msvc" if /i "%ARCH%" == "x86_64" call "C:\Program Files\Microsoft SDKs\Windows\v7.1\Bin\SetEnv.cmd" /x64 - - if /i "%ABI%" == "msvc" if /i "%ARCH%" == "x86_64" call "%VS140COMNTOOLS%\..\..\VC\vcvarsall.bat" x86_amd64 - artifacts: - - path: target\%TARGET%\debug\wasmer.exe + - path: target\debug\wasmer.exe name: wasmer.exe build_script: - - set BUILD_CMD=cargo +%TOOLCHAIN% build --target=%TARGET% - - echo [ %BUILD_CMD% ] & %BUILD_CMD% + - cargo build --verbose test_script: - - set TEST_CMD=cargo +%TOOLCHAIN% test --target=%TARGET% --no-fail-fast - - echo [ %TEST_CMD% ] & %TEST_CMD% + - set RUST_BACKTRACE=1 + - cargo test --verbose diff --git a/lib/clif-backend/src/resolver.rs b/lib/clif-backend/src/resolver.rs index 315bd154a..1e62c0c20 100644 --- a/lib/clif-backend/src/resolver.rs +++ b/lib/clif-backend/src/resolver.rs @@ -35,6 +35,13 @@ use wasmer_runtime_core::{ vm, vmcalls, }; +extern "C" { + #[cfg(not(target_os = "windows"))] + pub fn __rust_probestack(); + #[cfg(all(target_os = "windows", target_pointer_width = "64"))] + pub fn __chkstk(); +} + #[allow(dead_code)] pub struct FuncResolverBuilder { resolver: FuncResolver, @@ -215,7 +222,10 @@ impl FuncResolverBuilder { LibCall::FloorF64 => libcalls::floorf64 as isize, LibCall::TruncF64 => libcalls::truncf64 as isize, LibCall::NearestF64 => libcalls::nearbyintf64 as isize, - LibCall::Probestack => libcalls::__rust_probestack as isize, + #[cfg(all(target_pointer_width = "64", target_os = "windows"))] + Probestack => __chkstk as isize, + #[cfg(not(target_os = "windows"))] + Probestack => __rust_probestack as isize, }, RelocationType::Intrinsic(ref name) => match name.as_str() { "i32print" => i32_print as isize, diff --git a/lib/clif-backend/src/signal/windows.rs b/lib/clif-backend/src/signal/windows.rs index bdd272ce9..b715c616d 100644 --- a/lib/clif-backend/src/signal/windows.rs +++ b/lib/clif-backend/src/signal/windows.rs @@ -4,3 +4,7 @@ use wasmer_runtime_core::error::RuntimeResult; pub fn call_protected(handler_data: &HandlerData, f: impl FnOnce() -> T) -> RuntimeResult { unimplemented!("TODO"); } + +pub unsafe fn trigger_trap() -> ! { + unimplemented!("TODO"); +} diff --git a/lib/emscripten/src/env/windows/mod.rs b/lib/emscripten/src/env/windows/mod.rs index 8d7ba294c..b4171e13c 100644 --- a/lib/emscripten/src/env/windows/mod.rs +++ b/lib/emscripten/src/env/windows/mod.rs @@ -9,7 +9,6 @@ use crate::env::call_malloc; use crate::utils::{copy_cstr_into_wasm, read_string_from_wasm}; use wasmer_runtime_core::vm::Ctx; -#[link(name = "c")] extern "C" { #[link_name = "_putenv"] pub fn putenv(s: *const c_char) -> c_int; diff --git a/lib/emscripten/src/io/windows.rs b/lib/emscripten/src/io/windows.rs index 834de69f6..b85d9c54a 100644 --- a/lib/emscripten/src/io/windows.rs +++ b/lib/emscripten/src/io/windows.rs @@ -5,14 +5,14 @@ use wasmer_runtime_core::vm::Ctx; // this cfg_attr will try to link with the legacy lib that does not inline printf // this will allow for compiliation, but will produce a linker error if there is a problem // finding printf. -#[cfg_attr( - all(windows, target_env = "msvc"), - link(name = "legacy_stdio_definitions", kind = "static-nobundle") -)] -extern "C" { - #[link_name = "printf"] - pub fn _printf(s: *const c_char, ...) -> c_int; -} +//#[cfg_attr( +// all(windows, target_env = "msvc"), +// link(name = "legacy_stdio_definitions", kind = "static-nobundle") +//)] +//extern "C" { +// #[link_name = "printf"] +// pub fn _printf(s: *const c_char, ...) -> c_int; +//} /// putchar pub fn putchar(chr: i32, ctx: &mut Ctx) { @@ -22,8 +22,9 @@ pub fn putchar(chr: i32, ctx: &mut Ctx) { /// printf pub fn printf(memory_offset: i32, extra: i32, ctx: &mut Ctx) -> i32 { debug!("emscripten::printf {}, {}", memory_offset, extra); - unsafe { - let addr = emscripten_memory_pointer!(ctx.memory(0), memory_offset) as _; - _printf(addr, extra) - } + // unsafe { + // let addr = emscripten_memory_pointer!(ctx.memory(0), memory_offset) as _; + // _printf(addr, extra) + // } + -1 } diff --git a/lib/emscripten/src/stdio.rs b/lib/emscripten/src/stdio.rs index 20c9420a3..e3909f4c9 100644 --- a/lib/emscripten/src/stdio.rs +++ b/lib/emscripten/src/stdio.rs @@ -11,6 +11,16 @@ pub struct StdioCapturer { stderr_reader: libc::c_int, } +#[cfg(not(target_os = "windows"))] +use libc::{STDERR_FILENO, STDIN_FILENO, STDOUT_FILENO}; + +#[cfg(target_os = "windows")] +const STDIN_FILENO: libc::c_int = 0; +#[cfg(target_os = "windows")] +const STDOUT_FILENO: libc::c_int = 1; +#[cfg(target_os = "windows")] +const STDERR_FILENO: libc::c_int = 2; + // Implementation inspired in // https://github.com/rust-lang/rust/blob/7d52cbce6db83e4fc2d8706b4e4b9c7da76cbcf8/src/test/run-pass/issues/issue-30490.rs // Currently only works in Unix systems (Mac, Linux) @@ -30,14 +40,14 @@ impl StdioCapturer { } pub fn new() -> Self { - let stdout_backup = unsafe { libc::dup(libc::STDOUT_FILENO) }; - let stderr_backup = unsafe { libc::dup(libc::STDERR_FILENO) }; + let stdout_backup = unsafe { libc::dup(STDOUT_FILENO) }; + let stderr_backup = unsafe { libc::dup(STDERR_FILENO) }; let (stdout_reader, stdout_writer) = Self::pipe(); let (stderr_reader, stderr_writer) = Self::pipe(); - assert!(unsafe { libc::dup2(stdout_writer, libc::STDOUT_FILENO) } > -1); - assert!(unsafe { libc::dup2(stderr_writer, libc::STDERR_FILENO) } > -1); + assert!(unsafe { libc::dup2(stdout_writer, STDOUT_FILENO) } > -1); + assert!(unsafe { libc::dup2(stderr_writer, STDERR_FILENO) } > -1); // Make sure we close any duplicates of the writer end of the pipe, // otherwise we can get stuck reading from the pipe which has open @@ -57,8 +67,8 @@ impl StdioCapturer { // The Stdio passed into the Command took over (and closed) std{out, err} // so we should restore them as they were. - assert!(unsafe { libc::dup2(self.stdout_backup, libc::STDOUT_FILENO) } > -1); - assert!(unsafe { libc::dup2(self.stderr_backup, libc::STDERR_FILENO) } > -1); + assert!(unsafe { libc::dup2(self.stdout_backup, STDOUT_FILENO) } > -1); + assert!(unsafe { libc::dup2(self.stderr_backup, STDERR_FILENO) } > -1); let fd = FileDescriptor::new(self.stdout_reader); let mut reader = BufReader::new(fd); diff --git a/lib/emscripten/src/time.rs b/lib/emscripten/src/time.rs index dcf0bfaa2..2ecdfe6a8 100644 --- a/lib/emscripten/src/time.rs +++ b/lib/emscripten/src/time.rs @@ -10,7 +10,6 @@ use libc::{clockid_t, time as libc_time}; type clockid_t = c_int; #[cfg(target_os = "windows")] -#[link(name = "c")] extern "C" { #[link_name = "time"] pub fn libc_time(s: *const time_t) -> time_t; From e7c3b99ba962fbf6e5048fe864392512e4728fe4 Mon Sep 17 00:00:00 2001 From: Mackenzie Clark Date: Fri, 8 Feb 2019 17:47:51 -0800 Subject: [PATCH 02/14] add lua integration test (#109) --- .circleci/config.yml | 1 + Makefile | 2 +- integration_tests/lua/README.md | 9 +++++++++ integration_tests/lua/test.sh | 15 +++++++++++++++ lib/emscripten/src/jmp.rs | 27 +++++++++++++-------------- 5 files changed, 39 insertions(+), 15 deletions(-) create mode 100644 integration_tests/lua/README.md create mode 100755 integration_tests/lua/test.sh diff --git a/.circleci/config.yml b/.circleci/config.yml index 8162eef72..52160f216 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -42,6 +42,7 @@ jobs: command: | sudo apt-get install -y cmake - run: make test + - run: make integration-tests - save_cache: paths: - /usr/local/cargo/registry diff --git a/Makefile b/Makefile index d8e332668..c176dc7d1 100644 --- a/Makefile +++ b/Makefile @@ -23,7 +23,7 @@ install: integration-tests: release echo "Running Integration Tests" - # Commented for now until we fix emscripten + ./integration_tests/lua/test.sh ./integration_tests/nginx/test.sh lint: diff --git a/integration_tests/lua/README.md b/integration_tests/lua/README.md new file mode 100644 index 000000000..ce2b03f6f --- /dev/null +++ b/integration_tests/lua/README.md @@ -0,0 +1,9 @@ +# `lua` integration test + + +This starts wasmer with the lua wasm file. The test asserts on +the output of wasmer. Run test with: + +``` +> ./integration_tests/lua/test.sh +``` diff --git a/integration_tests/lua/test.sh b/integration_tests/lua/test.sh new file mode 100755 index 000000000..b45752f0b --- /dev/null +++ b/integration_tests/lua/test.sh @@ -0,0 +1,15 @@ +#! /bin/bash + +nohup ./target/release/wasmer run examples/lua.wasm & +sleep 3s + +if grep "Lua 5.4.0 Copyright (C) 1994-2018 Lua.org, PUC-Rio" ./nohup.out +then + echo "lua integration test succeeded" + rm ./nohup.out + exit 0 +else + echo "lua integration test failed" + rm ./nohup.out + exit -1 +fi diff --git a/lib/emscripten/src/jmp.rs b/lib/emscripten/src/jmp.rs index b0607c28e..0c63593aa 100644 --- a/lib/emscripten/src/jmp.rs +++ b/lib/emscripten/src/jmp.rs @@ -7,20 +7,19 @@ use wasmer_runtime_core::vm::Ctx; pub fn __setjmp(env_addr: u32, ctx: &mut Ctx) -> c_int { debug!("emscripten::__setjmp (setjmp)"); unsafe { - unimplemented!() - // // Rather than using the env as the holder of the jump buffer pointer, - // // we use the environment address to store the index relative to jumps - // // so the address of the jump it's outside the wasm memory itself. - // let jump_index = ctx.memory(0).as_ptr().add(env_addr as usize) as *mut i8; - // // We create the jump buffer outside of the wasm memory - // let jump_buf: UnsafeCell<[c_int; 27]> = UnsafeCell::new([0; 27]); - // let jumps = &mut get_emscripten_data(ctx).jumps; - // let result = setjmp(jump_buf.get() as _); - // // We set the jump index to be the last value of jumps - // *jump_index = jumps.len() as _; - // // We hold the reference of the jump buffer - // jumps.push(jump_buf); - // result + // Rather than using the env as the holder of the jump buffer pointer, + // we use the environment address to store the index relative to jumps + // so the address of the jump it's outside the wasm memory itself. + let jump_index = emscripten_memory_pointer!(ctx.memory(0), env_addr) as *mut i8; + // We create the jump buffer outside of the wasm memory + let jump_buf: UnsafeCell<[u32; 27]> = UnsafeCell::new([0; 27]); + let jumps = &mut get_emscripten_data(ctx).jumps; + let result = setjmp(jump_buf.get() as _); + // We set the jump index to be the last value of jumps + *jump_index = jumps.len() as _; + // We hold the reference of the jump buffer + jumps.push(jump_buf); + result } } From 4ef7dc339c8ff91a1689a8f55760aa57c63b2d0f Mon Sep 17 00:00:00 2001 From: Mackenzie Clark Date: Sat, 9 Feb 2019 13:31:28 -0800 Subject: [PATCH 03/14] optimize imports (#170) --- lib/emscripten/src/env/unix/mod.rs | 7 +++---- lib/emscripten/src/lib.rs | 17 ++++------------- lib/emscripten/src/stdio.rs | 2 +- lib/emscripten/src/syscalls/mod.rs | 18 ------------------ lib/emscripten/src/syscalls/unix.rs | 17 ----------------- lib/emscripten/src/time.rs | 5 ++++- lib/emscripten/src/utils.rs | 2 -- 7 files changed, 12 insertions(+), 56 deletions(-) diff --git a/lib/emscripten/src/env/unix/mod.rs b/lib/emscripten/src/env/unix/mod.rs index 55fe0c000..d701bd6e8 100644 --- a/lib/emscripten/src/env/unix/mod.rs +++ b/lib/emscripten/src/env/unix/mod.rs @@ -1,15 +1,14 @@ /// NOTE: These syscalls only support wasm_32 for now because they take u32 offset use libc::{ - c_int, c_long, getenv, getgrnam as libc_getgrnam, getpwnam as libc_getpwnam, putenv, setenv, - sysconf, unsetenv, + c_int, getenv, getgrnam as libc_getgrnam, getpwnam as libc_getpwnam, putenv, setenv, sysconf, + unsetenv, }; use std::ffi::CStr; use std::mem; use std::os::raw::c_char; use crate::env::call_malloc; -use crate::utils::{allocate_on_stack, copy_cstr_into_wasm, copy_terminated_array_of_cstrs}; -use crate::EmscriptenData; +use crate::utils::{copy_cstr_into_wasm, copy_terminated_array_of_cstrs}; use wasmer_runtime_core::vm::Ctx; // #[no_mangle] diff --git a/lib/emscripten/src/lib.rs b/lib/emscripten/src/lib.rs index 0fb07d72c..c8e98a985 100644 --- a/lib/emscripten/src/lib.rs +++ b/lib/emscripten/src/lib.rs @@ -1,29 +1,20 @@ #[macro_use] extern crate wasmer_runtime_core; -use byteorder::{ByteOrder, LittleEndian}; -use libc::c_int; use std::cell::UnsafeCell; -use std::{f64, ffi::c_void, fmt, mem, ptr}; +use std::{f64, ffi::c_void}; use wasmer_runtime_core::{ error::CallResult, - export::{Context, Export, FuncPointer}, + export::Export, func, global::Global, - import::{ImportObject, Namespace}, + import::ImportObject, imports, memory::Memory, table::Table, - types::{ - ElementType, FuncSig, GlobalDescriptor, MemoryDescriptor, TableDescriptor, - Type::{self, *}, - Value, - }, + types::{ElementType, MemoryDescriptor, TableDescriptor, Value}, units::Pages, vm::Ctx, - vm::LocalGlobal, - vm::LocalMemory, - vm::LocalTable, Func, Instance, Module, }; diff --git a/lib/emscripten/src/stdio.rs b/lib/emscripten/src/stdio.rs index e3909f4c9..d7d8ab736 100644 --- a/lib/emscripten/src/stdio.rs +++ b/lib/emscripten/src/stdio.rs @@ -12,7 +12,7 @@ pub struct StdioCapturer { } #[cfg(not(target_os = "windows"))] -use libc::{STDERR_FILENO, STDIN_FILENO, STDOUT_FILENO}; +use libc::{STDERR_FILENO, STDOUT_FILENO}; #[cfg(target_os = "windows")] const STDIN_FILENO: libc::c_int = 0; diff --git a/lib/emscripten/src/syscalls/mod.rs b/lib/emscripten/src/syscalls/mod.rs index edae4860c..9078af374 100644 --- a/lib/emscripten/src/syscalls/mod.rs +++ b/lib/emscripten/src/syscalls/mod.rs @@ -16,48 +16,30 @@ use byteorder::{ByteOrder, LittleEndian}; /// NOTE: TODO: These syscalls only support wasm_32 for now because they assume offsets are u32 /// Syscall list: https://www.cs.utexas.edu/~bismith/test/syscalls/syscalls32.html use libc::{ - accept, - bind, // ENOTTY, - c_char, c_int, c_void, chdir, // fcntl, setsockopt, getppid close, - connect, dup2, exit, fstat, - getpeername, getpid, - getsockname, - getsockopt, // iovec, - listen, lseek, - mkdir, - off_t, open, read, // readv, - recvfrom, rmdir, // writev, - sendto, - setsockopt, - sockaddr, - socket, - ssize_t, stat, write, - EINVAL, // sockaddr_in, }; use wasmer_runtime_core::vm::Ctx; use super::env; -use std::mem; use std::slice; // use std::sys::fd::FileDesc; diff --git a/lib/emscripten/src/syscalls/unix.rs b/lib/emscripten/src/syscalls/unix.rs index 00b3b47e8..1e38c39c6 100644 --- a/lib/emscripten/src/syscalls/unix.rs +++ b/lib/emscripten/src/syscalls/unix.rs @@ -1,5 +1,4 @@ use crate::varargs::VarArgs; -use byteorder::{ByteOrder, LittleEndian}; /// NOTE: TODO: These syscalls only support wasm_32 for now because they assume offsets are u32 /// Syscall list: https://www.cs.utexas.edu/~bismith/test/syscalls/syscalls32.html use libc::{ @@ -9,39 +8,28 @@ use libc::{ c_char, c_int, c_void, - chdir, chown, // fcntl, setsockopt, getppid - close, connect, dup2, - exit, fcntl, - fstat, getgid, getpeername, - getpid, getsockname, getsockopt, - gid_t, in_addr_t, in_port_t, ioctl, // iovec, listen, - lseek, mkdir, msghdr, - off_t, - open, pid_t, pread, pwrite, - read, // readv, recvfrom, recvmsg, - rmdir, // ENOTTY, rusage, sa_family_t, @@ -54,11 +42,8 @@ use libc::{ sockaddr, socket, socklen_t, - ssize_t, - stat, uname, utsname, - write, EINVAL, // sockaddr_in, FIOCLEX, @@ -71,9 +56,7 @@ use libc::{ }; use wasmer_runtime_core::vm::Ctx; -use super::env; use std::mem; -use std::slice; // Linking to functions that are not provided by rust libc #[cfg(target_os = "macos")] diff --git a/lib/emscripten/src/time.rs b/lib/emscripten/src/time.rs index 2ecdfe6a8..c270e1785 100644 --- a/lib/emscripten/src/time.rs +++ b/lib/emscripten/src/time.rs @@ -1,11 +1,14 @@ use super::utils::{copy_cstr_into_wasm, write_to_buf}; -use libc::{c_char, c_int, time_t}; +use libc::{c_char, c_int}; use std::mem; use std::time::SystemTime; #[cfg(not(target_os = "windows"))] use libc::{clockid_t, time as libc_time}; +#[cfg(target_os = "windows")] +use libc::time_t; + #[cfg(target_os = "windows")] type clockid_t = c_int; diff --git a/lib/emscripten/src/utils.rs b/lib/emscripten/src/utils.rs index fe3381d76..4437f6262 100644 --- a/lib/emscripten/src/utils.rs +++ b/lib/emscripten/src/utils.rs @@ -2,10 +2,8 @@ use super::env; use super::env::get_emscripten_data; use libc::stat; use std::ffi::CStr; -use std::ffi::CString; use std::mem::size_of; use std::os::raw::c_char; -use std::os::raw::c_int; use std::slice; use wasmer_runtime_core::memory::Memory; use wasmer_runtime_core::{ From 393b7dbdf3936ec9efceb844c5e45cf08a9e78be Mon Sep 17 00:00:00 2001 From: Syrus Date: Sat, 9 Feb 2019 13:33:22 -0800 Subject: [PATCH 04/14] Moved ctx in func macro to be first arg --- lib/runtime-core/src/import.rs | 2 +- lib/runtime-core/src/macros.rs | 2 +- lib/runtime-core/src/typed_func.rs | 10 +++++----- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/lib/runtime-core/src/import.rs b/lib/runtime-core/src/import.rs index cf833ec6e..7073a5ac1 100644 --- a/lib/runtime-core/src/import.rs +++ b/lib/runtime-core/src/import.rs @@ -32,7 +32,7 @@ impl IsExport for Export { /// }, /// }; /// -/// fn foo(n: i32, _: &mut Ctx) -> i32 { +/// fn foo(_: &mut Ctx, n: i32) -> i32 { /// n /// } /// ``` diff --git a/lib/runtime-core/src/macros.rs b/lib/runtime-core/src/macros.rs index 620f65046..a7bdff1b0 100644 --- a/lib/runtime-core/src/macros.rs +++ b/lib/runtime-core/src/macros.rs @@ -38,7 +38,7 @@ macro_rules! func { /// }, /// }; /// -/// fn foo(n: i32, _: &mut Ctx) -> i32 { +/// fn foo(_: &mut Ctx, n: i32) -> i32 { /// n /// } /// ``` diff --git a/lib/runtime-core/src/typed_func.rs b/lib/runtime-core/src/typed_func.rs index 9cbcdc911..9989764c6 100644 --- a/lib/runtime-core/src/typed_func.rs +++ b/lib/runtime-core/src/typed_func.rs @@ -183,16 +183,16 @@ macro_rules! impl_traits { } } - impl< $( $x: WasmExternType, )* Rets: WasmTypeList, Trap: TrapEarly, FN: Fn( $( $x, )* &mut Ctx) -> Trap> ExternalFunction<($( $x ),*), Rets> for FN { + impl< $( $x: WasmExternType, )* Rets: WasmTypeList, Trap: TrapEarly, FN: Fn( &mut Ctx $( ,$x )* ) -> Trap> ExternalFunction<($( $x ),*), Rets> for FN { #[allow(non_snake_case)] fn to_raw(&self) -> *const () { assert_eq!(mem::size_of::(), 0, "you cannot use a closure that captures state for `Func`."); - extern fn wrap<$( $x: WasmExternType, )* Rets: WasmTypeList, Trap: TrapEarly, FN: Fn( $( $x, )* &mut Ctx) -> Trap>( $( $x: $x, )* ctx: &mut Ctx) -> Rets::CStruct { + extern fn wrap<$( $x: WasmExternType, )* Rets: WasmTypeList, Trap: TrapEarly, FN: Fn( &mut Ctx $( ,$x )* ) -> Trap>( ctx: &mut Ctx $( ,$x: $x )* ) -> Rets::CStruct { let f: FN = unsafe { mem::transmute_copy(&()) }; let msg = match panic::catch_unwind(panic::AssertUnwindSafe(|| { - f( $( $x, )* ctx).report() + f( ctx $( ,$x )* ).report() })) { Ok(Ok(returns)) => return returns.into_c_struct(), Ok(Err(err)) => err, @@ -271,7 +271,7 @@ mod tests { use super::*; #[test] fn test_call() { - fn foo(a: i32, b: i32, _ctx: &mut Ctx) -> (i32, i32) { + fn foo(_ctx: &mut Ctx, a: i32, b: i32) -> (i32, i32) { (a, b) } @@ -282,7 +282,7 @@ mod tests { fn test_imports() { use crate::{func, imports}; - fn foo(a: i32, _ctx: &mut Ctx) -> i32 { + fn foo(_ctx: &mut Ctx, a: i32) -> i32 { a } From 6c7fd55b875363182045c13d429887d9a55ab1e7 Mon Sep 17 00:00:00 2001 From: Syrus Date: Sat, 9 Feb 2019 13:58:05 -0800 Subject: [PATCH 05/14] Moved ctx to be the first argument in emscripten --- lib/emscripten/src/README.md | 16 ++--- lib/emscripten/src/env/mod.rs | 16 ++--- lib/emscripten/src/env/unix/mod.rs | 18 +++--- lib/emscripten/src/env/windows/mod.rs | 18 +++--- lib/emscripten/src/errno.rs | 2 +- lib/emscripten/src/exception.rs | 6 +- lib/emscripten/src/io/unix.rs | 4 +- lib/emscripten/src/io/windows.rs | 4 +- lib/emscripten/src/jmp.rs | 6 +- lib/emscripten/src/lib.rs | 10 ++-- lib/emscripten/src/linking.rs | 6 +- lib/emscripten/src/lock.rs | 6 +- lib/emscripten/src/math.rs | 12 ++-- lib/emscripten/src/memory.rs | 6 +- lib/emscripten/src/nullfunc.rs | 52 ++++++++-------- lib/emscripten/src/process.rs | 42 ++++++------- lib/emscripten/src/signal.rs | 12 ++-- lib/emscripten/src/syscalls/mod.rs | 82 +++++++++++++------------- lib/emscripten/src/syscalls/unix.rs | 26 ++++---- lib/emscripten/src/syscalls/windows.rs | 26 ++++---- lib/emscripten/src/time.rs | 38 ++++++------ lib/emscripten/src/utils.rs | 10 ++-- 22 files changed, 209 insertions(+), 209 deletions(-) diff --git a/lib/emscripten/src/README.md b/lib/emscripten/src/README.md index 128ef1783..54b9f9dc1 100644 --- a/lib/emscripten/src/README.md +++ b/lib/emscripten/src/README.md @@ -10,7 +10,7 @@ ``` - **abort** ✅ 🔥     [:top:](#host-apis) ```rust - fn abort(message: u32, ctx: &mut Ctx) + fn abort(ctx: &mut Ctx, message: u32, ) ``` - **abort_on_cannot_grow_memory** ✅     [:top:](#host-apis) ```rust @@ -28,11 +28,11 @@ - **\_getenv** ✅     [:top:](#host-apis) ```rust - fn _getenv(name: c_int, ctx: &mut Ctx) + fn _getenv(ctx: &mut Ctx, name: c_int, ) ``` - **\_putenv** ✅     [:top:](#host-apis) ```rust - fn _putenv(name: c_int, ctx: &mut Ctx) + fn _putenv(ctx: &mut Ctx, name: c_int, ) ``` - **\_setenv** ✅     [:top:](#host-apis) ```rust @@ -40,7 +40,7 @@ ``` - **\_unsetenv** ✅     [:top:](#host-apis) ```rust - fn _unsetenv(name: c_int, ctx: &mut Ctx) + fn _unsetenv(ctx: &mut Ctx, name: c_int, ) ``` ###### THREAD @@ -70,7 +70,7 @@ - **\_emscripten_memcpy_big** ✅ 🔥     [:top:](#host-apis) ```rust - fn _emscripten_memcpy_big(dest: u32, src: u32, len: u32, ctx: &mut Ctx) -> u32 + fn _emscripten_memcpy_big(ctx: &mut Ctx, dest: u32, src: u32, len: u32, ) -> u32 ``` - **enlarge_memory** ✅     [:top:](#host-apis) ```rust @@ -78,7 +78,7 @@ ``` - **get_total_memory** ✅     [:top:](#host-apis) ```rust - fn get_total_memory(ctx: &mut Ctx) -> u32 + fn get_total_memory(ctx: &mut Ctx, ) -> u32 ``` ###### TIMING @@ -337,7 +337,7 @@ ``` - **open** (\_\_\_syscall5) ✅ ❗️ 🔥     [:top:](#host-apis) ```rust - fn open(path: u32, flags: c_int, mode: c_int, ctx: &mut Ctx) -> c_int + fn open(ctx: &mut Ctx, path: u32, flags: c_int, mode: c_int, ) -> c_int ``` - **openat** (\_\_\_syscall295)     [:top:](#host-apis) ```rust @@ -385,7 +385,7 @@ ``` - **read** (\_\_\_syscall3) ✅ ❗️     [:top:](#host-apis) ```rust - fn read(fd: c_int, buf: u32, count: size_t, ctx: &mut Ctx) -> ssize_t + fn read(ctx: &mut Ctx, fd: c_int, buf: u32, count: size_t, ) -> ssize_t ``` - **readlink** (\_\_\_syscall85)     [:top:](#host-apis) ```rust diff --git a/lib/emscripten/src/env/mod.rs b/lib/emscripten/src/env/mod.rs index 50b7a48f9..89f55fd09 100644 --- a/lib/emscripten/src/env/mod.rs +++ b/lib/emscripten/src/env/mod.rs @@ -14,16 +14,16 @@ use crate::{allocate_on_stack, EmscriptenData}; use std::os::raw::c_int; use wasmer_runtime_core::vm::Ctx; -pub fn _getaddrinfo(_one: i32, _two: i32, _three: i32, _four: i32, _ctx: &mut Ctx) -> i32 { +pub fn _getaddrinfo(_ctx: &mut Ctx, _one: i32, _two: i32, _three: i32, _four: i32) -> i32 { debug!("emscripten::_getaddrinfo"); -1 } -pub fn call_malloc(size: u32, ctx: &mut Ctx) -> u32 { +pub fn call_malloc(ctx: &mut Ctx, size: u32) -> u32 { get_emscripten_data(ctx).malloc.call(size).unwrap() } -pub fn call_memalign(alignment: u32, size: u32, ctx: &mut Ctx) -> u32 { +pub fn call_memalign(ctx: &mut Ctx, alignment: u32, size: u32) -> u32 { if let Some(memalign) = &get_emscripten_data(ctx).memalign { memalign.call(alignment, size).unwrap() } else { @@ -31,7 +31,7 @@ pub fn call_memalign(alignment: u32, size: u32, ctx: &mut Ctx) -> u32 { } } -pub fn call_memset(pointer: u32, value: u32, size: u32, ctx: &mut Ctx) -> u32 { +pub fn call_memset(ctx: &mut Ctx, pointer: u32, value: u32, size: u32) -> u32 { get_emscripten_data(ctx) .memset .call(pointer, value, size) @@ -48,16 +48,16 @@ pub fn _getpagesize(_ctx: &mut Ctx) -> u32 { } #[allow(clippy::cast_ptr_alignment)] -pub fn ___build_environment(environ: c_int, ctx: &mut Ctx) { +pub fn ___build_environment(ctx: &mut Ctx, environ: c_int) { debug!("emscripten::___build_environment {}", environ); const MAX_ENV_VALUES: u32 = 64; const TOTAL_ENV_SIZE: u32 = 1024; let environment = emscripten_memory_pointer!(ctx.memory(0), environ) as *mut c_int; unsafe { let (pool_offset, _pool_slice): (u32, &mut [u8]) = - allocate_on_stack(TOTAL_ENV_SIZE as u32, ctx); + allocate_on_stack(ctx, TOTAL_ENV_SIZE as u32); let (env_offset, _env_slice): (u32, &mut [u8]) = - allocate_on_stack((MAX_ENV_VALUES * 4) as u32, ctx); + allocate_on_stack(ctx, (MAX_ENV_VALUES * 4) as u32); let env_ptr = emscripten_memory_pointer!(ctx.memory(0), env_offset) as *mut c_int; let mut _pool_ptr = emscripten_memory_pointer!(ctx.memory(0), pool_offset) as *mut c_int; *env_ptr = pool_offset as i32; @@ -70,7 +70,7 @@ pub fn ___build_environment(environ: c_int, ctx: &mut Ctx) { // }; } -pub fn ___assert_fail(a: c_int, b: c_int, c: c_int, d: c_int, _ctx: &mut Ctx) { +pub fn ___assert_fail(_ctx: &mut Ctx, a: c_int, b: c_int, c: c_int, d: c_int) { debug!("emscripten::___assert_fail {} {} {} {}", a, b, c, d); // TODO: Implement like emscripten expects regarding memory/page size // TODO raise an error diff --git a/lib/emscripten/src/env/unix/mod.rs b/lib/emscripten/src/env/unix/mod.rs index 55fe0c000..5c4ef3d3a 100644 --- a/lib/emscripten/src/env/unix/mod.rs +++ b/lib/emscripten/src/env/unix/mod.rs @@ -14,7 +14,7 @@ use wasmer_runtime_core::vm::Ctx; // #[no_mangle] /// emscripten: _getenv // (name: *const char) -> *const c_char; -pub fn _getenv(name: i32, ctx: &mut Ctx) -> u32 { +pub fn _getenv(ctx: &mut Ctx, name: i32) -> u32 { debug!("emscripten::_getenv"); let name_addr = emscripten_memory_pointer!(ctx.memory(0), name) as *const c_char; @@ -30,7 +30,7 @@ pub fn _getenv(name: i32, ctx: &mut Ctx) -> u32 { } /// emscripten: _setenv // (name: *const char, name: *const value, overwrite: int); -pub fn _setenv(name: c_int, value: c_int, overwrite: c_int, ctx: &mut Ctx) -> c_int { +pub fn _setenv(ctx: &mut Ctx, name: c_int, value: c_int, overwrite: c_int) -> c_int { debug!("emscripten::_setenv"); let name_addr = emscripten_memory_pointer!(ctx.memory(0), name) as *const c_char; @@ -43,7 +43,7 @@ pub fn _setenv(name: c_int, value: c_int, overwrite: c_int, ctx: &mut Ctx) -> c_ } /// emscripten: _putenv // (name: *const char); -pub fn _putenv(name: c_int, ctx: &mut Ctx) -> c_int { +pub fn _putenv(ctx: &mut Ctx, name: c_int) -> c_int { debug!("emscripten::_putenv"); let name_addr = emscripten_memory_pointer!(ctx.memory(0), name) as *const c_char; @@ -54,7 +54,7 @@ pub fn _putenv(name: c_int, ctx: &mut Ctx) -> c_int { } /// emscripten: _unsetenv // (name: *const char); -pub fn _unsetenv(name: c_int, ctx: &mut Ctx) -> c_int { +pub fn _unsetenv(ctx: &mut Ctx, name: c_int) -> c_int { debug!("emscripten::_unsetenv"); let name_addr = emscripten_memory_pointer!(ctx.memory(0), name) as *const c_char; @@ -65,7 +65,7 @@ pub fn _unsetenv(name: c_int, ctx: &mut Ctx) -> c_int { } #[allow(clippy::cast_ptr_alignment)] -pub fn _getpwnam(name_ptr: c_int, ctx: &mut Ctx) -> c_int { +pub fn _getpwnam(ctx: &mut Ctx, name_ptr: c_int) -> c_int { debug!("emscripten::_getpwnam {}", name_ptr); #[repr(C)] @@ -86,7 +86,7 @@ pub fn _getpwnam(name_ptr: c_int, ctx: &mut Ctx) -> c_int { unsafe { let passwd = &*libc_getpwnam(name.as_ptr()); - let passwd_struct_offset = call_malloc(mem::size_of::() as _, ctx); + let passwd_struct_offset = call_malloc(ctx, mem::size_of::() as _); let passwd_struct_ptr = emscripten_memory_pointer!(ctx.memory(0), passwd_struct_offset) as *mut GuestPasswd; @@ -103,7 +103,7 @@ pub fn _getpwnam(name_ptr: c_int, ctx: &mut Ctx) -> c_int { } #[allow(clippy::cast_ptr_alignment)] -pub fn _getgrnam(name_ptr: c_int, ctx: &mut Ctx) -> c_int { +pub fn _getgrnam(ctx: &mut Ctx, name_ptr: c_int) -> c_int { debug!("emscripten::_getgrnam {}", name_ptr); #[repr(C)] @@ -121,7 +121,7 @@ pub fn _getgrnam(name_ptr: c_int, ctx: &mut Ctx) -> c_int { unsafe { let group = &*libc_getgrnam(name.as_ptr()); - let group_struct_offset = call_malloc(mem::size_of::() as _, ctx); + let group_struct_offset = call_malloc(ctx, mem::size_of::() as _); let group_struct_ptr = emscripten_memory_pointer!(ctx.memory(0), group_struct_offset) as *mut GuestGroup; @@ -134,7 +134,7 @@ pub fn _getgrnam(name_ptr: c_int, ctx: &mut Ctx) -> c_int { } } -pub fn _sysconf(name: c_int, _ctx: &mut Ctx) -> i32 { +pub fn _sysconf(_ctx: &mut Ctx, name: c_int) -> i32 { debug!("emscripten::_sysconf {}", name); // TODO: Implement like emscripten expects regarding memory/page size unsafe { sysconf(name) as i32 } // TODO review i64 diff --git a/lib/emscripten/src/env/windows/mod.rs b/lib/emscripten/src/env/windows/mod.rs index b4171e13c..b4ee6ecff 100644 --- a/lib/emscripten/src/env/windows/mod.rs +++ b/lib/emscripten/src/env/windows/mod.rs @@ -16,7 +16,7 @@ extern "C" { // #[no_mangle] /// emscripten: _getenv // (name: *const char) -> *const c_char; -pub fn _getenv(name: u32, ctx: &mut Ctx) -> u32 { +pub fn _getenv(ctx: &mut Ctx, name: u32) -> u32 { debug!("emscripten::_getenv"); let name_string = read_string_from_wasm(ctx.memory(0), name); debug!("=> name({:?})", name_string); @@ -28,7 +28,7 @@ pub fn _getenv(name: u32, ctx: &mut Ctx) -> u32 { } /// emscripten: _setenv // (name: *const char, name: *const value, overwrite: int); -pub fn _setenv(name: u32, value: u32, overwrite: u32, ctx: &mut Ctx) -> c_int { +pub fn _setenv(ctx: &mut Ctx, name: u32, value: u32, overwrite: u32) -> c_int { debug!("emscripten::_setenv"); let name_addr = emscripten_memory_pointer!(ctx.memory(0), name); let value_addr = emscripten_memory_pointer!(ctx.memory(0), value); @@ -44,7 +44,7 @@ pub fn _setenv(name: u32, value: u32, overwrite: u32, ctx: &mut Ctx) -> c_int { } /// emscripten: _putenv // (name: *const char); -pub fn _putenv(name: c_int, ctx: &mut Ctx) -> c_int { +pub fn _putenv(ctx: &mut Ctx, name: c_int) -> c_int { debug!("emscripten::_putenv"); let name_addr = emscripten_memory_pointer!(ctx.memory(0), name) as *const c_char; @@ -54,7 +54,7 @@ pub fn _putenv(name: c_int, ctx: &mut Ctx) -> c_int { } /// emscripten: _unsetenv // (name: *const char); -pub fn _unsetenv(name: u32, ctx: &mut Ctx) -> c_int { +pub fn _unsetenv(ctx: &mut Ctx, name: u32) -> c_int { debug!("emscripten::_unsetenv"); let name_addr = emscripten_memory_pointer!(ctx.memory(0), name); let name = read_string_from_wasm(ctx.memory(0), name); @@ -67,7 +67,7 @@ pub fn _unsetenv(name: u32, ctx: &mut Ctx) -> c_int { } #[allow(clippy::cast_ptr_alignment)] -pub fn _getpwnam(name_ptr: c_int, ctx: &mut Ctx) -> c_int { +pub fn _getpwnam(ctx: &mut Ctx, name_ptr: c_int) -> c_int { debug!("emscripten::_getpwnam {}", name_ptr); #[repr(C)] @@ -83,7 +83,7 @@ pub fn _getpwnam(name_ptr: c_int, ctx: &mut Ctx) -> c_int { // stub this in windows as it is not valid unsafe { - let passwd_struct_offset = call_malloc(mem::size_of::() as _, ctx); + let passwd_struct_offset = call_malloc(ctx, mem::size_of::() as _); let passwd_struct_ptr = emscripten_memory_pointer!(ctx.memory(0), passwd_struct_offset) as *mut GuestPasswd; (*passwd_struct_ptr).pw_name = 0; @@ -99,7 +99,7 @@ pub fn _getpwnam(name_ptr: c_int, ctx: &mut Ctx) -> c_int { } #[allow(clippy::cast_ptr_alignment)] -pub fn _getgrnam(name_ptr: c_int, ctx: &mut Ctx) -> c_int { +pub fn _getgrnam(ctx: &mut Ctx, name_ptr: c_int) -> c_int { debug!("emscripten::_getgrnam {}", name_ptr); #[repr(C)] @@ -112,7 +112,7 @@ pub fn _getgrnam(name_ptr: c_int, ctx: &mut Ctx) -> c_int { // stub the group struct as it is not supported on windows unsafe { - let group_struct_offset = call_malloc(mem::size_of::() as _, ctx); + let group_struct_offset = call_malloc(ctx, mem::size_of::() as _); let group_struct_ptr = emscripten_memory_pointer!(ctx.memory(0), group_struct_offset) as *mut GuestGroup; (*group_struct_ptr).gr_name = 0; @@ -123,7 +123,7 @@ pub fn _getgrnam(name_ptr: c_int, ctx: &mut Ctx) -> c_int { } } -pub fn _sysconf(name: c_int, _ctx: &mut Ctx) -> c_long { +pub fn _sysconf(_ctx: &mut Ctx, name: c_int) -> c_long { debug!("emscripten::_sysconf {}", name); // stub because sysconf is not valid on windows 0 diff --git a/lib/emscripten/src/errno.rs b/lib/emscripten/src/errno.rs index 647932810..06267e210 100644 --- a/lib/emscripten/src/errno.rs +++ b/lib/emscripten/src/errno.rs @@ -1,7 +1,7 @@ // use std::collections::HashMap; use wasmer_runtime_core::vm::Ctx; -pub fn ___seterrno(value: i32, _ctx: &mut Ctx) { +pub fn ___seterrno(_ctx: &mut Ctx, value: i32) { debug!("emscripten::___seterrno {}", value); // TODO: Incomplete impl eprintln!("failed to set errno!"); diff --git a/lib/emscripten/src/exception.rs b/lib/emscripten/src/exception.rs index b1814e107..b0aab78dd 100644 --- a/lib/emscripten/src/exception.rs +++ b/lib/emscripten/src/exception.rs @@ -3,14 +3,14 @@ use super::process::_abort; use wasmer_runtime_core::vm::Ctx; /// emscripten: ___cxa_allocate_exception -pub fn ___cxa_allocate_exception(size: u32, ctx: &mut Ctx) -> u32 { +pub fn ___cxa_allocate_exception(ctx: &mut Ctx, size: u32) -> u32 { debug!("emscripten::___cxa_allocate_exception"); - env::call_malloc(size as _, ctx) + env::call_malloc(ctx, size as _) } /// emscripten: ___cxa_throw /// TODO: We don't have support for exceptions yet -pub fn ___cxa_throw(_ptr: u32, _ty: u32, _destructor: u32, ctx: &mut Ctx) { +pub fn ___cxa_throw(ctx: &mut Ctx, _ptr: u32, _ty: u32, _destructor: u32) { debug!("emscripten::___cxa_throw"); _abort(ctx); } diff --git a/lib/emscripten/src/io/unix.rs b/lib/emscripten/src/io/unix.rs index a7c26a196..38324ac1e 100644 --- a/lib/emscripten/src/io/unix.rs +++ b/lib/emscripten/src/io/unix.rs @@ -3,12 +3,12 @@ use libc::printf as _printf; use wasmer_runtime_core::vm::Ctx; /// putchar -pub fn putchar(chr: i32, ctx: &mut Ctx) { +pub fn putchar(ctx: &mut Ctx, chr: i32) { unsafe { libc::putchar(chr) }; } /// printf -pub fn printf(memory_offset: i32, extra: i32, ctx: &mut Ctx) -> i32 { +pub fn printf(ctx: &mut Ctx, memory_offset: i32, extra: i32) -> i32 { debug!("emscripten::printf {}, {}", memory_offset, extra); unsafe { let addr = emscripten_memory_pointer!(ctx.memory(0), memory_offset) as _; diff --git a/lib/emscripten/src/io/windows.rs b/lib/emscripten/src/io/windows.rs index b85d9c54a..903d05900 100644 --- a/lib/emscripten/src/io/windows.rs +++ b/lib/emscripten/src/io/windows.rs @@ -15,12 +15,12 @@ use wasmer_runtime_core::vm::Ctx; //} /// putchar -pub fn putchar(chr: i32, ctx: &mut Ctx) { +pub fn putchar(ctx: &mut Ctx, chr: i32) { unsafe { libc::putchar(chr) }; } /// printf -pub fn printf(memory_offset: i32, extra: i32, ctx: &mut Ctx) -> i32 { +pub fn printf(ctx: &mut Ctx, memory_offset: i32, extra: i32) -> i32 { debug!("emscripten::printf {}, {}", memory_offset, extra); // unsafe { // let addr = emscripten_memory_pointer!(ctx.memory(0), memory_offset) as _; diff --git a/lib/emscripten/src/jmp.rs b/lib/emscripten/src/jmp.rs index 0c63593aa..c5b54f02b 100644 --- a/lib/emscripten/src/jmp.rs +++ b/lib/emscripten/src/jmp.rs @@ -4,7 +4,7 @@ use std::cell::UnsafeCell; use wasmer_runtime_core::vm::Ctx; /// setjmp -pub fn __setjmp(env_addr: u32, ctx: &mut Ctx) -> c_int { +pub fn __setjmp(ctx: &mut Ctx, env_addr: u32) -> c_int { debug!("emscripten::__setjmp (setjmp)"); unsafe { // Rather than using the env as the holder of the jump buffer pointer, @@ -15,7 +15,7 @@ pub fn __setjmp(env_addr: u32, ctx: &mut Ctx) -> c_int { let jump_buf: UnsafeCell<[u32; 27]> = UnsafeCell::new([0; 27]); let jumps = &mut get_emscripten_data(ctx).jumps; let result = setjmp(jump_buf.get() as _); - // We set the jump index to be the last value of jumps + // We set the jump index to be the last 3value of jumps *jump_index = jumps.len() as _; // We hold the reference of the jump buffer jumps.push(jump_buf); @@ -25,7 +25,7 @@ pub fn __setjmp(env_addr: u32, ctx: &mut Ctx) -> c_int { /// longjmp #[allow(unreachable_code)] -pub fn __longjmp(env_addr: u32, val: c_int, ctx: &mut Ctx) { +pub fn __longjmp(ctx: &mut Ctx, env_addr: u32, val: c_int) { debug!("emscripten::__longjmp (longmp)"); unsafe { // We retrieve the jump index from the env address diff --git a/lib/emscripten/src/lib.rs b/lib/emscripten/src/lib.rs index 0fb07d72c..999addb2e 100644 --- a/lib/emscripten/src/lib.rs +++ b/lib/emscripten/src/lib.rs @@ -141,7 +141,7 @@ pub fn run_emscripten_instance( let num_params = main_func.signature().params().len(); let _result = match num_params { 2 => { - let (argc, argv) = store_module_arguments(path, args, instance.context_mut()); + let (argc, argv) = store_module_arguments(instance.context_mut(), path, args); instance.call("_main", &[Value::I32(argc as i32), Value::I32(argv as i32)])?; } 0 => { @@ -158,17 +158,17 @@ pub fn run_emscripten_instance( Ok(()) } -fn store_module_arguments(path: &str, args: Vec<&str>, ctx: &mut Ctx) -> (u32, u32) { +fn store_module_arguments(ctx: &mut Ctx, path: &str, args: Vec<&str>) -> (u32, u32) { let argc = args.len() + 1; let mut args_slice = vec![0; argc]; - args_slice[0] = unsafe { allocate_cstr_on_stack(path, ctx).0 }; + args_slice[0] = unsafe { allocate_cstr_on_stack(ctx, path).0 }; for (slot, arg) in args_slice[1..argc].iter_mut().zip(args.iter()) { - *slot = unsafe { allocate_cstr_on_stack(&arg, ctx).0 }; + *slot = unsafe { allocate_cstr_on_stack(ctx, &arg).0 }; } let (argv_offset, argv_slice): (_, &mut [u32]) = - unsafe { allocate_on_stack(((argc + 1) * 4) as u32, ctx) }; + unsafe { allocate_on_stack(ctx, ((argc + 1) * 4) as u32) }; assert!(!argv_slice.is_empty()); for (slot, arg) in argv_slice[0..argc].iter_mut().zip(args_slice.iter()) { *slot = *arg diff --git a/lib/emscripten/src/linking.rs b/lib/emscripten/src/linking.rs index e61b9d1b1..831712e91 100644 --- a/lib/emscripten/src/linking.rs +++ b/lib/emscripten/src/linking.rs @@ -3,19 +3,19 @@ use wasmer_runtime_core::vm::Ctx; // TODO: Need to implement. /// emscripten: dlopen(filename: *const c_char, flag: c_int) -> *mut c_void -pub fn _dlopen(_filename: u32, _flag: u32, _ctx: &mut Ctx) -> i32 { +pub fn _dlopen(_ctx: &mut Ctx, _filename: u32, _flag: u32) -> i32 { debug!("emscripten::_dlopen"); -1 } /// emscripten: dlclose(handle: *mut c_void) -> c_int -pub fn _dlclose(_filename: u32, _ctx: &mut Ctx) -> i32 { +pub fn _dlclose(_ctx: &mut Ctx, _filename: u32) -> i32 { debug!("emscripten::_dlclose"); -1 } /// emscripten: dlsym(handle: *mut c_void, symbol: *const c_char) -> *mut c_void -pub fn _dlsym(_filepath: u32, _symbol: u32, _ctx: &mut Ctx) -> i32 { +pub fn _dlsym(_ctx: &mut Ctx, _filepath: u32, _symbol: u32) -> i32 { debug!("emscripten::_dlsym"); -1 } diff --git a/lib/emscripten/src/lock.rs b/lib/emscripten/src/lock.rs index 005a1baed..45f09581f 100644 --- a/lib/emscripten/src/lock.rs +++ b/lib/emscripten/src/lock.rs @@ -2,16 +2,16 @@ use libc::c_int; use wasmer_runtime_core::vm::Ctx; // NOTE: Not implemented by Emscripten -pub fn ___lock(what: c_int, _ctx: &mut Ctx) { +pub fn ___lock(_ctx: &mut Ctx, what: c_int) { debug!("emscripten::___lock {}", what); } // NOTE: Not implemented by Emscripten -pub fn ___unlock(what: c_int, _ctx: &mut Ctx) { +pub fn ___unlock(_ctx: &mut Ctx, what: c_int) { debug!("emscripten::___unlock {}", what); } // NOTE: Not implemented by Emscripten -pub fn ___wait(_which: u32, _varargs: u32, _three: u32, _four: u32, _ctx: &mut Ctx) { +pub fn ___wait(_ctx: &mut Ctx, _which: u32, _varargs: u32, _three: u32, _four: u32) { debug!("emscripten::___wait"); } diff --git a/lib/emscripten/src/math.rs b/lib/emscripten/src/math.rs index 16f3ed419..a60966a1c 100644 --- a/lib/emscripten/src/math.rs +++ b/lib/emscripten/src/math.rs @@ -1,23 +1,23 @@ use wasmer_runtime_core::vm::Ctx; /// emscripten: _llvm_log10_f64 -pub fn _llvm_log10_f64(value: f64, _ctx: &mut Ctx) -> f64 { +pub fn _llvm_log10_f64(_ctx: &mut Ctx, value: f64) -> f64 { debug!("emscripten::_llvm_log10_f64"); value.log10() } /// emscripten: _llvm_log2_f64 -pub fn _llvm_log2_f64(value: f64, _ctx: &mut Ctx) -> f64 { +pub fn _llvm_log2_f64(_ctx: &mut Ctx, value: f64) -> f64 { debug!("emscripten::_llvm_log2_f64"); value.log2() } -pub fn _llvm_log10_f32(_value: f64, _ctx: &mut Ctx) -> f64 { +pub fn _llvm_log10_f32(_ctx: &mut Ctx, _value: f64) -> f64 { debug!("emscripten::_llvm_log10_f32"); -1.0 } -pub fn _llvm_log2_f32(_value: f64, _ctx: &mut Ctx) -> f64 { +pub fn _llvm_log2_f32(_ctx: &mut Ctx, _value: f64) -> f64 { debug!("emscripten::_llvm_log10_f32"); -1.0 } @@ -28,12 +28,12 @@ pub fn _emscripten_random(_ctx: &mut Ctx) -> f64 { } // emscripten: f64-rem -pub fn f64_rem(x: f64, y: f64, _ctx: &mut Ctx) -> f64 { +pub fn f64_rem(_ctx: &mut Ctx, x: f64, y: f64) -> f64 { debug!("emscripten::f64-rem"); x % y } // emscripten: global.Math pow -pub fn pow(x: f64, y: f64, _ctx: &mut Ctx) -> f64 { +pub fn pow(_ctx: &mut Ctx, x: f64, y: f64) -> f64 { x.powf(y) } diff --git a/lib/emscripten/src/memory.rs b/lib/emscripten/src/memory.rs index e174e023d..c4540dff0 100644 --- a/lib/emscripten/src/memory.rs +++ b/lib/emscripten/src/memory.rs @@ -3,7 +3,7 @@ use libc::{c_int, c_void, memcpy, size_t}; use wasmer_runtime_core::vm::Ctx; /// emscripten: _emscripten_memcpy_big -pub fn _emscripten_memcpy_big(dest: u32, src: u32, len: u32, ctx: &mut Ctx) -> u32 { +pub fn _emscripten_memcpy_big(ctx: &mut Ctx, dest: u32, src: u32, len: u32) -> u32 { debug!( "emscripten::_emscripten_memcpy_big {}, {}, {}", dest, src, len @@ -35,12 +35,12 @@ pub fn enlarge_memory(_ctx: &mut Ctx) -> u32 { /// emscripten: abortOnCannotGrowMemory pub fn abort_on_cannot_grow_memory(ctx: &mut Ctx) -> u32 { debug!("emscripten::abort_on_cannot_grow_memory"); - abort_with_message("Cannot enlarge memory arrays!", ctx); + abort_with_message(ctx, "Cannot enlarge memory arrays!"); 0 } /// emscripten: ___map_file -pub fn ___map_file(_one: u32, _two: u32, _ctx: &mut Ctx) -> c_int { +pub fn ___map_file(_ctx: &mut Ctx, _one: u32, _two: u32) -> c_int { debug!("emscripten::___map_file"); // NOTE: TODO: Em returns -1 here as well. May need to implement properly -1 diff --git a/lib/emscripten/src/nullfunc.rs b/lib/emscripten/src/nullfunc.rs index 253edf8f6..7fb44ab11 100644 --- a/lib/emscripten/src/nullfunc.rs +++ b/lib/emscripten/src/nullfunc.rs @@ -1,67 +1,67 @@ use super::process::abort_with_message; use wasmer_runtime_core::vm::Ctx; -pub fn nullfunc_i(x: u32, ctx: &mut Ctx) { +pub fn nullfunc_i(ctx: &mut Ctx, x: u32) { debug!("emscripten::nullfunc_i {}", x); - abort_with_message("Invalid function pointer called with signature 'i'. Perhaps this is an invalid value (e.g. caused by calling a virtual method on a NULL pointer)? Or calling a function with an incorrect type, which will fail? (it is worth building your source files with -Werror (warnings are errors), as warnings can indicate undefined behavior which can cause this)", ctx); + abort_with_message(ctx, "Invalid function pointer called with signature 'i'. Perhaps this is an invalid value (e.g. caused by calling a virtual method on a NULL pointer)? Or calling a function with an incorrect type, which will fail? (it is worth building your source files with -Werror (warnings are errors), as warnings can indicate undefined behavior which can cause this)"); } -pub fn nullfunc_ii(x: u32, ctx: &mut Ctx) { +pub fn nullfunc_ii(ctx: &mut Ctx, x: u32) { debug!("emscripten::nullfunc_ii {}", x); - abort_with_message("Invalid function pointer called with signature 'ii'. Perhaps this is an invalid value (e.g. caused by calling a virtual method on a NULL pointer)? Or calling a function with an incorrect type, which will fail? (it is worth building your source files with -Werror (warnings are errors), as warnings can indicate undefined behavior which can cause this)", ctx); + abort_with_message(ctx, "Invalid function pointer called with signature 'ii'. Perhaps this is an invalid value (e.g. caused by calling a virtual method on a NULL pointer)? Or calling a function with an incorrect type, which will fail? (it is worth building your source files with -Werror (warnings are errors), as warnings can indicate undefined behavior which can cause this)"); } -pub fn nullfunc_iii(x: u32, ctx: &mut Ctx) { +pub fn nullfunc_iii(ctx: &mut Ctx, x: u32) { debug!("emscripten::nullfunc_iii {}", x); - abort_with_message("Invalid function pointer called with signature 'iii'. Perhaps this is an invalid value (e.g. caused by calling a virtual method on a NULL pointer)? Or calling a function with an incorrect type, which will fail? (it is worth building your source files with -Werror (warnings are errors), as warnings can indicate undefined behavior which can cause this)", ctx); + abort_with_message(ctx, "Invalid function pointer called with signature 'iii'. Perhaps this is an invalid value (e.g. caused by calling a virtual method on a NULL pointer)? Or calling a function with an incorrect type, which will fail? (it is worth building your source files with -Werror (warnings are errors), as warnings can indicate undefined behavior which can cause this)"); } -pub fn nullfunc_iiii(x: u32, ctx: &mut Ctx) { +pub fn nullfunc_iiii(ctx: &mut Ctx, x: u32) { debug!("emscripten::nullfunc_iiii {}", x); - abort_with_message("Invalid function pointer called with signature 'iiii'. Perhaps this is an invalid value (e.g. caused by calling a virtual method on a NULL pointer)? Or calling a function with an incorrect type, which will fail? (it is worth building your source files with -Werror (warnings are errors), as warnings can indicate undefined behavior which can cause this)", ctx); + abort_with_message(ctx, "Invalid function pointer called with signature 'iiii'. Perhaps this is an invalid value (e.g. caused by calling a virtual method on a NULL pointer)? Or calling a function with an incorrect type, which will fail? (it is worth building your source files with -Werror (warnings are errors), as warnings can indicate undefined behavior which can cause this)"); } -pub fn nullfunc_iiiii(x: u32, ctx: &mut Ctx) { +pub fn nullfunc_iiiii(ctx: &mut Ctx, x: u32) { debug!("emscripten::nullfunc_iiiii {}", x); - abort_with_message("Invalid function pointer called with signature 'iiiii'. Perhaps this is an invalid value (e.g. caused by calling a virtual method on a NULL pointer)? Or calling a function with an incorrect type, which will fail? (it is worth building your source files with -Werror (warnings are errors), as warnings can indicate undefined behavior which can cause this)", ctx); + abort_with_message(ctx, "Invalid function pointer called with signature 'iiiii'. Perhaps this is an invalid value (e.g. caused by calling a virtual method on a NULL pointer)? Or calling a function with an incorrect type, which will fail? (it is worth building your source files with -Werror (warnings are errors), as warnings can indicate undefined behavior which can cause this)"); } -pub fn nullfunc_iiiiii(x: u32, ctx: &mut Ctx) { +pub fn nullfunc_iiiiii(ctx: &mut Ctx, x: u32) { debug!("emscripten::nullfunc_iiiiii {}", x); - abort_with_message("Invalid function pointer called with signature 'iiiiii'. Perhaps this is an invalid value (e.g. caused by calling a virtual method on a NULL pointer)? Or calling a function with an incorrect type, which will fail? (it is worth building your source files with -Werror (warnings are errors), as warnings can indicate undefined behavior which can cause this)", ctx); + abort_with_message(ctx, "Invalid function pointer called with signature 'iiiiii'. Perhaps this is an invalid value (e.g. caused by calling a virtual method on a NULL pointer)? Or calling a function with an incorrect type, which will fail? (it is worth building your source files with -Werror (warnings are errors), as warnings can indicate undefined behavior which can cause this)"); } -pub fn nullfunc_v(x: u32, ctx: &mut Ctx) { +pub fn nullfunc_v(ctx: &mut Ctx, x: u32) { debug!("emscripten::nullfunc_v {}", x); - abort_with_message("Invalid function pointer called with signature 'v'. Perhaps this is an invalid value (e.g. caused by calling a virtual method on a NULL pointer)? Or calling a function with an incorrect type, which will fail? (it is worth building your source files with -Werror (warnings are errors), as warnings can indicate undefined behavior which can cause this)", ctx); + abort_with_message(ctx, "Invalid function pointer called with signature 'v'. Perhaps this is an invalid value (e.g. caused by calling a virtual method on a NULL pointer)? Or calling a function with an incorrect type, which will fail? (it is worth building your source files with -Werror (warnings are errors), as warnings can indicate undefined behavior which can cause this)"); } -pub fn nullfunc_vi(x: u32, ctx: &mut Ctx) { +pub fn nullfunc_vi(ctx: &mut Ctx, x: u32) { debug!("emscripten::nullfunc_vi {}", x); - abort_with_message("Invalid function pointer called with signature 'vi'. Perhaps this is an invalid value (e.g. caused by calling a virtual method on a NULL pointer)? Or calling a function with an incorrect type, which will fail? (it is worth building your source files with -Werror (warnings are errors), as warnings can indicate undefined behavior which can cause this)", ctx); + abort_with_message(ctx, "Invalid function pointer called with signature 'vi'. Perhaps this is an invalid value (e.g. caused by calling a virtual method on a NULL pointer)? Or calling a function with an incorrect type, which will fail? (it is worth building your source files with -Werror (warnings are errors), as warnings can indicate undefined behavior which can cause this)"); } -pub fn nullfunc_vii(x: u32, ctx: &mut Ctx) { +pub fn nullfunc_vii(ctx: &mut Ctx, x: u32) { debug!("emscripten::nullfunc_vii {}", x); - abort_with_message("Invalid function pointer called with signature 'vii'. Perhaps this is an invalid value (e.g. caused by calling a virtual method on a NULL pointer)? Or calling a function with an incorrect type, which will fail? (it is worth building your source files with -Werror (warnings are errors), as warnings can indicate undefined behavior which can cause this)", ctx); + abort_with_message(ctx, "Invalid function pointer called with signature 'vii'. Perhaps this is an invalid value (e.g. caused by calling a virtual method on a NULL pointer)? Or calling a function with an incorrect type, which will fail? (it is worth building your source files with -Werror (warnings are errors), as warnings can indicate undefined behavior which can cause this)"); } -pub fn nullfunc_viii(x: u32, ctx: &mut Ctx) { +pub fn nullfunc_viii(ctx: &mut Ctx, x: u32) { debug!("emscripten::nullfunc_viii {}", x); - abort_with_message("Invalid function pointer called with signature 'viii'. Perhaps this is an invalid value (e.g. caused by calling a virtual method on a NULL pointer)? Or calling a function with an incorrect type, which will fail? (it is worth building your source files with -Werror (warnings are errors), as warnings can indicate undefined behavior which can cause this)", ctx); + abort_with_message(ctx, "Invalid function pointer called with signature 'viii'. Perhaps this is an invalid value (e.g. caused by calling a virtual method on a NULL pointer)? Or calling a function with an incorrect type, which will fail? (it is worth building your source files with -Werror (warnings are errors), as warnings can indicate undefined behavior which can cause this)"); } -pub fn nullfunc_viiii(x: u32, ctx: &mut Ctx) { +pub fn nullfunc_viiii(ctx: &mut Ctx, x: u32) { debug!("emscripten::nullfunc_viiii {}", x); - abort_with_message("Invalid function pointer called with signature 'viiii'. Perhaps this is an invalid value (e.g. caused by calling a virtual method on a NULL pointer)? Or calling a function with an incorrect type, which will fail? (it is worth building your source files with -Werror (warnings are errors), as warnings can indicate undefined behavior which can cause this)", ctx); + abort_with_message(ctx, "Invalid function pointer called with signature 'viiii'. Perhaps this is an invalid value (e.g. caused by calling a virtual method on a NULL pointer)? Or calling a function with an incorrect type, which will fail? (it is worth building your source files with -Werror (warnings are errors), as warnings can indicate undefined behavior which can cause this)"); } -pub fn nullfunc_viiiii(_x: u32, ctx: &mut Ctx) { +pub fn nullfunc_viiiii(ctx: &mut Ctx, _x: u32) { debug!("emscripten::nullfunc_viiiii"); - abort_with_message("Invalid function pointer called with signature 'viiiii'. Perhaps this is an invalid value (e.g. caused by calling a virtual method on a NULL pointer)? Or calling a function with an incorrect type, which will fail? (it is worth building your source files with -Werror (warnings are errors), as warnings can indicate undefined behavior which can cause this)", ctx); + abort_with_message(ctx, "Invalid function pointer called with signature 'viiiii'. Perhaps this is an invalid value (e.g. caused by calling a virtual method on a NULL pointer)? Or calling a function with an incorrect type, which will fail? (it is worth building your source files with -Werror (warnings are errors), as warnings can indicate undefined behavior which can cause this)"); } -pub fn nullfunc_viiiiii(_x: u32, ctx: &mut Ctx) { +pub fn nullfunc_viiiiii(ctx: &mut Ctx, _x: u32) { debug!("emscripten::nullfunc_viiiiii"); - abort_with_message("Invalid function pointer called with signature 'viiiiii'. Perhaps this is an invalid value (e.g. caused by calling a virtual method on a NULL pointer)? Or calling a function with an incorrect type, which will fail? (it is worth building your source files with -Werror (warnings are errors), as warnings can indicate undefined behavior which can cause this)", ctx); + abort_with_message(ctx, "Invalid function pointer called with signature 'viiiiii'. Perhaps this is an invalid value (e.g. caused by calling a virtual method on a NULL pointer)? Or calling a function with an incorrect type, which will fail? (it is worth building your source files with -Werror (warnings are errors), as warnings can indicate undefined behavior which can cause this)"); } diff --git a/lib/emscripten/src/process.rs b/lib/emscripten/src/process.rs index d6be7a78b..8d1dddb48 100644 --- a/lib/emscripten/src/process.rs +++ b/lib/emscripten/src/process.rs @@ -9,7 +9,7 @@ type pid_t = c_int; use std::ffi::CStr; use wasmer_runtime_core::vm::Ctx; -pub fn abort_with_message(message: &str, ctx: &mut Ctx) { +pub fn abort_with_message(ctx: &mut Ctx, message: &str) { debug!("emscripten::abort_with_message"); println!("{}", message); _abort(ctx); @@ -34,19 +34,19 @@ pub fn _endgrent(_ctx: &mut Ctx) { debug!("emscripten::_endgrent"); } -pub fn _execve(_one: i32, _two: i32, _three: i32, _ctx: &mut Ctx) -> i32 { +pub fn _execve(_ctx: &mut Ctx, _one: i32, _two: i32, _three: i32) -> i32 { debug!("emscripten::_execve"); -1 } #[allow(unreachable_code)] -pub fn _exit(status: c_int, _ctx: &mut Ctx) { +pub fn _exit(_ctx: &mut Ctx, status: c_int) { // -> ! debug!("emscripten::_exit {}", status); unsafe { exit(status) } } -pub fn em_abort(message: u32, ctx: &mut Ctx) { +pub fn em_abort(ctx: &mut Ctx, message: u32) { debug!("emscripten::em_abort {}", message); let message_addr = emscripten_memory_pointer!(ctx.memory(0), message) as *mut c_char; unsafe { @@ -54,11 +54,11 @@ pub fn em_abort(message: u32, ctx: &mut Ctx) { .to_str() .unwrap_or("Unexpected abort"); - abort_with_message(message, ctx); + abort_with_message(ctx, message); } } -pub fn _kill(_one: i32, _two: i32, _ctx: &mut Ctx) -> i32 { +pub fn _kill(_ctx: &mut Ctx, _one: i32, _two: i32) -> i32 { debug!("emscripten::_kill"); -1 } @@ -73,26 +73,26 @@ pub fn _llvm_stacksave(_ctx: &mut Ctx) -> i32 { -1 } -pub fn _llvm_stackrestore(_one: i32, _ctx: &mut Ctx) { +pub fn _llvm_stackrestore(_ctx: &mut Ctx, _one: i32) { debug!("emscripten::_llvm_stackrestore"); } -pub fn _raise(_one: i32, _ctx: &mut Ctx) -> i32 { +pub fn _raise(_ctx: &mut Ctx, _one: i32) -> i32 { debug!("emscripten::_raise"); -1 } -pub fn _sem_init(_one: i32, _two: i32, _three: i32, _ctx: &mut Ctx) -> i32 { +pub fn _sem_init(_ctx: &mut Ctx, _one: i32, _two: i32, _three: i32) -> i32 { debug!("emscripten::_sem_init"); -1 } -pub fn _sem_post(_one: i32, _ctx: &mut Ctx) -> i32 { +pub fn _sem_post(_ctx: &mut Ctx, _one: i32) -> i32 { debug!("emscripten::_sem_post"); -1 } -pub fn _sem_wait(_one: i32, _ctx: &mut Ctx) -> i32 { +pub fn _sem_wait(_ctx: &mut Ctx, _one: i32) -> i32 { debug!("emscripten::_sem_post"); -1 } @@ -107,53 +107,53 @@ pub fn _setgrent(_ctx: &mut Ctx) { debug!("emscripten::_setgrent"); } -pub fn _setgroups(_one: i32, _two: i32, _ctx: &mut Ctx) -> i32 { +pub fn _setgroups(_ctx: &mut Ctx, _one: i32, _two: i32) -> i32 { debug!("emscripten::_setgroups"); -1 } -pub fn _setitimer(_one: i32, _two: i32, _three: i32, _ctx: &mut Ctx) -> i32 { +pub fn _setitimer(_ctx: &mut Ctx, _one: i32, _two: i32, _three: i32) -> i32 { debug!("emscripten::_setitimer"); -1 } -pub fn _usleep(_one: i32, _ctx: &mut Ctx) -> i32 { +pub fn _usleep(_ctx: &mut Ctx, _one: i32) -> i32 { debug!("emscripten::_usleep"); -1 } -pub fn _utimes(_one: i32, _two: i32, _ctx: &mut Ctx) -> i32 { +pub fn _utimes(_ctx: &mut Ctx, _one: i32, _two: i32) -> i32 { debug!("emscripten::_utimes"); -1 } -pub fn _waitpid(_one: i32, _two: i32, _three: i32, _ctx: &mut Ctx) -> i32 { +pub fn _waitpid(_ctx: &mut Ctx, _one: i32, _two: i32, _three: i32) -> i32 { debug!("emscripten::_waitpid"); -1 } -pub fn abort_stack_overflow(_what: c_int, ctx: &mut Ctx) { +pub fn abort_stack_overflow(ctx: &mut Ctx, _what: c_int) { debug!("emscripten::abort_stack_overflow"); // TODO: Message incomplete. Need to finish em runtime data first abort_with_message( - "Stack overflow! Attempted to allocate some bytes on the stack", ctx, + "Stack overflow! Attempted to allocate some bytes on the stack", ); } pub fn _llvm_trap(ctx: &mut Ctx) { debug!("emscripten::_llvm_trap"); - abort_with_message("abort!", ctx); + abort_with_message(ctx, "abort!"); } -pub fn _system(_one: i32, _ctx: &mut Ctx) -> c_int { +pub fn _system(_ctx: &mut Ctx, _one: i32) -> c_int { debug!("emscripten::_system"); // TODO: May need to change this Em impl to a working version eprintln!("Can't call external programs"); return EAGAIN; } -pub fn _popen(_one: i32, _two: i32, _ctx: &mut Ctx) -> c_int { +pub fn _popen(_ctx: &mut Ctx, _one: i32, _two: i32) -> c_int { debug!("emscripten::_popen"); // TODO: May need to change this Em impl to a working version eprintln!("Missing function: popen"); diff --git a/lib/emscripten/src/signal.rs b/lib/emscripten/src/signal.rs index 1a6d43078..f7657630b 100644 --- a/lib/emscripten/src/signal.rs +++ b/lib/emscripten/src/signal.rs @@ -2,7 +2,7 @@ use wasmer_runtime_core::vm::Ctx; #[allow(clippy::cast_ptr_alignment)] -pub fn _sigemptyset(set: u32, ctx: &mut Ctx) -> i32 { +pub fn _sigemptyset(ctx: &mut Ctx, set: u32) -> i32 { debug!("emscripten::_sigemptyset"); let set_addr = emscripten_memory_pointer!(ctx.memory(0), set) as *mut u32; unsafe { @@ -11,13 +11,13 @@ pub fn _sigemptyset(set: u32, ctx: &mut Ctx) -> i32 { 0 } -pub fn _sigaction(signum: u32, act: u32, oldact: u32, _ctx: &mut Ctx) -> i32 { +pub fn _sigaction(_ctx: &mut Ctx, signum: u32, act: u32, oldact: u32) -> i32 { debug!("emscripten::_sigaction {}, {}, {}", signum, act, oldact); 0 } #[allow(clippy::cast_ptr_alignment)] -pub fn _sigaddset(set: u32, signum: u32, ctx: &mut Ctx) -> i32 { +pub fn _sigaddset(ctx: &mut Ctx, set: u32, signum: u32) -> i32 { debug!("emscripten::_sigaddset {}, {}", set, signum); let set_addr = emscripten_memory_pointer!(ctx.memory(0), set) as *mut u32; unsafe { @@ -26,17 +26,17 @@ pub fn _sigaddset(set: u32, signum: u32, ctx: &mut Ctx) -> i32 { 0 } -pub fn _sigsuspend(_one: i32, _ctx: &mut Ctx) -> i32 { +pub fn _sigsuspend(_ctx: &mut Ctx, _one: i32) -> i32 { debug!("emscripten::_sigsuspend"); -1 } -pub fn _sigprocmask(_one: i32, _two: i32, _three: i32, _ctx: &mut Ctx) -> i32 { +pub fn _sigprocmask(_ctx: &mut Ctx, _one: i32, _two: i32, _three: i32) -> i32 { debug!("emscripten::_sigprocmask"); 0 } -pub fn _signal(sig: u32, _two: i32, _ctx: &mut Ctx) -> i32 { +pub fn _signal(_ctx: &mut Ctx, sig: u32, _two: i32) -> i32 { debug!("emscripten::_signal ({})", sig); 0 } diff --git a/lib/emscripten/src/syscalls/mod.rs b/lib/emscripten/src/syscalls/mod.rs index edae4860c..38c4157d1 100644 --- a/lib/emscripten/src/syscalls/mod.rs +++ b/lib/emscripten/src/syscalls/mod.rs @@ -70,7 +70,7 @@ use libc::SO_NOSIGPIPE; const SO_NOSIGPIPE: c_int = 0; /// exit -pub fn ___syscall1(which: c_int, mut varargs: VarArgs, ctx: &mut Ctx) { +pub fn ___syscall1(ctx: &mut Ctx, which: c_int, mut varargs: VarArgs) { debug!("emscripten::___syscall1 (exit) {}", which); let status: i32 = varargs.get(ctx); unsafe { @@ -79,7 +79,7 @@ pub fn ___syscall1(which: c_int, mut varargs: VarArgs, ctx: &mut Ctx) { } /// read -pub fn ___syscall3(which: i32, mut varargs: VarArgs, ctx: &mut Ctx) -> i32 { +pub fn ___syscall3(ctx: &mut Ctx, which: i32, mut varargs: VarArgs) -> i32 { // -> ssize_t debug!("emscripten::___syscall3 (read) {}", which); let fd: i32 = varargs.get(ctx); @@ -93,7 +93,7 @@ pub fn ___syscall3(which: i32, mut varargs: VarArgs, ctx: &mut Ctx) -> i32 { } /// write -pub fn ___syscall4(which: c_int, mut varargs: VarArgs, ctx: &mut Ctx) -> c_int { +pub fn ___syscall4(ctx: &mut Ctx, which: c_int, mut varargs: VarArgs) -> c_int { debug!("emscripten::___syscall4 (write) {}", which); let fd: i32 = varargs.get(ctx); let buf: u32 = varargs.get(ctx); @@ -104,7 +104,7 @@ pub fn ___syscall4(which: c_int, mut varargs: VarArgs, ctx: &mut Ctx) -> c_int { } /// open -pub fn ___syscall5(which: c_int, mut varargs: VarArgs, ctx: &mut Ctx) -> c_int { +pub fn ___syscall5(ctx: &mut Ctx, which: c_int, mut varargs: VarArgs) -> c_int { debug!("emscripten::___syscall5 (open) {}", which); let pathname: u32 = varargs.get(ctx); let flags: i32 = varargs.get(ctx); @@ -120,7 +120,7 @@ pub fn ___syscall5(which: c_int, mut varargs: VarArgs, ctx: &mut Ctx) -> c_int { } /// close -pub fn ___syscall6(which: c_int, mut varargs: VarArgs, ctx: &mut Ctx) -> c_int { +pub fn ___syscall6(ctx: &mut Ctx, which: c_int, mut varargs: VarArgs) -> c_int { debug!("emscripten::___syscall6 (close) {}", which); let fd: i32 = varargs.get(ctx); debug!("fd: {}", fd); @@ -128,7 +128,7 @@ pub fn ___syscall6(which: c_int, mut varargs: VarArgs, ctx: &mut Ctx) -> c_int { } // chdir -pub fn ___syscall12(which: c_int, mut varargs: VarArgs, ctx: &mut Ctx) -> c_int { +pub fn ___syscall12(ctx: &mut Ctx, which: c_int, mut varargs: VarArgs) -> c_int { debug!("emscripten::___syscall12 (chdir) {}", which); let path_addr: i32 = varargs.get(ctx); unsafe { @@ -140,42 +140,42 @@ pub fn ___syscall12(which: c_int, mut varargs: VarArgs, ctx: &mut Ctx) -> c_int } } -pub fn ___syscall10(_one: i32, _two: i32, _ctx: &mut Ctx) -> i32 { +pub fn ___syscall10(_ctx: &mut Ctx, _one: i32, _two: i32) -> i32 { debug!("emscripten::___syscall10"); -1 } -pub fn ___syscall15(_one: i32, _two: i32, _ctx: &mut Ctx) -> i32 { +pub fn ___syscall15(_ctx: &mut Ctx, _one: i32, _two: i32) -> i32 { debug!("emscripten::___syscall15"); -1 } // getpid -pub fn ___syscall20(_one: i32, _two: i32, _ctx: &mut Ctx) -> i32 { +pub fn ___syscall20(_ctx: &mut Ctx, _one: i32, _two: i32) -> i32 { debug!("emscripten::___syscall20 (getpid)"); unsafe { getpid() } } -pub fn ___syscall38(_one: i32, _two: i32, _ctx: &mut Ctx) -> i32 { +pub fn ___syscall38(_ctx: &mut Ctx, _one: i32, _two: i32) -> i32 { debug!("emscripten::___syscall38"); -1 } // rmdir -pub fn ___syscall40(_which: c_int, mut varargs: VarArgs, ctx: &mut Ctx) -> c_int { +pub fn ___syscall40(ctx: &mut Ctx, _which: c_int, mut varargs: VarArgs) -> c_int { debug!("emscripten::___syscall40 (rmdir)"); let pathname: u32 = varargs.get(ctx); let pathname_addr = emscripten_memory_pointer!(ctx.memory(0), pathname) as *const i8; unsafe { rmdir(pathname_addr) } } -pub fn ___syscall60(_one: i32, _two: i32, _ctx: &mut Ctx) -> i32 { +pub fn ___syscall60(_ctx: &mut Ctx, _one: i32, _two: i32) -> i32 { debug!("emscripten::___syscall60"); -1 } // dup2 -pub fn ___syscall63(which: c_int, mut varargs: VarArgs, ctx: &mut Ctx) -> c_int { +pub fn ___syscall63(ctx: &mut Ctx, which: c_int, mut varargs: VarArgs) -> c_int { debug!("emscripten::___syscall63 (dup2) {}", which); let src: i32 = varargs.get(ctx); @@ -185,43 +185,43 @@ pub fn ___syscall63(which: c_int, mut varargs: VarArgs, ctx: &mut Ctx) -> c_int } // getppid -pub fn ___syscall64(_one: i32, _two: i32, _ctx: &mut Ctx) -> i32 { +pub fn ___syscall64(_ctx: &mut Ctx, _one: i32, _two: i32) -> i32 { debug!("emscripten::___syscall64 (getppid)"); unsafe { getpid() } } -pub fn ___syscall66(_one: i32, _two: i32, _ctx: &mut Ctx) -> i32 { +pub fn ___syscall66(_ctx: &mut Ctx, _one: i32, _two: i32) -> i32 { debug!("emscripten::___syscall66"); -1 } -pub fn ___syscall75(_one: i32, _two: i32, _ctx: &mut Ctx) -> i32 { +pub fn ___syscall75(_ctx: &mut Ctx, _one: i32, _two: i32) -> i32 { debug!("emscripten::___syscall75"); -1 } -pub fn ___syscall85(_one: i32, _two: i32, _ctx: &mut Ctx) -> i32 { +pub fn ___syscall85(_ctx: &mut Ctx, _one: i32, _two: i32) -> i32 { debug!("emscripten::___syscall85"); -1 } -pub fn ___syscall91(_one: i32, _two: i32, _ctx: &mut Ctx) -> i32 { +pub fn ___syscall91(_ctx: &mut Ctx, _one: i32, _two: i32) -> i32 { debug!("emscripten::___syscall91"); -1 } -pub fn ___syscall97(_one: i32, _two: i32, _ctx: &mut Ctx) -> i32 { +pub fn ___syscall97(_ctx: &mut Ctx, _one: i32, _two: i32) -> i32 { debug!("emscripten::___syscall97"); -1 } -pub fn ___syscall110(_one: i32, _two: i32, _ctx: &mut Ctx) -> i32 { +pub fn ___syscall110(_ctx: &mut Ctx, _one: i32, _two: i32) -> i32 { debug!("emscripten::___syscall110"); -1 } // mmap2 -pub fn ___syscall192(which: c_int, mut varargs: VarArgs, ctx: &mut Ctx) -> c_int { +pub fn ___syscall192(ctx: &mut Ctx, which: c_int, mut varargs: VarArgs) -> c_int { debug!("emscripten::___syscall192 (mmap2) {}", which); let addr: i32 = varargs.get(ctx); let len: u32 = varargs.get(ctx); @@ -235,11 +235,11 @@ pub fn ___syscall192(which: c_int, mut varargs: VarArgs, ctx: &mut Ctx) -> c_int ); if fd == -1 { - let ptr = env::call_memalign(16384, len, ctx); + let ptr = env::call_memalign(ctx, 16384, len); if ptr == 0 { return -1; } - env::call_memset(ptr, 0, len, ctx); + env::call_memset(ctx, ptr, 0, len); ptr as _ } else { -1 @@ -247,7 +247,7 @@ pub fn ___syscall192(which: c_int, mut varargs: VarArgs, ctx: &mut Ctx) -> c_int } /// lseek -pub fn ___syscall140(which: i32, mut varargs: VarArgs, ctx: &mut Ctx) -> i32 { +pub fn ___syscall140(ctx: &mut Ctx, which: i32, mut varargs: VarArgs) -> i32 { // -> c_int debug!("emscripten::___syscall140 (lseek) {}", which); let fd: i32 = varargs.get(ctx); @@ -259,7 +259,7 @@ pub fn ___syscall140(which: i32, mut varargs: VarArgs, ctx: &mut Ctx) -> i32 { /// readv #[allow(clippy::cast_ptr_alignment)] -pub fn ___syscall145(which: c_int, mut varargs: VarArgs, ctx: &mut Ctx) -> i32 { +pub fn ___syscall145(ctx: &mut Ctx, which: c_int, mut varargs: VarArgs) -> i32 { // -> ssize_t debug!("emscripten::___syscall145 (readv) {}", which); // let fd: i32 = varargs.get(ctx); @@ -302,7 +302,7 @@ pub fn ___syscall145(which: c_int, mut varargs: VarArgs, ctx: &mut Ctx) -> i32 { // writev #[allow(clippy::cast_ptr_alignment)] -pub fn ___syscall146(which: i32, mut varargs: VarArgs, ctx: &mut Ctx) -> i32 { +pub fn ___syscall146(ctx: &mut Ctx, which: i32, mut varargs: VarArgs) -> i32 { // -> ssize_t debug!("emscripten::___syscall146 (writev) {}", which); let fd: i32 = varargs.get(ctx); @@ -336,33 +336,33 @@ pub fn ___syscall146(which: i32, mut varargs: VarArgs, ctx: &mut Ctx) -> i32 { } } -pub fn ___syscall168(_one: i32, _two: i32, _ctx: &mut Ctx) -> i32 { +pub fn ___syscall168(_ctx: &mut Ctx, _one: i32, _two: i32) -> i32 { debug!("emscripten::___syscall168"); -1 } -pub fn ___syscall191(_one: i32, _two: i32, _ctx: &mut Ctx) -> i32 { +pub fn ___syscall191(_ctx: &mut Ctx, _one: i32, _two: i32) -> i32 { debug!("emscripten::___syscall191 - stub"); -1 } -pub fn ___syscall194(_one: i32, _two: i32, _ctx: &mut Ctx) -> i32 { +pub fn ___syscall194(_ctx: &mut Ctx, _one: i32, _two: i32) -> i32 { debug!("emscripten::___syscall194 - stub"); -1 } -pub fn ___syscall196(_one: i32, _two: i32, _ctx: &mut Ctx) -> i32 { +pub fn ___syscall196(_ctx: &mut Ctx, _one: i32, _two: i32) -> i32 { debug!("emscripten::___syscall194 - stub"); -1 } -pub fn ___syscall199(_one: i32, _two: i32, _ctx: &mut Ctx) -> i32 { +pub fn ___syscall199(_ctx: &mut Ctx, _one: i32, _two: i32) -> i32 { debug!("emscripten::___syscall199 - stub"); -1 } // stat64 -pub fn ___syscall195(which: c_int, mut varargs: VarArgs, ctx: &mut Ctx) -> c_int { +pub fn ___syscall195(ctx: &mut Ctx, which: c_int, mut varargs: VarArgs) -> c_int { debug!("emscripten::___syscall195 (stat64) {}", which); let pathname: u32 = varargs.get(ctx); let buf: u32 = varargs.get(ctx); @@ -382,7 +382,7 @@ pub fn ___syscall195(which: c_int, mut varargs: VarArgs, ctx: &mut Ctx) -> c_int } // fstat64 -pub fn ___syscall197(which: c_int, mut varargs: VarArgs, ctx: &mut Ctx) -> c_int { +pub fn ___syscall197(ctx: &mut Ctx, which: c_int, mut varargs: VarArgs) -> c_int { debug!("emscripten::___syscall197 (fstat64) {}", which); let fd: c_int = varargs.get(ctx); let buf: u32 = varargs.get(ctx); @@ -400,13 +400,13 @@ pub fn ___syscall197(which: c_int, mut varargs: VarArgs, ctx: &mut Ctx) -> c_int 0 } -pub fn ___syscall220(_one: i32, _two: i32, _ctx: &mut Ctx) -> i32 { +pub fn ___syscall220(_ctx: &mut Ctx, _one: i32, _two: i32) -> i32 { debug!("emscripten::___syscall220"); -1 } // fcntl64 -pub fn ___syscall221(which: c_int, mut varargs: VarArgs, ctx: &mut Ctx) -> c_int { +pub fn ___syscall221(ctx: &mut Ctx, which: c_int, mut varargs: VarArgs) -> c_int { debug!("emscripten::___syscall221 (fcntl64) {}", which); // fcntl64 let _fd: i32 = varargs.get(ctx); @@ -417,33 +417,33 @@ pub fn ___syscall221(which: c_int, mut varargs: VarArgs, ctx: &mut Ctx) -> c_int } } -pub fn ___syscall268(_one: i32, _two: i32, _ctx: &mut Ctx) -> i32 { +pub fn ___syscall268(_ctx: &mut Ctx, _one: i32, _two: i32) -> i32 { debug!("emscripten::___syscall268"); -1 } -pub fn ___syscall272(_one: i32, _two: i32, _ctx: &mut Ctx) -> i32 { +pub fn ___syscall272(_ctx: &mut Ctx, _one: i32, _two: i32) -> i32 { debug!("emscripten::___syscall272"); -1 } -pub fn ___syscall295(_one: i32, _two: i32, _ctx: &mut Ctx) -> i32 { +pub fn ___syscall295(_ctx: &mut Ctx, _one: i32, _two: i32) -> i32 { debug!("emscripten::___syscall295"); -1 } -pub fn ___syscall300(_one: i32, _two: i32, _ctx: &mut Ctx) -> i32 { +pub fn ___syscall300(_ctx: &mut Ctx, _one: i32, _two: i32) -> i32 { debug!("emscripten::___syscall300"); -1 } -pub fn ___syscall334(_one: i32, _two: i32, _ctx: &mut Ctx) -> i32 { +pub fn ___syscall334(_ctx: &mut Ctx, _one: i32, _two: i32) -> i32 { debug!("emscripten::___syscall334"); -1 } // prlimit64 -pub fn ___syscall340(which: c_int, mut varargs: VarArgs, ctx: &mut Ctx) -> c_int { +pub fn ___syscall340(ctx: &mut Ctx, which: c_int, mut varargs: VarArgs) -> c_int { debug!("emscripten::___syscall340 (prlimit64), {}", which); // NOTE: Doesn't really matter. Wasm modules cannot exceed WASM_PAGE_SIZE anyway. let _pid: i32 = varargs.get(ctx); diff --git a/lib/emscripten/src/syscalls/unix.rs b/lib/emscripten/src/syscalls/unix.rs index 00b3b47e8..766f78b92 100644 --- a/lib/emscripten/src/syscalls/unix.rs +++ b/lib/emscripten/src/syscalls/unix.rs @@ -94,7 +94,7 @@ use libc::SO_NOSIGPIPE; const SO_NOSIGPIPE: c_int = 0; // chown -pub fn ___syscall212(which: c_int, mut varargs: VarArgs, ctx: &mut Ctx) -> c_int { +pub fn ___syscall212(ctx: &mut Ctx, which: c_int, mut varargs: VarArgs) -> c_int { debug!("emscripten::___syscall212 (chown) {}", which); let pathname: u32 = varargs.get(ctx); @@ -107,7 +107,7 @@ pub fn ___syscall212(which: c_int, mut varargs: VarArgs, ctx: &mut Ctx) -> c_int } // mkdir -pub fn ___syscall39(which: c_int, mut varargs: VarArgs, ctx: &mut Ctx) -> c_int { +pub fn ___syscall39(ctx: &mut Ctx, which: c_int, mut varargs: VarArgs) -> c_int { debug!("emscripten::___syscall39 (mkdir) {}", which); let pathname: u32 = varargs.get(ctx); let mode: u32 = varargs.get(ctx); @@ -116,7 +116,7 @@ pub fn ___syscall39(which: c_int, mut varargs: VarArgs, ctx: &mut Ctx) -> c_int } // getgid -pub fn ___syscall201(_one: i32, _two: i32, _ctx: &mut Ctx) -> i32 { +pub fn ___syscall201(_ctx: &mut Ctx, _one: i32, _two: i32) -> i32 { debug!("emscripten::___syscall201 (getgid)"); unsafe { // Maybe fix: Emscripten returns 0 always @@ -125,7 +125,7 @@ pub fn ___syscall201(_one: i32, _two: i32, _ctx: &mut Ctx) -> i32 { } // getgid32 -pub fn ___syscall202(_one: i32, _two: i32, _ctx: &mut Ctx) -> i32 { +pub fn ___syscall202(_ctx: &mut Ctx, _one: i32, _two: i32) -> i32 { // gid_t debug!("emscripten::___syscall202 (getgid32)"); unsafe { @@ -135,7 +135,7 @@ pub fn ___syscall202(_one: i32, _two: i32, _ctx: &mut Ctx) -> i32 { } /// dup3 -pub fn ___syscall330(_which: c_int, mut varargs: VarArgs, ctx: &mut Ctx) -> pid_t { +pub fn ___syscall330(ctx: &mut Ctx, _which: c_int, mut varargs: VarArgs) -> pid_t { // Implementation based on description at https://linux.die.net/man/2/dup3 debug!("emscripten::___syscall330 (dup3)"); let oldfd: c_int = varargs.get(ctx); @@ -169,7 +169,7 @@ pub fn ___syscall330(_which: c_int, mut varargs: VarArgs, ctx: &mut Ctx) -> pid_ } /// ioctl -pub fn ___syscall54(which: c_int, mut varargs: VarArgs, ctx: &mut Ctx) -> c_int { +pub fn ___syscall54(ctx: &mut Ctx, which: c_int, mut varargs: VarArgs) -> c_int { debug!("emscripten::___syscall54 (ioctl) {}", which); let fd: i32 = varargs.get(ctx); let request: u32 = varargs.get(ctx); @@ -212,7 +212,7 @@ pub fn ___syscall54(which: c_int, mut varargs: VarArgs, ctx: &mut Ctx) -> c_int // socketcall #[allow(clippy::cast_ptr_alignment)] -pub fn ___syscall102(which: c_int, mut varargs: VarArgs, ctx: &mut Ctx) -> c_int { +pub fn ___syscall102(ctx: &mut Ctx, which: c_int, mut varargs: VarArgs) -> c_int { debug!("emscripten::___syscall102 (socketcall) {}", which); let call: u32 = varargs.get(ctx); let mut socket_varargs: VarArgs = varargs.get(ctx); @@ -464,7 +464,7 @@ pub fn ___syscall102(which: c_int, mut varargs: VarArgs, ctx: &mut Ctx) -> c_int } // pread -pub fn ___syscall180(which: c_int, mut varargs: VarArgs, ctx: &mut Ctx) -> c_int { +pub fn ___syscall180(ctx: &mut Ctx, which: c_int, mut varargs: VarArgs) -> c_int { debug!("emscripten::___syscall180 (pread) {}", which); let fd: i32 = varargs.get(ctx); let buf: u32 = varargs.get(ctx); @@ -481,7 +481,7 @@ pub fn ___syscall180(which: c_int, mut varargs: VarArgs, ctx: &mut Ctx) -> c_int } // pwrite -pub fn ___syscall181(which: c_int, mut varargs: VarArgs, ctx: &mut Ctx) -> c_int { +pub fn ___syscall181(ctx: &mut Ctx, which: c_int, mut varargs: VarArgs) -> c_int { debug!("emscripten::___syscall181 (pwrite) {}", which); let fd: i32 = varargs.get(ctx); let buf: u32 = varargs.get(ctx); @@ -503,7 +503,7 @@ pub fn ___syscall181(which: c_int, mut varargs: VarArgs, ctx: &mut Ctx) -> c_int /// wait4 #[allow(clippy::cast_ptr_alignment)] -pub fn ___syscall114(_which: c_int, mut varargs: VarArgs, ctx: &mut Ctx) -> pid_t { +pub fn ___syscall114(ctx: &mut Ctx, _which: c_int, mut varargs: VarArgs) -> pid_t { debug!("emscripten::___syscall114 (wait4)"); let pid: pid_t = varargs.get(ctx); let status: u32 = varargs.get(ctx); @@ -521,7 +521,7 @@ pub fn ___syscall114(_which: c_int, mut varargs: VarArgs, ctx: &mut Ctx) -> pid_ // select #[allow(clippy::cast_ptr_alignment)] -pub fn ___syscall142(which: c_int, mut varargs: VarArgs, ctx: &mut Ctx) -> c_int { +pub fn ___syscall142(ctx: &mut Ctx, which: c_int, mut varargs: VarArgs) -> c_int { debug!("emscripten::___syscall142 (newselect) {}", which); let nfds: i32 = varargs.get(ctx); @@ -540,7 +540,7 @@ pub fn ___syscall142(which: c_int, mut varargs: VarArgs, ctx: &mut Ctx) -> c_int } // setpgid -pub fn ___syscall57(which: c_int, mut varargs: VarArgs, ctx: &mut Ctx) -> c_int { +pub fn ___syscall57(ctx: &mut Ctx, which: c_int, mut varargs: VarArgs) -> c_int { debug!("emscripten::___syscall57 (setpgid) {}", which); let pid: i32 = varargs.get(ctx); let pgid: i32 = varargs.get(ctx); @@ -549,7 +549,7 @@ pub fn ___syscall57(which: c_int, mut varargs: VarArgs, ctx: &mut Ctx) -> c_int /// uname // NOTE: Wondering if we should return custom utsname, like Emscripten. -pub fn ___syscall122(which: c_int, mut varargs: VarArgs, ctx: &mut Ctx) -> c_int { +pub fn ___syscall122(ctx: &mut Ctx, which: c_int, mut varargs: VarArgs) -> c_int { debug!("emscripten::___syscall122 (uname) {}", which); let buf: u32 = varargs.get(ctx); debug!("=> buf: {}", buf); diff --git a/lib/emscripten/src/syscalls/windows.rs b/lib/emscripten/src/syscalls/windows.rs index 2b577fcac..41c4cf7eb 100644 --- a/lib/emscripten/src/syscalls/windows.rs +++ b/lib/emscripten/src/syscalls/windows.rs @@ -6,13 +6,13 @@ use wasmer_runtime_core::vm::Ctx; type pid_t = c_int; // chown -pub fn ___syscall212(which: c_int, mut varargs: VarArgs, ctx: &mut Ctx) -> c_int { +pub fn ___syscall212(ctx: &mut Ctx, which: c_int, mut varargs: VarArgs) -> c_int { debug!("emscripten::___syscall212 (chown) {}", which); -1 } // mkdir -pub fn ___syscall39(which: c_int, mut varargs: VarArgs, ctx: &mut Ctx) -> c_int { +pub fn ___syscall39(ctx: &mut Ctx, which: c_int, mut varargs: VarArgs) -> c_int { debug!("emscripten::___syscall39 (mkdir) {}", which); let pathname: u32 = varargs.get(ctx); let mode: u32 = varargs.get(ctx); @@ -21,72 +21,72 @@ pub fn ___syscall39(which: c_int, mut varargs: VarArgs, ctx: &mut Ctx) -> c_int } // getgid -pub fn ___syscall201(_one: i32, _two: i32, _ctx: &mut Ctx) -> i32 { +pub fn ___syscall201(_ctx: &mut Ctx, _one: i32, _two: i32) -> i32 { debug!("emscripten::___syscall201 (getgid)"); -1 } // getgid32 -pub fn ___syscall202(_one: i32, _two: i32, _ctx: &mut Ctx) -> i32 { +pub fn ___syscall202(_ctx: &mut Ctx, _one: i32, _two: i32) -> i32 { // gid_t debug!("emscripten::___syscall202 (getgid32)"); -1 } /// dup3 -pub fn ___syscall330(_which: c_int, mut varargs: VarArgs, ctx: &mut Ctx) -> pid_t { +pub fn ___syscall330(ctx: &mut Ctx, _which: c_int, mut varargs: VarArgs) -> pid_t { debug!("emscripten::___syscall330 (dup3)"); -1 } /// ioctl -pub fn ___syscall54(which: c_int, mut varargs: VarArgs, ctx: &mut Ctx) -> c_int { +pub fn ___syscall54(ctx: &mut Ctx, which: c_int, mut varargs: VarArgs) -> c_int { debug!("emscripten::___syscall54 (ioctl) {}", which); -1 } // socketcall #[allow(clippy::cast_ptr_alignment)] -pub fn ___syscall102(which: c_int, mut varargs: VarArgs, ctx: &mut Ctx) -> c_int { +pub fn ___syscall102(ctx: &mut Ctx, which: c_int, mut varargs: VarArgs) -> c_int { debug!("emscripten::___syscall102 (socketcall) {}", which); -1 } // pread -pub fn ___syscall180(which: c_int, mut varargs: VarArgs, ctx: &mut Ctx) -> c_int { +pub fn ___syscall180(ctx: &mut Ctx, which: c_int, mut varargs: VarArgs) -> c_int { debug!("emscripten::___syscall180 (pread) {}", which); -1 } // pwrite -pub fn ___syscall181(which: c_int, mut varargs: VarArgs, ctx: &mut Ctx) -> c_int { +pub fn ___syscall181(ctx: &mut Ctx, which: c_int, mut varargs: VarArgs) -> c_int { debug!("emscripten::___syscall181 (pwrite) {}", which); -1 } /// wait4 #[allow(clippy::cast_ptr_alignment)] -pub fn ___syscall114(_which: c_int, mut varargs: VarArgs, ctx: &mut Ctx) -> pid_t { +pub fn ___syscall114(ctx: &mut Ctx, _which: c_int, mut varargs: VarArgs) -> pid_t { debug!("emscripten::___syscall114 (wait4)"); -1 } // select #[allow(clippy::cast_ptr_alignment)] -pub fn ___syscall142(which: c_int, mut varargs: VarArgs, ctx: &mut Ctx) -> c_int { +pub fn ___syscall142(ctx: &mut Ctx, which: c_int, mut varargs: VarArgs) -> c_int { debug!("emscripten::___syscall142 (newselect) {}", which); -1 } // setpgid -pub fn ___syscall57(which: c_int, mut varargs: VarArgs, ctx: &mut Ctx) -> c_int { +pub fn ___syscall57(ctx: &mut Ctx, which: c_int, mut varargs: VarArgs) -> c_int { debug!("emscripten::___syscall57 (setpgid) {}", which); -1 } /// uname // NOTE: Wondering if we should return custom utsname, like Emscripten. -pub fn ___syscall122(which: c_int, mut varargs: VarArgs, ctx: &mut Ctx) -> c_int { +pub fn ___syscall122(ctx: &mut Ctx, which: c_int, mut varargs: VarArgs) -> c_int { debug!("emscripten::___syscall122 (uname) {}", which); -1 } diff --git a/lib/emscripten/src/time.rs b/lib/emscripten/src/time.rs index 2ecdfe6a8..8386a36ae 100644 --- a/lib/emscripten/src/time.rs +++ b/lib/emscripten/src/time.rs @@ -38,7 +38,7 @@ const CLOCK_MONOTONIC_COARSE: clockid_t = 6; /// emscripten: _gettimeofday #[allow(clippy::cast_ptr_alignment)] -pub fn _gettimeofday(tp: c_int, tz: c_int, ctx: &mut Ctx) -> c_int { +pub fn _gettimeofday(ctx: &mut Ctx, tp: c_int, tz: c_int) -> c_int { debug!("emscripten::_gettimeofday {} {}", tp, tz); #[repr(C)] struct GuestTimeVal { @@ -63,7 +63,7 @@ pub fn _gettimeofday(tp: c_int, tz: c_int, ctx: &mut Ctx) -> c_int { /// emscripten: _clock_gettime #[allow(clippy::cast_ptr_alignment)] -pub fn _clock_gettime(clk_id: clockid_t, tp: c_int, ctx: &mut Ctx) -> c_int { +pub fn _clock_gettime(ctx: &mut Ctx, clk_id: clockid_t, tp: c_int) -> c_int { debug!("emscripten::_clock_gettime {} {}", clk_id, tp); // debug!("Memory {:?}", ctx.memory(0)[..]); #[repr(C)] @@ -94,9 +94,9 @@ pub fn _clock_gettime(clk_id: clockid_t, tp: c_int, ctx: &mut Ctx) -> c_int { } /// emscripten: ___clock_gettime -pub fn ___clock_gettime(clk_id: clockid_t, tp: c_int, ctx: &mut Ctx) -> c_int { +pub fn ___clock_gettime(ctx: &mut Ctx, clk_id: clockid_t, tp: c_int) -> c_int { debug!("emscripten::___clock_gettime {} {}", clk_id, tp); - _clock_gettime(clk_id, tp, ctx) + _clock_gettime(ctx, clk_id, tp) } /// emscripten: _clock @@ -106,22 +106,22 @@ pub fn _clock(_ctx: &mut Ctx) -> c_int { } /// emscripten: _difftime -pub fn _difftime(t0: u32, t1: u32, _ctx: &mut Ctx) -> f64 { +pub fn _difftime(_ctx: &mut Ctx, t0: u32, t1: u32) -> f64 { debug!("emscripten::_difftime"); (t0 - t1) as _ } -pub fn _gmtime_r(_one: i32, _two: i32, _ctx: &mut Ctx) -> i32 { +pub fn _gmtime_r(_ctx: &mut Ctx, _one: i32, _two: i32) -> i32 { debug!("emscripten::_gmtime_r"); -1 } -pub fn _mktime(_one: i32, _ctx: &mut Ctx) -> i32 { +pub fn _mktime(_ctx: &mut Ctx, _one: i32) -> i32 { debug!("emscripten::_mktime"); -1 } -pub fn _gmtime(_one: i32, _ctx: &mut Ctx) -> i32 { +pub fn _gmtime(_ctx: &mut Ctx, _one: i32) -> i32 { debug!("emscripten::_gmtime"); -1 } @@ -148,7 +148,7 @@ pub fn _tvset(_ctx: &mut Ctx) { /// formats time as a C string #[allow(clippy::cast_ptr_alignment)] -unsafe fn fmt_time(time: u32, ctx: &mut Ctx) -> *const c_char { +unsafe fn fmt_time(ctx: &mut Ctx, time: u32) -> *const c_char { let date = &*(emscripten_memory_pointer!(ctx.memory(0), time) as *mut guest_tm); let days = vec!["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"]; @@ -173,11 +173,11 @@ unsafe fn fmt_time(time: u32, ctx: &mut Ctx) -> *const c_char { } /// emscripten: _asctime -pub fn _asctime(time: u32, ctx: &mut Ctx) -> u32 { +pub fn _asctime(ctx: &mut Ctx, time: u32) -> u32 { debug!("emscripten::_asctime {}", time); unsafe { - let time_str_ptr = fmt_time(time, ctx); + let time_str_ptr = fmt_time(ctx, time); copy_cstr_into_wasm(ctx, time_str_ptr) // let c_str = emscripten_memory_pointer!(ctx.memory(0), res) as *mut i8; @@ -187,7 +187,7 @@ pub fn _asctime(time: u32, ctx: &mut Ctx) -> u32 { } /// emscripten: _asctime_r -pub fn _asctime_r(time: u32, buf: u32, ctx: &mut Ctx) -> u32 { +pub fn _asctime_r(ctx: &mut Ctx, time: u32, buf: u32) -> u32 { debug!("emscripten::_asctime_r {}, {}", time, buf); unsafe { @@ -195,8 +195,8 @@ pub fn _asctime_r(time: u32, buf: u32, ctx: &mut Ctx) -> u32 { // to write out more than 26 bytes (including the null terminator). // See http://pubs.opengroup.org/onlinepubs/9699919799/functions/asctime.html // Our undefined behavior is to truncate the write to at most 26 bytes, including null terminator. - let time_str_ptr = fmt_time(time, ctx); - write_to_buf(time_str_ptr, buf, 26, ctx) + let time_str_ptr = fmt_time(ctx, time); + write_to_buf(ctx, time_str_ptr, buf, 26) // let c_str = emscripten_memory_pointer!(ctx.memory(0), res) as *mut i8; // use std::ffi::CStr; @@ -206,7 +206,7 @@ pub fn _asctime_r(time: u32, buf: u32, ctx: &mut Ctx) -> u32 { /// emscripten: _localtime #[allow(clippy::cast_ptr_alignment)] -pub fn _localtime(time_p: u32, ctx: &mut Ctx) -> c_int { +pub fn _localtime(ctx: &mut Ctx, time_p: u32) -> c_int { debug!("emscripten::_localtime {}", time_p); // NOTE: emscripten seems to want tzset() called in this function // https://stackoverflow.com/questions/19170721/real-time-awareness-of-timezone-change-in-localtime-vs-localtime-r @@ -219,7 +219,7 @@ pub fn _localtime(time_p: u32, ctx: &mut Ctx) -> c_int { let result_tm = time::at(timespec); unsafe { - let tm_struct_offset = env::call_malloc(mem::size_of::() as _, ctx); + let tm_struct_offset = env::call_malloc(ctx, mem::size_of::() as _); let tm_struct_ptr = emscripten_memory_pointer!(ctx.memory(0), tm_struct_offset) as *mut guest_tm; // debug!( @@ -244,7 +244,7 @@ pub fn _localtime(time_p: u32, ctx: &mut Ctx) -> c_int { } /// emscripten: _localtime_r #[allow(clippy::cast_ptr_alignment)] -pub fn _localtime_r(time_p: u32, result: u32, ctx: &mut Ctx) -> c_int { +pub fn _localtime_r(ctx: &mut Ctx, time_p: u32, result: u32) -> c_int { debug!("emscripten::_localtime_r {}", time_p); // NOTE: emscripten seems to want tzset() called in this function @@ -281,7 +281,7 @@ pub fn _localtime_r(time_p: u32, result: u32, ctx: &mut Ctx) -> c_int { /// emscripten: _time #[allow(clippy::cast_ptr_alignment)] -pub fn _time(time_p: u32, ctx: &mut Ctx) -> i32 { +pub fn _time(ctx: &mut Ctx, time_p: u32) -> i32 { debug!("emscripten::_time {}", time_p); unsafe { @@ -292,11 +292,11 @@ pub fn _time(time_p: u32, ctx: &mut Ctx) -> i32 { /// emscripten: _strftime pub fn _strftime( + _ctx: &mut Ctx, s_ptr: c_int, maxsize: u32, format_ptr: c_int, tm_ptr: c_int, - _ctx: &mut Ctx, ) -> i32 { debug!( "emscripten::_strftime {} {} {} {}", diff --git a/lib/emscripten/src/utils.rs b/lib/emscripten/src/utils.rs index fe3381d76..92d51cf25 100644 --- a/lib/emscripten/src/utils.rs +++ b/lib/emscripten/src/utils.rs @@ -42,7 +42,7 @@ pub fn get_emscripten_memory_size(module: &Module) -> (Pages, Option) { (memory.minimum, memory.maximum) } -pub unsafe fn write_to_buf(string: *const c_char, buf: u32, max: u32, ctx: &mut Ctx) -> u32 { +pub unsafe fn write_to_buf(ctx: &mut Ctx, string: *const c_char, buf: u32, max: u32) -> u32 { let buf_addr = emscripten_memory_pointer!(ctx.memory(0), buf) as *mut c_char; for i in 0..max { @@ -56,7 +56,7 @@ pub unsafe fn write_to_buf(string: *const c_char, buf: u32, max: u32, ctx: &mut pub unsafe fn copy_cstr_into_wasm(ctx: &mut Ctx, cstr: *const c_char) -> u32 { let s = CStr::from_ptr(cstr).to_str().unwrap(); let cstr_len = s.len(); - let space_offset = env::call_malloc((cstr_len as u32) + 1, ctx); + let space_offset = env::call_malloc(ctx, (cstr_len as u32) + 1); let raw_memory = emscripten_memory_pointer!(ctx.memory(0), space_offset) as *mut c_char; let slice = slice::from_raw_parts_mut(raw_memory, cstr_len); @@ -71,7 +71,7 @@ pub unsafe fn copy_cstr_into_wasm(ctx: &mut Ctx, cstr: *const c_char) -> u32 { space_offset } -pub unsafe fn allocate_on_stack<'a, T: Copy>(count: u32, ctx: &'a mut Ctx) -> (u32, &'a mut [T]) { +pub unsafe fn allocate_on_stack<'a, T: Copy>(ctx: &'a mut Ctx, count: u32) -> (u32, &'a mut [T]) { let offset = get_emscripten_data(ctx) .stack_alloc .call(count * (size_of::() as u32)) @@ -82,8 +82,8 @@ pub unsafe fn allocate_on_stack<'a, T: Copy>(count: u32, ctx: &'a mut Ctx) -> (u (offset, slice) } -pub unsafe fn allocate_cstr_on_stack<'a>(s: &str, ctx: &'a mut Ctx) -> (u32, &'a [u8]) { - let (offset, slice) = allocate_on_stack((s.len() + 1) as u32, ctx); +pub unsafe fn allocate_cstr_on_stack<'a>(ctx: &'a mut Ctx, s: &str) -> (u32, &'a [u8]) { + let (offset, slice) = allocate_on_stack(ctx, (s.len() + 1) as u32); use std::iter; for (byte, loc) in s.bytes().chain(iter::once(0)).zip(slice.iter_mut()) { From 227d5e24cfe2a8da63e456fc72bcfbd93eab24ed Mon Sep 17 00:00:00 2001 From: Syrus Date: Sat, 9 Feb 2019 14:18:53 -0800 Subject: [PATCH 06/14] Moved ctx to first argument in Cranelift backend --- lib/clif-backend/src/func_env.rs | 10 +++++----- lib/clif-backend/src/module_env.rs | 10 +++++----- lib/clif-backend/src/resolver.rs | 13 +++++++------ lib/clif-backend/src/trampoline.rs | 2 +- 4 files changed, 18 insertions(+), 17 deletions(-) diff --git a/lib/clif-backend/src/func_env.rs b/lib/clif-backend/src/func_env.rs index 789195264..cada963d1 100644 --- a/lib/clif-backend/src/func_env.rs +++ b/lib/clif-backend/src/func_env.rs @@ -460,7 +460,7 @@ impl<'env, 'module, 'isa> FuncEnvironment for FuncEnv<'env, 'module, 'isa> { // and the vmctx parameter. let mut args = Vec::with_capacity(call_args.len() + 1); args.extend(call_args.iter().cloned()); - args.push(vmctx_ptr); + args.insert(0, vmctx_ptr); Ok(pos.ins().call_indirect(sig_ref, func_ptr, &args)) } @@ -486,7 +486,7 @@ impl<'env, 'module, 'isa> FuncEnvironment for FuncEnv<'env, 'module, 'isa> { let mut args = Vec::with_capacity(call_args.len() + 1); args.extend(call_args.iter().cloned()); - args.push(vmctx); + args.insert(0, vmctx); Ok(pos.ins().call(callee, &args)) } @@ -533,7 +533,7 @@ impl<'env, 'module, 'isa> FuncEnvironment for FuncEnv<'env, 'module, 'isa> { let mut args = Vec::with_capacity(call_args.len() + 1); args.extend(call_args.iter().cloned()); - args.push(imported_vmctx_addr); + args.insert(0, imported_vmctx_addr); Ok(pos .ins() @@ -604,7 +604,7 @@ impl<'env, 'module, 'isa> FuncEnvironment for FuncEnv<'env, 'module, 'isa> { let call_inst = pos .ins() - .call(mem_grow_func, &[const_mem_index, by_value, vmctx]); + .call(mem_grow_func, &[vmctx, const_mem_index, by_value]); Ok(*pos.func.dfg.inst_results(call_inst).first().unwrap()) } @@ -664,7 +664,7 @@ impl<'env, 'module, 'isa> FuncEnvironment for FuncEnv<'env, 'module, 'isa> { .special_param(ir::ArgumentPurpose::VMContext) .expect("missing vmctx parameter"); - let call_inst = pos.ins().call(mem_grow_func, &[const_mem_index, vmctx]); + let call_inst = pos.ins().call(mem_grow_func, &[vmctx, const_mem_index]); Ok(*pos.func.dfg.inst_results(call_inst).first().unwrap()) } diff --git a/lib/clif-backend/src/module_env.rs b/lib/clif-backend/src/module_env.rs index 8a26b2731..6b22b4ce6 100644 --- a/lib/clif-backend/src/module_env.rs +++ b/lib/clif-backend/src/module_env.rs @@ -536,14 +536,14 @@ impl<'module, 'isa, 'data> ModuleEnvironment<'data> for ModuleEnv<'module, 'isa> let func_index = pos.ins().iconst(ir::types::I32, func_index.index() as i64); - pos.ins().call(start_debug, &[func_index, vmctx]); + pos.ins().call(start_debug, &[vmctx, func_index]); for param in new_ebb_params.iter().cloned() { match pos.func.dfg.value_type(param) { - ir::types::I32 => pos.ins().call(i32_print, &[param, vmctx]), - ir::types::I64 => pos.ins().call(i64_print, &[param, vmctx]), - ir::types::F32 => pos.ins().call(f32_print, &[param, vmctx]), - ir::types::F64 => pos.ins().call(f64_print, &[param, vmctx]), + ir::types::I32 => pos.ins().call(i32_print, &[vmctx, param]), + ir::types::I64 => pos.ins().call(i64_print, &[vmctx, param]), + ir::types::F32 => pos.ins().call(f32_print, &[vmctx, param]), + ir::types::F64 => pos.ins().call(f64_print, &[vmctx, param]), _ => unimplemented!(), }; } diff --git a/lib/clif-backend/src/resolver.rs b/lib/clif-backend/src/resolver.rs index 1e62c0c20..ddc7cd3b9 100644 --- a/lib/clif-backend/src/resolver.rs +++ b/lib/clif-backend/src/resolver.rs @@ -34,6 +34,7 @@ use wasmer_runtime_core::{ types::{FuncSig, LocalFuncIndex, SigIndex}, vm, vmcalls, }; +use wasmer_runtime_core::vm::Ctx; extern "C" { #[cfg(not(target_os = "windows"))] @@ -350,21 +351,21 @@ fn round_up(n: usize, multiple: usize) -> usize { (n + multiple - 1) & !(multiple - 1) } -extern "C" fn i32_print(n: i32) { +extern "C" fn i32_print(_ctx: &mut Ctx, n: i32) { print!(" i32: {},", n); } -extern "C" fn i64_print(n: i64) { +extern "C" fn i64_print(_ctx: &mut Ctx, n: i64) { print!(" i64: {},", n); } -extern "C" fn f32_print(n: f32) { +extern "C" fn f32_print(_ctx: &mut Ctx, n: f32) { print!(" f32: {},", n); } -extern "C" fn f64_print(n: f64) { +extern "C" fn f64_print(_ctx: &mut Ctx, n: f64) { print!(" f64: {},", n); } -extern "C" fn start_debug(func_index: u32) { +extern "C" fn start_debug(_ctx: &mut Ctx, func_index: u32) { print!("func ({}), args: [", func_index); } -extern "C" fn end_debug() { +extern "C" fn end_debug(_ctx: &mut Ctx) { println!(" ]"); } diff --git a/lib/clif-backend/src/trampoline.rs b/lib/clif-backend/src/trampoline.rs index 0751cea14..a30dfd114 100644 --- a/lib/clif-backend/src/trampoline.rs +++ b/lib/clif-backend/src/trampoline.rs @@ -169,6 +169,7 @@ fn generate_func(func_sig: &FuncSig) -> ir::Function { let mut pos = FuncCursor::new(&mut func).at_first_insertion_point(entry_ebb); let mut args_vec = Vec::with_capacity(func_sig.params().len() + 1); + args_vec.push(vmctx_ptr); for (index, wasm_ty) in func_sig.params().iter().enumerate() { let mem_flags = ir::MemFlags::trusted(); @@ -180,7 +181,6 @@ fn generate_func(func_sig: &FuncSig) -> ir::Function { ); args_vec.push(val); } - args_vec.push(vmctx_ptr); let call_inst = pos.ins().call_indirect(export_sig_ref, func_ptr, &args_vec); From 4311a37defbdd65d2357e1afe2528b33d6ae2548 Mon Sep 17 00:00:00 2001 From: Syrus Date: Sat, 9 Feb 2019 14:19:04 -0800 Subject: [PATCH 07/14] Fixed simple spectests example compilation --- lib/clif-backend/src/func_env.rs | 8 ++++---- lib/clif-backend/src/resolver.rs | 13 ++++++------- lib/runtime-core/src/vmcalls.rs | 20 ++++++++++---------- lib/spectests/examples/simple/main.rs | 2 +- 4 files changed, 21 insertions(+), 22 deletions(-) diff --git a/lib/clif-backend/src/func_env.rs b/lib/clif-backend/src/func_env.rs index cada963d1..723ab71d9 100644 --- a/lib/clif-backend/src/func_env.rs +++ b/lib/clif-backend/src/func_env.rs @@ -32,7 +32,7 @@ impl<'env, 'module, 'isa> FuncEnv<'env, 'module, 'isa> { let mut signature = self.env.signatures[Converter(clif_sig_index).into()].clone(); // Add the vmctx parameter type to it - signature.params.push(ir::AbiParam::special( + signature.params.insert(0, ir::AbiParam::special( self.pointer_type(), ir::ArgumentPurpose::VMContext, )); @@ -559,9 +559,9 @@ impl<'env, 'module, 'isa> FuncEnvironment for FuncEnv<'env, 'module, 'isa> { let signature = pos.func.import_signature(ir::Signature { call_conv: self.target_config().default_call_conv, params: vec![ - ir::AbiParam::new(ir::types::I32), - ir::AbiParam::new(ir::types::I32), ir::AbiParam::special(self.pointer_type(), ir::ArgumentPurpose::VMContext), + ir::AbiParam::new(ir::types::I32), + ir::AbiParam::new(ir::types::I32), ], returns: vec![ir::AbiParam::new(ir::types::I32)], }); @@ -623,8 +623,8 @@ impl<'env, 'module, 'isa> FuncEnvironment for FuncEnv<'env, 'module, 'isa> { let signature = pos.func.import_signature(ir::Signature { call_conv: self.target_config().default_call_conv, params: vec![ - ir::AbiParam::new(ir::types::I32), ir::AbiParam::special(self.pointer_type(), ir::ArgumentPurpose::VMContext), + ir::AbiParam::new(ir::types::I32), ], returns: vec![ir::AbiParam::new(ir::types::I32)], }); diff --git a/lib/clif-backend/src/resolver.rs b/lib/clif-backend/src/resolver.rs index ddc7cd3b9..91e6102ef 100644 --- a/lib/clif-backend/src/resolver.rs +++ b/lib/clif-backend/src/resolver.rs @@ -34,7 +34,6 @@ use wasmer_runtime_core::{ types::{FuncSig, LocalFuncIndex, SigIndex}, vm, vmcalls, }; -use wasmer_runtime_core::vm::Ctx; extern "C" { #[cfg(not(target_os = "windows"))] @@ -351,21 +350,21 @@ fn round_up(n: usize, multiple: usize) -> usize { (n + multiple - 1) & !(multiple - 1) } -extern "C" fn i32_print(_ctx: &mut Ctx, n: i32) { +extern "C" fn i32_print(_ctx: &mut vm::Ctx, n: i32) { print!(" i32: {},", n); } -extern "C" fn i64_print(_ctx: &mut Ctx, n: i64) { +extern "C" fn i64_print(_ctx: &mut vm::Ctx, n: i64) { print!(" i64: {},", n); } -extern "C" fn f32_print(_ctx: &mut Ctx, n: f32) { +extern "C" fn f32_print(_ctx: &mut vm::Ctx, n: f32) { print!(" f32: {},", n); } -extern "C" fn f64_print(_ctx: &mut Ctx, n: f64) { +extern "C" fn f64_print(_ctx: &mut vm::Ctx, n: f64) { print!(" f64: {},", n); } -extern "C" fn start_debug(_ctx: &mut Ctx, func_index: u32) { +extern "C" fn start_debug(_ctx: &mut vm::Ctx, func_index: u32) { print!("func ({}), args: [", func_index); } -extern "C" fn end_debug(_ctx: &mut Ctx) { +extern "C" fn end_debug(_ctx: &mut vm::Ctx) { println!(" ]"); } diff --git a/lib/runtime-core/src/vmcalls.rs b/lib/runtime-core/src/vmcalls.rs index 8a6e683b5..576ca34ce 100644 --- a/lib/runtime-core/src/vmcalls.rs +++ b/lib/runtime-core/src/vmcalls.rs @@ -13,9 +13,9 @@ use crate::{ // +****************************+ pub unsafe extern "C" fn local_static_memory_grow( + ctx: &mut vm::Ctx, memory_index: LocalMemoryIndex, delta: Pages, - ctx: &mut vm::Ctx, ) -> i32 { let local_memory = *ctx.memories.add(memory_index.index()); let memory = (*local_memory).memory as *mut StaticMemory; @@ -28,8 +28,8 @@ pub unsafe extern "C" fn local_static_memory_grow( } pub unsafe extern "C" fn local_static_memory_size( - memory_index: LocalMemoryIndex, ctx: &vm::Ctx, + memory_index: LocalMemoryIndex, ) -> Pages { let local_memory = *ctx.memories.add(memory_index.index()); let memory = (*local_memory).memory as *mut StaticMemory; @@ -38,9 +38,9 @@ pub unsafe extern "C" fn local_static_memory_size( } pub unsafe extern "C" fn local_dynamic_memory_grow( + ctx: &mut vm::Ctx, memory_index: LocalMemoryIndex, delta: Pages, - ctx: &mut vm::Ctx, ) -> i32 { let local_memory = *ctx.memories.add(memory_index.index()); let memory = (*local_memory).memory as *mut DynamicMemory; @@ -53,8 +53,8 @@ pub unsafe extern "C" fn local_dynamic_memory_grow( } pub unsafe extern "C" fn local_dynamic_memory_size( - memory_index: LocalMemoryIndex, ctx: &vm::Ctx, + memory_index: LocalMemoryIndex, ) -> Pages { let local_memory = *ctx.memories.add(memory_index.index()); let memory = (*local_memory).memory as *mut DynamicMemory; @@ -67,9 +67,9 @@ pub unsafe extern "C" fn local_dynamic_memory_size( // +****************************+ pub unsafe extern "C" fn imported_static_memory_grow( + ctx: &mut vm::Ctx, import_memory_index: ImportedMemoryIndex, delta: Pages, - ctx: &mut vm::Ctx, ) -> i32 { let local_memory = *ctx.imported_memories.add(import_memory_index.index()); let memory = (*local_memory).memory as *mut StaticMemory; @@ -82,8 +82,8 @@ pub unsafe extern "C" fn imported_static_memory_grow( } pub unsafe extern "C" fn imported_static_memory_size( - import_memory_index: ImportedMemoryIndex, ctx: &vm::Ctx, + import_memory_index: ImportedMemoryIndex, ) -> Pages { let local_memory = *ctx.imported_memories.add(import_memory_index.index()); let memory = (*local_memory).memory as *mut StaticMemory; @@ -92,9 +92,9 @@ pub unsafe extern "C" fn imported_static_memory_size( } pub unsafe extern "C" fn imported_dynamic_memory_grow( + ctx: &mut vm::Ctx, memory_index: ImportedMemoryIndex, delta: Pages, - ctx: &mut vm::Ctx, ) -> i32 { let local_memory = *ctx.imported_memories.add(memory_index.index()); let memory = (*local_memory).memory as *mut DynamicMemory; @@ -107,8 +107,8 @@ pub unsafe extern "C" fn imported_dynamic_memory_grow( } pub unsafe extern "C" fn imported_dynamic_memory_size( - memory_index: ImportedMemoryIndex, ctx: &vm::Ctx, + memory_index: ImportedMemoryIndex, ) -> Pages { let local_memory = *ctx.imported_memories.add(memory_index.index()); let memory = (*local_memory).memory as *mut DynamicMemory; @@ -121,9 +121,9 @@ pub unsafe extern "C" fn imported_dynamic_memory_size( // +****************************+ pub unsafe extern "C" fn local_table_grow( + ctx: &mut vm::Ctx, table_index: LocalTableIndex, delta: u32, - ctx: &mut vm::Ctx, ) -> i32 { let _ = table_index; let _ = delta; @@ -131,7 +131,7 @@ pub unsafe extern "C" fn local_table_grow( unimplemented!() } -pub unsafe extern "C" fn local_table_size(table_index: LocalTableIndex, ctx: &vm::Ctx) -> u32 { +pub unsafe extern "C" fn local_table_size(ctx: &vm::Ctx, table_index: LocalTableIndex) -> u32 { let _ = table_index; let _ = ctx; unimplemented!() diff --git a/lib/spectests/examples/simple/main.rs b/lib/spectests/examples/simple/main.rs index fb215ee21..e418c9abe 100644 --- a/lib/spectests/examples/simple/main.rs +++ b/lib/spectests/examples/simple/main.rs @@ -61,7 +61,7 @@ fn main() -> error::Result<()> { Ok(()) } -fn print_num(n: i32, ctx: &mut vm::Ctx) -> Result { +fn print_num(ctx: &mut vm::Ctx, n: i32) -> Result { println!("print_num({})", n); let memory: &Memory = ctx.memory(0); From c40195cf77cdd2fef1147b81c443bf9dcdc96325 Mon Sep 17 00:00:00 2001 From: Syrus Date: Tue, 12 Feb 2019 10:04:11 -0800 Subject: [PATCH 08/14] Fixed spectests --- lib/clif-backend/src/func_env.rs | 8 ++++---- lib/clif-backend/src/trampoline.rs | 31 +++++++++++++++--------------- 2 files changed, 19 insertions(+), 20 deletions(-) diff --git a/lib/clif-backend/src/func_env.rs b/lib/clif-backend/src/func_env.rs index 723ab71d9..7f1f8b52f 100644 --- a/lib/clif-backend/src/func_env.rs +++ b/lib/clif-backend/src/func_env.rs @@ -32,10 +32,10 @@ impl<'env, 'module, 'isa> FuncEnv<'env, 'module, 'isa> { let mut signature = self.env.signatures[Converter(clif_sig_index).into()].clone(); // Add the vmctx parameter type to it - signature.params.insert(0, ir::AbiParam::special( - self.pointer_type(), - ir::ArgumentPurpose::VMContext, - )); + signature.params.insert( + 0, + ir::AbiParam::special(self.pointer_type(), ir::ArgumentPurpose::VMContext), + ); // Return signature signature diff --git a/lib/clif-backend/src/trampoline.rs b/lib/clif-backend/src/trampoline.rs index a30dfd114..b9d942ba1 100644 --- a/lib/clif-backend/src/trampoline.rs +++ b/lib/clif-backend/src/trampoline.rs @@ -229,22 +229,21 @@ fn generate_trampoline_signature() -> ir::Signature { fn generate_export_signature(func_sig: &FuncSig) -> ir::Signature { let mut export_clif_sig = ir::Signature::new(isa::CallConv::SystemV); - export_clif_sig.params = func_sig - .params() - .iter() - .map(|wasm_ty| ir::AbiParam { - value_type: wasm_ty_to_clif(*wasm_ty), - purpose: ir::ArgumentPurpose::Normal, - extension: ir::ArgumentExtension::None, - location: ir::ArgumentLoc::Unassigned, - }) - .chain(iter::once(ir::AbiParam { - value_type: ir::types::I64, - purpose: ir::ArgumentPurpose::VMContext, - extension: ir::ArgumentExtension::None, - location: ir::ArgumentLoc::Unassigned, - })) - .collect(); + let func_sig_iter = func_sig.params().iter().map(|wasm_ty| ir::AbiParam { + value_type: wasm_ty_to_clif(*wasm_ty), + purpose: ir::ArgumentPurpose::Normal, + extension: ir::ArgumentExtension::None, + location: ir::ArgumentLoc::Unassigned, + }); + + export_clif_sig.params = iter::once(ir::AbiParam { + value_type: ir::types::I64, + purpose: ir::ArgumentPurpose::VMContext, + extension: ir::ArgumentExtension::None, + location: ir::ArgumentLoc::Unassigned, + }) + .chain(func_sig_iter) + .collect(); export_clif_sig.returns = func_sig .returns() From 44d1a0d1f963b1cb13f4e4dbfc9bf844959846f5 Mon Sep 17 00:00:00 2001 From: Syrus Date: Tue, 12 Feb 2019 10:49:43 -0800 Subject: [PATCH 09/14] Fixed debug function context position --- lib/clif-backend/src/module_env.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/lib/clif-backend/src/module_env.rs b/lib/clif-backend/src/module_env.rs index 6b22b4ce6..65bd5f839 100644 --- a/lib/clif-backend/src/module_env.rs +++ b/lib/clif-backend/src/module_env.rs @@ -419,8 +419,8 @@ impl<'module, 'isa, 'data> ModuleEnvironment<'data> for ModuleEnv<'module, 'isa> let signature = pos.func.import_signature(ir::Signature { call_conv: self.target_config().default_call_conv, params: vec![ - ir::AbiParam::new(ir::types::I32), ir::AbiParam::special(ir::types::I64, ir::ArgumentPurpose::VMContext), + ir::AbiParam::new(ir::types::I32), ], returns: vec![], }); @@ -457,8 +457,8 @@ impl<'module, 'isa, 'data> ModuleEnvironment<'data> for ModuleEnv<'module, 'isa> let signature = pos.func.import_signature(ir::Signature { call_conv: self.target_config().default_call_conv, params: vec![ - ir::AbiParam::new(ir::types::I32), ir::AbiParam::special(ir::types::I64, ir::ArgumentPurpose::VMContext), + ir::AbiParam::new(ir::types::I32), ], returns: vec![], }); @@ -476,8 +476,8 @@ impl<'module, 'isa, 'data> ModuleEnvironment<'data> for ModuleEnv<'module, 'isa> let signature = pos.func.import_signature(ir::Signature { call_conv: self.target_config().default_call_conv, params: vec![ - ir::AbiParam::new(ir::types::I64), ir::AbiParam::special(ir::types::I64, ir::ArgumentPurpose::VMContext), + ir::AbiParam::new(ir::types::I64), ], returns: vec![], }); @@ -495,8 +495,8 @@ impl<'module, 'isa, 'data> ModuleEnvironment<'data> for ModuleEnv<'module, 'isa> let signature = pos.func.import_signature(ir::Signature { call_conv: self.target_config().default_call_conv, params: vec![ - ir::AbiParam::new(ir::types::F32), ir::AbiParam::special(ir::types::I64, ir::ArgumentPurpose::VMContext), + ir::AbiParam::new(ir::types::F32), ], returns: vec![], }); @@ -514,8 +514,8 @@ impl<'module, 'isa, 'data> ModuleEnvironment<'data> for ModuleEnv<'module, 'isa> let signature = pos.func.import_signature(ir::Signature { call_conv: self.target_config().default_call_conv, params: vec![ - ir::AbiParam::new(ir::types::F64), ir::AbiParam::special(ir::types::I64, ir::ArgumentPurpose::VMContext), + ir::AbiParam::new(ir::types::F64), ], returns: vec![], }); From b7c3cc09d122f533415db830ce2c8ca62696e06c Mon Sep 17 00:00:00 2001 From: Syrus Date: Tue, 12 Feb 2019 11:14:20 -0800 Subject: [PATCH 10/14] Fixed typed func implementation --- lib/runtime-core/src/typed_func.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/runtime-core/src/typed_func.rs b/lib/runtime-core/src/typed_func.rs index 9989764c6..e16307d8e 100644 --- a/lib/runtime-core/src/typed_func.rs +++ b/lib/runtime-core/src/typed_func.rs @@ -138,9 +138,9 @@ impl WasmTypeList for (A,) { } #[allow(non_snake_case)] unsafe fn call(self, f: *const (), ctx: *mut Ctx) -> Rets { - let f: extern "C" fn(A, *mut Ctx) -> Rets = mem::transmute(f); + let f: extern "C" fn(*mut Ctx, A) -> Rets = mem::transmute(f); let (a,) = self; - f(a, ctx) + f(ctx, a) } } @@ -175,10 +175,10 @@ macro_rules! impl_traits { } #[allow(non_snake_case)] unsafe fn call(self, f: *const (), ctx: *mut Ctx) -> Rets { - let f: extern fn( $( $x, )* *mut Ctx) -> Rets::CStruct = mem::transmute(f); + let f: extern fn(*mut Ctx $( ,$x )*) -> Rets::CStruct = mem::transmute(f); #[allow(unused_parens)] let ( $( $x ),* ) = self; - let c_struct = f( $( $x, )* ctx); + let c_struct = f(ctx $( ,$x )*); Rets::from_c_struct(c_struct) } } From b6416068a8dc84039d6c8d96426d892daeffb296 Mon Sep 17 00:00:00 2001 From: Syrus Date: Tue, 12 Feb 2019 11:17:09 -0800 Subject: [PATCH 11/14] Use vec.push instead of .insert for vmctx arg --- lib/clif-backend/src/func_env.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/clif-backend/src/func_env.rs b/lib/clif-backend/src/func_env.rs index 7f1f8b52f..8670e0000 100644 --- a/lib/clif-backend/src/func_env.rs +++ b/lib/clif-backend/src/func_env.rs @@ -459,8 +459,8 @@ impl<'env, 'module, 'isa> FuncEnvironment for FuncEnv<'env, 'module, 'isa> { // Build a value list for the indirect call instruction containing the call_args // and the vmctx parameter. let mut args = Vec::with_capacity(call_args.len() + 1); + args.push(vmctx_ptr); args.extend(call_args.iter().cloned()); - args.insert(0, vmctx_ptr); Ok(pos.ins().call_indirect(sig_ref, func_ptr, &args)) } @@ -485,8 +485,8 @@ impl<'env, 'module, 'isa> FuncEnvironment for FuncEnv<'env, 'module, 'isa> { .expect("missing vmctx parameter"); let mut args = Vec::with_capacity(call_args.len() + 1); + args.push(vmctx); args.extend(call_args.iter().cloned()); - args.insert(0, vmctx); Ok(pos.ins().call(callee, &args)) } @@ -532,8 +532,8 @@ impl<'env, 'module, 'isa> FuncEnvironment for FuncEnv<'env, 'module, 'isa> { let sig_ref = pos.func.dfg.ext_funcs[callee].signature; let mut args = Vec::with_capacity(call_args.len() + 1); + args.push(imported_vmctx_addr); args.extend(call_args.iter().cloned()); - args.insert(0, imported_vmctx_addr); Ok(pos .ins() From 6a1fdb7f91ac25fec86663e283da646dcda5c554 Mon Sep 17 00:00:00 2001 From: Mackenzie Clark Date: Thu, 14 Feb 2019 09:58:33 -0800 Subject: [PATCH 12/14] add windows exception handling in C (#175) --- .appveyor.yml | 3 +- Cargo.lock | 290 +++++++++++++++++- Cargo.toml | 2 +- README.md | 10 +- lib/clif-backend/Cargo.toml | 6 +- lib/clif-backend/src/resolver.rs | 4 +- lib/clif-backend/src/signal/mod.rs | 12 + lib/clif-backend/src/signal/windows.rs | 114 ++++++- lib/clif-backend/src/trampoline.rs | 17 +- lib/runtime-core/src/sys/windows/memory.rs | 3 +- lib/runtime-core/src/vm.rs | 1 + lib/spectests/examples/simple/main.rs | 3 - lib/win-exception-handler/Cargo.toml | 18 ++ lib/win-exception-handler/build.rs | 11 + .../exception_handling/.gitignore | 1 + .../exception_handling/CMakeLists.txt | 6 + .../exception_handling/exception_handling.c | 74 +++++ .../exception_handling/exception_handling.h | 25 ++ .../src/exception_handling.rs | 55 ++++ lib/win-exception-handler/src/lib.rs | 5 + src/bin/wasmer.rs | 2 +- 21 files changed, 630 insertions(+), 32 deletions(-) create mode 100644 lib/win-exception-handler/Cargo.toml create mode 100644 lib/win-exception-handler/build.rs create mode 100644 lib/win-exception-handler/exception_handling/.gitignore create mode 100644 lib/win-exception-handler/exception_handling/CMakeLists.txt create mode 100644 lib/win-exception-handler/exception_handling/exception_handling.c create mode 100644 lib/win-exception-handler/exception_handling/exception_handling.h create mode 100644 lib/win-exception-handler/src/exception_handling.rs create mode 100644 lib/win-exception-handler/src/lib.rs diff --git a/.appveyor.yml b/.appveyor.yml index 8bcc3b4c7..5da647f54 100644 --- a/.appveyor.yml +++ b/.appveyor.yml @@ -29,4 +29,5 @@ build_script: test_script: - set RUST_BACKTRACE=1 - - cargo test --verbose + - cd ./lib/spectests && cargo test -- --test-threads 1 && cd ../.. + diff --git a/Cargo.lock b/Cargo.lock index d061df27b..5f55a2ea5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,3 +1,13 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "aho-corasick" +version = "0.6.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "memchr 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "ansi_term" version = "0.11.0" @@ -21,6 +31,49 @@ name = "autocfg" version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "backtrace" +version = "0.3.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "autocfg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "backtrace-sys 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-demangle 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "backtrace-sys" +version = "0.1.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "cc 1.0.28 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "bindgen" +version = "0.46.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "cexpr 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", + "clang-sys 0.26.4 (registry+https://github.com/rust-lang/crates.io-index)", + "clap 2.32.0 (registry+https://github.com/rust-lang/crates.io-index)", + "env_logger 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", + "hashbrown 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "peeking_take_while 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 0.4.26 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 0.6.11 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "which 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "bitflags" version = "1.0.4" @@ -65,11 +118,29 @@ name = "cc" version = "1.0.28" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "cexpr" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "nom 4.2.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "cfg-if" version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "clang-sys" +version = "0.26.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)", + "libloading 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "clap" version = "2.32.0" @@ -178,6 +249,18 @@ dependencies = [ "generic-array 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "env_logger" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", + "humantime 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "termcolor 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "errno" version = "0.2.4" @@ -202,6 +285,7 @@ name = "failure" version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ + "backtrace 0.3.13 (registry+https://github.com/rust-lang/crates.io-index)", "failure_derive 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -276,6 +360,14 @@ dependencies = [ "unicode-segmentation 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "humantime" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "quick-error 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "indexmap" version = "1.0.2" @@ -310,6 +402,15 @@ name = "libc" version = "0.2.48" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "libloading" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "cc 1.0.28 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "lock_api" version = "0.1.5" @@ -327,6 +428,11 @@ dependencies = [ "cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "memchr" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "memmap" version = "0.7.0" @@ -360,6 +466,15 @@ dependencies = [ "void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "nom" +version = "4.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "memchr 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "opaque-debug" version = "0.2.2" @@ -404,6 +519,19 @@ dependencies = [ "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "peeking_take_while" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "proc-macro2" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "proc-macro2" version = "0.4.26" @@ -412,6 +540,19 @@ dependencies = [ "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "quick-error" +version = "1.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "quote" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "proc-macro2 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "quote" version = "0.6.11" @@ -547,6 +688,31 @@ dependencies = [ "redox_syscall 0.1.51 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "regex" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "aho-corasick 0.6.9 (registry+https://github.com/rust-lang/crates.io-index)", + "memchr 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "regex-syntax 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", + "thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", + "utf8-ranges 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "regex-syntax" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "ucd-util 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "rustc-demangle" +version = "0.1.13" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "rustc_version" version = "0.2.3" @@ -602,12 +768,12 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.85" +version = "1.0.58" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "proc-macro2 0.4.26 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 0.6.11 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 0.15.26 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 0.13.11 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -669,6 +835,16 @@ dependencies = [ "syn 0.15.26 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "syn" +version = "0.13.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "proc-macro2 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", + "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "syn" version = "0.15.26" @@ -700,6 +876,14 @@ dependencies = [ "serde_json 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "termcolor" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "wincolor 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "termion" version = "1.5.1" @@ -718,6 +902,14 @@ dependencies = [ "unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "thread_local" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "time" version = "0.1.42" @@ -733,6 +925,11 @@ name = "typenum" version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "ucd-util" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "unicode-segmentation" version = "1.2.1" @@ -756,11 +953,21 @@ dependencies = [ "void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "utf8-ranges" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "vec_map" version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "version_check" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "void" version = "1.0.2" @@ -772,7 +979,7 @@ version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "serde 1.0.85 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.85 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.58 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)", "wabt-sys 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -815,10 +1022,12 @@ dependencies = [ "serde 1.0.85 (registry+https://github.com/rust-lang/crates.io-index)", "serde-bench 0.0.7 (registry+https://github.com/rust-lang/crates.io-index)", "serde_bytes 0.10.4 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.85 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.58 (registry+https://github.com/rust-lang/crates.io-index)", "target-lexicon 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "wasmer-runtime-core 0.1.2", + "wasmer-win-exception-handler 0.0.1", "wasmparser 0.23.0 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -860,7 +1069,7 @@ dependencies = [ "serde 1.0.85 (registry+https://github.com/rust-lang/crates.io-index)", "serde-bench 0.0.7 (registry+https://github.com/rust-lang/crates.io-index)", "serde_bytes 0.10.4 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.85 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.58 (registry+https://github.com/rust-lang/crates.io-index)", "sha2 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", "wasmer-clif-backend 0.1.2", "wasmparser 0.23.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -876,6 +1085,18 @@ dependencies = [ "wasmer-runtime-core 0.1.2", ] +[[package]] +name = "wasmer-win-exception-handler" +version = "0.0.1" +dependencies = [ + "bindgen 0.46.0 (registry+https://github.com/rust-lang/crates.io-index)", + "cmake 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "wasmer-runtime-core 0.1.2", + "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "wasmparser" version = "0.22.1" @@ -886,6 +1107,15 @@ name = "wasmparser" version = "0.23.0" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "which" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "winapi" version = "0.2.8" @@ -910,15 +1140,36 @@ name = "winapi-i686-pc-windows-gnu" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "winapi-util" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "winapi-x86_64-pc-windows-gnu" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "wincolor" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi-util 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + [metadata] +"checksum aho-corasick 0.6.9 (registry+https://github.com/rust-lang/crates.io-index)" = "1e9a933f4e58658d7b12defcf96dc5c720f20832deebe3e0a19efd3b6aaeeb9e" "checksum ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b" "checksum atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "9a7d5b8723950951411ee34d271d99dddcc2035a16ab25310ea2c8cfd4369652" "checksum autocfg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a6d640bee2da49f60a4068a7fae53acde8982514ab7bae8b8cea9e88cbcfd799" +"checksum backtrace 0.3.13 (registry+https://github.com/rust-lang/crates.io-index)" = "b5b493b66e03090ebc4343eb02f94ff944e0cbc9ac6571491d170ba026741eb5" +"checksum backtrace-sys 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)" = "797c830ac25ccc92a7f8a7b9862bde440715531514594a6154e3d4a54dd769b6" +"checksum bindgen 0.46.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8f7f7f0701772b17de73e4f5cbcb1dd6926f4706cba4c1ab62c5367f8bdc94e1" "checksum bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "228047a76f468627ca71776ecdebd732a3423081fcf5125585bcd7c49886ce12" "checksum block-buffer 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "509de513cca6d92b6aacf9c61acfe7eaa160837323a81068d690cc1f8e5740da" "checksum block-padding 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "d75255892aeb580d3c566f213a2b6fdc1c66667839f45719ee1d30ebf2aea591" @@ -926,7 +1177,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a019b10a2a7cdeb292db131fc8113e57ea2a908f6e7894b0c3c671893b65dbeb" "checksum cast 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "926013f2860c46252efceabb19f4a6b308197505082c609025aa6706c011d427" "checksum cc 1.0.28 (registry+https://github.com/rust-lang/crates.io-index)" = "bb4a8b715cb4597106ea87c7c84b2f1d452c7492033765df7f32651e66fcf749" +"checksum cexpr 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "644d693ecfa91955ed32dcc7eda4914e1be97a641fb6f0645a37348e20b230da" "checksum cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "082bb9b28e00d3c9d39cc03e64ce4cea0f1bb9b3fde493f0cbc008472d22bdf4" +"checksum clang-sys 0.26.4 (registry+https://github.com/rust-lang/crates.io-index)" = "6ef0c1bcf2e99c649104bd7a7012d8f8802684400e03db0ec0af48583c6fa0e4" "checksum clap 2.32.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b957d88f4b6a63b9d70d5f454ac8011819c6efa7727858f458ab71c756ce2d3e" "checksum cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f" "checksum cmake 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)" = "6ec65ee4f9c9d16f335091d23693457ed4928657ba4982289d7fafee03bc614a" @@ -938,6 +1191,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum cranelift-native 0.26.0 (registry+https://github.com/rust-lang/crates.io-index)" = "474bee81d620a473bf43411a3d6f10ffbf7965141dc5e5b76d8d2151dde3285d" "checksum cranelift-wasm 0.26.0 (registry+https://github.com/rust-lang/crates.io-index)" = "49723365dab9a48b354bdc24cb6d9d5719bc1d3b858ffd2ea179d0d7d885804a" "checksum digest 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "05f47366984d3ad862010e22c7ce81a7dbcaebbdfb37241a620f8b6596ee135c" +"checksum env_logger 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "afb070faf94c85d17d50ca44f6ad076bce18ae92f0037d350947240a36e9d42e" "checksum errno 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "c2a071601ed01b988f896ab14b95e67335d1eeb50190932a1320f7fe3cadc84e" "checksum errno-dragonfly 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "14ca354e36190500e1e1fb267c647932382b54053c50b14970856c0b00a35067" "checksum failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "795bd83d3abeb9220f257e597aa0080a508b27533824adf336529648f6abf7e2" @@ -951,23 +1205,31 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "8be18de09a56b60ed0edf84bc9df007e30040691af7acd1c41874faac5895bfb" "checksum hashbrown 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "3bae29b6653b3412c2e71e9d486db9f9df5d701941d86683005efb9f2d28e3da" "checksum heck 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "20564e78d53d2bb135c343b3f47714a56af2061f1c928fdb541dc7b9fdd94205" +"checksum humantime 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3ca7e5f2e110db35f93b837c81797f3714500b81d517bf20c431b16d3ca4f114" "checksum indexmap 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7e81a7c05f79578dbc15793d8b619db9ba32b4577003ef3af1a91c416798c58d" "checksum itoa 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "1306f3464951f30e30d12373d31c79fbd52d236e5e896fd92f96ec7babbbe60b" "checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d" "checksum lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a374c89b9db55895453a74c1e38861d9deec0b01b405a82516e9d5de4820dea1" "checksum libc 0.2.48 (git+https://github.com/rust-lang/libc)" = "" "checksum libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)" = "e962c7641008ac010fa60a7dfdc1712449f29c44ef2d4702394aea943ee75047" +"checksum libloading 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9c3ad660d7cb8c5822cd83d10897b0f1f1526792737a179e73896152f85b88c2" "checksum lock_api 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "62ebf1391f6acad60e5c8b43706dde4582df75c06698ab44511d15016bc2442c" "checksum log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c84ec4b527950aa83a329754b01dbe3f58361d1c5efacd1f6d68c494d08a17c6" +"checksum memchr 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2efc7bc57c883d4a4d6e3246905283d8dae951bb3bd32f49d6ef297f546e1c39" "checksum memmap 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6585fd95e7bb50d6cc31e20d4cf9afb4e2ba16c5846fc76793f11218da9c475b" "checksum nix 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = "921f61dc817b379d0834e45d5ec45beaacfae97082090a49c2cf30dcbc30206f" "checksum nix 0.13.0 (registry+https://github.com/rust-lang/crates.io-index)" = "46f0f3210768d796e8fa79ec70ee6af172dacbe7147f5e69be5240a47778302b" +"checksum nom 4.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b30adc557058ce00c9d0d7cb3c6e0b5bc6f36e2e2eabe74b0ba726d194abd588" "checksum opaque-debug 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "93f5bb2e8e8dec81642920ccff6b61f1eb94fa3020c5a325c9851ff604152409" "checksum owning_ref 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "49a4b8ea2179e6a2e27411d3bca09ca6dd630821cf6894c6c7c8467a8ee7ef13" "checksum page_size 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f89ef58b3d32420dbd1a43d2f38ae92f6239ef12bb556ab09ca55445f5a67242" "checksum parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ab41b4aed082705d1056416ae4468b6ea99d52599ecf3169b00088d43113e337" "checksum parking_lot_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "94c8c7923936b28d546dfd14d4472eaf34c99b14e1c973a32b3e6d4eb04298c9" +"checksum peeking_take_while 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099" +"checksum proc-macro2 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "1b06e2f335f48d24442b35a19df506a835fb3547bc3c06ef27340da9acf5cae7" "checksum proc-macro2 0.4.26 (registry+https://github.com/rust-lang/crates.io-index)" = "38fddd23d98b2144d197c0eca5705632d4fe2667d14a6be5df8934f8d74f1978" +"checksum quick-error 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9274b940887ce9addde99c4eee6b5c44cc494b182b97e73dc8ffdcb3397fd3f0" +"checksum quote 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9949cfe66888ffe1d53e6ec9d9f3b70714083854be20fd5e271b232a017401e8" "checksum quote 0.6.11 (registry+https://github.com/rust-lang/crates.io-index)" = "cdd8e04bd9c52e0342b406469d494fcb033be4bdbe5c606016defbb1681411e1" "checksum rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)" = "6d71dacdc3c88c1fde3885a3be3fbab9f35724e6ce99467f7d9c5026132184ca" "checksum rand_chacha 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "556d3a1ca6600bfcbab7c7c91ccb085ac7fbbcd70e008a98742e7847f4f7bcef" @@ -983,6 +1245,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum rdrand 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2" "checksum redox_syscall 0.1.51 (registry+https://github.com/rust-lang/crates.io-index)" = "423e376fffca3dfa06c9e9790a9ccd282fafb3cc6e6397d01dbf64f9bacc6b85" "checksum redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7e891cfe48e9100a70a3b6eb652fef28920c117d366339687bd5576160db0f76" +"checksum regex 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "37e7cbbd370869ce2e8dff25c7018702d10b21a20ef7135316f8daecd6c25b7f" +"checksum regex-syntax 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)" = "8c2f35eedad5295fdf00a63d7d4b238135723f92b434ec06774dad15c7ab0861" +"checksum rustc-demangle 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)" = "adacaae16d02b6ec37fdc7acfcddf365978de76d1983d3ee22afc260e1ca9619" "checksum rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" "checksum ryu 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)" = "eb9e9b8cde282a9fe6a42dd4681319bfb63f121b8a8ee9439c6f4107e58a46f7" "checksum scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "94258f53601af11e6a49f722422f6e3425c52b06245a5cf9bc09908b174f5e27" @@ -991,7 +1256,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum serde 1.0.85 (registry+https://github.com/rust-lang/crates.io-index)" = "534b8b91a95e0f71bca3ed5824752d558da048d4248c91af873b63bd60519752" "checksum serde-bench 0.0.7 (registry+https://github.com/rust-lang/crates.io-index)" = "d733da87e79faaac25616e33d26299a41143fd4cd42746cbb0e91d8feea243fd" "checksum serde_bytes 0.10.4 (registry+https://github.com/rust-lang/crates.io-index)" = "adb6e51a6b3696b301bc221d785f898b4457c619b51d7ce195a6d20baecb37b3" -"checksum serde_derive 1.0.85 (registry+https://github.com/rust-lang/crates.io-index)" = "a915306b0f1ac5607797697148c223bedeaa36bcc2e28a01441cd638cc6567b4" +"checksum serde_derive 1.0.58 (registry+https://github.com/rust-lang/crates.io-index)" = "ac38f51a52a556cd17545798e29536885fb1a3fa63d6399f5ef650f4a7d35901" "checksum serde_json 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)" = "4b90a9fbe1211e57d3e1c15670f1cb00802988fb23a1a4aad7a2b63544f1920e" "checksum sha2 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7b4d8bfd0e469f417657573d8451fb33d16cfe0989359b93baf3a1ffc639543d" "checksum smallvec 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)" = "88aea073965ab29f6edb5493faf96ad662fb18aa9eeb186a3b7057951605ed15" @@ -999,25 +1264,34 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum strsim 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bb4f380125926a99e52bc279241539c018323fab05ad6368b56f93d9369ff550" "checksum structopt 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)" = "670ad348dc73012fcf78c71f06f9d942232cdd4c859d4b6975e27836c3efc0c3" "checksum structopt-derive 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)" = "ef98172b1a00b0bec738508d3726540edcbd186d50dfd326f2b1febbb3559f04" +"checksum syn 0.13.11 (registry+https://github.com/rust-lang/crates.io-index)" = "14f9bf6292f3a61d2c716723fdb789a41bbe104168e6f496dc6497e531ea1b9b" "checksum syn 0.15.26 (registry+https://github.com/rust-lang/crates.io-index)" = "f92e629aa1d9c827b2bb8297046c1ccffc57c99b947a680d3ccff1f136a3bee9" "checksum synstructure 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "73687139bf99285483c96ac0add482c3776528beac1d97d444f6e91f203a2015" "checksum target-lexicon 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4af5e2227f0b887d591d3724b796a96eff04226104d872f5b3883fcd427d64b9" +"checksum termcolor 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "4096add70612622289f2fdcdbd5086dc81c1e2675e6ae58d6c4f62a16c6d7f2f" "checksum termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "689a3bdfaab439fd92bc87df5c4c78417d3cbe537487274e9b0b2dce76e92096" "checksum textwrap 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "307686869c93e71f94da64286f9a9524c0f308a9e1c87a583de8e9c9039ad3f6" +"checksum thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c6b53e329000edc2b34dbe8545fd20e55a333362d0a321909685a19bd28c3f1b" "checksum time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)" = "db8dcfca086c1143c9270ac42a2bbd8a7ee477b78ac8e45b19abfb0cbede4b6f" "checksum typenum 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "612d636f949607bdf9b123b4a6f6d966dedf3ff669f7f045890d3a4a73948169" +"checksum ucd-util 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "535c204ee4d8434478593480b8f86ab45ec9aae0e83c568ca81abf0fd0e88f86" "checksum unicode-segmentation 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "aa6024fc12ddfd1c6dbc14a80fa2324d4568849869b779f6bd37e5e4c03344d1" "checksum unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "882386231c45df4700b275c7ff55b6f3698780a650026380e72dabe76fa46526" "checksum unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc" "checksum unreachable 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "382810877fe448991dfc7f0dd6e3ae5d58088fd0ea5e35189655f84e6814fa56" +"checksum utf8-ranges 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "796f7e48bef87609f7ade7e06495a87d5cd06c7866e6a5cbfceffc558a243737" "checksum vec_map 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "05c78687fb1a80548ae3250346c3db86a80a7cdd77bda190189f2d0a0987c81a" +"checksum version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "914b1a6776c4c929a602fafd8bc742e06365d4bcbe48c30f9cca5824f70dc9dd" "checksum void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" "checksum wabt 0.7.4 (registry+https://github.com/rust-lang/crates.io-index)" = "74e463a508e390cc7447e70f640fbf44ad52e1bd095314ace1fdf99516d32add" "checksum wabt-sys 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)" = "a6265b25719e82598d104b3717375e37661d41753e2c84cde3f51050c7ed7e3c" "checksum wasmparser 0.22.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f46e666ecb4a406483a59a49f9d0c17f327e70da53a128eccddae2eadb95865c" "checksum wasmparser 0.23.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b5e01c420bc7d36e778bd242e1167b079562ba8b34087122cc9057187026d060" +"checksum which 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b57acb10231b9493c8472b20cb57317d0679a49e0bdbee44b3b803a6473af164" "checksum winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a" "checksum winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "92c1eb33641e276cfa214a0522acad57be5c56b10cb348b3c5117db75f3ac4b0" "checksum winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc" "checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" +"checksum winapi-util 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7168bab6e1daee33b4557efd0e95d5ca70a03706d39fa5f3fe7a236f584b03c9" "checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" +"checksum wincolor 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "561ed901ae465d6185fa7864d63fbd5720d0ef718366c9a4dc83cf6170d7e9ba" diff --git a/Cargo.toml b/Cargo.toml index b570c9b09..9d96e28cd 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -27,7 +27,7 @@ wasmer-runtime-core = { path = "lib/runtime-core" } wasmer-emscripten = { path = "lib/emscripten" } [workspace] -members = ["lib/clif-backend", "lib/runtime", "lib/runtime-core", "lib/emscripten", "lib/spectests"] +members = ["lib/clif-backend", "lib/runtime", "lib/runtime-core", "lib/emscripten", "lib/spectests", "lib/win-exception-handler"] [build-dependencies] wabt = "0.7.2" diff --git a/README.md b/README.md index 2aae6e086..df4ac0186 100644 --- a/README.md +++ b/README.md @@ -47,10 +47,10 @@ Wasmer is structured into different directories: Building wasmer requires [rustup](https://rustup.rs/). -To install on Windows, download and run [`rustup-init.exe`](https://win.rustup.rs/) +To build on Windows, download and run [`rustup-init.exe`](https://win.rustup.rs/) then follow the onscreen instructions. -To install on other systems, run: +To build on other systems, run: ```sh curl https://sh.rustup.rs -sSf | sh @@ -86,8 +86,8 @@ sudo apt install cmake #### Windows (MSVC) -Right now Windows support is _highly experimental_. -We are working on this so Wasmer can soon be released for Windows. +Windows support is _highly experimental_. Only simple wasm programs may be run, and no syscalls are allowed. This means +nginx and lua do not work on Windows. See [this issue for ongoing Emscripten syscall polyfills for Windows](https://github.com/wasmerio/wasmer/pull/176). 1. Install Python for Windows (https://www.python.org/downloads/release/python-2714/). The Windows x86-64 MSI installer is fine. You should change the installation to install the "Add python.exe to Path" feature. @@ -95,6 +95,8 @@ We are working on this so Wasmer can soon be released for Windows. 2. Install Git for Windows (https://git-scm.com/download/win). DO allow it to add git.exe to the PATH (default settings for the installer are fine). +3. Install CMake (https://cmake.org/download/). Ensure CMake is in the PATH. + ## Building Wasmer is built with [Cargo](https://crates.io/), the Rust package manager. diff --git a/lib/clif-backend/Cargo.toml b/lib/clif-backend/Cargo.toml index 5b565676b..becb71a04 100644 --- a/lib/clif-backend/Cargo.toml +++ b/lib/clif-backend/Cargo.toml @@ -37,6 +37,10 @@ optional = true version = "0.0.7" optional = true +[target.'cfg(windows)'.dependencies] +winapi = { version = "0.3", features = ["errhandlingapi", "minwindef", "minwinbase", "winnt"] } +wasmer-win-exception-handler = { path = "../win-exception-handler", version = "0.0.1" } + [features] cache = ["serde", "serde_derive", "serde_bytes", "serde-bench", "wasmer-runtime-core/cache"] -debug = ["wasmer-runtime-core/debug"] \ No newline at end of file +debug = ["wasmer-runtime-core/debug"] diff --git a/lib/clif-backend/src/resolver.rs b/lib/clif-backend/src/resolver.rs index 91e6102ef..48ea5c7e5 100644 --- a/lib/clif-backend/src/resolver.rs +++ b/lib/clif-backend/src/resolver.rs @@ -223,9 +223,9 @@ impl FuncResolverBuilder { LibCall::TruncF64 => libcalls::truncf64 as isize, LibCall::NearestF64 => libcalls::nearbyintf64 as isize, #[cfg(all(target_pointer_width = "64", target_os = "windows"))] - Probestack => __chkstk as isize, + LibCall::Probestack => __chkstk as isize, #[cfg(not(target_os = "windows"))] - Probestack => __rust_probestack as isize, + LibCall::Probestack => __rust_probestack as isize, }, RelocationType::Intrinsic(ref name) => match name.as_str() { "i32print" => i32_print as isize, diff --git a/lib/clif-backend/src/signal/mod.rs b/lib/clif-backend/src/signal/mod.rs index eab9e62e7..31dbb44dd 100644 --- a/lib/clif-backend/src/signal/mod.rs +++ b/lib/clif-backend/src/signal/mod.rs @@ -110,6 +110,7 @@ impl ProtectedCaller for Caller { .lookup(sig_index) .expect("that trampoline doesn't exist"); + #[cfg(not(target_os = "windows"))] call_protected(&self.handler_data, || unsafe { // Leap of faith. trampoline( @@ -120,6 +121,17 @@ impl ProtectedCaller for Caller { ); })?; + // the trampoline is called from C on windows + #[cfg(target_os = "windows")] + call_protected( + &self.handler_data, + trampoline, + vmctx_ptr, + func_ptr, + param_vec.as_ptr(), + return_vec.as_mut_ptr(), + )?; + Ok(return_vec .iter() .zip(signature.returns().iter()) diff --git a/lib/clif-backend/src/signal/windows.rs b/lib/clif-backend/src/signal/windows.rs index b715c616d..191085d91 100644 --- a/lib/clif-backend/src/signal/windows.rs +++ b/lib/clif-backend/src/signal/windows.rs @@ -1,10 +1,116 @@ +use crate::relocation::{TrapCode, TrapData}; use crate::signal::HandlerData; -use wasmer_runtime_core::error::RuntimeResult; +use crate::trampoline::Trampoline; +use std::cell::Cell; +use std::ffi::c_void; +use std::ptr; +use wasmer_runtime_core::vm::Ctx; +use wasmer_runtime_core::vm::Func; +use wasmer_runtime_core::{ + error::{RuntimeError, RuntimeResult}, + structures::TypedIndex, + types::{MemoryIndex, TableIndex}, +}; +use wasmer_win_exception_handler::CallProtectedData; +pub use wasmer_win_exception_handler::_call_protected; +use winapi::shared::minwindef::DWORD; +use winapi::um::minwinbase::{ + EXCEPTION_ACCESS_VIOLATION, EXCEPTION_FLT_DENORMAL_OPERAND, EXCEPTION_FLT_DIVIDE_BY_ZERO, + EXCEPTION_FLT_INEXACT_RESULT, EXCEPTION_FLT_INVALID_OPERATION, EXCEPTION_FLT_OVERFLOW, + EXCEPTION_FLT_STACK_CHECK, EXCEPTION_FLT_UNDERFLOW, EXCEPTION_ILLEGAL_INSTRUCTION, + EXCEPTION_INT_DIVIDE_BY_ZERO, EXCEPTION_INT_OVERFLOW, EXCEPTION_STACK_OVERFLOW, +}; -pub fn call_protected(handler_data: &HandlerData, f: impl FnOnce() -> T) -> RuntimeResult { - unimplemented!("TODO"); +thread_local! { + pub static CURRENT_EXECUTABLE_BUFFER: Cell<*const c_void> = Cell::new(ptr::null()); +} + +pub fn call_protected( + handler_data: &HandlerData, + trampoline: Trampoline, + ctx: *mut Ctx, + func: *const Func, + param_vec: *const u64, + return_vec: *mut u64, +) -> RuntimeResult<()> { + // TODO: trap early + // user code error + // if let Some(msg) = super::TRAP_EARLY_DATA.with(|cell| cell.replace(None)) { + // return Err(RuntimeError::User { msg }); + // } + + let result = _call_protected(trampoline, ctx, func, param_vec, return_vec); + + if let Ok(_) = result { + return Ok(()); + } + + let CallProtectedData { + code: signum, + exceptionAddress: exception_address, + instructionPointer: instruction_pointer, + } = result.unwrap_err(); + + if let Some(TrapData { + trapcode, + srcloc: _, + }) = handler_data.lookup(instruction_pointer as _) + { + Err(match signum as DWORD { + EXCEPTION_ACCESS_VIOLATION => RuntimeError::OutOfBoundsAccess { + memory: MemoryIndex::new(0), + addr: None, + }, + EXCEPTION_ILLEGAL_INSTRUCTION => match trapcode { + TrapCode::BadSignature => RuntimeError::IndirectCallSignature { + table: TableIndex::new(0), + }, + TrapCode::IndirectCallToNull => RuntimeError::IndirectCallToNull { + table: TableIndex::new(0), + }, + TrapCode::HeapOutOfBounds => RuntimeError::OutOfBoundsAccess { + memory: MemoryIndex::new(0), + addr: None, + }, + TrapCode::TableOutOfBounds => RuntimeError::TableOutOfBounds { + table: TableIndex::new(0), + }, + _ => RuntimeError::Unknown { + msg: "unknown trap".to_string(), + }, + }, + EXCEPTION_STACK_OVERFLOW => RuntimeError::Unknown { + msg: "unknown trap".to_string(), + }, + EXCEPTION_INT_DIVIDE_BY_ZERO => RuntimeError::IllegalArithmeticOperation, + EXCEPTION_INT_OVERFLOW => RuntimeError::IllegalArithmeticOperation, + _ => RuntimeError::Unknown { + msg: "unknown trap".to_string(), + }, + } + .into()) + } else { + let signal = match signum as DWORD { + EXCEPTION_FLT_DENORMAL_OPERAND + | EXCEPTION_FLT_DIVIDE_BY_ZERO + | EXCEPTION_FLT_INEXACT_RESULT + | EXCEPTION_FLT_INVALID_OPERATION + | EXCEPTION_FLT_OVERFLOW + | EXCEPTION_FLT_STACK_CHECK + | EXCEPTION_FLT_UNDERFLOW => "floating-point exception", + EXCEPTION_ILLEGAL_INSTRUCTION => "illegal instruction", + EXCEPTION_ACCESS_VIOLATION => "segmentation violation", + _ => "unkown trapped signal", + }; + + Err(RuntimeError::Unknown { + msg: format!("trap at {} - {}", exception_address, signal), + } + .into()) + } } pub unsafe fn trigger_trap() -> ! { - unimplemented!("TODO"); + // TODO + unimplemented!(); } diff --git a/lib/clif-backend/src/trampoline.rs b/lib/clif-backend/src/trampoline.rs index b9d942ba1..76fb521d6 100644 --- a/lib/clif-backend/src/trampoline.rs +++ b/lib/clif-backend/src/trampoline.rs @@ -7,6 +7,7 @@ use cranelift_codegen::{ isa, Context, }; use hashbrown::HashMap; +use std::ffi::c_void; use std::{iter, mem}; use wasmer_runtime_core::{ backend::sys::{Memory, Protect}, @@ -23,6 +24,9 @@ impl RelocSink for NullRelocSink { fn reloc_jt(&mut self, _: u32, _: Reloc, _: ir::JumpTable) {} } +pub type Trampoline = + unsafe extern "C" fn(*mut vm::Ctx, *const vm::Func, *const u64, *mut u64) -> c_void; + pub struct Trampolines { memory: Memory, offsets: HashMap, @@ -138,10 +142,7 @@ impl Trampolines { } } - pub fn lookup( - &self, - sig_index: SigIndex, - ) -> Option { + pub fn lookup(&self, sig_index: SigIndex) -> Option { let offset = *self.offsets.get(&sig_index)?; let ptr = unsafe { self.memory.as_ptr().add(offset) }; @@ -212,7 +213,9 @@ fn wasm_ty_to_clif(ty: Type) -> ir::types::Type { } fn generate_trampoline_signature() -> ir::Signature { - let mut sig = ir::Signature::new(isa::CallConv::SystemV); + let isa = super::get_isa(); + let call_convention = isa.default_call_conv(); + let mut sig = ir::Signature::new(call_convention); let ptr_param = ir::AbiParam { value_type: ir::types::I64, @@ -227,7 +230,9 @@ fn generate_trampoline_signature() -> ir::Signature { } fn generate_export_signature(func_sig: &FuncSig) -> ir::Signature { - let mut export_clif_sig = ir::Signature::new(isa::CallConv::SystemV); + let isa = super::get_isa(); + let call_convention = isa.default_call_conv(); + let mut export_clif_sig = ir::Signature::new(call_convention); let func_sig_iter = func_sig.params().iter().map(|wasm_ty| ir::AbiParam { value_type: wasm_ty_to_clif(*wasm_ty), diff --git a/lib/runtime-core/src/sys/windows/memory.rs b/lib/runtime-core/src/sys/windows/memory.rs index baf4d27a5..c8fd197eb 100644 --- a/lib/runtime-core/src/sys/windows/memory.rs +++ b/lib/runtime-core/src/sys/windows/memory.rs @@ -150,7 +150,8 @@ impl Drop for Memory { fn drop(&mut self) { if !self.ptr.is_null() { let success = unsafe { VirtualFree(self.ptr as _, self.size, MEM_DECOMMIT) }; - assert_eq!(success, 0, "failed to unmap memory: {}", errno::errno()); + // If the function succeeds, the return value is nonzero. + assert_eq!(success, 1, "failed to unmap memory: {}", errno::errno()); } } } diff --git a/lib/runtime-core/src/vm.rs b/lib/runtime-core/src/vm.rs index 8cb9f0986..faee819be 100644 --- a/lib/runtime-core/src/vm.rs +++ b/lib/runtime-core/src/vm.rs @@ -169,6 +169,7 @@ enum InnerFunc {} /// Used to provide type safety (ish) for passing around function pointers. /// The typesystem ensures this cannot be dereferenced since an /// empty enum cannot actually exist. +#[repr(C)] pub struct Func(InnerFunc); /// An imported function, which contains the vmctx that owns this function. diff --git a/lib/spectests/examples/simple/main.rs b/lib/spectests/examples/simple/main.rs index e418c9abe..029cec1ac 100644 --- a/lib/spectests/examples/simple/main.rs +++ b/lib/spectests/examples/simple/main.rs @@ -1,8 +1,6 @@ -use std::fs::remove_file; use wabt::wat2wasm; use wasmer_clif_backend::CraneliftCompiler; use wasmer_runtime_core::{ - cache::Cache, error, global::Global, memory::Memory, @@ -15,7 +13,6 @@ use wasmer_runtime_core::{ static EXAMPLE_WASM: &'static [u8] = include_bytes!("simple.wasm"); fn main() -> error::Result<()> { - let compiler = CraneliftCompiler::new(); let wasm_binary = wat2wasm(IMPORT_MODULE.as_bytes()).expect("WAST not valid or malformed"); let inner_module = wasmer_runtime_core::compile_with(&wasm_binary, &CraneliftCompiler::new())?; diff --git a/lib/win-exception-handler/Cargo.toml b/lib/win-exception-handler/Cargo.toml new file mode 100644 index 000000000..043dc3c59 --- /dev/null +++ b/lib/win-exception-handler/Cargo.toml @@ -0,0 +1,18 @@ +[package] +name = "wasmer-win-exception-handler" +version = "0.0.1" +description = "Wasmer runtime exception handling for Windows" +license = "MIT" +authors = ["The Wasmer Engineering Team "] +repository = "https://github.com/wasmerio/wasmer" +edition = "2018" + +[target.'cfg(windows)'.dependencies] +wasmer-runtime-core = { path = "../runtime-core", version = "0.1.2" } +winapi = { version = "0.3", features = ["winbase", "errhandlingapi", "minwindef", "minwinbase", "winnt"] } +libc = "0.2.48" + +[build-dependencies] +cmake = "0.1.35" +bindgen = "0.46.0" +regex = "1.0.6" diff --git a/lib/win-exception-handler/build.rs b/lib/win-exception-handler/build.rs new file mode 100644 index 000000000..7376c6329 --- /dev/null +++ b/lib/win-exception-handler/build.rs @@ -0,0 +1,11 @@ +use cmake::Config; + +fn main() { + #[cfg(target_os = "windows")] + { + let project_name = "exception_handling"; + let dst = Config::new(project_name).build(); + println!("cargo:rustc-link-search=native={}", dst.display()); + println!("cargo:rustc-link-lib=static={}", project_name); + } +} diff --git a/lib/win-exception-handler/exception_handling/.gitignore b/lib/win-exception-handler/exception_handling/.gitignore new file mode 100644 index 000000000..8eee68fef --- /dev/null +++ b/lib/win-exception-handler/exception_handling/.gitignore @@ -0,0 +1 @@ +cmake-build-* diff --git a/lib/win-exception-handler/exception_handling/CMakeLists.txt b/lib/win-exception-handler/exception_handling/CMakeLists.txt new file mode 100644 index 000000000..47376c78f --- /dev/null +++ b/lib/win-exception-handler/exception_handling/CMakeLists.txt @@ -0,0 +1,6 @@ +cmake_minimum_required(VERSION 3.0) +project(exception_handling C) + +add_library(exception_handling STATIC exception_handling.c) + +install(TARGETS exception_handling DESTINATION .) diff --git a/lib/win-exception-handler/exception_handling/exception_handling.c b/lib/win-exception-handler/exception_handling/exception_handling.c new file mode 100644 index 000000000..3284034cc --- /dev/null +++ b/lib/win-exception-handler/exception_handling/exception_handling.c @@ -0,0 +1,74 @@ +#include +#include +#include "exception_handling.h" + +#define CALL_FIRST 1 + +__declspec(thread) jmp_buf jmpBuf; +__declspec(thread) PVOID caughtExceptionAddress; +__declspec(thread) DWORD64 caughtInstructionPointer; +__declspec(thread) PVOID savedStackPointer; +__declspec(thread) BOOL exceptionHandlerInstalled = FALSE; +__declspec(thread) BOOL alreadyHandlingException = FALSE; + +void longjmpOutOfHere() { + longjmp(jmpBuf, 1); +} + +/// Get the current address that we use to jmp, the no inline is important +static __declspec(noinline) void *get_callee_frame_address(void) { + return _AddressOfReturnAddress(); +} + +static LONG WINAPI +exceptionHandler(struct _EXCEPTION_POINTERS *ExceptionInfo) { + EXCEPTION_RECORD* pExceptionRecord = ExceptionInfo->ExceptionRecord; + PCONTEXT pCONTEXT = ExceptionInfo->ContextRecord; + caughtExceptionAddress = pExceptionRecord->ExceptionAddress; + caughtInstructionPointer = pCONTEXT->Rip; + if (alreadyHandlingException == TRUE) { + return EXCEPTION_CONTINUE_SEARCH; + } + alreadyHandlingException = TRUE; + + // Basically, here, we coerce the os to resume us into a context that calls `longjmp` instead of just continuing. + // Presumably, we cannot `longjmp` out of the signal/exception context, like we can on unix. + pCONTEXT->Rip = (uintptr_t)(&longjmpOutOfHere); + pCONTEXT->Rsp = (uintptr_t)(savedStackPointer); + return EXCEPTION_CONTINUE_EXECUTION; +} + +uint8_t callProtected(trampoline_t trampoline, + const struct wasmer_instance_context_t* ctx, + const struct func_t* func, + const uint64_t* param_vec, + uint64_t* return_vec, + struct call_protected_result_t* out_result) { + + // install exception handler + if (exceptionHandlerInstalled == FALSE) { + exceptionHandlerInstalled = TRUE; + AddVectoredExceptionHandler(CALL_FIRST, exceptionHandler); + } + + // jmp jmp jmp! + int signum = setjmp(jmpBuf); + if (signum == 0) { + // save the stack pointer + savedStackPointer = get_callee_frame_address(); + trampoline(ctx, func, param_vec, return_vec); + out_result->code = 0; + out_result->exceptionAddress = 0; + out_result->instructionPointer = 0; + return TRUE; + } + + out_result->code = (uint64_t)signum; + out_result->exceptionAddress = (uint64_t)caughtExceptionAddress; + out_result->instructionPointer = caughtInstructionPointer; + + caughtExceptionAddress = 0; + caughtInstructionPointer = 0; + + return FALSE; +} diff --git a/lib/win-exception-handler/exception_handling/exception_handling.h b/lib/win-exception-handler/exception_handling/exception_handling.h new file mode 100644 index 000000000..cd5472149 --- /dev/null +++ b/lib/win-exception-handler/exception_handling/exception_handling.h @@ -0,0 +1,25 @@ +#ifndef WASMER_EXCEPTION_HANDLING_H +#define WASMER_EXCEPTION_HANDLING_H + +#include + +struct func_t; +struct wasmer_instance_context_t; + +typedef void(*trampoline_t)(struct wasmer_instance_context_t*, const struct func_t*, const uint64_t*, uint64_t*); + +struct call_protected_result_t { + uint64_t code; + uint64_t exceptionAddress; + uint64_t instructionPointer; +}; + +uint8_t callProtected( + trampoline_t trampoline, + const struct wasmer_instance_context_t* ctx, + const struct func_t* func, + const uint64_t* param_vec, + uint64_t* return_vec, + struct call_protected_result_t* out_result); + +#endif //WASMER_EXCEPTION_HANDLING_H diff --git a/lib/win-exception-handler/src/exception_handling.rs b/lib/win-exception-handler/src/exception_handling.rs new file mode 100644 index 000000000..82992e721 --- /dev/null +++ b/lib/win-exception-handler/src/exception_handling.rs @@ -0,0 +1,55 @@ +use std::ffi::c_void; +use wasmer_runtime_core::vm::{Ctx, Func}; + +type Trampoline = unsafe extern "C" fn(*mut Ctx, *const Func, *const u64, *mut u64) -> c_void; +type CallProtectedResult = Result<(), CallProtectedData>; + +#[repr(C)] +pub struct CallProtectedData { + pub code: u64, + pub exceptionAddress: u64, + pub instructionPointer: u64, +} + +extern "C" { + #[link_name = "callProtected"] + pub fn __call_protected( + trampoline: Trampoline, + ctx: *mut Ctx, + func: *const Func, + param_vec: *const u64, + return_vec: *mut u64, + out_result: *mut CallProtectedData, + ) -> u8; +} + +pub fn _call_protected( + trampoline: Trampoline, + ctx: *mut Ctx, + func: *const Func, + param_vec: *const u64, + return_vec: *mut u64, +) -> CallProtectedResult { + let mut out_result = CallProtectedData { + code: 0, + exceptionAddress: 0, + instructionPointer: 0, + }; + let result = unsafe { + __call_protected( + trampoline, + ctx, + func, + param_vec, + return_vec, + &mut out_result, + ) + }; + println!("result from __call_protected: {}", result); + if result == 1 { + Ok(()) + } else { + println!("returning error from _call_protected"); + Err(out_result) + } +} diff --git a/lib/win-exception-handler/src/lib.rs b/lib/win-exception-handler/src/lib.rs new file mode 100644 index 000000000..bc4a142b5 --- /dev/null +++ b/lib/win-exception-handler/src/lib.rs @@ -0,0 +1,5 @@ +#[cfg(windows)] +mod exception_handling; + +#[cfg(windows)] +pub use self::exception_handling::*; diff --git a/src/bin/wasmer.rs b/src/bin/wasmer.rs index 4ebfb76d3..63f6e20e2 100644 --- a/src/bin/wasmer.rs +++ b/src/bin/wasmer.rs @@ -69,7 +69,7 @@ fn execute_wasm(options: &Run) -> Result<(), String> { let module = webassembly::compile(&wasm_binary[..]) .map_err(|e| format!("Can't compile module: {:?}", e))?; - let (_abi, import_object, em_globals) = if wasmer_emscripten::is_emscripten_module(&module) { + let (_abi, import_object, _em_globals) = if wasmer_emscripten::is_emscripten_module(&module) { let mut emscripten_globals = wasmer_emscripten::EmscriptenGlobals::new(&module); ( InstanceABI::Emscripten, From 0c7532b1ba1218b83ff4ca3506ed21c26b250d2b Mon Sep 17 00:00:00 2001 From: Mackenzie Clark Date: Thu, 14 Feb 2019 11:11:35 -0800 Subject: [PATCH 13/14] remove unnecessary print statements (#177) --- lib/win-exception-handler/src/exception_handling.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/lib/win-exception-handler/src/exception_handling.rs b/lib/win-exception-handler/src/exception_handling.rs index 82992e721..04c3c7f2e 100644 --- a/lib/win-exception-handler/src/exception_handling.rs +++ b/lib/win-exception-handler/src/exception_handling.rs @@ -45,11 +45,9 @@ pub fn _call_protected( &mut out_result, ) }; - println!("result from __call_protected: {}", result); if result == 1 { Ok(()) } else { - println!("returning error from _call_protected"); Err(out_result) } } From 5948fa1d203a757abb9f43bccd30a2cc6172759f Mon Sep 17 00:00:00 2001 From: Mackenzie Clark Date: Thu, 14 Feb 2019 15:30:42 -0800 Subject: [PATCH 14/14] Fix/windows installer (#178) --- .appveyor.yml | 30 ++++++++++++++----- installer/wasmer.iss | 71 ++++++++++++++++++++++++++++++++++++++++++++ src/bin/wasmer.rs | 5 ++++ 3 files changed, 98 insertions(+), 8 deletions(-) create mode 100644 installer/wasmer.iss diff --git a/.appveyor.yml b/.appveyor.yml index 5da647f54..16432ed6b 100644 --- a/.appveyor.yml +++ b/.appveyor.yml @@ -1,11 +1,10 @@ -branches: - except: - - master - version: "{build} ~ {branch}" os: Visual Studio 2017 +# Do not build feature branch with open Pull Requests +skip_branch_with_pr: true + environment: matrix: - CHANNEL: stable @@ -20,10 +19,6 @@ install: - rustc -vV - cargo -vV -artifacts: - - path: target\debug\wasmer.exe - name: wasmer.exe - build_script: - cargo build --verbose @@ -31,3 +26,22 @@ test_script: - set RUST_BACKTRACE=1 - cd ./lib/spectests && cargo test -- --test-threads 1 && cd ../.. +before_deploy: + - cd installer + - iscc wasmer.iss + - copy /y .\WasmerInstaller.exe ..\WasmerInstaller-%APPVEYOR_REPO_TAG_NAME%.exe + - appveyor PushArtifact WasmerInstaller-%APPVEYOR_REPO_TAG_NAME%.exe + +artifacts: + - path: WasmerInstaller-%APPVEYOR_REPO_TAG_NAME%.exe + name: WasmerInstaller.exe + +deploy: + description: 'WasmerInstaller' + artifact: /.*\.exe/ + auth_token: + secure: CaKtncy7S1PWxzDUQ0p2264pe3HwxzDn5VIyRizDaa72/SVfskNcoMjwwRh0ut22 + provider: GitHub + on: + branch: master + appveyor_repo_tag: true diff --git a/installer/wasmer.iss b/installer/wasmer.iss new file mode 100644 index 000000000..04850eb7a --- /dev/null +++ b/installer/wasmer.iss @@ -0,0 +1,71 @@ +[Setup] +AppName=Wasmer +AppVersion=1.5 +DefaultDirName={pf}\Wasmer +DefaultGroupName=Wasmer +Compression=lzma2 +SolidCompression=yes +OutputDir=.\ +DisableProgramGroupPage=yes +ChangesEnvironment=yes +OutputBaseFilename=WasmerInstaller + +[Files] +Source: "..\target\release\wasmer.exe"; DestDir: "{app}\bin" + +[Code] +const EnvironmentKey = 'SYSTEM\CurrentControlSet\Control\Session Manager\Environment'; + +procedure EnvAddPath(Path: string); +var + Paths: string; +begin + { Retrieve current path (use empty string if entry not exists) } + if not RegQueryStringValue(HKEY_LOCAL_MACHINE, EnvironmentKey, 'Path', Paths) + then Paths := ''; + + { Skip if string already found in path } + if Pos(';' + Uppercase(Path) + ';', ';' + Uppercase(Paths) + ';') > 0 then exit; + + { App string to the end of the path variable } + Paths := Paths + ';'+ Path +';' + + { Overwrite (or create if missing) path environment variable } + if RegWriteStringValue(HKEY_LOCAL_MACHINE, EnvironmentKey, 'Path', Paths) + then Log(Format('The [%s] added to PATH: [%s]', [Path, Paths])) + else Log(Format('Error while adding the [%s] to PATH: [%s]', [Path, Paths])); +end; + +procedure EnvRemovePath(Path: string); +var + Paths: string; + P: Integer; +begin + { Skip if registry entry not exists } + if not RegQueryStringValue(HKEY_LOCAL_MACHINE, EnvironmentKey, 'Path', Paths) then + exit; + + { Skip if string not found in path } + P := Pos(';' + Uppercase(Path) + ';', ';' + Uppercase(Paths) + ';'); + if P = 0 then exit; + + { Update path variable } + Delete(Paths, P - 1, Length(Path) + 1); + + { Overwrite path environment variable } + if RegWriteStringValue(HKEY_LOCAL_MACHINE, EnvironmentKey, 'Path', Paths) + then Log(Format('The [%s] removed from PATH: [%s]', [Path, Paths])) + else Log(Format('Error while removing the [%s] from PATH: [%s]', [Path, Paths])); +end; + +procedure CurStepChanged(CurStep: TSetupStep); +begin + if CurStep = ssPostInstall + then EnvAddPath(ExpandConstant('{app}') +'\bin'); +end; + +procedure CurUninstallStepChanged(CurUninstallStep: TUninstallStep); +begin + if CurUninstallStep = usPostUninstall + then EnvRemovePath(ExpandConstant('{app}') +'\bin'); +end; \ No newline at end of file diff --git a/src/bin/wasmer.rs b/src/bin/wasmer.rs index 63f6e20e2..2ec707f83 100644 --- a/src/bin/wasmer.rs +++ b/src/bin/wasmer.rs @@ -113,6 +113,11 @@ fn main() { let options = CLIOptions::from_args(); match options { CLIOptions::Run(options) => run(options), + #[cfg(not(target_os = "windows"))] CLIOptions::SelfUpdate => update::self_update(), + #[cfg(target_os = "windows")] + CLIOptions::SelfUpdate => { + println!("Self update is not supported on Windows. Use install instructions on the Wasmer homepage: https://wasmer.io"); + } } }