Merge branch 'master' into feature/c-api

This commit is contained in:
Brandon Fish 2019-02-15 19:12:30 -06:00
commit 768a2fae18
54 changed files with 1143 additions and 333 deletions

View File

@ -1,11 +1,10 @@
branches:
except:
- master
version: "{build} ~ {branch}" version: "{build} ~ {branch}"
os: Visual Studio 2017 os: Visual Studio 2017
# Do not build feature branch with open Pull Requests
skip_branch_with_pr: true
environment: environment:
matrix: matrix:
- CHANNEL: stable - CHANNEL: stable
@ -20,13 +19,29 @@ install:
- rustc -vV - rustc -vV
- cargo -vV - cargo -vV
artifacts:
- path: target\debug\wasmer.exe
name: wasmer.exe
build_script: build_script:
- cargo build --verbose - cargo build --verbose
test_script: test_script:
- set RUST_BACKTRACE=1 - set RUST_BACKTRACE=1
- cargo test --verbose - 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

245
Cargo.lock generated
View File

@ -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]] [[package]]
name = "ansi_term" name = "ansi_term"
version = "0.11.0" version = "0.11.0"
@ -21,6 +31,49 @@ name = "autocfg"
version = "0.1.2" version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index" 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]] [[package]]
name = "bitflags" name = "bitflags"
version = "1.0.4" version = "1.0.4"
@ -80,11 +133,29 @@ name = "cc"
version = "1.0.28" version = "1.0.28"
source = "registry+https://github.com/rust-lang/crates.io-index" 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]] [[package]]
name = "cfg-if" name = "cfg-if"
version = "0.1.6" version = "0.1.6"
source = "registry+https://github.com/rust-lang/crates.io-index" 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]] [[package]]
name = "clap" name = "clap"
version = "2.32.0" version = "2.32.0"
@ -193,6 +264,18 @@ dependencies = [
"generic-array 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", "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]] [[package]]
name = "errno" name = "errno"
version = "0.2.4" version = "0.2.4"
@ -217,6 +300,7 @@ name = "failure"
version = "0.1.5" version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [ 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)", "failure_derive 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
@ -291,6 +375,14 @@ dependencies = [
"unicode-segmentation 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "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]] [[package]]
name = "indexmap" name = "indexmap"
version = "1.0.2" version = "1.0.2"
@ -325,6 +417,15 @@ name = "libc"
version = "0.2.48" version = "0.2.48"
source = "registry+https://github.com/rust-lang/crates.io-index" 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]] [[package]]
name = "lock_api" name = "lock_api"
version = "0.1.5" version = "0.1.5"
@ -342,6 +443,11 @@ dependencies = [
"cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "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]] [[package]]
name = "memmap" name = "memmap"
version = "0.7.0" version = "0.7.0"
@ -375,6 +481,15 @@ dependencies = [
"void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", "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]] [[package]]
name = "opaque-debug" name = "opaque-debug"
version = "0.2.2" version = "0.2.2"
@ -419,6 +534,11 @@ dependencies = [
"winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", "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]] [[package]]
name = "proc-macro2" name = "proc-macro2"
version = "0.3.8" version = "0.3.8"
@ -435,6 +555,11 @@ dependencies = [
"unicode-xid 0.1.0 (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 = "quick-error"
version = "1.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]] [[package]]
name = "quote" name = "quote"
version = "0.5.2" version = "0.5.2"
@ -578,6 +703,26 @@ dependencies = [
"redox_syscall 0.1.51 (registry+https://github.com/rust-lang/crates.io-index)", "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]] [[package]]
name = "remove_dir_all" name = "remove_dir_all"
version = "0.5.1" version = "0.5.1"
@ -586,6 +731,11 @@ dependencies = [
"winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.6 (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]] [[package]]
name = "rustc_version" name = "rustc_version"
version = "0.2.3" version = "0.2.3"
@ -765,6 +915,14 @@ dependencies = [
"winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.6 (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]] [[package]]
name = "termion" name = "termion"
version = "1.5.1" version = "1.5.1"
@ -783,6 +941,14 @@ dependencies = [
"unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "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]] [[package]]
name = "time" name = "time"
version = "0.1.42" version = "0.1.42"
@ -806,6 +972,11 @@ name = "typenum"
version = "1.10.0" version = "1.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index" 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]] [[package]]
name = "unicode-segmentation" name = "unicode-segmentation"
version = "1.2.1" version = "1.2.1"
@ -829,11 +1000,21 @@ dependencies = [
"void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", "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]] [[package]]
name = "vec_map" name = "vec_map"
version = "0.8.1" version = "0.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index" 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]] [[package]]
name = "void" name = "void"
version = "1.0.2" version = "1.0.2"
@ -891,7 +1072,9 @@ dependencies = [
"serde_derive 1.0.58 (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)", "target-lexicon 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"wasmer-runtime-core 0.1.2", "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)", "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]] [[package]]
@ -959,6 +1142,18 @@ dependencies = [
"wasmer-runtime-core 0.1.2", "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]] [[package]]
name = "wasmparser" name = "wasmparser"
version = "0.22.1" version = "0.22.1"
@ -969,6 +1164,15 @@ name = "wasmparser"
version = "0.23.0" version = "0.23.0"
source = "registry+https://github.com/rust-lang/crates.io-index" 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]] [[package]]
name = "winapi" name = "winapi"
version = "0.2.8" version = "0.2.8"
@ -993,15 +1197,36 @@ name = "winapi-i686-pc-windows-gnu"
version = "0.4.0" version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index" 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]] [[package]]
name = "winapi-x86_64-pc-windows-gnu" name = "winapi-x86_64-pc-windows-gnu"
version = "0.4.0" version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index" 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] [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 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 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 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 bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "228047a76f468627ca71776ecdebd732a3423081fcf5125585bcd7c49886ce12"
"checksum block-buffer 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "49665c62e0e700857531fa5d3763e91b539ff1abeebd56808d378b495870d60d" "checksum block-buffer 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "49665c62e0e700857531fa5d3763e91b539ff1abeebd56808d378b495870d60d"
"checksum block-padding 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "d75255892aeb580d3c566f213a2b6fdc1c66667839f45719ee1d30ebf2aea591" "checksum block-padding 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "d75255892aeb580d3c566f213a2b6fdc1c66667839f45719ee1d30ebf2aea591"
@ -1010,7 +1235,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
"checksum cast 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "926013f2860c46252efceabb19f4a6b308197505082c609025aa6706c011d427" "checksum cast 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "926013f2860c46252efceabb19f4a6b308197505082c609025aa6706c011d427"
"checksum cbindgen 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "32e01024aaf5390d6a8145047371a4f5b0063a14c1e411bc731353bd2278ca44" "checksum cbindgen 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "32e01024aaf5390d6a8145047371a4f5b0063a14c1e411bc731353bd2278ca44"
"checksum cc 1.0.28 (registry+https://github.com/rust-lang/crates.io-index)" = "bb4a8b715cb4597106ea87c7c84b2f1d452c7492033765df7f32651e66fcf749" "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 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 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 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" "checksum cmake 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)" = "6ec65ee4f9c9d16f335091d23693457ed4928657ba4982289d7fafee03bc614a"
@ -1022,6 +1249,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-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 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 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 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 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" "checksum failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "795bd83d3abeb9220f257e597aa0080a508b27533824adf336529648f6abf7e2"
@ -1035,24 +1263,30 @@ 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 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 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 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 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 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 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 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)" = "<none>" "checksum libc 0.2.48 (git+https://github.com/rust-lang/libc)" = "<none>"
"checksum libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)" = "e962c7641008ac010fa60a7dfdc1712449f29c44ef2d4702394aea943ee75047" "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 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 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 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.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 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 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 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 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 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 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.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 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.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 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 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)" = "6d71dacdc3c88c1fde3885a3be3fbab9f35724e6ce99467f7d9c5026132184ca"
@ -1069,7 +1303,10 @@ 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 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_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 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 remove_dir_all 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3488ba1b9a2084d38645c4c08276a1752dcbf2c7130d74f1569681ad5d2799c5" "checksum remove_dir_all 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3488ba1b9a2084d38645c4c08276a1752dcbf2c7130d74f1569681ad5d2799c5"
"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 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 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" "checksum scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "94258f53601af11e6a49f722422f6e3425c52b06245a5cf9bc09908b174f5e27"
@ -1091,23 +1328,31 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
"checksum synstructure 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "73687139bf99285483c96ac0add482c3776528beac1d97d444f6e91f203a2015" "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 target-lexicon 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4af5e2227f0b887d591d3724b796a96eff04226104d872f5b3883fcd427d64b9"
"checksum tempfile 3.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "37daa55a7240c4931c84559f03b3cad7d19535840d1c4a0cc4e9b2fb0dcf70ff" "checksum tempfile 3.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "37daa55a7240c4931c84559f03b3cad7d19535840d1c4a0cc4e9b2fb0dcf70ff"
"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 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 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 time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)" = "db8dcfca086c1143c9270ac42a2bbd8a7ee477b78ac8e45b19abfb0cbede4b6f"
"checksum toml 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)" = "758664fc71a3a69038656bee8b6be6477d2a6c315a6b81f7081f591bffa4111f" "checksum toml 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)" = "758664fc71a3a69038656bee8b6be6477d2a6c315a6b81f7081f591bffa4111f"
"checksum typenum 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "612d636f949607bdf9b123b4a6f6d966dedf3ff669f7f045890d3a4a73948169" "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-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-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 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 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 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 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 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 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.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 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.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 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-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-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 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"

View File

@ -27,7 +27,7 @@ wasmer-runtime-core = { path = "lib/runtime-core" }
wasmer-emscripten = { path = "lib/emscripten" } wasmer-emscripten = { path = "lib/emscripten" }
[workspace] [workspace]
members = ["lib/clif-backend", "lib/runtime", "lib/runtime-core", "lib/emscripten", "lib/spectests", "lib/runtime-c-api"] members = ["lib/clif-backend", "lib/runtime", "lib/runtime-core", "lib/emscripten", "lib/spectests", "lib/win-exception-handler", "lib/runtime-c-api"]
[build-dependencies] [build-dependencies]
wabt = "0.7.2" wabt = "0.7.2"

View File

@ -47,10 +47,10 @@ Wasmer is structured into different directories:
Building wasmer requires [rustup](https://rustup.rs/). 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. then follow the onscreen instructions.
To install on other systems, run: To build on other systems, run:
```sh ```sh
curl https://sh.rustup.rs -sSf | sh curl https://sh.rustup.rs -sSf | sh
@ -86,8 +86,8 @@ sudo apt install cmake
#### Windows (MSVC) #### Windows (MSVC)
Right now Windows support is _highly experimental_. Windows support is _highly experimental_. Only simple wasm programs may be run, and no syscalls are allowed. This means
We are working on this so Wasmer can soon be released for Windows. 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. 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. 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 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). settings for the installer are fine).
3. Install CMake (https://cmake.org/download/). Ensure CMake is in the PATH.
## Building ## Building
Wasmer is built with [Cargo](https://crates.io/), the Rust package manager. Wasmer is built with [Cargo](https://crates.io/), the Rust package manager.

71
installer/wasmer.iss Normal file
View File

@ -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;

View File

@ -37,6 +37,10 @@ optional = true
version = "0.0.7" version = "0.0.7"
optional = true 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] [features]
cache = ["serde", "serde_derive", "serde_bytes", "serde-bench", "wasmer-runtime-core/cache"] cache = ["serde", "serde_derive", "serde_bytes", "serde-bench", "wasmer-runtime-core/cache"]
debug = ["wasmer-runtime-core/debug"] debug = ["wasmer-runtime-core/debug"]

View File

@ -32,10 +32,10 @@ impl<'env, 'module, 'isa> FuncEnv<'env, 'module, 'isa> {
let mut signature = self.env.signatures[Converter(clif_sig_index).into()].clone(); let mut signature = self.env.signatures[Converter(clif_sig_index).into()].clone();
// Add the vmctx parameter type to it // Add the vmctx parameter type to it
signature.params.push(ir::AbiParam::special( signature.params.insert(
self.pointer_type(), 0,
ir::ArgumentPurpose::VMContext, ir::AbiParam::special(self.pointer_type(), ir::ArgumentPurpose::VMContext),
)); );
// Return signature // Return signature
signature signature
@ -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 // Build a value list for the indirect call instruction containing the call_args
// and the vmctx parameter. // and the vmctx parameter.
let mut args = Vec::with_capacity(call_args.len() + 1); let mut args = Vec::with_capacity(call_args.len() + 1);
args.extend(call_args.iter().cloned());
args.push(vmctx_ptr); args.push(vmctx_ptr);
args.extend(call_args.iter().cloned());
Ok(pos.ins().call_indirect(sig_ref, func_ptr, &args)) 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"); .expect("missing vmctx parameter");
let mut args = Vec::with_capacity(call_args.len() + 1); let mut args = Vec::with_capacity(call_args.len() + 1);
args.extend(call_args.iter().cloned());
args.push(vmctx); args.push(vmctx);
args.extend(call_args.iter().cloned());
Ok(pos.ins().call(callee, &args)) 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 sig_ref = pos.func.dfg.ext_funcs[callee].signature;
let mut args = Vec::with_capacity(call_args.len() + 1); let mut args = Vec::with_capacity(call_args.len() + 1);
args.extend(call_args.iter().cloned());
args.push(imported_vmctx_addr); args.push(imported_vmctx_addr);
args.extend(call_args.iter().cloned());
Ok(pos Ok(pos
.ins() .ins()
@ -559,9 +559,9 @@ impl<'env, 'module, 'isa> FuncEnvironment for FuncEnv<'env, 'module, 'isa> {
let signature = pos.func.import_signature(ir::Signature { let signature = pos.func.import_signature(ir::Signature {
call_conv: self.target_config().default_call_conv, call_conv: self.target_config().default_call_conv,
params: vec![ 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::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)], returns: vec![ir::AbiParam::new(ir::types::I32)],
}); });
@ -604,7 +604,7 @@ impl<'env, 'module, 'isa> FuncEnvironment for FuncEnv<'env, 'module, 'isa> {
let call_inst = pos let call_inst = pos
.ins() .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()) Ok(*pos.func.dfg.inst_results(call_inst).first().unwrap())
} }
@ -623,8 +623,8 @@ impl<'env, 'module, 'isa> FuncEnvironment for FuncEnv<'env, 'module, 'isa> {
let signature = pos.func.import_signature(ir::Signature { let signature = pos.func.import_signature(ir::Signature {
call_conv: self.target_config().default_call_conv, call_conv: self.target_config().default_call_conv,
params: vec![ params: vec![
ir::AbiParam::new(ir::types::I32),
ir::AbiParam::special(self.pointer_type(), ir::ArgumentPurpose::VMContext), ir::AbiParam::special(self.pointer_type(), ir::ArgumentPurpose::VMContext),
ir::AbiParam::new(ir::types::I32),
], ],
returns: vec![ir::AbiParam::new(ir::types::I32)], returns: vec![ir::AbiParam::new(ir::types::I32)],
}); });
@ -664,7 +664,7 @@ impl<'env, 'module, 'isa> FuncEnvironment for FuncEnv<'env, 'module, 'isa> {
.special_param(ir::ArgumentPurpose::VMContext) .special_param(ir::ArgumentPurpose::VMContext)
.expect("missing vmctx parameter"); .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()) Ok(*pos.func.dfg.inst_results(call_inst).first().unwrap())
} }

View File

@ -419,8 +419,8 @@ impl<'module, 'isa, 'data> ModuleEnvironment<'data> for ModuleEnv<'module, 'isa>
let signature = pos.func.import_signature(ir::Signature { let signature = pos.func.import_signature(ir::Signature {
call_conv: self.target_config().default_call_conv, call_conv: self.target_config().default_call_conv,
params: vec![ params: vec![
ir::AbiParam::new(ir::types::I32),
ir::AbiParam::special(ir::types::I64, ir::ArgumentPurpose::VMContext), ir::AbiParam::special(ir::types::I64, ir::ArgumentPurpose::VMContext),
ir::AbiParam::new(ir::types::I32),
], ],
returns: vec![], returns: vec![],
}); });
@ -457,8 +457,8 @@ impl<'module, 'isa, 'data> ModuleEnvironment<'data> for ModuleEnv<'module, 'isa>
let signature = pos.func.import_signature(ir::Signature { let signature = pos.func.import_signature(ir::Signature {
call_conv: self.target_config().default_call_conv, call_conv: self.target_config().default_call_conv,
params: vec![ params: vec![
ir::AbiParam::new(ir::types::I32),
ir::AbiParam::special(ir::types::I64, ir::ArgumentPurpose::VMContext), ir::AbiParam::special(ir::types::I64, ir::ArgumentPurpose::VMContext),
ir::AbiParam::new(ir::types::I32),
], ],
returns: vec![], returns: vec![],
}); });
@ -476,8 +476,8 @@ impl<'module, 'isa, 'data> ModuleEnvironment<'data> for ModuleEnv<'module, 'isa>
let signature = pos.func.import_signature(ir::Signature { let signature = pos.func.import_signature(ir::Signature {
call_conv: self.target_config().default_call_conv, call_conv: self.target_config().default_call_conv,
params: vec![ params: vec![
ir::AbiParam::new(ir::types::I64),
ir::AbiParam::special(ir::types::I64, ir::ArgumentPurpose::VMContext), ir::AbiParam::special(ir::types::I64, ir::ArgumentPurpose::VMContext),
ir::AbiParam::new(ir::types::I64),
], ],
returns: vec![], returns: vec![],
}); });
@ -495,8 +495,8 @@ impl<'module, 'isa, 'data> ModuleEnvironment<'data> for ModuleEnv<'module, 'isa>
let signature = pos.func.import_signature(ir::Signature { let signature = pos.func.import_signature(ir::Signature {
call_conv: self.target_config().default_call_conv, call_conv: self.target_config().default_call_conv,
params: vec![ params: vec![
ir::AbiParam::new(ir::types::F32),
ir::AbiParam::special(ir::types::I64, ir::ArgumentPurpose::VMContext), ir::AbiParam::special(ir::types::I64, ir::ArgumentPurpose::VMContext),
ir::AbiParam::new(ir::types::F32),
], ],
returns: vec![], returns: vec![],
}); });
@ -514,8 +514,8 @@ impl<'module, 'isa, 'data> ModuleEnvironment<'data> for ModuleEnv<'module, 'isa>
let signature = pos.func.import_signature(ir::Signature { let signature = pos.func.import_signature(ir::Signature {
call_conv: self.target_config().default_call_conv, call_conv: self.target_config().default_call_conv,
params: vec![ params: vec![
ir::AbiParam::new(ir::types::F64),
ir::AbiParam::special(ir::types::I64, ir::ArgumentPurpose::VMContext), ir::AbiParam::special(ir::types::I64, ir::ArgumentPurpose::VMContext),
ir::AbiParam::new(ir::types::F64),
], ],
returns: vec![], returns: vec![],
}); });
@ -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); 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() { for param in new_ebb_params.iter().cloned() {
match pos.func.dfg.value_type(param) { match pos.func.dfg.value_type(param) {
ir::types::I32 => pos.ins().call(i32_print, &[param, vmctx]), ir::types::I32 => pos.ins().call(i32_print, &[vmctx, param]),
ir::types::I64 => pos.ins().call(i64_print, &[param, vmctx]), ir::types::I64 => pos.ins().call(i64_print, &[vmctx, param]),
ir::types::F32 => pos.ins().call(f32_print, &[param, vmctx]), ir::types::F32 => pos.ins().call(f32_print, &[vmctx, param]),
ir::types::F64 => pos.ins().call(f64_print, &[param, vmctx]), ir::types::F64 => pos.ins().call(f64_print, &[vmctx, param]),
_ => unimplemented!(), _ => unimplemented!(),
}; };
} }

