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}"
os: Visual Studio 2017
# Do not build feature branch with open Pull Requests
skip_branch_with_pr: true
environment:
matrix:
- CHANNEL: stable
@ -20,13 +19,29 @@ install:
- rustc -vV
- cargo -vV
artifacts:
- path: target\debug\wasmer.exe
name: wasmer.exe
build_script:
- cargo build --verbose
test_script:
- 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]]
name = "ansi_term"
version = "0.11.0"
@ -21,6 +31,49 @@ name = "autocfg"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "backtrace"
version = "0.3.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"autocfg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"backtrace-sys 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)",
"cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc-demangle 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "backtrace-sys"
version = "0.1.28"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cc 1.0.28 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "bindgen"
version = "0.46.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
"cexpr 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
"cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
"clang-sys 0.26.4 (registry+https://github.com/rust-lang/crates.io-index)",
"clap 2.32.0 (registry+https://github.com/rust-lang/crates.io-index)",
"env_logger 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
"hashbrown 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
"peeking_take_while 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"proc-macro2 0.4.26 (registry+https://github.com/rust-lang/crates.io-index)",
"quote 0.6.11 (registry+https://github.com/rust-lang/crates.io-index)",
"regex 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"which 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "bitflags"
version = "1.0.4"
@ -80,11 +133,29 @@ name = "cc"
version = "1.0.28"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "cexpr"
version = "0.3.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"nom 4.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "cfg-if"
version = "0.1.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "clang-sys"
version = "0.26.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)",
"libloading 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "clap"
version = "2.32.0"
@ -193,6 +264,18 @@ dependencies = [
"generic-array 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "env_logger"
version = "0.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
"humantime 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
"regex 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"termcolor 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "errno"
version = "0.2.4"
@ -217,6 +300,7 @@ name = "failure"
version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"backtrace 0.3.13 (registry+https://github.com/rust-lang/crates.io-index)",
"failure_derive 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
]
@ -291,6 +375,14 @@ dependencies = [
"unicode-segmentation 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "humantime"
version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"quick-error 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "indexmap"
version = "1.0.2"
@ -325,6 +417,15 @@ name = "libc"
version = "0.2.48"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "libloading"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cc 1.0.28 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "lock_api"
version = "0.1.5"
@ -342,6 +443,11 @@ dependencies = [
"cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "memchr"
version = "2.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "memmap"
version = "0.7.0"
@ -375,6 +481,15 @@ dependencies = [
"void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "nom"
version = "4.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"memchr 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "opaque-debug"
version = "0.2.2"
@ -419,6 +534,11 @@ dependencies = [
"winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "peeking_take_while"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "proc-macro2"
version = "0.3.8"
@ -435,6 +555,11 @@ dependencies = [
"unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "quick-error"
version = "1.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "quote"
version = "0.5.2"
@ -578,6 +703,26 @@ dependencies = [
"redox_syscall 0.1.51 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "regex"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"aho-corasick 0.6.9 (registry+https://github.com/rust-lang/crates.io-index)",
"memchr 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"regex-syntax 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
"thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
"utf8-ranges 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "regex-syntax"
version = "0.6.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"ucd-util 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "remove_dir_all"
version = "0.5.1"
@ -586,6 +731,11 @@ dependencies = [
"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]]
name = "rustc_version"
version = "0.2.3"
@ -765,6 +915,14 @@ dependencies = [
"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]]
name = "termion"
version = "1.5.1"
@ -783,6 +941,14 @@ dependencies = [
"unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "thread_local"
version = "0.3.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "time"
version = "0.1.42"
@ -806,6 +972,11 @@ name = "typenum"
version = "1.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "ucd-util"
version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "unicode-segmentation"
version = "1.2.1"
@ -829,11 +1000,21 @@ dependencies = [
"void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "utf8-ranges"
version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "vec_map"
version = "0.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "version_check"
version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "void"
version = "1.0.2"
@ -891,7 +1072,9 @@ dependencies = [
"serde_derive 1.0.58 (registry+https://github.com/rust-lang/crates.io-index)",
"target-lexicon 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"wasmer-runtime-core 0.1.2",
"wasmer-win-exception-handler 0.0.1",
"wasmparser 0.23.0 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@ -959,6 +1142,18 @@ dependencies = [
"wasmer-runtime-core 0.1.2",
]
[[package]]
name = "wasmer-win-exception-handler"
version = "0.0.1"
dependencies = [
"bindgen 0.46.0 (registry+https://github.com/rust-lang/crates.io-index)",
"cmake 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)",
"regex 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"wasmer-runtime-core 0.1.2",
"winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "wasmparser"
version = "0.22.1"
@ -969,6 +1164,15 @@ name = "wasmparser"
version = "0.23.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "which"
version = "2.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "winapi"
version = "0.2.8"
@ -993,15 +1197,36 @@ name = "winapi-i686-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "winapi-util"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "winapi-x86_64-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "wincolor"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi-util 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
[metadata]
"checksum aho-corasick 0.6.9 (registry+https://github.com/rust-lang/crates.io-index)" = "1e9a933f4e58658d7b12defcf96dc5c720f20832deebe3e0a19efd3b6aaeeb9e"
"checksum ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b"
"checksum atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "9a7d5b8723950951411ee34d271d99dddcc2035a16ab25310ea2c8cfd4369652"
"checksum autocfg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a6d640bee2da49f60a4068a7fae53acde8982514ab7bae8b8cea9e88cbcfd799"
"checksum backtrace 0.3.13 (registry+https://github.com/rust-lang/crates.io-index)" = "b5b493b66e03090ebc4343eb02f94ff944e0cbc9ac6571491d170ba026741eb5"
"checksum backtrace-sys 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)" = "797c830ac25ccc92a7f8a7b9862bde440715531514594a6154e3d4a54dd769b6"
"checksum bindgen 0.46.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8f7f7f0701772b17de73e4f5cbcb1dd6926f4706cba4c1ab62c5367f8bdc94e1"
"checksum bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "228047a76f468627ca71776ecdebd732a3423081fcf5125585bcd7c49886ce12"
"checksum block-buffer 0.7.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"
@ -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 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 cexpr 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "644d693ecfa91955ed32dcc7eda4914e1be97a641fb6f0645a37348e20b230da"
"checksum cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "082bb9b28e00d3c9d39cc03e64ce4cea0f1bb9b3fde493f0cbc008472d22bdf4"
"checksum clang-sys 0.26.4 (registry+https://github.com/rust-lang/crates.io-index)" = "6ef0c1bcf2e99c649104bd7a7012d8f8802684400e03db0ec0af48583c6fa0e4"
"checksum clap 2.32.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b957d88f4b6a63b9d70d5f454ac8011819c6efa7727858f458ab71c756ce2d3e"
"checksum cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f"
"checksum cmake 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)" = "6ec65ee4f9c9d16f335091d23693457ed4928657ba4982289d7fafee03bc614a"
@ -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-wasm 0.26.0 (registry+https://github.com/rust-lang/crates.io-index)" = "49723365dab9a48b354bdc24cb6d9d5719bc1d3b858ffd2ea179d0d7d885804a"
"checksum digest 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "05f47366984d3ad862010e22c7ce81a7dbcaebbdfb37241a620f8b6596ee135c"
"checksum env_logger 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "afb070faf94c85d17d50ca44f6ad076bce18ae92f0037d350947240a36e9d42e"
"checksum errno 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "c2a071601ed01b988f896ab14b95e67335d1eeb50190932a1320f7fe3cadc84e"
"checksum errno-dragonfly 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "14ca354e36190500e1e1fb267c647932382b54053c50b14970856c0b00a35067"
"checksum failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "795bd83d3abeb9220f257e597aa0080a508b27533824adf336529648f6abf7e2"
@ -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 hashbrown 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "3bae29b6653b3412c2e71e9d486db9f9df5d701941d86683005efb9f2d28e3da"
"checksum heck 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "20564e78d53d2bb135c343b3f47714a56af2061f1c928fdb541dc7b9fdd94205"
"checksum humantime 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3ca7e5f2e110db35f93b837c81797f3714500b81d517bf20c431b16d3ca4f114"
"checksum indexmap 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7e81a7c05f79578dbc15793d8b619db9ba32b4577003ef3af1a91c416798c58d"
"checksum itoa 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "1306f3464951f30e30d12373d31c79fbd52d236e5e896fd92f96ec7babbbe60b"
"checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d"
"checksum lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a374c89b9db55895453a74c1e38861d9deec0b01b405a82516e9d5de4820dea1"
"checksum libc 0.2.48 (git+https://github.com/rust-lang/libc)" = "<none>"
"checksum libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)" = "e962c7641008ac010fa60a7dfdc1712449f29c44ef2d4702394aea943ee75047"
"checksum libloading 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9c3ad660d7cb8c5822cd83d10897b0f1f1526792737a179e73896152f85b88c2"
"checksum lock_api 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "62ebf1391f6acad60e5c8b43706dde4582df75c06698ab44511d15016bc2442c"
"checksum log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c84ec4b527950aa83a329754b01dbe3f58361d1c5efacd1f6d68c494d08a17c6"
"checksum memchr 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2efc7bc57c883d4a4d6e3246905283d8dae951bb3bd32f49d6ef297f546e1c39"
"checksum memmap 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6585fd95e7bb50d6cc31e20d4cf9afb4e2ba16c5846fc76793f11218da9c475b"
"checksum nix 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = "921f61dc817b379d0834e45d5ec45beaacfae97082090a49c2cf30dcbc30206f"
"checksum nix 0.13.0 (registry+https://github.com/rust-lang/crates.io-index)" = "46f0f3210768d796e8fa79ec70ee6af172dacbe7147f5e69be5240a47778302b"
"checksum nom 4.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b30adc557058ce00c9d0d7cb3c6e0b5bc6f36e2e2eabe74b0ba726d194abd588"
"checksum opaque-debug 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "93f5bb2e8e8dec81642920ccff6b61f1eb94fa3020c5a325c9851ff604152409"
"checksum owning_ref 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "49a4b8ea2179e6a2e27411d3bca09ca6dd630821cf6894c6c7c8467a8ee7ef13"
"checksum page_size 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f89ef58b3d32420dbd1a43d2f38ae92f6239ef12bb556ab09ca55445f5a67242"
"checksum parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ab41b4aed082705d1056416ae4468b6ea99d52599ecf3169b00088d43113e337"
"checksum parking_lot_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "94c8c7923936b28d546dfd14d4472eaf34c99b14e1c973a32b3e6d4eb04298c9"
"checksum peeking_take_while 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099"
"checksum proc-macro2 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "1b06e2f335f48d24442b35a19df506a835fb3547bc3c06ef27340da9acf5cae7"
"checksum proc-macro2 0.4.26 (registry+https://github.com/rust-lang/crates.io-index)" = "38fddd23d98b2144d197c0eca5705632d4fe2667d14a6be5df8934f8d74f1978"
"checksum quick-error 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9274b940887ce9addde99c4eee6b5c44cc494b182b97e73dc8ffdcb3397fd3f0"
"checksum quote 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9949cfe66888ffe1d53e6ec9d9f3b70714083854be20fd5e271b232a017401e8"
"checksum quote 0.6.11 (registry+https://github.com/rust-lang/crates.io-index)" = "cdd8e04bd9c52e0342b406469d494fcb033be4bdbe5c606016defbb1681411e1"
"checksum rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)" = "6d71dacdc3c88c1fde3885a3be3fbab9f35724e6ce99467f7d9c5026132184ca"
@ -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 redox_syscall 0.1.51 (registry+https://github.com/rust-lang/crates.io-index)" = "423e376fffca3dfa06c9e9790a9ccd282fafb3cc6e6397d01dbf64f9bacc6b85"
"checksum redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7e891cfe48e9100a70a3b6eb652fef28920c117d366339687bd5576160db0f76"
"checksum regex 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "37e7cbbd370869ce2e8dff25c7018702d10b21a20ef7135316f8daecd6c25b7f"
"checksum regex-syntax 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)" = "8c2f35eedad5295fdf00a63d7d4b238135723f92b434ec06774dad15c7ab0861"
"checksum 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 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"
@ -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 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 termcolor 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "4096add70612622289f2fdcdbd5086dc81c1e2675e6ae58d6c4f62a16c6d7f2f"
"checksum termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "689a3bdfaab439fd92bc87df5c4c78417d3cbe537487274e9b0b2dce76e92096"
"checksum textwrap 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "307686869c93e71f94da64286f9a9524c0f308a9e1c87a583de8e9c9039ad3f6"
"checksum thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c6b53e329000edc2b34dbe8545fd20e55a333362d0a321909685a19bd28c3f1b"
"checksum time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)" = "db8dcfca086c1143c9270ac42a2bbd8a7ee477b78ac8e45b19abfb0cbede4b6f"
"checksum 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 ucd-util 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "535c204ee4d8434478593480b8f86ab45ec9aae0e83c568ca81abf0fd0e88f86"
"checksum unicode-segmentation 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "aa6024fc12ddfd1c6dbc14a80fa2324d4568849869b779f6bd37e5e4c03344d1"
"checksum unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "882386231c45df4700b275c7ff55b6f3698780a650026380e72dabe76fa46526"
"checksum unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc"
"checksum unreachable 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "382810877fe448991dfc7f0dd6e3ae5d58088fd0ea5e35189655f84e6814fa56"
"checksum utf8-ranges 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "796f7e48bef87609f7ade7e06495a87d5cd06c7866e6a5cbfceffc558a243737"
"checksum vec_map 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "05c78687fb1a80548ae3250346c3db86a80a7cdd77bda190189f2d0a0987c81a"
"checksum version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "914b1a6776c4c929a602fafd8bc742e06365d4bcbe48c30f9cca5824f70dc9dd"
"checksum void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d"
"checksum wabt 0.7.4 (registry+https://github.com/rust-lang/crates.io-index)" = "74e463a508e390cc7447e70f640fbf44ad52e1bd095314ace1fdf99516d32add"
"checksum wabt-sys 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)" = "a6265b25719e82598d104b3717375e37661d41753e2c84cde3f51050c7ed7e3c"
"checksum wasmparser 0.22.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f46e666ecb4a406483a59a49f9d0c17f327e70da53a128eccddae2eadb95865c"
"checksum wasmparser 0.23.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b5e01c420bc7d36e778bd242e1167b079562ba8b34087122cc9057187026d060"
"checksum which 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b57acb10231b9493c8472b20cb57317d0679a49e0bdbee44b3b803a6473af164"
"checksum winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a"
"checksum winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "92c1eb33641e276cfa214a0522acad57be5c56b10cb348b3c5117db75f3ac4b0"
"checksum winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc"
"checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
"checksum winapi-util 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7168bab6e1daee33b4557efd0e95d5ca70a03706d39fa5f3fe7a236f584b03c9"
"checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
"checksum wincolor 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "561ed901ae465d6185fa7864d63fbd5720d0ef718366c9a4dc83cf6170d7e9ba"

View File

@ -27,7 +27,7 @@ wasmer-runtime-core = { path = "lib/runtime-core" }
wasmer-emscripten = { path = "lib/emscripten" }
[workspace]
members = ["lib/clif-backend", "lib/runtime", "lib/runtime-core", "lib/emscripten", "lib/spectests", "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]
wabt = "0.7.2"

View File

@ -47,10 +47,10 @@ Wasmer is structured into different directories:
Building wasmer requires [rustup](https://rustup.rs/).
To install on Windows, download and run [`rustup-init.exe`](https://win.rustup.rs/)
To build on Windows, download and run [`rustup-init.exe`](https://win.rustup.rs/)
then follow the onscreen instructions.
To install on other systems, run:
To build on other systems, run:
```sh
curl https://sh.rustup.rs -sSf | sh
@ -86,8 +86,8 @@ sudo apt install cmake
#### Windows (MSVC)
Right now Windows support is _highly experimental_.
We are working on this so Wasmer can soon be released for Windows.
Windows support is _highly experimental_. Only simple wasm programs may be run, and no syscalls are allowed. This means
nginx and lua do not work on Windows. See [this issue for ongoing Emscripten syscall polyfills for Windows](https://github.com/wasmerio/wasmer/pull/176).
1. Install Python for Windows (https://www.python.org/downloads/release/python-2714/). The Windows x86-64 MSI installer is fine.
You should change the installation to install the "Add python.exe to Path" feature.
@ -95,6 +95,8 @@ We are working on this so Wasmer can soon be released for Windows.
2. Install Git for Windows (https://git-scm.com/download/win). DO allow it to add git.exe to the PATH (default
settings for the installer are fine).
3. Install CMake (https://cmake.org/download/). Ensure CMake is in the PATH.
## Building
Wasmer is built with [Cargo](https://crates.io/), the Rust package manager.

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"
optional = true
[target.'cfg(windows)'.dependencies]
winapi = { version = "0.3", features = ["errhandlingapi", "minwindef", "minwinbase", "winnt"] }
wasmer-win-exception-handler = { path = "../win-exception-handler", version = "0.0.1" }
[features]
cache = ["serde", "serde_derive", "serde_bytes", "serde-bench", "wasmer-runtime-core/cache"]
debug = ["wasmer-runtime-core/debug"]
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();
// Add the vmctx parameter type to it
signature.params.push(ir::AbiParam::special(
self.pointer_type(),
ir::ArgumentPurpose::VMContext,
));
signature.params.insert(
0,
ir::AbiParam::special(self.pointer_type(), ir::ArgumentPurpose::VMContext),
);
// Return signature
signature
@ -459,8 +459,8 @@ impl<'env, 'module, 'isa> FuncEnvironment for FuncEnv<'env, 'module, 'isa> {
// Build a value list for the indirect call instruction containing the call_args
// and the vmctx parameter.
let mut args = Vec::with_capacity(call_args.len() + 1);
args.extend(call_args.iter().cloned());
args.push(vmctx_ptr);
args.extend(call_args.iter().cloned());
Ok(pos.ins().call_indirect(sig_ref, func_ptr, &args))
}
@ -485,8 +485,8 @@ impl<'env, 'module, 'isa> FuncEnvironment for FuncEnv<'env, 'module, 'isa> {
.expect("missing vmctx parameter");
let mut args = Vec::with_capacity(call_args.len() + 1);
args.extend(call_args.iter().cloned());
args.push(vmctx);
args.extend(call_args.iter().cloned());
Ok(pos.ins().call(callee, &args))
}
@ -532,8 +532,8 @@ impl<'env, 'module, 'isa> FuncEnvironment for FuncEnv<'env, 'module, 'isa> {
let sig_ref = pos.func.dfg.ext_funcs[callee].signature;
let mut args = Vec::with_capacity(call_args.len() + 1);
args.extend(call_args.iter().cloned());
args.push(imported_vmctx_addr);
args.extend(call_args.iter().cloned());
Ok(pos
.ins()
@ -559,9 +559,9 @@ impl<'env, 'module, 'isa> FuncEnvironment for FuncEnv<'env, 'module, 'isa> {
let signature = pos.func.import_signature(ir::Signature {
call_conv: self.target_config().default_call_conv,
params: vec![
ir::AbiParam::new(ir::types::I32),
ir::AbiParam::new(ir::types::I32),
ir::AbiParam::special(self.pointer_type(), ir::ArgumentPurpose::VMContext),
ir::AbiParam::new(ir::types::I32),
ir::AbiParam::new(ir::types::I32),
],
returns: vec![ir::AbiParam::new(ir::types::I32)],
});
@ -604,7 +604,7 @@ impl<'env, 'module, 'isa> FuncEnvironment for FuncEnv<'env, 'module, 'isa> {
let call_inst = pos
.ins()
.call(mem_grow_func, &[const_mem_index, by_value, vmctx]);
.call(mem_grow_func, &[vmctx, const_mem_index, by_value]);
Ok(*pos.func.dfg.inst_results(call_inst).first().unwrap())
}
@ -623,8 +623,8 @@ impl<'env, 'module, 'isa> FuncEnvironment for FuncEnv<'env, 'module, 'isa> {
let signature = pos.func.import_signature(ir::Signature {
call_conv: self.target_config().default_call_conv,
params: vec![
ir::AbiParam::new(ir::types::I32),
ir::AbiParam::special(self.pointer_type(), ir::ArgumentPurpose::VMContext),
ir::AbiParam::new(ir::types::I32),
],
returns: vec![ir::AbiParam::new(ir::types::I32)],
});
@ -664,7 +664,7 @@ impl<'env, 'module, 'isa> FuncEnvironment for FuncEnv<'env, 'module, 'isa> {
.special_param(ir::ArgumentPurpose::VMContext)
.expect("missing vmctx parameter");
let call_inst = pos.ins().call(mem_grow_func, &[const_mem_index, vmctx]);
let call_inst = pos.ins().call(mem_grow_func, &[vmctx, const_mem_index]);
Ok(*pos.func.dfg.inst_results(call_inst).first().unwrap())
}

View File

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

View File

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

View File

@ -110,6 +110,7 @@ impl ProtectedCaller for Caller {
.lookup(sig_index)
.expect("that trampoline doesn't exist");
#[cfg(not(target_os = "windows"))]
call_protected(&self.handler_data, || unsafe {
// Leap of faith.
trampoline(
@ -120,6 +121,17 @@ impl ProtectedCaller for Caller {
);
})?;
// the trampoline is called from C on windows
#[cfg(target_os = "windows")]
call_protected(
&self.handler_data,
trampoline,
vmctx_ptr,
func_ptr,
param_vec.as_ptr(),
return_vec.as_mut_ptr(),
)?;
Ok(return_vec
.iter()
.zip(signature.returns().iter())

View File

@ -1,10 +1,116 @@
use crate::relocation::{TrapCode, TrapData};
use crate::signal::HandlerData;
use wasmer_runtime_core::error::RuntimeResult;
use crate::trampoline::Trampoline;
use std::cell::Cell;
use std::ffi::c_void;
use std::ptr;
use wasmer_runtime_core::vm::Ctx;
use wasmer_runtime_core::vm::Func;
use wasmer_runtime_core::{
error::{RuntimeError, RuntimeResult},
structures::TypedIndex,
types::{MemoryIndex, TableIndex},
};
use wasmer_win_exception_handler::CallProtectedData;
pub use wasmer_win_exception_handler::_call_protected;
use winapi::shared::minwindef::DWORD;
use winapi::um::minwinbase::{
EXCEPTION_ACCESS_VIOLATION, EXCEPTION_FLT_DENORMAL_OPERAND, EXCEPTION_FLT_DIVIDE_BY_ZERO,
EXCEPTION_FLT_INEXACT_RESULT, EXCEPTION_FLT_INVALID_OPERATION, EXCEPTION_FLT_OVERFLOW,
EXCEPTION_FLT_STACK_CHECK, EXCEPTION_FLT_UNDERFLOW, EXCEPTION_ILLEGAL_INSTRUCTION,
EXCEPTION_INT_DIVIDE_BY_ZERO, EXCEPTION_INT_OVERFLOW, EXCEPTION_STACK_OVERFLOW,
};
pub fn call_protected<T>(handler_data: &HandlerData, f: impl FnOnce() -> T) -> RuntimeResult<T> {
unimplemented!("TODO");
thread_local! {
pub static CURRENT_EXECUTABLE_BUFFER: Cell<*const c_void> = Cell::new(ptr::null());
}
pub fn call_protected(
handler_data: &HandlerData,
trampoline: Trampoline,
ctx: *mut Ctx,
func: *const Func,
param_vec: *const u64,
return_vec: *mut u64,
) -> RuntimeResult<()> {
// TODO: trap early
// user code error
// if let Some(msg) = super::TRAP_EARLY_DATA.with(|cell| cell.replace(None)) {
// return Err(RuntimeError::User { msg });
// }
let result = _call_protected(trampoline, ctx, func, param_vec, return_vec);
if let Ok(_) = result {
return Ok(());
}
let CallProtectedData {
code: signum,
exceptionAddress: exception_address,
instructionPointer: instruction_pointer,
} = result.unwrap_err();
if let Some(TrapData {
trapcode,
srcloc: _,
}) = handler_data.lookup(instruction_pointer as _)
{
Err(match signum as DWORD {
EXCEPTION_ACCESS_VIOLATION => RuntimeError::OutOfBoundsAccess {
memory: MemoryIndex::new(0),
addr: None,
},
EXCEPTION_ILLEGAL_INSTRUCTION => match trapcode {
TrapCode::BadSignature => RuntimeError::IndirectCallSignature {
table: TableIndex::new(0),
},
TrapCode::IndirectCallToNull => RuntimeError::IndirectCallToNull {
table: TableIndex::new(0),
},
TrapCode::HeapOutOfBounds => RuntimeError::OutOfBoundsAccess {
memory: MemoryIndex::new(0),
addr: None,
},
TrapCode::TableOutOfBounds => RuntimeError::TableOutOfBounds {
table: TableIndex::new(0),
},
_ => RuntimeError::Unknown {
msg: "unknown trap".to_string(),
},
},
EXCEPTION_STACK_OVERFLOW => RuntimeError::Unknown {
msg: "unknown trap".to_string(),
},
EXCEPTION_INT_DIVIDE_BY_ZERO => RuntimeError::IllegalArithmeticOperation,
EXCEPTION_INT_OVERFLOW => RuntimeError::IllegalArithmeticOperation,
_ => RuntimeError::Unknown {
msg: "unknown trap".to_string(),
},
}
.into())
} else {
let signal = match signum as DWORD {
EXCEPTION_FLT_DENORMAL_OPERAND
| EXCEPTION_FLT_DIVIDE_BY_ZERO
| EXCEPTION_FLT_INEXACT_RESULT
| EXCEPTION_FLT_INVALID_OPERATION
| EXCEPTION_FLT_OVERFLOW
| EXCEPTION_FLT_STACK_CHECK
| EXCEPTION_FLT_UNDERFLOW => "floating-point exception",
EXCEPTION_ILLEGAL_INSTRUCTION => "illegal instruction",
EXCEPTION_ACCESS_VIOLATION => "segmentation violation",
_ => "unkown trapped signal",
};
Err(RuntimeError::Unknown {
msg: format!("trap at {} - {}", exception_address, signal),
}
.into())
}
}
pub unsafe fn trigger_trap() -> ! {
unimplemented!("TODO");
// TODO
unimplemented!();
}

View File

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

View File

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

View File

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

View File

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

View File

@ -16,7 +16,7 @@ extern "C" {
// #[no_mangle]
/// emscripten: _getenv // (name: *const char) -> *const c_char;
pub fn _getenv(name: u32, ctx: &mut Ctx) -> u32 {
pub fn _getenv(ctx: &mut Ctx, name: u32) -> u32 {
debug!("emscripten::_getenv");
let name_string = read_string_from_wasm(ctx.memory(0), name);
debug!("=> name({:?})", name_string);
@ -28,7 +28,7 @@ pub fn _getenv(name: u32, ctx: &mut Ctx) -> u32 {
}
/// emscripten: _setenv // (name: *const char, name: *const value, overwrite: int);
pub fn _setenv(name: u32, value: u32, overwrite: u32, ctx: &mut Ctx) -> c_int {
pub fn _setenv(ctx: &mut Ctx, name: u32, value: u32, overwrite: u32) -> c_int {
debug!("emscripten::_setenv");
let name_addr = emscripten_memory_pointer!(ctx.memory(0), name);
let value_addr = emscripten_memory_pointer!(ctx.memory(0), value);
@ -44,7 +44,7 @@ pub fn _setenv(name: u32, value: u32, overwrite: u32, ctx: &mut Ctx) -> c_int {
}
/// emscripten: _putenv // (name: *const char);
pub fn _putenv(name: c_int, ctx: &mut Ctx) -> c_int {
pub fn _putenv(ctx: &mut Ctx, name: c_int) -> c_int {
debug!("emscripten::_putenv");
let name_addr = emscripten_memory_pointer!(ctx.memory(0), name) as *const c_char;
@ -54,7 +54,7 @@ pub fn _putenv(name: c_int, ctx: &mut Ctx) -> c_int {
}
/// emscripten: _unsetenv // (name: *const char);
pub fn _unsetenv(name: u32, ctx: &mut Ctx) -> c_int {
pub fn _unsetenv(ctx: &mut Ctx, name: u32) -> c_int {
debug!("emscripten::_unsetenv");
let name_addr = emscripten_memory_pointer!(ctx.memory(0), name);
let name = read_string_from_wasm(ctx.memory(0), name);
@ -67,7 +67,7 @@ pub fn _unsetenv(name: u32, ctx: &mut Ctx) -> c_int {
}
#[allow(clippy::cast_ptr_alignment)]
pub fn _getpwnam(name_ptr: c_int, ctx: &mut Ctx) -> c_int {
pub fn _getpwnam(ctx: &mut Ctx, name_ptr: c_int) -> c_int {
debug!("emscripten::_getpwnam {}", name_ptr);
#[repr(C)]
@ -83,7 +83,7 @@ pub fn _getpwnam(name_ptr: c_int, ctx: &mut Ctx) -> c_int {
// stub this in windows as it is not valid
unsafe {
let passwd_struct_offset = call_malloc(mem::size_of::<GuestPasswd>() as _, ctx);
let passwd_struct_offset = call_malloc(ctx, mem::size_of::<GuestPasswd>() as _);
let passwd_struct_ptr =
emscripten_memory_pointer!(ctx.memory(0), passwd_struct_offset) as *mut GuestPasswd;
(*passwd_struct_ptr).pw_name = 0;
@ -99,7 +99,7 @@ pub fn _getpwnam(name_ptr: c_int, ctx: &mut Ctx) -> c_int {
}
#[allow(clippy::cast_ptr_alignment)]
pub fn _getgrnam(name_ptr: c_int, ctx: &mut Ctx) -> c_int {
pub fn _getgrnam(ctx: &mut Ctx, name_ptr: c_int) -> c_int {
debug!("emscripten::_getgrnam {}", name_ptr);
#[repr(C)]
@ -112,7 +112,7 @@ pub fn _getgrnam(name_ptr: c_int, ctx: &mut Ctx) -> c_int {
// stub the group struct as it is not supported on windows
unsafe {
let group_struct_offset = call_malloc(mem::size_of::<GuestGroup>() as _, ctx);
let group_struct_offset = call_malloc(ctx, mem::size_of::<GuestGroup>() as _);
let group_struct_ptr =
emscripten_memory_pointer!(ctx.memory(0), group_struct_offset) as *mut GuestGroup;
(*group_struct_ptr).gr_name = 0;
@ -123,7 +123,7 @@ pub fn _getgrnam(name_ptr: c_int, ctx: &mut Ctx) -> c_int {
}
}
pub fn _sysconf(name: c_int, _ctx: &mut Ctx) -> c_long {
pub fn _sysconf(_ctx: &mut Ctx, name: c_int) -> c_long {
debug!("emscripten::_sysconf {}", name);
// stub because sysconf is not valid on windows
0

View File

@ -1,7 +1,7 @@
// use std::collections::HashMap;
use wasmer_runtime_core::vm::Ctx;
pub fn ___seterrno(value: i32, _ctx: &mut Ctx) {
pub fn ___seterrno(_ctx: &mut Ctx, value: i32) {
debug!("emscripten::___seterrno {}", value);
// TODO: Incomplete impl
eprintln!("failed to set errno!");

View File

@ -3,14 +3,14 @@ use super::process::_abort;
use wasmer_runtime_core::vm::Ctx;
/// emscripten: ___cxa_allocate_exception
pub fn ___cxa_allocate_exception(size: u32, ctx: &mut Ctx) -> u32 {
pub fn ___cxa_allocate_exception(ctx: &mut Ctx, size: u32) -> u32 {
debug!("emscripten::___cxa_allocate_exception");
env::call_malloc(size as _, ctx)
env::call_malloc(ctx, size as _)
}
/// emscripten: ___cxa_throw
/// TODO: We don't have support for exceptions yet
pub fn ___cxa_throw(_ptr: u32, _ty: u32, _destructor: u32, ctx: &mut Ctx) {
pub fn ___cxa_throw(ctx: &mut Ctx, _ptr: u32, _ty: u32, _destructor: u32) {
debug!("emscripten::___cxa_throw");
_abort(ctx);
}

View File

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

View File

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

View File

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

View File

@ -132,7 +132,7 @@ pub fn run_emscripten_instance(
let num_params = main_func.signature().params().len();
let _result = match num_params {
2 => {
let (argc, argv) = store_module_arguments(path, args, instance.context_mut());
let (argc, argv) = store_module_arguments(instance.context_mut(), path, args);
instance.call("_main", &[Value::I32(argc as i32), Value::I32(argv as i32)])?;
}
0 => {
@ -149,17 +149,17 @@ pub fn run_emscripten_instance(
Ok(())
}
fn store_module_arguments(path: &str, args: Vec<&str>, ctx: &mut Ctx) -> (u32, u32) {
fn store_module_arguments(ctx: &mut Ctx, path: &str, args: Vec<&str>) -> (u32, u32) {
let argc = args.len() + 1;
let mut args_slice = vec![0; argc];
args_slice[0] = unsafe { allocate_cstr_on_stack(path, ctx).0 };
args_slice[0] = unsafe { allocate_cstr_on_stack(ctx, path).0 };
for (slot, arg) in args_slice[1..argc].iter_mut().zip(args.iter()) {
*slot = unsafe { allocate_cstr_on_stack(&arg, ctx).0 };
*slot = unsafe { allocate_cstr_on_stack(ctx, &arg).0 };
}
let (argv_offset, argv_slice): (_, &mut [u32]) =
unsafe { allocate_on_stack(((argc + 1) * 4) as u32, ctx) };
unsafe { allocate_on_stack(ctx, ((argc + 1) * 4) as u32) };
assert!(!argv_slice.is_empty());
for (slot, arg) in argv_slice[0..argc].iter_mut().zip(args_slice.iter()) {
*slot = *arg

View File

@ -3,19 +3,19 @@ use wasmer_runtime_core::vm::Ctx;
// TODO: Need to implement.
/// emscripten: dlopen(filename: *const c_char, flag: c_int) -> *mut c_void
pub fn _dlopen(_filename: u32, _flag: u32, _ctx: &mut Ctx) -> i32 {
pub fn _dlopen(_ctx: &mut Ctx, _filename: u32, _flag: u32) -> i32 {
debug!("emscripten::_dlopen");
-1
}
/// emscripten: dlclose(handle: *mut c_void) -> c_int
pub fn _dlclose(_filename: u32, _ctx: &mut Ctx) -> i32 {
pub fn _dlclose(_ctx: &mut Ctx, _filename: u32) -> i32 {
debug!("emscripten::_dlclose");
-1
}
/// emscripten: dlsym(handle: *mut c_void, symbol: *const c_char) -> *mut c_void
pub fn _dlsym(_filepath: u32, _symbol: u32, _ctx: &mut Ctx) -> i32 {
pub fn _dlsym(_ctx: &mut Ctx, _filepath: u32, _symbol: u32) -> i32 {
debug!("emscripten::_dlsym");
-1
}

View File

@ -2,16 +2,16 @@ use libc::c_int;
use wasmer_runtime_core::vm::Ctx;
// NOTE: Not implemented by Emscripten
pub fn ___lock(what: c_int, _ctx: &mut Ctx) {
pub fn ___lock(_ctx: &mut Ctx, what: c_int) {
debug!("emscripten::___lock {}", what);
}
// NOTE: Not implemented by Emscripten
pub fn ___unlock(what: c_int, _ctx: &mut Ctx) {
pub fn ___unlock(_ctx: &mut Ctx, what: c_int) {
debug!("emscripten::___unlock {}", what);
}
// NOTE: Not implemented by Emscripten
pub fn ___wait(_which: u32, _varargs: u32, _three: u32, _four: u32, _ctx: &mut Ctx) {
pub fn ___wait(_ctx: &mut Ctx, _which: u32, _varargs: u32, _three: u32, _four: u32) {
debug!("emscripten::___wait");
}

View File

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

View File

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

View File

@ -1,67 +1,67 @@
use super::process::abort_with_message;
use wasmer_runtime_core::vm::Ctx;
pub fn nullfunc_i(x: u32, ctx: &mut Ctx) {
pub fn nullfunc_i(ctx: &mut Ctx, x: u32) {
debug!("emscripten::nullfunc_i {}", x);
abort_with_message("Invalid function pointer called with signature 'i'. Perhaps this is an invalid value (e.g. caused by calling a virtual method on a NULL pointer)? Or calling a function with an incorrect type, which will fail? (it is worth building your source files with -Werror (warnings are errors), as warnings can indicate undefined behavior which can cause this)", ctx);
abort_with_message(ctx, "Invalid function pointer called with signature 'i'. Perhaps this is an invalid value (e.g. caused by calling a virtual method on a NULL pointer)? Or calling a function with an incorrect type, which will fail? (it is worth building your source files with -Werror (warnings are errors), as warnings can indicate undefined behavior which can cause this)");
}
pub fn nullfunc_ii(x: u32, ctx: &mut Ctx) {
pub fn nullfunc_ii(ctx: &mut Ctx, x: u32) {
debug!("emscripten::nullfunc_ii {}", x);
abort_with_message("Invalid function pointer called with signature 'ii'. Perhaps this is an invalid value (e.g. caused by calling a virtual method on a NULL pointer)? Or calling a function with an incorrect type, which will fail? (it is worth building your source files with -Werror (warnings are errors), as warnings can indicate undefined behavior which can cause this)", ctx);
abort_with_message(ctx, "Invalid function pointer called with signature 'ii'. Perhaps this is an invalid value (e.g. caused by calling a virtual method on a NULL pointer)? Or calling a function with an incorrect type, which will fail? (it is worth building your source files with -Werror (warnings are errors), as warnings can indicate undefined behavior which can cause this)");
}
pub fn nullfunc_iii(x: u32, ctx: &mut Ctx) {
pub fn nullfunc_iii(ctx: &mut Ctx, x: u32) {
debug!("emscripten::nullfunc_iii {}", x);
abort_with_message("Invalid function pointer called with signature 'iii'. Perhaps this is an invalid value (e.g. caused by calling a virtual method on a NULL pointer)? Or calling a function with an incorrect type, which will fail? (it is worth building your source files with -Werror (warnings are errors), as warnings can indicate undefined behavior which can cause this)", ctx);
abort_with_message(ctx, "Invalid function pointer called with signature 'iii'. Perhaps this is an invalid value (e.g. caused by calling a virtual method on a NULL pointer)? Or calling a function with an incorrect type, which will fail? (it is worth building your source files with -Werror (warnings are errors), as warnings can indicate undefined behavior which can cause this)");
}
pub fn nullfunc_iiii(x: u32, ctx: &mut Ctx) {
pub fn nullfunc_iiii(ctx: &mut Ctx, x: u32) {
debug!("emscripten::nullfunc_iiii {}", x);
abort_with_message("Invalid function pointer called with signature 'iiii'. Perhaps this is an invalid value (e.g. caused by calling a virtual method on a NULL pointer)? Or calling a function with an incorrect type, which will fail? (it is worth building your source files with -Werror (warnings are errors), as warnings can indicate undefined behavior which can cause this)", ctx);
abort_with_message(ctx, "Invalid function pointer called with signature 'iiii'. Perhaps this is an invalid value (e.g. caused by calling a virtual method on a NULL pointer)? Or calling a function with an incorrect type, which will fail? (it is worth building your source files with -Werror (warnings are errors), as warnings can indicate undefined behavior which can cause this)");
}
pub fn nullfunc_iiiii(x: u32, ctx: &mut Ctx) {
pub fn nullfunc_iiiii(ctx: &mut Ctx, x: u32) {
debug!("emscripten::nullfunc_iiiii {}", x);
abort_with_message("Invalid function pointer called with signature 'iiiii'. Perhaps this is an invalid value (e.g. caused by calling a virtual method on a NULL pointer)? Or calling a function with an incorrect type, which will fail? (it is worth building your source files with -Werror (warnings are errors), as warnings can indicate undefined behavior which can cause this)", ctx);
abort_with_message(ctx, "Invalid function pointer called with signature 'iiiii'. Perhaps this is an invalid value (e.g. caused by calling a virtual method on a NULL pointer)? Or calling a function with an incorrect type, which will fail? (it is worth building your source files with -Werror (warnings are errors), as warnings can indicate undefined behavior which can cause this)");
}
pub fn nullfunc_iiiiii(x: u32, ctx: &mut Ctx) {
pub fn nullfunc_iiiiii(ctx: &mut Ctx, x: u32) {
debug!("emscripten::nullfunc_iiiiii {}", x);
abort_with_message("Invalid function pointer called with signature 'iiiiii'. Perhaps this is an invalid value (e.g. caused by calling a virtual method on a NULL pointer)? Or calling a function with an incorrect type, which will fail? (it is worth building your source files with -Werror (warnings are errors), as warnings can indicate undefined behavior which can cause this)", ctx);
abort_with_message(ctx, "Invalid function pointer called with signature 'iiiiii'. Perhaps this is an invalid value (e.g. caused by calling a virtual method on a NULL pointer)? Or calling a function with an incorrect type, which will fail? (it is worth building your source files with -Werror (warnings are errors), as warnings can indicate undefined behavior which can cause this)");
}
pub fn nullfunc_v(x: u32, ctx: &mut Ctx) {
pub fn nullfunc_v(ctx: &mut Ctx, x: u32) {
debug!("emscripten::nullfunc_v {}", x);
abort_with_message("Invalid function pointer called with signature 'v'. Perhaps this is an invalid value (e.g. caused by calling a virtual method on a NULL pointer)? Or calling a function with an incorrect type, which will fail? (it is worth building your source files with -Werror (warnings are errors), as warnings can indicate undefined behavior which can cause this)", ctx);
abort_with_message(ctx, "Invalid function pointer called with signature 'v'. Perhaps this is an invalid value (e.g. caused by calling a virtual method on a NULL pointer)? Or calling a function with an incorrect type, which will fail? (it is worth building your source files with -Werror (warnings are errors), as warnings can indicate undefined behavior which can cause this)");
}
pub fn nullfunc_vi(x: u32, ctx: &mut Ctx) {
pub fn nullfunc_vi(ctx: &mut Ctx, x: u32) {
debug!("emscripten::nullfunc_vi {}", x);
abort_with_message("Invalid function pointer called with signature 'vi'. Perhaps this is an invalid value (e.g. caused by calling a virtual method on a NULL pointer)? Or calling a function with an incorrect type, which will fail? (it is worth building your source files with -Werror (warnings are errors), as warnings can indicate undefined behavior which can cause this)", ctx);
abort_with_message(ctx, "Invalid function pointer called with signature 'vi'. Perhaps this is an invalid value (e.g. caused by calling a virtual method on a NULL pointer)? Or calling a function with an incorrect type, which will fail? (it is worth building your source files with -Werror (warnings are errors), as warnings can indicate undefined behavior which can cause this)");
}
pub fn nullfunc_vii(x: u32, ctx: &mut Ctx) {
pub fn nullfunc_vii(ctx: &mut Ctx, x: u32) {
debug!("emscripten::nullfunc_vii {}", x);
abort_with_message("Invalid function pointer called with signature 'vii'. Perhaps this is an invalid value (e.g. caused by calling a virtual method on a NULL pointer)? Or calling a function with an incorrect type, which will fail? (it is worth building your source files with -Werror (warnings are errors), as warnings can indicate undefined behavior which can cause this)", ctx);
abort_with_message(ctx, "Invalid function pointer called with signature 'vii'. Perhaps this is an invalid value (e.g. caused by calling a virtual method on a NULL pointer)? Or calling a function with an incorrect type, which will fail? (it is worth building your source files with -Werror (warnings are errors), as warnings can indicate undefined behavior which can cause this)");
}
pub fn nullfunc_viii(x: u32, ctx: &mut Ctx) {
pub fn nullfunc_viii(ctx: &mut Ctx, x: u32) {
debug!("emscripten::nullfunc_viii {}", x);
abort_with_message("Invalid function pointer called with signature 'viii'. Perhaps this is an invalid value (e.g. caused by calling a virtual method on a NULL pointer)? Or calling a function with an incorrect type, which will fail? (it is worth building your source files with -Werror (warnings are errors), as warnings can indicate undefined behavior which can cause this)", ctx);
abort_with_message(ctx, "Invalid function pointer called with signature 'viii'. Perhaps this is an invalid value (e.g. caused by calling a virtual method on a NULL pointer)? Or calling a function with an incorrect type, which will fail? (it is worth building your source files with -Werror (warnings are errors), as warnings can indicate undefined behavior which can cause this)");
}
pub fn nullfunc_viiii(x: u32, ctx: &mut Ctx) {
pub fn nullfunc_viiii(ctx: &mut Ctx, x: u32) {
debug!("emscripten::nullfunc_viiii {}", x);
abort_with_message("Invalid function pointer called with signature 'viiii'. Perhaps this is an invalid value (e.g. caused by calling a virtual method on a NULL pointer)? Or calling a function with an incorrect type, which will fail? (it is worth building your source files with -Werror (warnings are errors), as warnings can indicate undefined behavior which can cause this)", ctx);
abort_with_message(ctx, "Invalid function pointer called with signature 'viiii'. Perhaps this is an invalid value (e.g. caused by calling a virtual method on a NULL pointer)? Or calling a function with an incorrect type, which will fail? (it is worth building your source files with -Werror (warnings are errors), as warnings can indicate undefined behavior which can cause this)");
}
pub fn nullfunc_viiiii(_x: u32, ctx: &mut Ctx) {
pub fn nullfunc_viiiii(ctx: &mut Ctx, _x: u32) {
debug!("emscripten::nullfunc_viiiii");
abort_with_message("Invalid function pointer called with signature 'viiiii'. Perhaps this is an invalid value (e.g. caused by calling a virtual method on a NULL pointer)? Or calling a function with an incorrect type, which will fail? (it is worth building your source files with -Werror (warnings are errors), as warnings can indicate undefined behavior which can cause this)", ctx);
abort_with_message(ctx, "Invalid function pointer called with signature 'viiiii'. Perhaps this is an invalid value (e.g. caused by calling a virtual method on a NULL pointer)? Or calling a function with an incorrect type, which will fail? (it is worth building your source files with -Werror (warnings are errors), as warnings can indicate undefined behavior which can cause this)");
}
pub fn nullfunc_viiiiii(_x: u32, ctx: &mut Ctx) {
pub fn nullfunc_viiiiii(ctx: &mut Ctx, _x: u32) {
debug!("emscripten::nullfunc_viiiiii");
abort_with_message("Invalid function pointer called with signature 'viiiiii'. Perhaps this is an invalid value (e.g. caused by calling a virtual method on a NULL pointer)? Or calling a function with an incorrect type, which will fail? (it is worth building your source files with -Werror (warnings are errors), as warnings can indicate undefined behavior which can cause this)", ctx);
abort_with_message(ctx, "Invalid function pointer called with signature 'viiiiii'. Perhaps this is an invalid value (e.g. caused by calling a virtual method on a NULL pointer)? Or calling a function with an incorrect type, which will fail? (it is worth building your source files with -Werror (warnings are errors), as warnings can indicate undefined behavior which can cause this)");
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -1,8 +1,7 @@
use crate::types::{
FuncSig, GlobalDescriptor, MemoryDescriptor, MemoryIndex, TableDescriptor, TableIndex, Type,
};
use std::error::Error as StdError;
use std::fmt;
use core::borrow::Borrow;
use std::sync::Arc;
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
/// 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
/// 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
/// 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
/// exported from a module.
///
@ -156,20 +251,22 @@ impl PartialEq for CallError {
}
}
impl fmt::Display for CallError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "Call error")
impl std::fmt::Display for CallError {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
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,
/// like a `Memory` or a `Table`.
#[derive(Debug, Clone)]
pub enum CreationError {
UnableToCreateMemory,
UnableToCreateTable,
InvalidDescriptor(String),
}
impl PartialEq for CreationError {
@ -178,13 +275,21 @@ impl PartialEq for CreationError {
}
}
impl fmt::Display for CreationError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "Creation error")
impl std::fmt::Display for CreationError {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
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
/// during the compilation, instantiation, or execution
@ -254,3 +359,11 @@ impl From<ResolveError> for CallError {
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
/// }
/// ```

View File

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

View File

@ -63,6 +63,15 @@ impl Memory {
/// # }
/// ```
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 {
MemoryVariant::Unshared(UnsharedMemory::new(desc)?)
} else {

View File

@ -150,7 +150,8 @@ impl Drop for Memory {
fn drop(&mut self) {
if !self.ptr.is_null() {
let success = unsafe { VirtualFree(self.ptr as _, self.size, MEM_DECOMMIT) };
assert_eq!(success, 0, "failed to unmap memory: {}", errno::errno());
// If the function succeeds, the return value is nonzero.
assert_eq!(success, 1, "failed to unmap memory: {}", errno::errno());
}
}
}

View File

@ -50,6 +50,14 @@ impl Table {
/// # }
/// ```
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 {
base: ptr::null_mut(),
count: 0,

View File

@ -138,9 +138,9 @@ impl<A: WasmExternType> WasmTypeList for (A,) {
}
#[allow(non_snake_case)]
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;
f(a, ctx)
f(ctx, a)
}
}
@ -154,8 +154,8 @@ where
}
macro_rules! impl_traits {
( $struct_name:ident, $( $x:ident ),* ) => {
#[repr(C)]
( [$repr:ident] $struct_name:ident, $( $x:ident ),* ) => {
#[repr($repr)]
pub struct $struct_name <$( $x ),*> ( $( $x ),* );
impl< $( $x: WasmExternType, )* > WasmTypeList for ( $( $x ),* ) {
@ -175,24 +175,24 @@ macro_rules! impl_traits {
}
#[allow(non_snake_case)]
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)]
let ( $( $x ),* ) = self;
let c_struct = f( $( $x, )* ctx);
let c_struct = f(ctx $( ,$x )*);
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)]
fn to_raw(&self) -> *const () {
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 msg = match panic::catch_unwind(panic::AssertUnwindSafe(|| {
f( $( $x, )* ctx).report()
f( ctx $( ,$x )* ).report()
})) {
Ok(Ok(returns)) => return returns.into_c_struct(),
Ok(Err(err)) => err,
@ -234,18 +234,18 @@ macro_rules! impl_traits {
};
}
impl_traits!(S0,);
impl_traits!(S1, A);
impl_traits!(S2, A, B);
impl_traits!(S3, A, B, C);
impl_traits!(S4, A, B, C, D);
impl_traits!(S5, A, B, C, D, E);
impl_traits!(S6, A, B, C, D, E, F);
impl_traits!(S7, A, B, C, D, E, F, G);
impl_traits!(S8, A, B, C, D, E, F, G, H);
impl_traits!(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!(S11, A, B, C, D, E, F, G, H, I, J, K);
impl_traits!([C] S0,);
impl_traits!([transparent] S1, A);
impl_traits!([C] S2, A, B);
impl_traits!([C] S3, A, B, C);
impl_traits!([C] S4, A, B, C, D);
impl_traits!([C] S5, A, B, C, D, E);
impl_traits!([C] S6, A, B, C, D, E, F);
impl_traits!([C] S7, A, B, C, D, E, F, G);
impl_traits!([C] S8, A, B, C, D, E, F, G, H);
impl_traits!([C] S9, A, B, C, D, E, F, G, H, I);
impl_traits!([C] S10, A, B, C, D, E, F, G, H, I, J);
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>
where
@ -271,7 +271,7 @@ mod tests {
use super::*;
#[test]
fn test_call() {
fn foo(a: i32, b: i32, _ctx: &mut Ctx) -> (i32, i32) {
fn foo(_ctx: &mut Ctx, a: i32, b: i32) -> (i32, i32) {
(a, b)
}
@ -282,7 +282,7 @@ mod tests {
fn test_imports() {
use crate::{func, imports};
fn foo(a: i32, _ctx: &mut Ctx) -> i32 {
fn foo(_ctx: &mut Ctx, a: i32) -> i32 {
a
}

View File

@ -15,6 +15,12 @@ pub enum Type {
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.
///
/// 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 {
type Local: TypedIndex;
type Import: TypedIndex;

View File

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

View File

@ -13,9 +13,9 @@ use crate::{
// +****************************+
pub unsafe extern "C" fn local_static_memory_grow(
ctx: &mut vm::Ctx,
memory_index: LocalMemoryIndex,
delta: Pages,
ctx: &mut vm::Ctx,
) -> i32 {
let local_memory = *ctx.memories.add(memory_index.index());
let memory = (*local_memory).memory as *mut StaticMemory;
@ -28,8 +28,8 @@ pub unsafe extern "C" fn local_static_memory_grow(
}
pub unsafe extern "C" fn local_static_memory_size(
memory_index: LocalMemoryIndex,
ctx: &vm::Ctx,
memory_index: LocalMemoryIndex,
) -> Pages {
let local_memory = *ctx.memories.add(memory_index.index());
let memory = (*local_memory).memory as *mut StaticMemory;
@ -38,9 +38,9 @@ pub unsafe extern "C" fn local_static_memory_size(
}
pub unsafe extern "C" fn local_dynamic_memory_grow(
ctx: &mut vm::Ctx,
memory_index: LocalMemoryIndex,
delta: Pages,
ctx: &mut vm::Ctx,
) -> i32 {
let local_memory = *ctx.memories.add(memory_index.index());
let memory = (*local_memory).memory as *mut DynamicMemory;
@ -53,8 +53,8 @@ pub unsafe extern "C" fn local_dynamic_memory_grow(
}
pub unsafe extern "C" fn local_dynamic_memory_size(
memory_index: LocalMemoryIndex,
ctx: &vm::Ctx,
memory_index: LocalMemoryIndex,
) -> Pages {
let local_memory = *ctx.memories.add(memory_index.index());
let memory = (*local_memory).memory as *mut DynamicMemory;
@ -67,9 +67,9 @@ pub unsafe extern "C" fn local_dynamic_memory_size(
// +****************************+
pub unsafe extern "C" fn imported_static_memory_grow(
ctx: &mut vm::Ctx,
import_memory_index: ImportedMemoryIndex,
delta: Pages,
ctx: &mut vm::Ctx,
) -> i32 {
let local_memory = *ctx.imported_memories.add(import_memory_index.index());
let memory = (*local_memory).memory as *mut StaticMemory;
@ -82,8 +82,8 @@ pub unsafe extern "C" fn imported_static_memory_grow(
}
pub unsafe extern "C" fn imported_static_memory_size(
import_memory_index: ImportedMemoryIndex,
ctx: &vm::Ctx,
import_memory_index: ImportedMemoryIndex,
) -> Pages {
let local_memory = *ctx.imported_memories.add(import_memory_index.index());
let memory = (*local_memory).memory as *mut StaticMemory;
@ -92,9 +92,9 @@ pub unsafe extern "C" fn imported_static_memory_size(
}
pub unsafe extern "C" fn imported_dynamic_memory_grow(
ctx: &mut vm::Ctx,
memory_index: ImportedMemoryIndex,
delta: Pages,
ctx: &mut vm::Ctx,
) -> i32 {
let local_memory = *ctx.imported_memories.add(memory_index.index());
let memory = (*local_memory).memory as *mut DynamicMemory;
@ -107,8 +107,8 @@ pub unsafe extern "C" fn imported_dynamic_memory_grow(
}
pub unsafe extern "C" fn imported_dynamic_memory_size(
memory_index: ImportedMemoryIndex,
ctx: &vm::Ctx,
memory_index: ImportedMemoryIndex,
) -> Pages {
let local_memory = *ctx.imported_memories.add(memory_index.index());
let memory = (*local_memory).memory as *mut DynamicMemory;
@ -121,9 +121,9 @@ pub unsafe extern "C" fn imported_dynamic_memory_size(
// +****************************+
pub unsafe extern "C" fn local_table_grow(
ctx: &mut vm::Ctx,
table_index: LocalTableIndex,
delta: u32,
ctx: &mut vm::Ctx,
) -> i32 {
let _ = table_index;
let _ = delta;
@ -131,7 +131,7 @@ pub unsafe extern "C" fn local_table_grow(
unimplemented!()
}
pub unsafe extern "C" fn local_table_size(table_index: LocalTableIndex, ctx: &vm::Ctx) -> u32 {
pub unsafe extern "C" fn local_table_size(ctx: &vm::Ctx, table_index: LocalTableIndex) -> u32 {
let _ = table_index;
let _ = ctx;
unimplemented!()

View File

@ -1,8 +1,6 @@
use std::fs::remove_file;
use wabt::wat2wasm;
use wasmer_clif_backend::CraneliftCompiler;
use wasmer_runtime_core::{
cache::Cache,
error,
global::Global,
memory::Memory,
@ -15,7 +13,6 @@ use wasmer_runtime_core::{
static EXAMPLE_WASM: &'static [u8] = include_bytes!("simple.wasm");
fn main() -> error::Result<()> {
let compiler = CraneliftCompiler::new();
let wasm_binary = wat2wasm(IMPORT_MODULE.as_bytes()).expect("WAST not valid or malformed");
let inner_module = wasmer_runtime_core::compile_with(&wasm_binary, &CraneliftCompiler::new())?;
@ -61,7 +58,7 @@ fn main() -> error::Result<()> {
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);
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[..])
.map_err(|e| format!("Can't compile module: {:?}", e))?;
let (_abi, import_object, em_globals) = if wasmer_emscripten::is_emscripten_module(&module) {
let (_abi, import_object, _em_globals) = if wasmer_emscripten::is_emscripten_module(&module) {
let mut emscripten_globals = wasmer_emscripten::EmscriptenGlobals::new(&module);
(
InstanceABI::Emscripten,
@ -113,6 +113,11 @@ fn main() {
let options = CLIOptions::from_args();
match options {
CLIOptions::Run(options) => run(options),
#[cfg(not(target_os = "windows"))]
CLIOptions::SelfUpdate => update::self_update(),
#[cfg(target_os = "windows")]
CLIOptions::SelfUpdate => {
println!("Self update is not supported on Windows. Use install instructions on the Wasmer homepage: https://wasmer.io");
}
}
}