View File

@ -223,9 +223,9 @@ impl FuncResolverBuilder {
LibCall::TruncF64 => libcalls::truncf64 as isize, LibCall::TruncF64 => libcalls::truncf64 as isize,
LibCall::NearestF64 => libcalls::nearbyintf64 as isize, LibCall::NearestF64 => libcalls::nearbyintf64 as isize,
#[cfg(all(target_pointer_width = "64", target_os = "windows"))] #[cfg(all(target_pointer_width = "64", target_os = "windows"))]
Probestack => __chkstk as isize, LibCall::Probestack => __chkstk as isize,
#[cfg(not(target_os = "windows"))] #[cfg(not(target_os = "windows"))]
Probestack => __rust_probestack as isize, LibCall::Probestack => __rust_probestack as isize,
}, },
RelocationType::Intrinsic(ref name) => match name.as_str() { RelocationType::Intrinsic(ref name) => match name.as_str() {
"i32print" => i32_print as isize, "i32print" => i32_print as isize,
@ -350,21 +350,21 @@ fn round_up(n: usize, multiple: usize) -> usize {
(n + multiple - 1) & !(multiple - 1) (n + multiple - 1) & !(multiple - 1)
} }
extern "C" fn i32_print(n: i32) { extern "C" fn i32_print(_ctx: &mut vm::Ctx, n: i32) {
print!(" i32: {},", n); print!(" i32: {},", n);
} }
extern "C" fn i64_print(n: i64) { extern "C" fn i64_print(_ctx: &mut vm::Ctx, n: i64) {
print!(" i64: {},", n); print!(" i64: {},", n);
} }
extern "C" fn f32_print(n: f32) { extern "C" fn f32_print(_ctx: &mut vm::Ctx, n: f32) {
print!(" f32: {},", n); print!(" f32: {},", n);
} }
extern "C" fn f64_print(n: f64) { extern "C" fn f64_print(_ctx: &mut vm::Ctx, n: f64) {
print!(" f64: {},", n); print!(" f64: {},", n);
} }
extern "C" fn start_debug(func_index: u32) { extern "C" fn start_debug(_ctx: &mut vm::Ctx, func_index: u32) {
print!("func ({}), args: [", func_index); print!("func ({}), args: [", func_index);
} }
extern "C" fn end_debug() { extern "C" fn end_debug(_ctx: &mut vm::Ctx) {
println!(" ]"); println!(" ]");
} }

View File

@ -110,6 +110,7 @@ impl ProtectedCaller for Caller {
.lookup(sig_index) .lookup(sig_index)
.expect("that trampoline doesn't exist"); .expect("that trampoline doesn't exist");
#[cfg(not(target_os = "windows"))]
call_protected(&self.handler_data, || unsafe { call_protected(&self.handler_data, || unsafe {
// Leap of faith. // Leap of faith.
trampoline( 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 Ok(return_vec
.iter() .iter()
.zip(signature.returns().iter()) .zip(signature.returns().iter())

View File

@ -1,10 +1,116 @@
use crate::relocation::{TrapCode, TrapData};
use crate::signal::HandlerData; 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<T>(handler_data: &HandlerData, f: impl FnOnce() -> T) -> RuntimeResult<T> { thread_local! {
unimplemented!("TODO"); 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() -> ! { pub unsafe fn trigger_trap() -> ! {
unimplemented!("TODO"); // TODO
unimplemented!();
} }

View File

@ -7,6 +7,7 @@ use cranelift_codegen::{
isa, Context, isa, Context,
}; };
use hashbrown::HashMap; use hashbrown::HashMap;
use std::ffi::c_void;
use std::{iter, mem}; use std::{iter, mem};
use wasmer_runtime_core::{ use wasmer_runtime_core::{
backend::sys::{Memory, Protect}, backend::sys::{Memory, Protect},
@ -23,6 +24,9 @@ impl RelocSink for NullRelocSink {
fn reloc_jt(&mut self, _: u32, _: Reloc, _: ir::JumpTable) {} 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 { pub struct Trampolines {
memory: Memory, memory: Memory,
offsets: HashMap<SigIndex, usize>, offsets: HashMap<SigIndex, usize>,
@ -138,10 +142,7 @@ impl Trampolines {
} }
} }
pub fn lookup( pub fn lookup(&self, sig_index: SigIndex) -> Option<Trampoline> {
&self,
sig_index: SigIndex,
) -> Option<unsafe extern "C" fn(*mut vm::Ctx, *const vm::Func, *const u64, *mut u64)> {
let offset = *self.offsets.get(&sig_index)?; let offset = *self.offsets.get(&sig_index)?;
let ptr = unsafe { self.memory.as_ptr().add(offset) }; let ptr = unsafe { self.memory.as_ptr().add(offset) };
@ -169,6 +170,7 @@ fn generate_func(func_sig: &FuncSig) -> ir::Function {
let mut pos = FuncCursor::new(&mut func).at_first_insertion_point(entry_ebb); 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); 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() { for (index, wasm_ty) in func_sig.params().iter().enumerate() {
let mem_flags = ir::MemFlags::trusted(); let mem_flags = ir::MemFlags::trusted();
@ -180,7 +182,6 @@ fn generate_func(func_sig: &FuncSig) -> ir::Function {
); );
args_vec.push(val); args_vec.push(val);
} }
args_vec.push(vmctx_ptr);
let call_inst = pos.ins().call_indirect(export_sig_ref, func_ptr, &args_vec); let call_inst = pos.ins().call_indirect(export_sig_ref, func_ptr, &args_vec);
@ -212,7 +213,9 @@ fn wasm_ty_to_clif(ty: Type) -> ir::types::Type {
} }
fn generate_trampoline_signature() -> ir::Signature { 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 { let ptr_param = ir::AbiParam {
value_type: ir::types::I64, value_type: ir::types::I64,
@ -227,24 +230,25 @@ fn generate_trampoline_signature() -> ir::Signature {
} }
fn generate_export_signature(func_sig: &FuncSig) -> 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);
export_clif_sig.params = func_sig let func_sig_iter = func_sig.params().iter().map(|wasm_ty| ir::AbiParam {
.params() value_type: wasm_ty_to_clif(*wasm_ty),
.iter() purpose: ir::ArgumentPurpose::Normal,
.map(|wasm_ty| ir::AbiParam { extension: ir::ArgumentExtension::None,
value_type: wasm_ty_to_clif(*wasm_ty), location: ir::ArgumentLoc::Unassigned,
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,
.chain(iter::once(ir::AbiParam { purpose: ir::ArgumentPurpose::VMContext,
value_type: ir::types::I64, extension: ir::ArgumentExtension::None,
purpose: ir::ArgumentPurpose::VMContext, location: ir::ArgumentLoc::Unassigned,
extension: ir::ArgumentExtension::None, })
location: ir::ArgumentLoc::Unassigned, .chain(func_sig_iter)
})) .collect();
.collect();
export_clif_sig.returns = func_sig export_clif_sig.returns = func_sig
.returns() .returns()

View File

@ -10,7 +10,7 @@
``` ```
- **abort** ✅ 🔥 &nbsp;&nbsp;&nbsp;&nbsp;[:top:](#host-apis) - **abort** ✅ 🔥 &nbsp;&nbsp;&nbsp;&nbsp;[:top:](#host-apis)
```rust ```rust
fn abort(message: u32, ctx: &mut Ctx) fn abort(ctx: &mut Ctx, message: u32, )
``` ```
- **abort_on_cannot_grow_memory**&nbsp;&nbsp;&nbsp;&nbsp;[:top:](#host-apis) - **abort_on_cannot_grow_memory**&nbsp;&nbsp;&nbsp;&nbsp;[:top:](#host-apis)
```rust ```rust
@ -28,11 +28,11 @@
- **\_getenv** ✅ &nbsp;&nbsp;&nbsp;&nbsp;[:top:](#host-apis) - **\_getenv** ✅ &nbsp;&nbsp;&nbsp;&nbsp;[:top:](#host-apis)
```rust ```rust
fn _getenv(name: c_int, ctx: &mut Ctx) fn _getenv(ctx: &mut Ctx, name: c_int, )
``` ```
- **\_putenv** ✅ &nbsp;&nbsp;&nbsp;&nbsp;[:top:](#host-apis) - **\_putenv** ✅ &nbsp;&nbsp;&nbsp;&nbsp;[:top:](#host-apis)
```rust ```rust
fn _putenv(name: c_int, ctx: &mut Ctx) fn _putenv(ctx: &mut Ctx, name: c_int, )
``` ```
- **\_setenv** ✅ &nbsp;&nbsp;&nbsp;&nbsp;[:top:](#host-apis) - **\_setenv** ✅ &nbsp;&nbsp;&nbsp;&nbsp;[:top:](#host-apis)
```rust ```rust
@ -40,7 +40,7 @@
``` ```
- **\_unsetenv** ✅ &nbsp;&nbsp;&nbsp;&nbsp;[:top:](#host-apis) - **\_unsetenv** ✅ &nbsp;&nbsp;&nbsp;&nbsp;[:top:](#host-apis)
```rust ```rust
fn _unsetenv(name: c_int, ctx: &mut Ctx) fn _unsetenv(ctx: &mut Ctx, name: c_int, )
``` ```
###### THREAD ###### THREAD
@ -70,7 +70,7 @@
- **\_emscripten_memcpy_big** ✅ 🔥 &nbsp;&nbsp;&nbsp;&nbsp;[:top:](#host-apis) - **\_emscripten_memcpy_big** ✅ 🔥 &nbsp;&nbsp;&nbsp;&nbsp;[:top:](#host-apis)
```rust ```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**&nbsp;&nbsp;&nbsp;&nbsp;[:top:](#host-apis) - **enlarge_memory**&nbsp;&nbsp;&nbsp;&nbsp;[:top:](#host-apis)
```rust ```rust
@ -78,7 +78,7 @@
``` ```
- **get_total_memory**&nbsp;&nbsp;&nbsp;&nbsp;[:top:](#host-apis) - **get_total_memory**&nbsp;&nbsp;&nbsp;&nbsp;[:top:](#host-apis)
```rust ```rust
fn get_total_memory(ctx: &mut Ctx) -> u32 fn get_total_memory(ctx: &mut Ctx, ) -> u32
``` ```
###### TIMING ###### TIMING
@ -337,7 +337,7 @@
``` ```
- **open** (\_\_\_syscall5) ✅ ❗️ 🔥 &nbsp;&nbsp;&nbsp;&nbsp;[:top:](#host-apis) - **open** (\_\_\_syscall5) ✅ ❗️ 🔥 &nbsp;&nbsp;&nbsp;&nbsp;[:top:](#host-apis)
```rust ```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) &nbsp;&nbsp;&nbsp;&nbsp;[:top:](#host-apis) - **openat** (\_\_\_syscall295) &nbsp;&nbsp;&nbsp;&nbsp;[:top:](#host-apis)
```rust ```rust
@ -385,7 +385,7 @@
``` ```
- **read** (\_\_\_syscall3) ✅ ❗️ &nbsp;&nbsp;&nbsp;&nbsp;[:top:](#host-apis) - **read** (\_\_\_syscall3) ✅ ❗️ &nbsp;&nbsp;&nbsp;&nbsp;[:top:](#host-apis)
```rust ```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) &nbsp;&nbsp;&nbsp;&nbsp;[:top:](#host-apis) - **readlink** (\_\_\_syscall85) &nbsp;&nbsp;&nbsp;&nbsp;[:top:](#host-apis)
```rust ```rust

View File

@ -14,16 +14,16 @@ use crate::{allocate_on_stack, EmscriptenData};
use std::os::raw::c_int; use std::os::raw::c_int;
use wasmer_runtime_core::vm::Ctx; 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"); debug!("emscripten::_getaddrinfo");
-1 -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() 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 { if let Some(memalign) = &get_emscripten_data(ctx).memalign {
memalign.call(alignment, size).unwrap() memalign.call(alignment, size).unwrap()
} else { } 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) get_emscripten_data(ctx)
.memset .memset
.call(pointer, value, size) .call(pointer, value, size)
@ -48,16 +48,16 @@ pub fn _getpagesize(_ctx: &mut Ctx) -> u32 {
} }
#[allow(clippy::cast_ptr_alignment)] #[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); debug!("emscripten::___build_environment {}", environ);
const MAX_ENV_VALUES: u32 = 64; const MAX_ENV_VALUES: u32 = 64;
const TOTAL_ENV_SIZE: u32 = 1024; const TOTAL_ENV_SIZE: u32 = 1024;
let environment = emscripten_memory_pointer!(ctx.memory(0), environ) as *mut c_int; let environment = emscripten_memory_pointer!(ctx.memory(0), environ) as *mut c_int;
unsafe { unsafe {
let (pool_offset, _pool_slice): (u32, &mut [u8]) = 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]) = 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 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; let mut _pool_ptr = emscripten_memory_pointer!(ctx.memory(0), pool_offset) as *mut c_int;
*env_ptr = pool_offset as i32; *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); debug!("emscripten::___assert_fail {} {} {} {}", a, b, c, d);
// TODO: Implement like emscripten expects regarding memory/page size // TODO: Implement like emscripten expects regarding memory/page size
// TODO raise an error // TODO raise an error

View File

@ -13,7 +13,7 @@ use wasmer_runtime_core::vm::Ctx;
// #[no_mangle] // #[no_mangle]
/// emscripten: _getenv // (name: *const char) -> *const c_char; /// 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"); debug!("emscripten::_getenv");
let name_addr = emscripten_memory_pointer!(ctx.memory(0), name) as *const c_char; let name_addr = emscripten_memory_pointer!(ctx.memory(0), name) as *const c_char;
@ -29,7 +29,7 @@ pub fn _getenv(name: i32, ctx: &mut Ctx) -> u32 {
} }
/// emscripten: _setenv // (name: *const char, name: *const value, overwrite: int); /// 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"); debug!("emscripten::_setenv");
let name_addr = emscripten_memory_pointer!(ctx.memory(0), name) as *const c_char; let name_addr = emscripten_memory_pointer!(ctx.memory(0), name) as *const c_char;
@ -42,7 +42,7 @@ pub fn _setenv(name: c_int, value: c_int, overwrite: c_int, ctx: &mut Ctx) -> c_
} }
/// emscripten: _putenv // (name: *const char); /// 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"); debug!("emscripten::_putenv");
let name_addr = emscripten_memory_pointer!(ctx.memory(0), name) as *const c_char; let name_addr = emscripten_memory_pointer!(ctx.memory(0), name) as *const c_char;
@ -53,7 +53,7 @@ pub fn _putenv(name: c_int, ctx: &mut Ctx) -> c_int {
} }
/// emscripten: _unsetenv // (name: *const char); /// 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"); debug!("emscripten::_unsetenv");
let name_addr = emscripten_memory_pointer!(ctx.memory(0), name) as *const c_char; let name_addr = emscripten_memory_pointer!(ctx.memory(0), name) as *const c_char;
@ -64,7 +64,7 @@ pub fn _unsetenv(name: c_int, ctx: &mut Ctx) -> c_int {
} }
#[allow(clippy::cast_ptr_alignment)] #[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); debug!("emscripten::_getpwnam {}", name_ptr);
#[repr(C)] #[repr(C)]
@ -85,7 +85,7 @@ pub fn _getpwnam(name_ptr: c_int, ctx: &mut Ctx) -> c_int {
unsafe { unsafe {
let passwd = &*libc_getpwnam(name.as_ptr()); let passwd = &*libc_getpwnam(name.as_ptr());
let passwd_struct_offset = call_malloc(mem::size_of::<GuestPasswd>() as _, ctx); let passwd_struct_offset = call_malloc(ctx, mem::size_of::<GuestPasswd>() as _);
let passwd_struct_ptr = let passwd_struct_ptr =
emscripten_memory_pointer!(ctx.memory(0), passwd_struct_offset) as *mut GuestPasswd; emscripten_memory_pointer!(ctx.memory(0), passwd_struct_offset) as *mut GuestPasswd;
@ -102,7 +102,7 @@ pub fn _getpwnam(name_ptr: c_int, ctx: &mut Ctx) -> c_int {
} }
#[allow(clippy::cast_ptr_alignment)] #[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); debug!("emscripten::_getgrnam {}", name_ptr);
#[repr(C)] #[repr(C)]
@ -120,7 +120,7 @@ pub fn _getgrnam(name_ptr: c_int, ctx: &mut Ctx) -> c_int {
unsafe { unsafe {
let group = &*libc_getgrnam(name.as_ptr()); let group = &*libc_getgrnam(name.as_ptr());
let group_struct_offset = call_malloc(mem::size_of::<GuestGroup>() as _, ctx); let group_struct_offset = call_malloc(ctx, mem::size_of::<GuestGroup>() as _);
let group_struct_ptr = let group_struct_ptr =
emscripten_memory_pointer!(ctx.memory(0), group_struct_offset) as *mut GuestGroup; emscripten_memory_pointer!(ctx.memory(0), group_struct_offset) as *mut GuestGroup;
@ -133,7 +133,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); debug!("emscripten::_sysconf {}", name);
// TODO: Implement like emscripten expects regarding memory/page size // TODO: Implement like emscripten expects regarding memory/page size
unsafe { sysconf(name) as i32 } // TODO review i64 unsafe { sysconf(name) as i32 } // TODO review i64

View File

@ -16,7 +16,7 @@ extern "C" {
// #[no_mangle] // #[no_mangle]
/// emscripten: _getenv // (name: *const char) -> *const c_char; /// 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"); debug!("emscripten::_getenv");
let name_string = read_string_from_wasm(ctx.memory(0), name); let name_string = read_string_from_wasm(ctx.memory(0), name);
debug!("=> name({:?})", name_string); 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); /// 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"); debug!("emscripten::_setenv");
let name_addr = emscripten_memory_pointer!(ctx.memory(0), name); let name_addr = emscripten_memory_pointer!(ctx.memory(0), name);
let value_addr = emscripten_memory_pointer!(ctx.memory(0), value); 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); /// 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"); debug!("emscripten::_putenv");
let name_addr = emscripten_memory_pointer!(ctx.memory(0), name) as *const c_char; 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); /// 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"); debug!("emscripten::_unsetenv");
let name_addr = emscripten_memory_pointer!(ctx.memory(0), name); let name_addr = emscripten_memory_pointer!(ctx.memory(0), name);
let name = read_string_from_wasm(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)] #[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); debug!("emscripten::_getpwnam {}", name_ptr);
#[repr(C)] #[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 // stub this in windows as it is not valid
unsafe { unsafe {
let passwd_struct_offset = call_malloc(mem::size_of::<GuestPasswd>() as _, ctx); let passwd_struct_offset = call_malloc(ctx, mem::size_of::<GuestPasswd>() as _);
let passwd_struct_ptr = let passwd_struct_ptr =
emscripten_memory_pointer!(ctx.memory(0), passwd_struct_offset) as *mut GuestPasswd; emscripten_memory_pointer!(ctx.memory(0), passwd_struct_offset) as *mut GuestPasswd;
(*passwd_struct_ptr).pw_name = 0; (*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)] #[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); debug!("emscripten::_getgrnam {}", name_ptr);
#[repr(C)] #[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 // stub the group struct as it is not supported on windows
unsafe { unsafe {
let group_struct_offset = call_malloc(mem::size_of::<GuestGroup>() as _, ctx); let group_struct_offset = call_malloc(ctx, mem::size_of::<GuestGroup>() as _);
let group_struct_ptr = let group_struct_ptr =
emscripten_memory_pointer!(ctx.memory(0), group_struct_offset) as *mut GuestGroup; emscripten_memory_pointer!(ctx.memory(0), group_struct_offset) as *mut GuestGroup;
(*group_struct_ptr).gr_name = 0; (*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); debug!("emscripten::_sysconf {}", name);
// stub because sysconf is not valid on windows // stub because sysconf is not valid on windows
0 0

View File

@ -1,7 +1,7 @@
// use std::collections::HashMap; // use std::collections::HashMap;
use wasmer_runtime_core::vm::Ctx; 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); debug!("emscripten::___seterrno {}", value);
// TODO: Incomplete impl // TODO: Incomplete impl
eprintln!("failed to set errno!"); eprintln!("failed to set errno!");

View File

@ -3,14 +3,14 @@ use super::process::_abort;
use wasmer_runtime_core::vm::Ctx; use wasmer_runtime_core::vm::Ctx;
/// emscripten: ___cxa_allocate_exception /// 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"); debug!("emscripten::___cxa_allocate_exception");
env::call_malloc(size as _, ctx) env::call_malloc(ctx, size as _)
} }
/// emscripten: ___cxa_throw /// emscripten: ___cxa_throw
/// TODO: We don't have support for exceptions yet /// 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"); debug!("emscripten::___cxa_throw");
_abort(ctx); _abort(ctx);
} }

View File

@ -3,12 +3,12 @@ use libc::printf as _printf;
use wasmer_runtime_core::vm::Ctx; use wasmer_runtime_core::vm::Ctx;
/// putchar /// putchar
pub fn putchar(chr: i32, ctx: &mut Ctx) { pub fn putchar(ctx: &mut Ctx, chr: i32) {
unsafe { libc::putchar(chr) }; unsafe { libc::putchar(chr) };
} }
/// printf /// 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); debug!("emscripten::printf {}, {}", memory_offset, extra);
unsafe { unsafe {
let addr = emscripten_memory_pointer!(ctx.memory(0), memory_offset) as _; let addr = emscripten_memory_pointer!(ctx.memory(0), memory_offset) as _;

View File

@ -15,12 +15,12 @@ use wasmer_runtime_core::vm::Ctx;
//} //}
/// putchar /// putchar
pub fn putchar(chr: i32, ctx: &mut Ctx) { pub fn putchar(ctx: &mut Ctx, chr: i32) {
unsafe { libc::putchar(chr) }; unsafe { libc::putchar(chr) };
} }
/// printf /// 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); debug!("emscripten::printf {}, {}", memory_offset, extra);
// unsafe { // unsafe {
// let addr = emscripten_memory_pointer!(ctx.memory(0), memory_offset) as _; // let addr = emscripten_memory_pointer!(ctx.memory(0), memory_offset) as _;

View File

@ -4,7 +4,7 @@ use std::cell::UnsafeCell;
use wasmer_runtime_core::vm::Ctx; use wasmer_runtime_core::vm::Ctx;
/// setjmp /// 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)"); debug!("emscripten::__setjmp (setjmp)");
unsafe { unsafe {
// Rather than using the env as the holder of the jump buffer pointer, // 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 jump_buf: UnsafeCell<[u32; 27]> = UnsafeCell::new([0; 27]);
let jumps = &mut get_emscripten_data(ctx).jumps; let jumps = &mut get_emscripten_data(ctx).jumps;
let result = setjmp(jump_buf.get() as _); 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 _; *jump_index = jumps.len() as _;
// We hold the reference of the jump buffer // We hold the reference of the jump buffer
jumps.push(jump_buf); jumps.push(jump_buf);
@ -25,7 +25,7 @@ pub fn __setjmp(env_addr: u32, ctx: &mut Ctx) -> c_int {
/// longjmp /// longjmp
#[allow(unreachable_code)] #[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)"); debug!("emscripten::__longjmp (longmp)");
unsafe { unsafe {
// We retrieve the jump index from the env address // We retrieve the jump index from the env address

View File

@ -132,7 +132,7 @@ pub fn run_emscripten_instance(
let num_params = main_func.signature().params().len(); let num_params = main_func.signature().params().len();
let _result = match num_params { let _result = match num_params {
2 => { 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)])?; instance.call("_main", &[Value::I32(argc as i32), Value::I32(argv as i32)])?;
} }
0 => { 0 => {
@ -149,17 +149,17 @@ pub fn run_emscripten_instance(
Ok(()) 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 argc = args.len() + 1;
let mut args_slice = vec![0; argc]; 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()) { 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]) = 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()); assert!(!argv_slice.is_empty());
for (slot, arg) in argv_slice[0..argc].iter_mut().zip(args_slice.iter()) { for (slot, arg) in argv_slice[0..argc].iter_mut().zip(args_slice.iter()) {
*slot = *arg *slot = *arg

View File

@ -3,19 +3,19 @@ use wasmer_runtime_core::vm::Ctx;
// TODO: Need to implement. // TODO: Need to implement.
/// emscripten: dlopen(filename: *const c_char, flag: c_int) -> *mut c_void /// 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"); debug!("emscripten::_dlopen");
-1 -1
} }
/// emscripten: dlclose(handle: *mut c_void) -> c_int /// 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"); debug!("emscripten::_dlclose");
-1 -1
} }
/// emscripten: dlsym(handle: *mut c_void, symbol: *const c_char) -> *mut c_void /// 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"); debug!("emscripten::_dlsym");
-1 -1
} }

View File

@ -2,16 +2,16 @@ use libc::c_int;
use wasmer_runtime_core::vm::Ctx; use wasmer_runtime_core::vm::Ctx;
// NOTE: Not implemented by Emscripten // 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); debug!("emscripten::___lock {}", what);
} }
// NOTE: Not implemented by Emscripten // 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); debug!("emscripten::___unlock {}", what);
} }
// NOTE: Not implemented by Emscripten // 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"); debug!("emscripten::___wait");
} }

View File

@ -1,23 +1,23 @@
use wasmer_runtime_core::vm::Ctx; use wasmer_runtime_core::vm::Ctx;
/// emscripten: _llvm_log10_f64 /// 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"); debug!("emscripten::_llvm_log10_f64");
value.log10() value.log10()
} }
/// emscripten: _llvm_log2_f64 /// 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"); debug!("emscripten::_llvm_log2_f64");
value.log2() 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"); debug!("emscripten::_llvm_log10_f32");
-1.0 -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"); debug!("emscripten::_llvm_log10_f32");
-1.0 -1.0
} }
@ -28,12 +28,12 @@ pub fn _emscripten_random(_ctx: &mut Ctx) -> f64 {
} }
// emscripten: f64-rem // 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"); debug!("emscripten::f64-rem");
x % y x % y
} }
// emscripten: global.Math pow // 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) x.powf(y)
} }

View File

@ -3,7 +3,7 @@ use libc::{c_int, c_void, memcpy, size_t};
use wasmer_runtime_core::vm::Ctx; use wasmer_runtime_core::vm::Ctx;
/// emscripten: _emscripten_memcpy_big /// 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!( debug!(
"emscripten::_emscripten_memcpy_big {}, {}, {}", "emscripten::_emscripten_memcpy_big {}, {}, {}",
dest, src, len dest, src, len
@ -35,12 +35,12 @@ pub fn enlarge_memory(_ctx: &mut Ctx) -> u32 {
/// emscripten: abortOnCannotGrowMemory /// emscripten: abortOnCannotGrowMemory
pub fn abort_on_cannot_grow_memory(ctx: &mut Ctx) -> u32 { pub fn abort_on_cannot_grow_memory(ctx: &mut Ctx) -> u32 {
debug!("emscripten::abort_on_cannot_grow_memory"); debug!("emscripten::abort_on_cannot_grow_memory");
abort_with_message("Cannot enlarge memory arrays!", ctx); abort_with_message(ctx, "Cannot enlarge memory arrays!");
0 0
} }
/// emscripten: ___map_file /// 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"); debug!("emscripten::___map_file");
// NOTE: TODO: Em returns -1 here as well. May need to implement properly // NOTE: TODO: Em returns -1 here as well. May need to implement properly
-1 -1

View File

@ -1,67 +1,67 @@
use super::process::abort_with_message; use super::process::abort_with_message;
use wasmer_runtime_core::vm::Ctx; 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); 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); 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); 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); 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); 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); 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); 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); 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); 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); 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); 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"); 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"); 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)");
} }

View File

@ -9,7 +9,7 @@ type pid_t = c_int;
use std::ffi::CStr; use std::ffi::CStr;
use wasmer_runtime_core::vm::Ctx; 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"); debug!("emscripten::abort_with_message");
println!("{}", message); println!("{}", message);
_abort(ctx); _abort(ctx);
@ -34,19 +34,19 @@ pub fn _endgrent(_ctx: &mut Ctx) {
debug!("emscripten::_endgrent"); 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"); debug!("emscripten::_execve");
-1 -1
} }
#[allow(unreachable_code)] #[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); debug!("emscripten::_exit {}", status);
unsafe { 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); debug!("emscripten::em_abort {}", message);
let message_addr = emscripten_memory_pointer!(ctx.memory(0), message) as *mut c_char; let message_addr = emscripten_memory_pointer!(ctx.memory(0), message) as *mut c_char;
unsafe { unsafe {
@ -54,11 +54,11 @@ pub fn em_abort(message: u32, ctx: &mut Ctx) {
.to_str() .to_str()
.unwrap_or("Unexpected abort"); .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"); debug!("emscripten::_kill");
-1 -1
} }
@ -73,26 +73,26 @@ pub fn _llvm_stacksave(_ctx: &mut Ctx) -> i32 {
-1 -1
} }
pub fn _llvm_stackrestore(_one: i32, _ctx: &mut Ctx) { pub fn _llvm_stackrestore(_ctx: &mut Ctx, _one: i32) {
debug!("emscripten::_llvm_stackrestore"); 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"); debug!("emscripten::_raise");
-1 -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"); debug!("emscripten::_sem_init");
-1 -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"); debug!("emscripten::_sem_post");
-1 -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"); debug!("emscripten::_sem_post");
-1 -1
} }
@ -107,53 +107,53 @@ pub fn _setgrent(_ctx: &mut Ctx) {
debug!("emscripten::_setgrent"); 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"); debug!("emscripten::_setgroups");
-1 -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"); debug!("emscripten::_setitimer");
-1 -1
} }
pub fn _usleep(_one: i32, _ctx: &mut Ctx) -> i32 { pub fn _usleep(_ctx: &mut Ctx, _one: i32) -> i32 {
debug!("emscripten::_usleep"); debug!("emscripten::_usleep");
-1 -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"); debug!("emscripten::_utimes");
-1 -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"); debug!("emscripten::_waitpid");
-1 -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"); debug!("emscripten::abort_stack_overflow");
// TODO: Message incomplete. Need to finish em runtime data first // TODO: Message incomplete. Need to finish em runtime data first
abort_with_message( abort_with_message(
"Stack overflow! Attempted to allocate some bytes on the stack",
ctx, ctx,
"Stack overflow! Attempted to allocate some bytes on the stack",
); );
} }
pub fn _llvm_trap(ctx: &mut Ctx) { pub fn _llvm_trap(ctx: &mut Ctx) {
debug!("emscripten::_llvm_trap"); 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"); debug!("emscripten::_system");
// TODO: May need to change this Em impl to a working version // TODO: May need to change this Em impl to a working version
eprintln!("Can't call external programs"); eprintln!("Can't call external programs");
return EAGAIN; 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"); debug!("emscripten::_popen");
// TODO: May need to change this Em impl to a working version // TODO: May need to change this Em impl to a working version
eprintln!("Missing function: popen"); eprintln!("Missing function: popen");

View File

@ -2,7 +2,7 @@
use wasmer_runtime_core::vm::Ctx; use wasmer_runtime_core::vm::Ctx;
#[allow(clippy::cast_ptr_alignment)] #[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"); debug!("emscripten::_sigemptyset");
let set_addr = emscripten_memory_pointer!(ctx.memory(0), set) as *mut u32; let set_addr = emscripten_memory_pointer!(ctx.memory(0), set) as *mut u32;
unsafe { unsafe {
@ -11,13 +11,13 @@ pub fn _sigemptyset(set: u32, ctx: &mut Ctx) -> i32 {
0 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); debug!("emscripten::_sigaction {}, {}, {}", signum, act, oldact);
0 0
} }
#[allow(clippy::cast_ptr_alignment)] #[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); debug!("emscripten::_sigaddset {}, {}", set, signum);
let set_addr = emscripten_memory_pointer!(ctx.memory(0), set) as *mut u32; let set_addr = emscripten_memory_pointer!(ctx.memory(0), set) as *mut u32;
unsafe { unsafe {
@ -26,17 +26,17 @@ pub fn _sigaddset(set: u32, signum: u32, ctx: &mut Ctx) -> i32 {
0 0
} }
pub fn _sigsuspend(_one: i32, _ctx: &mut Ctx) -> i32 { pub fn _sigsuspend(_ctx: &mut Ctx, _one: i32) -> i32 {
debug!("emscripten::_sigsuspend"); debug!("emscripten::_sigsuspend");
-1 -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"); debug!("emscripten::_sigprocmask");
0 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); debug!("emscripten::_signal ({})", sig);
0 0
} }

View File

@ -52,7 +52,7 @@ use libc::SO_NOSIGPIPE;
const SO_NOSIGPIPE: c_int = 0; const SO_NOSIGPIPE: c_int = 0;
/// exit /// 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); debug!("emscripten::___syscall1 (exit) {}", which);
let status: i32 = varargs.get(ctx); let status: i32 = varargs.get(ctx);
unsafe { unsafe {
@ -61,7 +61,7 @@ pub fn ___syscall1(which: c_int, mut varargs: VarArgs, ctx: &mut Ctx) {
} }
/// read /// 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 // -> ssize_t
debug!("emscripten::___syscall3 (read) {}", which); debug!("emscripten::___syscall3 (read) {}", which);
let fd: i32 = varargs.get(ctx); let fd: i32 = varargs.get(ctx);
@ -75,7 +75,7 @@ pub fn ___syscall3(which: i32, mut varargs: VarArgs, ctx: &mut Ctx) -> i32 {
} }
/// write /// 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); debug!("emscripten::___syscall4 (write) {}", which);
let fd: i32 = varargs.get(ctx); let fd: i32 = varargs.get(ctx);
let buf: u32 = varargs.get(ctx); let buf: u32 = varargs.get(ctx);
@ -86,7 +86,7 @@ pub fn ___syscall4(which: c_int, mut varargs: VarArgs, ctx: &mut Ctx) -> c_int {
} }
/// open /// 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); debug!("emscripten::___syscall5 (open) {}", which);
let pathname: u32 = varargs.get(ctx); let pathname: u32 = varargs.get(ctx);
let flags: i32 = varargs.get(ctx); let flags: i32 = varargs.get(ctx);
@ -102,7 +102,7 @@ pub fn ___syscall5(which: c_int, mut varargs: VarArgs, ctx: &mut Ctx) -> c_int {
} }
/// close /// 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); debug!("emscripten::___syscall6 (close) {}", which);
let fd: i32 = varargs.get(ctx); let fd: i32 = varargs.get(ctx);
debug!("fd: {}", fd); debug!("fd: {}", fd);
@ -110,7 +110,7 @@ pub fn ___syscall6(which: c_int, mut varargs: VarArgs, ctx: &mut Ctx) -> c_int {
} }
// chdir // 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); debug!("emscripten::___syscall12 (chdir) {}", which);
let path_addr: i32 = varargs.get(ctx); let path_addr: i32 = varargs.get(ctx);
unsafe { unsafe {
@ -122,42 +122,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"); debug!("emscripten::___syscall10");
-1 -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"); debug!("emscripten::___syscall15");
-1 -1
} }
// getpid // 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)"); debug!("emscripten::___syscall20 (getpid)");
unsafe { 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"); debug!("emscripten::___syscall38");
-1 -1
} }
// rmdir // 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)"); debug!("emscripten::___syscall40 (rmdir)");
let pathname: u32 = varargs.get(ctx); let pathname: u32 = varargs.get(ctx);
let pathname_addr = emscripten_memory_pointer!(ctx.memory(0), pathname) as *const i8; let pathname_addr = emscripten_memory_pointer!(ctx.memory(0), pathname) as *const i8;
unsafe { rmdir(pathname_addr) } 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"); debug!("emscripten::___syscall60");
-1 -1
} }
// dup2 // 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); debug!("emscripten::___syscall63 (dup2) {}", which);
let src: i32 = varargs.get(ctx); let src: i32 = varargs.get(ctx);
@ -167,43 +167,43 @@ pub fn ___syscall63(which: c_int, mut varargs: VarArgs, ctx: &mut Ctx) -> c_int
} }
// getppid // 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)"); debug!("emscripten::___syscall64 (getppid)");
unsafe { getpid() } 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"); debug!("emscripten::___syscall66");
-1 -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"); debug!("emscripten::___syscall75");
-1 -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"); debug!("emscripten::___syscall85");
-1 -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"); debug!("emscripten::___syscall91");
-1 -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"); debug!("emscripten::___syscall97");
-1 -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"); debug!("emscripten::___syscall110");
-1 -1
} }
// mmap2 // 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); debug!("emscripten::___syscall192 (mmap2) {}", which);
let addr: i32 = varargs.get(ctx); let addr: i32 = varargs.get(ctx);
let len: u32 = varargs.get(ctx); let len: u32 = varargs.get(ctx);
@ -217,11 +217,11 @@ pub fn ___syscall192(which: c_int, mut varargs: VarArgs, ctx: &mut Ctx) -> c_int
); );
if fd == -1 { if fd == -1 {
let ptr = env::call_memalign(16384, len, ctx); let ptr = env::call_memalign(ctx, 16384, len);
if ptr == 0 { if ptr == 0 {
return -1; return -1;
} }
env::call_memset(ptr, 0, len, ctx); env::call_memset(ctx, ptr, 0, len);
ptr as _ ptr as _
} else { } else {
-1 -1
@ -229,7 +229,7 @@ pub fn ___syscall192(which: c_int, mut varargs: VarArgs, ctx: &mut Ctx) -> c_int
} }
/// lseek /// 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 // -> c_int
debug!("emscripten::___syscall140 (lseek) {}", which); debug!("emscripten::___syscall140 (lseek) {}", which);
let fd: i32 = varargs.get(ctx); let fd: i32 = varargs.get(ctx);
@ -241,7 +241,7 @@ pub fn ___syscall140(which: i32, mut varargs: VarArgs, ctx: &mut Ctx) -> i32 {
/// readv /// readv
#[allow(clippy::cast_ptr_alignment)] #[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 // -> ssize_t
debug!("emscripten::___syscall145 (readv) {}", which); debug!("emscripten::___syscall145 (readv) {}", which);
// let fd: i32 = varargs.get(ctx); // let fd: i32 = varargs.get(ctx);
@ -284,7 +284,7 @@ pub fn ___syscall145(which: c_int, mut varargs: VarArgs, ctx: &mut Ctx) -> i32 {
// writev // writev
#[allow(clippy::cast_ptr_alignment)] #[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 // -> ssize_t
debug!("emscripten::___syscall146 (writev) {}", which); debug!("emscripten::___syscall146 (writev) {}", which);
let fd: i32 = varargs.get(ctx); let fd: i32 = varargs.get(ctx);
@ -318,33 +318,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"); debug!("emscripten::___syscall168");
-1 -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"); debug!("emscripten::___syscall191 - stub");
-1 -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"); debug!("emscripten::___syscall194 - stub");
-1 -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"); debug!("emscripten::___syscall194 - stub");
-1 -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"); debug!("emscripten::___syscall199 - stub");
-1 -1
} }
// stat64 // 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); debug!("emscripten::___syscall195 (stat64) {}", which);
let pathname: u32 = varargs.get(ctx); let pathname: u32 = varargs.get(ctx);
let buf: u32 = varargs.get(ctx); let buf: u32 = varargs.get(ctx);
@ -364,7 +364,7 @@ pub fn ___syscall195(which: c_int, mut varargs: VarArgs, ctx: &mut Ctx) -> c_int
} }
// fstat64 // 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); debug!("emscripten::___syscall197 (fstat64) {}", which);
let fd: c_int = varargs.get(ctx); let fd: c_int = varargs.get(ctx);
let buf: u32 = varargs.get(ctx); let buf: u32 = varargs.get(ctx);
@ -382,13 +382,13 @@ pub fn ___syscall197(which: c_int, mut varargs: VarArgs, ctx: &mut Ctx) -> c_int
0 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"); debug!("emscripten::___syscall220");
-1 -1
} }
// fcntl64 // 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); debug!("emscripten::___syscall221 (fcntl64) {}", which);
// fcntl64 // fcntl64
let _fd: i32 = varargs.get(ctx); let _fd: i32 = varargs.get(ctx);
@ -399,33 +399,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"); debug!("emscripten::___syscall268");
-1 -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"); debug!("emscripten::___syscall272");
-1 -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"); debug!("emscripten::___syscall295");
-1 -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"); debug!("emscripten::___syscall300");
-1 -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"); debug!("emscripten::___syscall334");
-1 -1
} }
// prlimit64 // 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); debug!("emscripten::___syscall340 (prlimit64), {}", which);
// NOTE: Doesn't really matter. Wasm modules cannot exceed WASM_PAGE_SIZE anyway. // NOTE: Doesn't really matter. Wasm modules cannot exceed WASM_PAGE_SIZE anyway.
let _pid: i32 = varargs.get(ctx); let _pid: i32 = varargs.get(ctx);

View File

@ -77,7 +77,7 @@ use libc::SO_NOSIGPIPE;
const SO_NOSIGPIPE: c_int = 0; const SO_NOSIGPIPE: c_int = 0;
// chown // 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); debug!("emscripten::___syscall212 (chown) {}", which);
let pathname: u32 = varargs.get(ctx); let pathname: u32 = varargs.get(ctx);
@ -90,7 +90,7 @@ pub fn ___syscall212(which: c_int, mut varargs: VarArgs, ctx: &mut Ctx) -> c_int
} }
// mkdir // 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); debug!("emscripten::___syscall39 (mkdir) {}", which);
let pathname: u32 = varargs.get(ctx); let pathname: u32 = varargs.get(ctx);
let mode: u32 = varargs.get(ctx); let mode: u32 = varargs.get(ctx);
@ -99,7 +99,7 @@ pub fn ___syscall39(which: c_int, mut varargs: VarArgs, ctx: &mut Ctx) -> c_int
} }
// getgid // 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)"); debug!("emscripten::___syscall201 (getgid)");
unsafe { unsafe {
// Maybe fix: Emscripten returns 0 always // Maybe fix: Emscripten returns 0 always
@ -108,7 +108,7 @@ pub fn ___syscall201(_one: i32, _two: i32, _ctx: &mut Ctx) -> i32 {
} }
// getgid32 // 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 // gid_t
debug!("emscripten::___syscall202 (getgid32)"); debug!("emscripten::___syscall202 (getgid32)");
unsafe { unsafe {
@ -118,7 +118,7 @@ pub fn ___syscall202(_one: i32, _two: i32, _ctx: &mut Ctx) -> i32 {
} }
/// dup3 /// 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 // Implementation based on description at https://linux.die.net/man/2/dup3
debug!("emscripten::___syscall330 (dup3)"); debug!("emscripten::___syscall330 (dup3)");
let oldfd: c_int = varargs.get(ctx); let oldfd: c_int = varargs.get(ctx);
@ -152,7 +152,7 @@ pub fn ___syscall330(_which: c_int, mut varargs: VarArgs, ctx: &mut Ctx) -> pid_
} }
/// ioctl /// 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); debug!("emscripten::___syscall54 (ioctl) {}", which);
let fd: i32 = varargs.get(ctx); let fd: i32 = varargs.get(ctx);
let request: u32 = varargs.get(ctx); let request: u32 = varargs.get(ctx);
@ -195,7 +195,7 @@ pub fn ___syscall54(which: c_int, mut varargs: VarArgs, ctx: &mut Ctx) -> c_int
// socketcall // socketcall
#[allow(clippy::cast_ptr_alignment)] #[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); debug!("emscripten::___syscall102 (socketcall) {}", which);
let call: u32 = varargs.get(ctx); let call: u32 = varargs.get(ctx);
let mut socket_varargs: VarArgs = varargs.get(ctx); let mut socket_varargs: VarArgs = varargs.get(ctx);
@ -447,7 +447,7 @@ pub fn ___syscall102(which: c_int, mut varargs: VarArgs, ctx: &mut Ctx) -> c_int
} }
// pread // 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); debug!("emscripten::___syscall180 (pread) {}", which);
let fd: i32 = varargs.get(ctx); let fd: i32 = varargs.get(ctx);
let buf: u32 = varargs.get(ctx); let buf: u32 = varargs.get(ctx);
@ -464,7 +464,7 @@ pub fn ___syscall180(which: c_int, mut varargs: VarArgs, ctx: &mut Ctx) -> c_int
} }
// pwrite // 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); debug!("emscripten::___syscall181 (pwrite) {}", which);
let fd: i32 = varargs.get(ctx); let fd: i32 = varargs.get(ctx);
let buf: u32 = varargs.get(ctx); let buf: u32 = varargs.get(ctx);
@ -486,7 +486,7 @@ pub fn ___syscall181(which: c_int, mut varargs: VarArgs, ctx: &mut Ctx) -> c_int
/// wait4 /// wait4
#[allow(clippy::cast_ptr_alignment)] #[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)"); debug!("emscripten::___syscall114 (wait4)");
let pid: pid_t = varargs.get(ctx); let pid: pid_t = varargs.get(ctx);
let status: u32 = varargs.get(ctx); let status: u32 = varargs.get(ctx);
@ -504,7 +504,7 @@ pub fn ___syscall114(_which: c_int, mut varargs: VarArgs, ctx: &mut Ctx) -> pid_
// select // select
#[allow(clippy::cast_ptr_alignment)] #[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); debug!("emscripten::___syscall142 (newselect) {}", which);
let nfds: i32 = varargs.get(ctx); let nfds: i32 = varargs.get(ctx);
@ -523,7 +523,7 @@ pub fn ___syscall142(which: c_int, mut varargs: VarArgs, ctx: &mut Ctx) -> c_int
} }
// setpgid // 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); debug!("emscripten::___syscall57 (setpgid) {}", which);
let pid: i32 = varargs.get(ctx); let pid: i32 = varargs.get(ctx);
let pgid: i32 = varargs.get(ctx); let pgid: i32 = varargs.get(ctx);
@ -532,7 +532,7 @@ pub fn ___syscall57(which: c_int, mut varargs: VarArgs, ctx: &mut Ctx) -> c_int
/// uname /// uname
// NOTE: Wondering if we should return custom utsname, like Emscripten. // 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); debug!("emscripten::___syscall122 (uname) {}", which);
let buf: u32 = varargs.get(ctx); let buf: u32 = varargs.get(ctx);
debug!("=> buf: {}", buf); debug!("=> buf: {}", buf);

View File

@ -6,13 +6,13 @@ use wasmer_runtime_core::vm::Ctx;
type pid_t = c_int; type pid_t = c_int;
// chown // 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); debug!("emscripten::___syscall212 (chown) {}", which);
-1 -1
} }
// mkdir // 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); debug!("emscripten::___syscall39 (mkdir) {}", which);
let pathname: u32 = varargs.get(ctx); let pathname: u32 = varargs.get(ctx);
let mode: 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 // 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)"); debug!("emscripten::___syscall201 (getgid)");
-1 -1
} }
// getgid32 // 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 // gid_t
debug!("emscripten::___syscall202 (getgid32)"); debug!("emscripten::___syscall202 (getgid32)");
-1 -1
} }
/// dup3 /// 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)"); debug!("emscripten::___syscall330 (dup3)");
-1 -1
} }
/// ioctl /// 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); debug!("emscripten::___syscall54 (ioctl) {}", which);
-1 -1
} }
// socketcall // socketcall
#[allow(clippy::cast_ptr_alignment)] #[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); debug!("emscripten::___syscall102 (socketcall) {}", which);
-1 -1
} }
// pread // 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); debug!("emscripten::___syscall180 (pread) {}", which);
-1 -1
} }
// pwrite // 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); debug!("emscripten::___syscall181 (pwrite) {}", which);
-1 -1
} }
/// wait4 /// wait4
#[allow(clippy::cast_ptr_alignment)] #[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)"); debug!("emscripten::___syscall114 (wait4)");
-1 -1
} }
// select // select
#[allow(clippy::cast_ptr_alignment)] #[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); debug!("emscripten::___syscall142 (newselect) {}", which);
-1 -1
} }
// setpgid // 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); debug!("emscripten::___syscall57 (setpgid) {}", which);
-1 -1
} }
/// uname /// uname
// NOTE: Wondering if we should return custom utsname, like Emscripten. // 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); debug!("emscripten::___syscall122 (uname) {}", which);
-1 -1
} }

View File

@ -41,7 +41,7 @@ const CLOCK_MONOTONIC_COARSE: clockid_t = 6;
/// emscripten: _gettimeofday /// emscripten: _gettimeofday
#[allow(clippy::cast_ptr_alignment)] #[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); debug!("emscripten::_gettimeofday {} {}", tp, tz);
#[repr(C)] #[repr(C)]
struct GuestTimeVal { struct GuestTimeVal {
@ -66,7 +66,7 @@ pub fn _gettimeofday(tp: c_int, tz: c_int, ctx: &mut Ctx) -> c_int {
/// emscripten: _clock_gettime /// emscripten: _clock_gettime
#[allow(clippy::cast_ptr_alignment)] #[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!("emscripten::_clock_gettime {} {}", clk_id, tp);
// debug!("Memory {:?}", ctx.memory(0)[..]); // debug!("Memory {:?}", ctx.memory(0)[..]);
#[repr(C)] #[repr(C)]
@ -97,9 +97,9 @@ pub fn _clock_gettime(clk_id: clockid_t, tp: c_int, ctx: &mut Ctx) -> c_int {
} }
/// emscripten: ___clock_gettime /// 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); debug!("emscripten::___clock_gettime {} {}", clk_id, tp);
_clock_gettime(clk_id, tp, ctx) _clock_gettime(ctx, clk_id, tp)
} }
/// emscripten: _clock /// emscripten: _clock
@ -109,22 +109,22 @@ pub fn _clock(_ctx: &mut Ctx) -> c_int {
} }
/// emscripten: _difftime /// 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"); debug!("emscripten::_difftime");
(t0 - t1) as _ (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"); debug!("emscripten::_gmtime_r");
-1 -1
} }
pub fn _mktime(_one: i32, _ctx: &mut Ctx) -> i32 { pub fn _mktime(_ctx: &mut Ctx, _one: i32) -> i32 {
debug!("emscripten::_mktime"); debug!("emscripten::_mktime");
-1 -1
} }
pub fn _gmtime(_one: i32, _ctx: &mut Ctx) -> i32 { pub fn _gmtime(_ctx: &mut Ctx, _one: i32) -> i32 {
debug!("emscripten::_gmtime"); debug!("emscripten::_gmtime");
-1 -1
} }
@ -151,7 +151,7 @@ pub fn _tvset(_ctx: &mut Ctx) {
/// formats time as a C string /// formats time as a C string
#[allow(clippy::cast_ptr_alignment)] #[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 date = &*(emscripten_memory_pointer!(ctx.memory(0), time) as *mut guest_tm);
let days = vec!["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"]; let days = vec!["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];
@ -176,11 +176,11 @@ unsafe fn fmt_time(time: u32, ctx: &mut Ctx) -> *const c_char {
} }
/// emscripten: _asctime /// emscripten: _asctime
pub fn _asctime(time: u32, ctx: &mut Ctx) -> u32 { pub fn _asctime(ctx: &mut Ctx, time: u32) -> u32 {
debug!("emscripten::_asctime {}", time); debug!("emscripten::_asctime {}", time);
unsafe { 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) copy_cstr_into_wasm(ctx, time_str_ptr)
// let c_str = emscripten_memory_pointer!(ctx.memory(0), res) as *mut i8; // let c_str = emscripten_memory_pointer!(ctx.memory(0), res) as *mut i8;
@ -190,7 +190,7 @@ pub fn _asctime(time: u32, ctx: &mut Ctx) -> u32 {
} }
/// emscripten: _asctime_r /// 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); debug!("emscripten::_asctime_r {}, {}", time, buf);
unsafe { unsafe {
@ -198,8 +198,8 @@ pub fn _asctime_r(time: u32, buf: u32, ctx: &mut Ctx) -> u32 {
// to write out more than 26 bytes (including the null terminator). // to write out more than 26 bytes (including the null terminator).
// See http://pubs.opengroup.org/onlinepubs/9699919799/functions/asctime.html // 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. // Our undefined behavior is to truncate the write to at most 26 bytes, including null terminator.
let time_str_ptr = fmt_time(time, ctx); let time_str_ptr = fmt_time(ctx, time);
write_to_buf(time_str_ptr, buf, 26, ctx) write_to_buf(ctx, time_str_ptr, buf, 26)
// let c_str = emscripten_memory_pointer!(ctx.memory(0), res) as *mut i8; // let c_str = emscripten_memory_pointer!(ctx.memory(0), res) as *mut i8;
// use std::ffi::CStr; // use std::ffi::CStr;
@ -209,7 +209,7 @@ pub fn _asctime_r(time: u32, buf: u32, ctx: &mut Ctx) -> u32 {
/// emscripten: _localtime /// emscripten: _localtime
#[allow(clippy::cast_ptr_alignment)] #[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); debug!("emscripten::_localtime {}", time_p);
// NOTE: emscripten seems to want tzset() called in this function // 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 // https://stackoverflow.com/questions/19170721/real-time-awareness-of-timezone-change-in-localtime-vs-localtime-r
@ -222,7 +222,7 @@ pub fn _localtime(time_p: u32, ctx: &mut Ctx) -> c_int {
let result_tm = time::at(timespec); let result_tm = time::at(timespec);
unsafe { unsafe {
let tm_struct_offset = env::call_malloc(mem::size_of::<guest_tm>() as _, ctx); let tm_struct_offset = env::call_malloc(ctx, mem::size_of::<guest_tm>() as _);
let tm_struct_ptr = let tm_struct_ptr =
emscripten_memory_pointer!(ctx.memory(0), tm_struct_offset) as *mut guest_tm; emscripten_memory_pointer!(ctx.memory(0), tm_struct_offset) as *mut guest_tm;
// debug!( // debug!(
@ -247,7 +247,7 @@ pub fn _localtime(time_p: u32, ctx: &mut Ctx) -> c_int {
} }
/// emscripten: _localtime_r /// emscripten: _localtime_r
#[allow(clippy::cast_ptr_alignment)] #[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); debug!("emscripten::_localtime_r {}", time_p);
// NOTE: emscripten seems to want tzset() called in this function // NOTE: emscripten seems to want tzset() called in this function
@ -284,7 +284,7 @@ pub fn _localtime_r(time_p: u32, result: u32, ctx: &mut Ctx) -> c_int {
/// emscripten: _time /// emscripten: _time
#[allow(clippy::cast_ptr_alignment)] #[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); debug!("emscripten::_time {}", time_p);
unsafe { unsafe {
@ -295,11 +295,11 @@ pub fn _time(time_p: u32, ctx: &mut Ctx) -> i32 {
/// emscripten: _strftime /// emscripten: _strftime
pub fn _strftime( pub fn _strftime(
_ctx: &mut Ctx,
s_ptr: c_int, s_ptr: c_int,
maxsize: u32, maxsize: u32,
format_ptr: c_int, format_ptr: c_int,
tm_ptr: c_int, tm_ptr: c_int,
_ctx: &mut Ctx,
) -> i32 { ) -> i32 {
debug!( debug!(
"emscripten::_strftime {} {} {} {}", "emscripten::_strftime {} {} {} {}",

View File

@ -40,7 +40,7 @@ pub fn get_emscripten_memory_size(module: &Module) -> (Pages, Option<Pages>) {
(memory.minimum, memory.maximum) (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; let buf_addr = emscripten_memory_pointer!(ctx.memory(0), buf) as *mut c_char;
for i in 0..max { for i in 0..max {
@ -54,7 +54,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 { 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 s = CStr::from_ptr(cstr).to_str().unwrap();
let cstr_len = s.len(); 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 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); let slice = slice::from_raw_parts_mut(raw_memory, cstr_len);
@ -69,7 +69,7 @@ pub unsafe fn copy_cstr_into_wasm(ctx: &mut Ctx, cstr: *const c_char) -> u32 {
space_offset 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) let offset = get_emscripten_data(ctx)
.stack_alloc .stack_alloc
.call(count * (size_of::<T>() as u32)) .call(count * (size_of::<T>() as u32))
@ -80,8 +80,8 @@ pub unsafe fn allocate_on_stack<'a, T: Copy>(count: u32, ctx: &'a mut Ctx) -> (u
(offset, slice) (offset, slice)
} }
pub unsafe fn allocate_cstr_on_stack<'a>(s: &str, ctx: &'a mut Ctx) -> (u32, &'a [u8]) { pub unsafe fn allocate_cstr_on_stack<'a>(ctx: &'a mut Ctx, s: &str) -> (u32, &'a [u8]) {
let (offset, slice) = allocate_on_stack((s.len() + 1) as u32, ctx); let (offset, slice) = allocate_on_stack(ctx, (s.len() + 1) as u32);
use std::iter; use std::iter;
for (byte, loc) in s.bytes().chain(iter::once(0)).zip(slice.iter_mut()) { for (byte, loc) in s.bytes().chain(iter::once(0)).zip(slice.iter_mut()) {

View File

@ -1,8 +1,7 @@
use crate::types::{ use crate::types::{
FuncSig, GlobalDescriptor, MemoryDescriptor, MemoryIndex, TableDescriptor, TableIndex, Type, FuncSig, GlobalDescriptor, MemoryDescriptor, MemoryIndex, TableDescriptor, TableIndex, Type,
}; };
use std::error::Error as StdError; use core::borrow::Borrow;
use std::fmt;
use std::sync::Arc; use std::sync::Arc;
pub type Result<T> = std::result::Result<T, Error>; pub type Result<T> = std::result::Result<T, Error>;
@ -29,6 +28,19 @@ impl PartialEq for CompileError {
} }
} }
impl std::fmt::Display for CompileError {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
match self {
CompileError::InternalError { msg } => {
write!(f, "Internal compiler error: \"{}\"", msg)
}
CompileError::ValidationError { msg } => write!(f, "Validation error \"{}\"", msg),
}
}
}
impl std::error::Error for CompileError {}
/// This is returned when the runtime is unable to /// This is returned when the runtime is unable to
/// correctly link the module with the provided imports. /// correctly link the module with the provided imports.
/// ///
@ -77,6 +89,31 @@ impl PartialEq for LinkError {
} }
} }
impl std::fmt::Display for LinkError {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
match self {
LinkError::ImportNotFound {namespace, name} => write!(f, "Import not found, namespace: {}, name: {}", namespace, name),
LinkError::IncorrectGlobalDescriptor {namespace, name,expected,found} => {
write!(f, "Incorrect global descriptor, namespace: {}, name: {}, expected global descriptor: {:?}, found global descriptor: {:?}", namespace, name, expected, found)
},
LinkError::IncorrectImportSignature{namespace, name,expected,found} => {
write!(f, "Incorrect import signature, namespace: {}, name: {}, expected signature: {}, found signature: {}", namespace, name, expected, found)
}
LinkError::IncorrectImportType{namespace, name,expected,found} => {
write!(f, "Incorrect import type, namespace: {}, name: {}, expected type: {}, found type: {}", namespace, name, expected, found)
}
LinkError::IncorrectMemoryDescriptor{namespace, name,expected,found} => {
write!(f, "Incorrect memory descriptor, namespace: {}, name: {}, expected memory descriptor: {:?}, found memory descriptor: {:?}", namespace, name, expected, found)
},
LinkError::IncorrectTableDescriptor{namespace, name,expected,found} => {
write!(f, "Incorrect table descriptor, namespace: {}, name: {}, expected table descriptor: {:?}, found table descriptor: {:?}", namespace, name, expected, found)
},
}
}
}
impl std::error::Error for LinkError {}
/// This is the error type returned when calling /// This is the error type returned when calling
/// a webassembly function. /// a webassembly function.
/// ///
@ -113,6 +150,39 @@ impl PartialEq for RuntimeError {
} }
} }
impl std::fmt::Display for RuntimeError {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
match self {
RuntimeError::IndirectCallSignature { table } => write!(
f,
"Indirect call signature error with Table Index \"{:?}\"",
table
),
RuntimeError::IndirectCallToNull { table } => {
write!(f, "Indirect call to null with table index \"{:?}\"", table)
}
RuntimeError::IllegalArithmeticOperation => write!(f, "Illegal arithmetic operation"),
RuntimeError::OutOfBoundsAccess { memory, addr } => match addr {
Some(addr) => write!(
f,
"Out-of-bounds access with memory index {:?} and address {}",
memory, addr
),
None => write!(f, "Out-of-bounds access with memory index {:?}", memory),
},
RuntimeError::TableOutOfBounds { table } => {
write!(f, "Table out of bounds with table index \"{:?}\"", table)
}
RuntimeError::Unknown { msg } => {
write!(f, "Unknown runtime error with message: \"{}\"", msg)
}
RuntimeError::User { msg } => write!(f, "User runtime error with message: \"{}\"", msg),
}
}
}
impl std::error::Error for RuntimeError {}
/// This error type is produced by resolving a wasm function /// This error type is produced by resolving a wasm function
/// given its name. /// given its name.
/// ///
@ -137,6 +207,31 @@ impl PartialEq for ResolveError {
} }
} }
impl std::fmt::Display for ResolveError {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
match self {
ResolveError::ExportNotFound { name } => write!(f, "Export not found: {}", name),
ResolveError::ExportWrongType { name } => write!(f, "Export wrong type: {}", name),
ResolveError::Signature { expected, found } => {
let found = found
.as_slice()
.iter()
.map(|p| p.to_string())
.collect::<Vec<_>>()
.join(", ");
let expected: &FuncSig = expected.borrow();
write!(
f,
"Parameters of type [{}] did not match signature {}",
found, expected
)
}
}
}
}
impl std::error::Error for ResolveError {}
/// This error type is produced by calling a wasm function /// This error type is produced by calling a wasm function
/// exported from a module. /// exported from a module.
/// ///
@ -156,20 +251,22 @@ impl PartialEq for CallError {
} }
} }
impl fmt::Display for CallError { impl std::fmt::Display for CallError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
write!(f, "Call error") match self {
CallError::Resolve(resolve_error) => write!(f, "Call error: {}", resolve_error),
CallError::Runtime(runtime_error) => write!(f, "Call error: {}", runtime_error),
}
} }
} }
impl StdError for CallError {}
/// This error type is produced when creating something, /// This error type is produced when creating something,
/// like a `Memory` or a `Table`. /// like a `Memory` or a `Table`.
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub enum CreationError { pub enum CreationError {
UnableToCreateMemory, UnableToCreateMemory,
UnableToCreateTable, UnableToCreateTable,
InvalidDescriptor(String),
} }
impl PartialEq for CreationError { impl PartialEq for CreationError {
@ -178,13 +275,21 @@ impl PartialEq for CreationError {
} }
} }
impl fmt::Display for CreationError { impl std::fmt::Display for CreationError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
write!(f, "Creation error") match self {
CreationError::UnableToCreateMemory => write!(f, "Unable to Create Memory"),
CreationError::UnableToCreateTable => write!(f, "Unable to Create Table"),
CreationError::InvalidDescriptor(msg) => write!(
f,
"Unable to create because the supplied descriptor is invalid: \"{}\"",
msg
),
}
} }
} }
impl StdError for CreationError {} impl std::error::Error for CreationError {}
/// The amalgamation of all errors that can occur /// The amalgamation of all errors that can occur
/// during the compilation, instantiation, or execution /// during the compilation, instantiation, or execution
@ -254,3 +359,11 @@ impl From<ResolveError> for CallError {
CallError::Resolve(resolve_err) CallError::Resolve(resolve_err)
} }
} }
impl std::fmt::Display for Error {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
write!(f, "{}", self)
}
}
impl std::error::Error for Error {}

View File

@ -32,7 +32,7 @@ impl IsExport for Export {
/// }, /// },
/// }; /// };
/// ///
/// fn foo(n: i32, _: &mut Ctx) -> i32 { /// fn foo(_: &mut Ctx, n: i32) -> i32 {
/// n /// n
/// } /// }
/// ``` /// ```

View File

@ -38,7 +38,7 @@ macro_rules! func {
/// }, /// },
/// }; /// };
/// ///
/// fn foo(n: i32, _: &mut Ctx) -> i32 { /// fn foo(_: &mut Ctx, n: i32) -> i32 {
/// n /// n
/// } /// }
/// ``` /// ```

View File

@ -63,6 +63,15 @@ impl Memory {
/// # } /// # }
/// ``` /// ```
pub fn new(desc: MemoryDescriptor) -> Result<Self, CreationError> { pub fn new(desc: MemoryDescriptor) -> Result<Self, CreationError> {
if let Some(max) = desc.maximum {
if max < desc.minimum {
return Err(CreationError::InvalidDescriptor(
"Max number of memory pages is less than the minimum number of pages"
.to_string(),
));
}
}
let variant = if !desc.shared { let variant = if !desc.shared {
MemoryVariant::Unshared(UnsharedMemory::new(desc)?) MemoryVariant::Unshared(UnsharedMemory::new(desc)?)
} else { } else {

View File

@ -150,7 +150,8 @@ impl Drop for Memory {
fn drop(&mut self) { fn drop(&mut self) {
if !self.ptr.is_null() { if !self.ptr.is_null() {
let success = unsafe { VirtualFree(self.ptr as _, self.size, MEM_DECOMMIT) }; 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());
} }
} }
} }

View File

@ -50,6 +50,14 @@ impl Table {
/// # } /// # }
/// ``` /// ```
pub fn new(desc: TableDescriptor) -> Result<Self, CreationError> { pub fn new(desc: TableDescriptor) -> Result<Self, CreationError> {
if let Some(max) = desc.maximum {
if max < desc.minimum {
return Err(CreationError::InvalidDescriptor(
"Max table size is less than the minimum size".to_string(),
));
}
}
let mut local = vm::LocalTable { let mut local = vm::LocalTable {
base: ptr::null_mut(), base: ptr::null_mut(),
count: 0, count: 0,

View File

@ -138,9 +138,9 @@ impl<A: WasmExternType> WasmTypeList for (A,) {
} }
#[allow(non_snake_case)] #[allow(non_snake_case)]
unsafe fn call<Rets: WasmTypeList>(self, f: *const (), ctx: *mut Ctx) -> Rets { unsafe fn call<Rets: WasmTypeList>(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; let (a,) = self;
f(a, ctx) f(ctx, a)
} }
} }
@ -154,8 +154,8 @@ where
} }
macro_rules! impl_traits { macro_rules! impl_traits {
( $struct_name:ident, $( $x:ident ),* ) => { ( [$repr:ident] $struct_name:ident, $( $x:ident ),* ) => {
#[repr(C)] #[repr($repr)]
pub struct $struct_name <$( $x ),*> ( $( $x ),* ); pub struct $struct_name <$( $x ),*> ( $( $x ),* );
impl< $( $x: WasmExternType, )* > WasmTypeList for ( $( $x ),* ) { impl< $( $x: WasmExternType, )* > WasmTypeList for ( $( $x ),* ) {
@ -175,24 +175,24 @@ macro_rules! impl_traits {
} }
#[allow(non_snake_case)] #[allow(non_snake_case)]
unsafe fn call<Rets: WasmTypeList>(self, f: *const (), ctx: *mut Ctx) -> Rets { unsafe fn call<Rets: WasmTypeList>(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)] #[allow(unused_parens)]
let ( $( $x ),* ) = self; let ( $( $x ),* ) = self;
let c_struct = f( $( $x, )* ctx); let c_struct = f(ctx $( ,$x )*);
Rets::from_c_struct(c_struct) Rets::from_c_struct(c_struct)
} }
} }
impl< $( $x: WasmExternType, )* Rets: WasmTypeList, Trap: TrapEarly<Rets>, FN: Fn( $( $x, )* &mut Ctx) -> Trap> ExternalFunction<($( $x ),*), Rets> for FN { impl< $( $x: WasmExternType, )* Rets: WasmTypeList, Trap: TrapEarly<Rets>, FN: Fn( &mut Ctx $( ,$x )* ) -> Trap> ExternalFunction<($( $x ),*), Rets> for FN {
#[allow(non_snake_case)] #[allow(non_snake_case)]
fn to_raw(&self) -> *const () { fn to_raw(&self) -> *const () {
assert_eq!(mem::size_of::<Self>(), 0, "you cannot use a closure that captures state for `Func`."); assert_eq!(mem::size_of::<Self>(), 0, "you cannot use a closure that captures state for `Func`.");
extern fn wrap<$( $x: WasmExternType, )* Rets: WasmTypeList, Trap: TrapEarly<Rets>, FN: Fn( $( $x, )* &mut Ctx) -> Trap>( $( $x: $x, )* ctx: &mut Ctx) -> Rets::CStruct { extern fn wrap<$( $x: WasmExternType, )* Rets: WasmTypeList, Trap: TrapEarly<Rets>, FN: Fn( &mut Ctx $( ,$x )* ) -> Trap>( ctx: &mut Ctx $( ,$x: $x )* ) -> Rets::CStruct {
let f: FN = unsafe { mem::transmute_copy(&()) }; let f: FN = unsafe { mem::transmute_copy(&()) };
let msg = match panic::catch_unwind(panic::AssertUnwindSafe(|| { 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(Ok(returns)) => return returns.into_c_struct(),
Ok(Err(err)) => err, Ok(Err(err)) => err,
@ -234,18 +234,18 @@ macro_rules! impl_traits {
}; };
} }
impl_traits!(S0,); impl_traits!([C] S0,);
impl_traits!(S1, A); impl_traits!([transparent] S1, A);
impl_traits!(S2, A, B); impl_traits!([C] S2, A, B);
impl_traits!(S3, A, B, C); impl_traits!([C] S3, A, B, C);
impl_traits!(S4, A, B, C, D); impl_traits!([C] S4, A, B, C, D);
impl_traits!(S5, A, B, C, D, E); impl_traits!([C] S5, A, B, C, D, E);
impl_traits!(S6, A, B, C, D, E, F); impl_traits!([C] S6, A, B, C, D, E, F);
impl_traits!(S7, A, B, C, D, E, F, G); impl_traits!([C] S7, A, B, C, D, E, F, G);
impl_traits!(S8, A, B, C, D, E, F, G, H); impl_traits!([C] S8, A, B, C, D, E, F, G, H);
impl_traits!(S9, A, B, C, D, E, F, G, H, I); impl_traits!([C] S9, A, B, C, D, E, F, G, H, I);
impl_traits!(S10, A, B, C, D, E, F, G, H, I, J); impl_traits!([C] S10, A, B, C, D, E, F, G, H, I, J);
impl_traits!(S11, A, B, C, D, E, F, G, H, I, J, K); impl_traits!([C] S11, A, B, C, D, E, F, G, H, I, J, K);
impl<'a, Args, Rets, Safety> IsExport for Func<'a, Args, Rets, Safety> impl<'a, Args, Rets, Safety> IsExport for Func<'a, Args, Rets, Safety>
where where
@ -271,7 +271,7 @@ mod tests {
use super::*; use super::*;
#[test] #[test]
fn test_call() { 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) (a, b)
} }
@ -282,7 +282,7 @@ mod tests {
fn test_imports() { fn test_imports() {
use crate::{func, imports}; use crate::{func, imports};
fn foo(a: i32, _ctx: &mut Ctx) -> i32 { fn foo(_ctx: &mut Ctx, a: i32) -> i32 {
a a
} }

View File

@ -15,6 +15,12 @@ pub enum Type {
F64, F64,
} }
impl std::fmt::Display for Type {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
write!(f, "{:?}", self)
}
}
/// Represents a WebAssembly value. /// Represents a WebAssembly value.
/// ///
/// As the number of types in WebAssembly expand, /// As the number of types in WebAssembly expand,
@ -292,6 +298,24 @@ impl FuncSig {
} }
} }
impl std::fmt::Display for FuncSig {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
let params = self
.params
.iter()
.map(|p| p.to_string())
.collect::<Vec<_>>()
.join(", ");
let returns = self
.returns
.iter()
.map(|p| p.to_string())
.collect::<Vec<_>>()
.join(", ");
write!(f, "[{}] -> [{}]", params, returns)
}
}
pub trait LocalImport { pub trait LocalImport {
type Local: TypedIndex; type Local: TypedIndex;
type Import: TypedIndex; type Import: TypedIndex;

View File

@ -169,6 +169,7 @@ enum InnerFunc {}
/// Used to provide type safety (ish) for passing around function pointers. /// Used to provide type safety (ish) for passing around function pointers.
/// The typesystem ensures this cannot be dereferenced since an /// The typesystem ensures this cannot be dereferenced since an
/// empty enum cannot actually exist. /// empty enum cannot actually exist.
#[repr(C)]
pub struct Func(InnerFunc); pub struct Func(InnerFunc);
/// An imported function, which contains the vmctx that owns this function. /// An imported function, which contains the vmctx that owns this function.

View File

@ -13,9 +13,9 @@ use crate::{
// +****************************+ // +****************************+
pub unsafe extern "C" fn local_static_memory_grow( pub unsafe extern "C" fn local_static_memory_grow(
ctx: &mut vm::Ctx,
memory_index: LocalMemoryIndex, memory_index: LocalMemoryIndex,
delta: Pages, delta: Pages,
ctx: &mut vm::Ctx,
) -> i32 { ) -> i32 {
let local_memory = *ctx.memories.add(memory_index.index()); let local_memory = *ctx.memories.add(memory_index.index());
let memory = (*local_memory).memory as *mut StaticMemory; 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( pub unsafe extern "C" fn local_static_memory_size(
memory_index: LocalMemoryIndex,
ctx: &vm::Ctx, ctx: &vm::Ctx,
memory_index: LocalMemoryIndex,
) -> Pages { ) -> Pages {
let local_memory = *ctx.memories.add(memory_index.index()); let local_memory = *ctx.memories.add(memory_index.index());
let memory = (*local_memory).memory as *mut StaticMemory; 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( pub unsafe extern "C" fn local_dynamic_memory_grow(
ctx: &mut vm::Ctx,
memory_index: LocalMemoryIndex, memory_index: LocalMemoryIndex,
delta: Pages, delta: Pages,
ctx: &mut vm::Ctx,
) -> i32 { ) -> i32 {
let local_memory = *ctx.memories.add(memory_index.index()); let local_memory = *ctx.memories.add(memory_index.index());
let memory = (*local_memory).memory as *mut DynamicMemory; 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( pub unsafe extern "C" fn local_dynamic_memory_size(
memory_index: LocalMemoryIndex,
ctx: &vm::Ctx, ctx: &vm::Ctx,
memory_index: LocalMemoryIndex,
) -> Pages { ) -> Pages {
let local_memory = *ctx.memories.add(memory_index.index()); let local_memory = *ctx.memories.add(memory_index.index());
let memory = (*local_memory).memory as *mut DynamicMemory; 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( pub unsafe extern "C" fn imported_static_memory_grow(
ctx: &mut vm::Ctx,
import_memory_index: ImportedMemoryIndex, import_memory_index: ImportedMemoryIndex,
delta: Pages, delta: Pages,
ctx: &mut vm::Ctx,
) -> i32 { ) -> i32 {
let local_memory = *ctx.imported_memories.add(import_memory_index.index()); let local_memory = *ctx.imported_memories.add(import_memory_index.index());
let memory = (*local_memory).memory as *mut StaticMemory; 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( pub unsafe extern "C" fn imported_static_memory_size(
import_memory_index: ImportedMemoryIndex,
ctx: &vm::Ctx, ctx: &vm::Ctx,
import_memory_index: ImportedMemoryIndex,
) -> Pages { ) -> Pages {
let local_memory = *ctx.imported_memories.add(import_memory_index.index()); let local_memory = *ctx.imported_memories.add(import_memory_index.index());
let memory = (*local_memory).memory as *mut StaticMemory; 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( pub unsafe extern "C" fn imported_dynamic_memory_grow(
ctx: &mut vm::Ctx,
memory_index: ImportedMemoryIndex, memory_index: ImportedMemoryIndex,
delta: Pages, delta: Pages,
ctx: &mut vm::Ctx,
) -> i32 { ) -> i32 {
let local_memory = *ctx.imported_memories.add(memory_index.index()); let local_memory = *ctx.imported_memories.add(memory_index.index());
let memory = (*local_memory).memory as *mut DynamicMemory; 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( pub unsafe extern "C" fn imported_dynamic_memory_size(
memory_index: ImportedMemoryIndex,
ctx: &vm::Ctx, ctx: &vm::Ctx,
memory_index: ImportedMemoryIndex,
) -> Pages { ) -> Pages {
let local_memory = *ctx.imported_memories.add(memory_index.index()); let local_memory = *ctx.imported_memories.add(memory_index.index());
let memory = (*local_memory).memory as *mut DynamicMemory; 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( pub unsafe extern "C" fn local_table_grow(
ctx: &mut vm::Ctx,
table_index: LocalTableIndex, table_index: LocalTableIndex,
delta: u32, delta: u32,
ctx: &mut vm::Ctx,
) -> i32 { ) -> i32 {
let _ = table_index; let _ = table_index;
let _ = delta; let _ = delta;
@ -131,7 +131,7 @@ pub unsafe extern "C" fn local_table_grow(
unimplemented!() 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 _ = table_index;
let _ = ctx; let _ = ctx;
unimplemented!() unimplemented!()

View File

@ -1,8 +1,6 @@
use std::fs::remove_file;
use wabt::wat2wasm; use wabt::wat2wasm;
use wasmer_clif_backend::CraneliftCompiler; use wasmer_clif_backend::CraneliftCompiler;
use wasmer_runtime_core::{ use wasmer_runtime_core::{
cache::Cache,
error, error,
global::Global, global::Global,
memory::Memory, memory::Memory,
@ -15,7 +13,6 @@ use wasmer_runtime_core::{
static EXAMPLE_WASM: &'static [u8] = include_bytes!("simple.wasm"); static EXAMPLE_WASM: &'static [u8] = include_bytes!("simple.wasm");
fn main() -> error::Result<()> { fn main() -> error::Result<()> {
let compiler = CraneliftCompiler::new();
let wasm_binary = wat2wasm(IMPORT_MODULE.as_bytes()).expect("WAST not valid or malformed"); 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())?; let inner_module = wasmer_runtime_core::compile_with(&wasm_binary, &CraneliftCompiler::new())?;
@ -61,7 +58,7 @@ fn main() -> error::Result<()> {
Ok(()) Ok(())
} }
fn print_num(n: i32, ctx: &mut vm::Ctx) -> Result<i32, ()> { fn print_num(ctx: &mut vm::Ctx, n: i32) -> Result<i32, ()> {
println!("print_num({})", n); println!("print_num({})", n);
let memory: &Memory = ctx.memory(0); let memory: &Memory = ctx.memory(0);

View File

@ -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 <engineering@wasmer.io>"]
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"

View File

@ -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);
}
}

View File

@ -0,0 +1 @@
cmake-build-*

View File

@ -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 .)

View File

@ -0,0 +1,74 @@
#include <windows.h>
#include <setjmp.h>
#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;
}

View File

@ -0,0 +1,25 @@
#ifndef WASMER_EXCEPTION_HANDLING_H
#define WASMER_EXCEPTION_HANDLING_H
#include <stdint.h>
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

View File

@ -0,0 +1,53 @@
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,
)
};
if result == 1 {
Ok(())
} else {
Err(out_result)
}
}

View File

@ -0,0 +1,5 @@
#[cfg(windows)]
mod exception_handling;
#[cfg(windows)]
pub use self::exception_handling::*;

View File

@ -69,7 +69,7 @@ fn execute_wasm(options: &Run) -> Result<(), String> {
let module = webassembly::compile(&wasm_binary[..]) let module = webassembly::compile(&wasm_binary[..])
.map_err(|e| format!("Can't compile module: {:?}", e))?; .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); let mut emscripten_globals = wasmer_emscripten::EmscriptenGlobals::new(&module);
( (
InstanceABI::Emscripten, InstanceABI::Emscripten,
@ -113,6 +113,11 @@ fn main() {
let options = CLIOptions::from_args(); let options = CLIOptions::from_args();
match options { match options {
CLIOptions::Run(options) => run(options), CLIOptions::Run(options) => run(options),
#[cfg(not(target_os = "windows"))]
CLIOptions::SelfUpdate => update::self_update(), 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");
}
} }
} }