mirror of
https://github.com/mii443/wasmer.git
synced 2025-12-13 13:58:38 +00:00
Merge branch 'master' into native-engine
# Conflicts: # Cargo.lock
This commit is contained in:
6
.github/workflows/main.yaml
vendored
6
.github/workflows/main.yaml
vendored
@@ -45,6 +45,12 @@ jobs:
|
|||||||
toolchain: ${{ matrix.rust }}
|
toolchain: ${{ matrix.rust }}
|
||||||
override: true
|
override: true
|
||||||
- run: cargo test --release
|
- run: cargo test --release
|
||||||
|
- name: Set up dependencies for Mac OS
|
||||||
|
run: brew install automake
|
||||||
|
if: matrix.os == 'macos-latest'
|
||||||
|
- name: Set up dependencies for Windows
|
||||||
|
run: choco install llvm
|
||||||
|
if: matrix.os == 'windows-latest'
|
||||||
- name: Build and Test C API
|
- name: Build and Test C API
|
||||||
run: |
|
run: |
|
||||||
make capi
|
make capi
|
||||||
|
|||||||
192
Cargo.lock
generated
192
Cargo.lock
generated
@@ -1,5 +1,11 @@
|
|||||||
# This file is automatically @generated by Cargo.
|
# This file is automatically @generated by Cargo.
|
||||||
# It is not intended for manual editing.
|
# It is not intended for manual editing.
|
||||||
|
[[package]]
|
||||||
|
name = "abort_on_panic"
|
||||||
|
version = "2.0.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "955f37ac58af2416bac687c8ab66a4ccba282229bd7422a28d2281a5e66a6116"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ahash"
|
name = "ahash"
|
||||||
version = "0.3.2"
|
version = "0.3.2"
|
||||||
@@ -97,6 +103,30 @@ dependencies = [
|
|||||||
"serde",
|
"serde",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "bindgen"
|
||||||
|
version = "0.52.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f1c85344eb535a31b62f0af37be84441ba9e7f0f4111eb0530f43d15e513fe57"
|
||||||
|
dependencies = [
|
||||||
|
"bitflags",
|
||||||
|
"cexpr",
|
||||||
|
"cfg-if",
|
||||||
|
"clang-sys",
|
||||||
|
"clap",
|
||||||
|
"env_logger",
|
||||||
|
"lazy_static",
|
||||||
|
"lazycell",
|
||||||
|
"log",
|
||||||
|
"peeking_take_while",
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"regex",
|
||||||
|
"rustc-hash",
|
||||||
|
"shlex",
|
||||||
|
"which",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bitflags"
|
name = "bitflags"
|
||||||
version = "1.2.1"
|
version = "1.2.1"
|
||||||
@@ -162,12 +192,32 @@ version = "1.0.50"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "95e28fa049fda1c330bcf9d723be7663a899c4679724b34c81e9f5a326aab8cd"
|
checksum = "95e28fa049fda1c330bcf9d723be7663a899c4679724b34c81e9f5a326aab8cd"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "cexpr"
|
||||||
|
version = "0.3.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "fce5b5fb86b0c57c20c834c1b412fd09c77c8a59b9473f86272709e78874cd1d"
|
||||||
|
dependencies = [
|
||||||
|
"nom",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cfg-if"
|
name = "cfg-if"
|
||||||
version = "0.1.10"
|
version = "0.1.10"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822"
|
checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "clang-sys"
|
||||||
|
version = "0.28.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "81de550971c976f176130da4b2978d3b524eaa0fd9ac31f3ceb5ae1231fb4853"
|
||||||
|
dependencies = [
|
||||||
|
"glob",
|
||||||
|
"libc",
|
||||||
|
"libloading 0.5.2",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "clap"
|
name = "clap"
|
||||||
version = "2.33.0"
|
version = "2.33.0"
|
||||||
@@ -452,6 +502,19 @@ dependencies = [
|
|||||||
"syn",
|
"syn",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "env_logger"
|
||||||
|
version = "0.7.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "44533bbbb3bb3c1fa17d9f2e4e38bbbaf8396ba82193c4cb1b6445d711445d36"
|
||||||
|
dependencies = [
|
||||||
|
"atty",
|
||||||
|
"humantime",
|
||||||
|
"log",
|
||||||
|
"regex",
|
||||||
|
"termcolor",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "erased-serde"
|
name = "erased-serde"
|
||||||
version = "0.3.11"
|
version = "0.3.11"
|
||||||
@@ -601,6 +664,15 @@ version = "0.4.2"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "644f9158b2f133fd50f5fb3242878846d9eb792e445c893805ff0e3824006e35"
|
checksum = "644f9158b2f133fd50f5fb3242878846d9eb792e445c893805ff0e3824006e35"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "humantime"
|
||||||
|
version = "1.3.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "df004cfca50ef23c36850aaaa59ad52cc70d0e90243c3c7737a4dd32dc7a3c4f"
|
||||||
|
dependencies = [
|
||||||
|
"quick-error",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ident_case"
|
name = "ident_case"
|
||||||
version = "1.0.1"
|
version = "1.0.1"
|
||||||
@@ -684,6 +756,12 @@ version = "1.4.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
|
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "lazycell"
|
||||||
|
version = "1.2.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b294d6fa9ee409a054354afc4352b0b9ef7ca222c69b8812cbea9e7d2bf3783f"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "leb128"
|
name = "leb128"
|
||||||
version = "0.2.4"
|
version = "0.2.4"
|
||||||
@@ -696,6 +774,39 @@ version = "0.2.70"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "3baa92041a6fec78c687fa0cc2b3fae8884f743d672cf551bed1d6dac6988d0f"
|
checksum = "3baa92041a6fec78c687fa0cc2b3fae8884f743d672cf551bed1d6dac6988d0f"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "libffi"
|
||||||
|
version = "0.9.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c18efe55925cc7f83bf60a61394696a734ae90e668d1f2bbd954354416fec6f2"
|
||||||
|
dependencies = [
|
||||||
|
"abort_on_panic",
|
||||||
|
"libc",
|
||||||
|
"libffi-sys",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "libffi-sys"
|
||||||
|
version = "0.9.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "6f00e48ce437c5741a4da3b51738498343b5158c37bfa02bcb969efcc44e4e06"
|
||||||
|
dependencies = [
|
||||||
|
"bindgen",
|
||||||
|
"cc",
|
||||||
|
"make-cmd",
|
||||||
|
"pkg-config",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "libloading"
|
||||||
|
version = "0.5.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f2b111a074963af1d37a139918ac6d49ad1d0d5e47f72fd55388619691a7d753"
|
||||||
|
dependencies = [
|
||||||
|
"cc",
|
||||||
|
"winapi",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "libloading"
|
name = "libloading"
|
||||||
version = "0.6.2"
|
version = "0.6.2"
|
||||||
@@ -745,6 +856,12 @@ dependencies = [
|
|||||||
"libc",
|
"libc",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "make-cmd"
|
||||||
|
version = "0.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a8ca8afbe8af1785e09636acb5a41e08a765f5f0340568716c18a8700ba3c0d3"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "maybe-uninit"
|
name = "maybe-uninit"
|
||||||
version = "2.0.0"
|
version = "2.0.0"
|
||||||
@@ -796,6 +913,16 @@ version = "0.2.1"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "0debeb9fcf88823ea64d64e4a815ab1643f33127d995978e099942ce38f25238"
|
checksum = "0debeb9fcf88823ea64d64e4a815ab1643f33127d995978e099942ce38f25238"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "nom"
|
||||||
|
version = "4.2.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "2ad2a91a8e869eeb30b9cb3119ae87773a8f4ae617f41b1eb9c154b2905f7bd6"
|
||||||
|
dependencies = [
|
||||||
|
"memchr",
|
||||||
|
"version_check 0.1.5",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "num"
|
name = "num"
|
||||||
version = "0.1.42"
|
version = "0.1.42"
|
||||||
@@ -896,6 +1023,12 @@ dependencies = [
|
|||||||
"winapi",
|
"winapi",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "peeking_take_while"
|
||||||
|
version = "0.1.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pkg-config"
|
name = "pkg-config"
|
||||||
version = "0.3.17"
|
version = "0.3.17"
|
||||||
@@ -924,7 +1057,7 @@ dependencies = [
|
|||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn",
|
"syn",
|
||||||
"version_check",
|
"version_check 0.9.1",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -937,7 +1070,7 @@ dependencies = [
|
|||||||
"quote",
|
"quote",
|
||||||
"syn",
|
"syn",
|
||||||
"syn-mid",
|
"syn-mid",
|
||||||
"version_check",
|
"version_check 0.9.1",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -949,6 +1082,12 @@ dependencies = [
|
|||||||
"unicode-xid",
|
"unicode-xid",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "quick-error"
|
||||||
|
version = "1.2.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "quote"
|
name = "quote"
|
||||||
version = "1.0.3"
|
version = "1.0.3"
|
||||||
@@ -1206,6 +1345,12 @@ version = "0.1.16"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "4c691c0e608126e00913e33f0ccf3727d5fc84573623b8d65b2df340b5201783"
|
checksum = "4c691c0e608126e00913e33f0ccf3727d5fc84573623b8d65b2df340b5201783"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rustc-hash"
|
||||||
|
version = "1.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rustc_version"
|
name = "rustc_version"
|
||||||
version = "0.2.3"
|
version = "0.2.3"
|
||||||
@@ -1326,6 +1471,12 @@ dependencies = [
|
|||||||
"serde",
|
"serde",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "shlex"
|
||||||
|
version = "0.1.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7fdf1b9db47230893d76faad238fd6097fd6d6a9245cd7a4d90dbd639536bbd2"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "smallvec"
|
name = "smallvec"
|
||||||
version = "1.4.0"
|
version = "1.4.0"
|
||||||
@@ -1431,6 +1582,15 @@ dependencies = [
|
|||||||
"winapi",
|
"winapi",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "termcolor"
|
||||||
|
version = "1.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "bb6bfa289a4d7c5766392812c0a1f4c1ba45afa1ad47803c11e1f407d846d75f"
|
||||||
|
dependencies = [
|
||||||
|
"winapi-util",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "test-generator"
|
name = "test-generator"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
@@ -1592,6 +1752,12 @@ version = "0.8.1"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "05c78687fb1a80548ae3250346c3db86a80a7cdd77bda190189f2d0a0987c81a"
|
checksum = "05c78687fb1a80548ae3250346c3db86a80a7cdd77bda190189f2d0a0987c81a"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "version_check"
|
||||||
|
version = "0.1.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "914b1a6776c4c929a602fafd8bc742e06365d4bcbe48c30f9cca5824f70dc9dd"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "version_check"
|
name = "version_check"
|
||||||
version = "0.9.1"
|
version = "0.9.1"
|
||||||
@@ -1795,7 +1961,7 @@ dependencies = [
|
|||||||
"cfg-if",
|
"cfg-if",
|
||||||
"faerie",
|
"faerie",
|
||||||
"leb128",
|
"leb128",
|
||||||
"libloading",
|
"libloading 0.6.2",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_bytes",
|
"serde_bytes",
|
||||||
"tempfile",
|
"tempfile",
|
||||||
@@ -1830,6 +1996,8 @@ dependencies = [
|
|||||||
"cbindgen",
|
"cbindgen",
|
||||||
"lazy_static",
|
"lazy_static",
|
||||||
"libc",
|
"libc",
|
||||||
|
"libffi",
|
||||||
|
"wasm-common",
|
||||||
"wasmer",
|
"wasmer",
|
||||||
"wasmer-wasi",
|
"wasmer-wasi",
|
||||||
]
|
]
|
||||||
@@ -1898,6 +2066,15 @@ dependencies = [
|
|||||||
"wast",
|
"wast",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "which"
|
||||||
|
version = "3.1.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d011071ae14a2f6671d0b74080ae0cd8ebf3a6f8c9589a2cd45f23126fe29724"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "winapi"
|
name = "winapi"
|
||||||
version = "0.3.8"
|
version = "0.3.8"
|
||||||
@@ -1914,6 +2091,15 @@ version = "0.4.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
|
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "winapi-util"
|
||||||
|
version = "0.1.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178"
|
||||||
|
dependencies = [
|
||||||
|
"winapi",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "winapi-x86_64-pc-windows-gnu"
|
name = "winapi-x86_64-pc-windows-gnu"
|
||||||
version = "0.4.0"
|
version = "0.4.0"
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
# Wasmer [](https://dev.azure.com/wasmerio/wasmer/_build/latest?definitionId=3&branchName=master) [](https://slack.wasmer.io) [](https://github.com/wasmerio/wasmer/blob/master/LICENSE)
|
# Wasmer [](https://dev.azure.com/wasmerio/wasmer/_build/latest?definitionId=3&branchName=master) [](https://slack.wasmer.io) [](https://github.com/wasmerio/wasmer/blob/master/LICENSE)
|
||||||
|
|
||||||
[`Wasmer`](https://wasmer.io/) is the most popular [WebAssembly](https://webassembly.org/)
|
[`Wasmer`](https://wasmer.io/) is the most popular [WebAssembly](https://webassembly.org/)
|
||||||
runtime for Rust. It supports JIT (Just in Time) and AOT (Ahead of time)
|
runtime for Rust (...and also [the fastest]()!). It supports JIT (Just in Time) and AOT (Ahead of time)
|
||||||
compilation as well as mulitple compiler implementations.
|
compilation as well as pluggable compilers suited to your needs.
|
||||||
|
|
||||||
It's designed to be safe and secure, and runnable in any kind of environment.
|
It's designed to be safe and secure, and runnable in any kind of environment.
|
||||||
|
|
||||||
|
|||||||
@@ -543,8 +543,8 @@ impl Function {
|
|||||||
VMDynamicFunctionImportContext::from_context(VMDynamicFunctionWithoutEnv {
|
VMDynamicFunctionImportContext::from_context(VMDynamicFunctionWithoutEnv {
|
||||||
func: Box::new(func),
|
func: Box::new(func),
|
||||||
});
|
});
|
||||||
let address = std::ptr::null() as *const () as *const VMFunctionBody;
|
let address = std::ptr::null() as *const VMFunctionBody;
|
||||||
let vmctx = Box::leak(Box::new(dynamic_ctx)) as *mut _ as *mut VMContext;
|
let vmctx = Box::into_raw(Box::new(dynamic_ctx)) as *mut VMContext;
|
||||||
let signature = store.engine().register_signature(&ty);
|
let signature = store.engine().register_signature(&ty);
|
||||||
Self {
|
Self {
|
||||||
store: store.clone(),
|
store: store.clone(),
|
||||||
@@ -569,8 +569,8 @@ impl Function {
|
|||||||
env,
|
env,
|
||||||
func: Box::new(func),
|
func: Box::new(func),
|
||||||
});
|
});
|
||||||
let address = std::ptr::null() as *const () as *const VMFunctionBody;
|
let address = std::ptr::null() as *const VMFunctionBody;
|
||||||
let vmctx = Box::leak(Box::new(dynamic_ctx)) as *mut _ as *mut VMContext;
|
let vmctx = Box::into_raw(Box::new(dynamic_ctx)) as *mut VMContext;
|
||||||
let signature = store.engine().register_signature(&ty);
|
let signature = store.engine().register_signature(&ty);
|
||||||
Self {
|
Self {
|
||||||
store: store.clone(),
|
store: store.clone(),
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ pub use wasmer_compiler::{Features, Target};
|
|||||||
pub use wasmer_engine::{
|
pub use wasmer_engine::{
|
||||||
DeserializeError, Engine, InstantiationError, LinkError, RuntimeError, SerializeError,
|
DeserializeError, Engine, InstantiationError, LinkError, RuntimeError, SerializeError,
|
||||||
};
|
};
|
||||||
pub use wasmer_runtime::MemoryError;
|
pub use wasmer_runtime::{raise_user_trap, MemoryError};
|
||||||
|
|
||||||
// The compilers are mutually exclusive
|
// The compilers are mutually exclusive
|
||||||
#[cfg(any(
|
#[cfg(any(
|
||||||
|
|||||||
@@ -326,11 +326,11 @@ impl Module {
|
|||||||
&self.store
|
&self.store
|
||||||
}
|
}
|
||||||
|
|
||||||
// The ABI of the ModuleInfo is very unstable, we refactor it very often.
|
/// The ABI of the ModuleInfo is very unstable, we refactor it very often.
|
||||||
// This funciton is public because in some cases it can be useful to get some
|
/// This funciton is public because in some cases it can be useful to get some
|
||||||
// extra information from the module.
|
/// extra information from the module.
|
||||||
//
|
///
|
||||||
// However, the usage is highly discouraged.
|
/// However, the usage is highly discouraged.
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
pub fn info(&self) -> &ModuleInfo {
|
pub fn info(&self) -> &ModuleInfo {
|
||||||
&self.compiled.module()
|
&self.compiled.module()
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ crate-type = ["cdylib", "staticlib"]
|
|||||||
[dependencies]
|
[dependencies]
|
||||||
lazy_static = "1"
|
lazy_static = "1"
|
||||||
libc = { version = "0.2.70", default-features = false }
|
libc = { version = "0.2.70", default-features = false }
|
||||||
|
libffi = { version = "0.9" }
|
||||||
# for generating code in the same way thot the wasm-c-api does
|
# for generating code in the same way thot the wasm-c-api does
|
||||||
# Commented out for now until we can find a solution to the exported function problem
|
# Commented out for now until we can find a solution to the exported function problem
|
||||||
# wasmer-wasm-c-api = { version = "0.16.2", path = "crates/wasm-c-api" }
|
# wasmer-wasm-c-api = { version = "0.16.2", path = "crates/wasm-c-api" }
|
||||||
@@ -27,6 +28,11 @@ features = ["compiler", "engine", "jit", "cranelift"]
|
|||||||
path = "../api"
|
path = "../api"
|
||||||
version = "0.16.2"
|
version = "0.16.2"
|
||||||
|
|
||||||
|
[dependencies.wasm-common]
|
||||||
|
default-features = false
|
||||||
|
path = "../wasm-common"
|
||||||
|
version = "0.16.2"
|
||||||
|
|
||||||
[dependencies.wasmer-wasi]
|
[dependencies.wasmer-wasi]
|
||||||
default-features = false
|
default-features = false
|
||||||
path = "../wasi"
|
path = "../wasi"
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ use crate::{
|
|||||||
error::{update_last_error, CApiError},
|
error::{update_last_error, CApiError},
|
||||||
global::wasmer_global_t,
|
global::wasmer_global_t,
|
||||||
import::wasmer_import_func_t,
|
import::wasmer_import_func_t,
|
||||||
|
instance::CAPIInstance,
|
||||||
memory::wasmer_memory_t,
|
memory::wasmer_memory_t,
|
||||||
module::wasmer_module_t,
|
module::wasmer_module_t,
|
||||||
table::wasmer_table_t,
|
table::wasmer_table_t,
|
||||||
@@ -14,7 +15,7 @@ use crate::{
|
|||||||
use libc::{c_int, c_uint};
|
use libc::{c_int, c_uint};
|
||||||
use std::ptr::{self, NonNull};
|
use std::ptr::{self, NonNull};
|
||||||
use std::slice;
|
use std::slice;
|
||||||
use wasmer::{ExportType, ExternType, Function, ImportType, Instance, Memory, Module, Val};
|
use wasmer::{ExportType, ExternType, Function, ImportType, Memory, Module, Val};
|
||||||
|
|
||||||
/// Intermediate representation of an `Export` instance that is
|
/// Intermediate representation of an `Export` instance that is
|
||||||
/// exposed to C.
|
/// exposed to C.
|
||||||
@@ -23,7 +24,7 @@ pub(crate) struct NamedExport {
|
|||||||
pub(crate) export_type: ExportType,
|
pub(crate) export_type: ExportType,
|
||||||
|
|
||||||
/// The instance that holds the export.
|
/// The instance that holds the export.
|
||||||
pub(crate) instance: NonNull<Instance>,
|
pub(crate) instance: NonNull<CAPIInstance>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Opaque pointer to `ImportType`.
|
/// Opaque pointer to `ImportType`.
|
||||||
@@ -403,6 +404,7 @@ pub unsafe extern "C" fn wasmer_export_to_memory(
|
|||||||
let instance = named_export.instance.as_ref();
|
let instance = named_export.instance.as_ref();
|
||||||
|
|
||||||
if let Ok(exported_memory) = instance
|
if let Ok(exported_memory) = instance
|
||||||
|
.instance
|
||||||
.exports
|
.exports
|
||||||
.get::<Memory>(&named_export.export_type.name())
|
.get::<Memory>(&named_export.export_type.name())
|
||||||
{
|
{
|
||||||
@@ -477,7 +479,11 @@ pub unsafe extern "C" fn wasmer_export_func_call(
|
|||||||
let results: &mut [wasmer_value_t] = slice::from_raw_parts_mut(results, results_len as usize);
|
let results: &mut [wasmer_value_t] = slice::from_raw_parts_mut(results, results_len as usize);
|
||||||
|
|
||||||
let instance = named_export.instance.as_ref();
|
let instance = named_export.instance.as_ref();
|
||||||
let f: &Function = match instance.exports.get(&named_export.export_type.name()) {
|
let f: &Function = match instance
|
||||||
|
.instance
|
||||||
|
.exports
|
||||||
|
.get(&named_export.export_type.name())
|
||||||
|
{
|
||||||
Ok(f) => f,
|
Ok(f) => f,
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
update_last_error(err);
|
update_last_error(err);
|
||||||
|
|||||||
@@ -1,7 +1,11 @@
|
|||||||
//! Functions and types for dealing with Emscripten imports
|
//! Functions and types for dealing with Emscripten imports
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
use crate::{get_slice_checked, instance::wasmer_instance_t, module::wasmer_module_t};
|
use crate::{
|
||||||
|
get_slice_checked,
|
||||||
|
instance::{wasmer_instance_t, CAPIInstance},
|
||||||
|
module::wasmer_module_t,
|
||||||
|
};
|
||||||
|
|
||||||
use std::ptr;
|
use std::ptr;
|
||||||
use wasmer::wasm::{Instance, Module};
|
use wasmer::wasm::{Instance, Module};
|
||||||
@@ -54,16 +58,16 @@ pub unsafe extern "C" fn wasmer_emscripten_set_up(
|
|||||||
if globals.is_null() || instance.is_null() {
|
if globals.is_null() || instance.is_null() {
|
||||||
return wasmer_result_t::WASMER_ERROR;
|
return wasmer_result_t::WASMER_ERROR;
|
||||||
}
|
}
|
||||||
let instance = &mut *(instance as *mut Instance);
|
let instance = &mut *(instance as *mut CAPIInstance);
|
||||||
let globals = &*(globals as *mut EmscriptenGlobals);
|
let globals = &*(globals as *mut EmscriptenGlobals);
|
||||||
let em_data = Box::into_raw(Box::new(EmscriptenData::new(
|
let em_data = Box::into_raw(Box::new(EmscriptenData::new(
|
||||||
instance,
|
instance.instance,
|
||||||
&globals.data,
|
&globals.data,
|
||||||
Default::default(),
|
Default::default(),
|
||||||
))) as *mut c_void;
|
))) as *mut c_void;
|
||||||
instance.context_mut().data = em_data;
|
instance.context_mut().data = em_data;
|
||||||
|
|
||||||
match wasmer_emscripten::set_up_emscripten(instance) {
|
match wasmer_emscripten::set_up_emscripten(instance.instance) {
|
||||||
Ok(_) => wasmer_result_t::WASMER_OK,
|
Ok(_) => wasmer_result_t::WASMER_OK,
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
update_last_error(e);
|
update_last_error(e);
|
||||||
@@ -90,7 +94,7 @@ pub unsafe extern "C" fn wasmer_emscripten_call_main(
|
|||||||
if instance.is_null() || args.is_null() {
|
if instance.is_null() || args.is_null() {
|
||||||
return wasmer_result_t::WASMER_ERROR;
|
return wasmer_result_t::WASMER_ERROR;
|
||||||
}
|
}
|
||||||
let instance = &mut *(instance as *mut Instance);
|
let instance = &mut *(instance as *mut CAPIInstance);
|
||||||
|
|
||||||
let arg_list = get_slice_checked(args, args_len as usize);
|
let arg_list = get_slice_checked(args, args_len as usize);
|
||||||
let arg_process_result: Result<Vec<&str>, _> =
|
let arg_process_result: Result<Vec<&str>, _> =
|
||||||
@@ -113,7 +117,7 @@ pub unsafe extern "C" fn wasmer_emscripten_call_main(
|
|||||||
return wasmer_result_t::WASMER_ERROR;
|
return wasmer_result_t::WASMER_ERROR;
|
||||||
};
|
};
|
||||||
|
|
||||||
match wasmer_emscripten::emscripten_call_main(instance, prog_name, &arg_vec[1..]) {
|
match wasmer_emscripten::emscripten_call_main(instance.instance, prog_name, &arg_vec[1..]) {
|
||||||
Ok(_) => wasmer_result_t::WASMER_OK,
|
Ok(_) => wasmer_result_t::WASMER_OK,
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
update_last_error(e);
|
update_last_error(e);
|
||||||
|
|||||||
@@ -4,22 +4,23 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
error::{update_last_error, CApiError},
|
error::{update_last_error, CApiError},
|
||||||
export::{wasmer_import_export_kind, wasmer_import_export_value},
|
export::{wasmer_import_export_kind, wasmer_import_export_value},
|
||||||
instance::wasmer_instance_context_t,
|
instance::{wasmer_instance_context_t, CAPIInstance},
|
||||||
module::wasmer_module_t,
|
module::wasmer_module_t,
|
||||||
value::wasmer_value_tag,
|
value::wasmer_value_tag,
|
||||||
wasmer_byte_array, wasmer_result_t,
|
wasmer_byte_array, wasmer_result_t,
|
||||||
};
|
};
|
||||||
use libc::c_uint;
|
use libc::c_uint;
|
||||||
use std::ptr::NonNull;
|
use std::ptr::{self, NonNull};
|
||||||
use std::{
|
use std::{
|
||||||
//convert::TryFrom,
|
//convert::TryFrom,
|
||||||
ffi::c_void,
|
ffi::{c_void, CStr},
|
||||||
os::raw::c_char,
|
os::raw::c_char,
|
||||||
slice,
|
slice,
|
||||||
//sync::Arc,
|
//sync::Arc,
|
||||||
};
|
};
|
||||||
use wasmer::{
|
use wasmer::{
|
||||||
Function, Global, ImportObject, ImportObjectIterator, ImportType, Memory, Module, Table,
|
Function, FunctionType, Global, ImportObject, ImportObjectIterator, ImportType, Memory, Module,
|
||||||
|
RuntimeError, Table, Val, ValType,
|
||||||
};
|
};
|
||||||
//use wasmer::wasm::{Export, FuncSig, Global, Memory, Module, Table, Type};
|
//use wasmer::wasm::{Export, FuncSig, Global, Memory, Module, Table, Type};
|
||||||
/*use wasmer_runtime_core::{
|
/*use wasmer_runtime_core::{
|
||||||
@@ -440,7 +441,9 @@ pub unsafe extern "C" fn wasmer_import_object_extend(
|
|||||||
Extern::Memory((&*mem).clone())
|
Extern::Memory((&*mem).clone())
|
||||||
}
|
}
|
||||||
wasmer_import_export_kind::WASM_FUNCTION => {
|
wasmer_import_export_kind::WASM_FUNCTION => {
|
||||||
let func_export = import.value.func as *mut Function;
|
// TODO: investigate consistent usage of `FunctionWrapper` in this context
|
||||||
|
let func_wrapper = import.value.func as *mut FunctionWrapper;
|
||||||
|
let func_export = func_wrapper.func.as_ptr();
|
||||||
Extern::Function((&*func_export).clone())
|
Extern::Function((&*func_export).clone())
|
||||||
}
|
}
|
||||||
wasmer_import_export_kind::WASM_GLOBAL => {
|
wasmer_import_export_kind::WASM_GLOBAL => {
|
||||||
@@ -460,7 +463,7 @@ pub unsafe extern "C" fn wasmer_import_object_extend(
|
|||||||
import_object.extend(extensions);
|
import_object.extend(extensions);
|
||||||
|
|
||||||
return wasmer_result_t::WASMER_OK;
|
return wasmer_result_t::WASMER_OK;
|
||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Gets import descriptors for the given module
|
/// Gets import descriptors for the given module
|
||||||
@@ -589,6 +592,29 @@ pub unsafe extern "C" fn wasmer_import_func_params_arity(
|
|||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// struct used to pass in context to functions (which must be back-patched)
|
||||||
|
#[derive(Debug, Default)]
|
||||||
|
pub(crate) struct LegacyEnv {
|
||||||
|
pub(crate) instance_ptr: Option<NonNull<CAPIInstance>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl LegacyEnv {
|
||||||
|
pub(crate) fn ctx_ptr(&self) -> *mut CAPIInstance {
|
||||||
|
self.instance_ptr
|
||||||
|
.map(|p| p.as_ptr())
|
||||||
|
.unwrap_or(ptr::null_mut())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// struct used to hold on to `LegacyEnv` pointer as well as the function.
|
||||||
|
/// we need to do this to initialize the context ptr inside of `LegacyEnv` when
|
||||||
|
/// instantiating the module.
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub(crate) struct FunctionWrapper {
|
||||||
|
pub(crate) func: NonNull<Function>,
|
||||||
|
pub(crate) legacy_env: NonNull<LegacyEnv>,
|
||||||
|
}
|
||||||
|
|
||||||
/// Creates new host function, aka imported function. `func` is a
|
/// Creates new host function, aka imported function. `func` is a
|
||||||
/// function pointer, where the first argument is the famous `vm::Ctx`
|
/// function pointer, where the first argument is the famous `vm::Ctx`
|
||||||
/// (in Rust), or `wasmer_instance_context_t` (in C). All arguments
|
/// (in Rust), or `wasmer_instance_context_t` (in C). All arguments
|
||||||
@@ -615,20 +641,61 @@ pub unsafe extern "C" fn wasmer_import_func_new(
|
|||||||
returns: *const wasmer_value_tag,
|
returns: *const wasmer_value_tag,
|
||||||
returns_len: c_uint,
|
returns_len: c_uint,
|
||||||
) -> *mut wasmer_import_func_t {
|
) -> *mut wasmer_import_func_t {
|
||||||
unimplemented!("`wasmer_import_func_new` cannot be implemented yet")
|
|
||||||
/*
|
|
||||||
let params: &[wasmer_value_tag] = slice::from_raw_parts(params, params_len as usize);
|
let params: &[wasmer_value_tag] = slice::from_raw_parts(params, params_len as usize);
|
||||||
let params: Vec<Type> = params.iter().cloned().map(|x| x.into()).collect();
|
let params: Vec<ValType> = params.iter().cloned().map(|x| x.into()).collect();
|
||||||
let returns: &[wasmer_value_tag] = slice::from_raw_parts(returns, returns_len as usize);
|
let returns: &[wasmer_value_tag] = slice::from_raw_parts(returns, returns_len as usize);
|
||||||
let returns: Vec<Type> = returns.iter().cloned().map(|x| x.into()).collect();
|
let returns: Vec<ValType> = returns.iter().cloned().map(|x| x.into()).collect();
|
||||||
|
let func_type = FunctionType::new(params, &returns[..]);
|
||||||
|
|
||||||
let export = Box::new(Extern::Function {
|
let store = crate::get_global_store();
|
||||||
func: FuncPointer::new(func as _),
|
|
||||||
ctx: Context::Internal,
|
let env_ptr = Box::into_raw(Box::new(LegacyEnv::default()));
|
||||||
signature: Arc::new(FuncSig::new(params, returns)),
|
|
||||||
|
let func = Function::new_dynamic_env(store, &func_type, &mut *env_ptr, move |env, args| {
|
||||||
|
use libffi::high::call::{call, Arg};
|
||||||
|
use libffi::low::CodePtr;
|
||||||
|
|
||||||
|
let ctx_ptr = env.ctx_ptr();
|
||||||
|
let ctx_ptr_val = ctx_ptr as *const _ as isize as i64;
|
||||||
|
|
||||||
|
let ffi_args: Vec<Arg> = {
|
||||||
|
let mut ffi_args = Vec::with_capacity(args.len() + 1);
|
||||||
|
ffi_args.push(Arg::new::<i64>(&ctx_ptr_val));
|
||||||
|
ffi_args.extend(args.iter().map(|ty| match ty {
|
||||||
|
Val::I32(v) => Arg::new::<i32>(v),
|
||||||
|
Val::I64(v) => Arg::new::<i64>(v),
|
||||||
|
Val::F32(v) => Arg::new::<f32>(v),
|
||||||
|
Val::F64(v) => Arg::new::<f64>(v),
|
||||||
|
_ => todo!("Unsupported type in C API"),
|
||||||
|
}));
|
||||||
|
|
||||||
|
ffi_args
|
||||||
|
};
|
||||||
|
let code_ptr = CodePtr::from_ptr(func as _);
|
||||||
|
|
||||||
|
assert!(returns.len() <= 1);
|
||||||
|
|
||||||
|
let return_value = if returns.len() == 1 {
|
||||||
|
vec![match returns[0] {
|
||||||
|
ValType::I32 => Val::I32(call::<i32>(code_ptr, &ffi_args)),
|
||||||
|
ValType::I64 => Val::I64(call::<i64>(code_ptr, &ffi_args)),
|
||||||
|
ValType::F32 => Val::F32(call::<f32>(code_ptr, &ffi_args)),
|
||||||
|
ValType::F64 => Val::F64(call::<f64>(code_ptr, &ffi_args)),
|
||||||
|
_ => todo!("Unsupported type in C API"),
|
||||||
|
}]
|
||||||
|
} else {
|
||||||
|
call::<()>(code_ptr, &ffi_args);
|
||||||
|
vec![]
|
||||||
|
};
|
||||||
|
|
||||||
|
Ok(return_value)
|
||||||
});
|
});
|
||||||
Box::into_raw(export) as *mut wasmer_import_func_t
|
|
||||||
*/
|
let function_wrapper = FunctionWrapper {
|
||||||
|
func: NonNull::new_unchecked(Box::into_raw(Box::new(func))),
|
||||||
|
legacy_env: NonNull::new_unchecked(env_ptr),
|
||||||
|
};
|
||||||
|
Box::into_raw(Box::new(function_wrapper)) as *mut wasmer_import_func_t
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Stop the execution of a host function, aka imported function. The
|
/// Stop the execution of a host function, aka imported function. The
|
||||||
@@ -648,19 +715,9 @@ pub unsafe extern "C" fn wasmer_import_func_new(
|
|||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
#[allow(clippy::cast_ptr_alignment)]
|
#[allow(clippy::cast_ptr_alignment)]
|
||||||
pub unsafe extern "C" fn wasmer_trap(
|
pub unsafe extern "C" fn wasmer_trap(
|
||||||
ctx: *const wasmer_instance_context_t,
|
_ctx: *const wasmer_instance_context_t,
|
||||||
error_message: *const c_char,
|
error_message: *const c_char,
|
||||||
) -> wasmer_result_t {
|
) -> wasmer_result_t {
|
||||||
todo!("wasmer_trap: manually trap without Ctx")
|
|
||||||
/*
|
|
||||||
if ctx.is_null() {
|
|
||||||
update_last_error(CApiError {
|
|
||||||
msg: "ctx ptr is null in wasmer_trap".to_string(),
|
|
||||||
});
|
|
||||||
|
|
||||||
return wasmer_result_t::WASMER_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
if error_message.is_null() {
|
if error_message.is_null() {
|
||||||
update_last_error(CApiError {
|
update_last_error(CApiError {
|
||||||
msg: "error_message is null in wasmer_trap".to_string(),
|
msg: "error_message is null in wasmer_trap".to_string(),
|
||||||
@@ -669,12 +726,9 @@ pub unsafe extern "C" fn wasmer_trap(
|
|||||||
return wasmer_result_t::WASMER_ERROR;
|
return wasmer_result_t::WASMER_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
let ctx = &*(ctx as *const Ctx);
|
|
||||||
let error_message = CStr::from_ptr(error_message).to_str().unwrap();
|
let error_message = CStr::from_ptr(error_message).to_str().unwrap();
|
||||||
|
|
||||||
(&*ctx.module)
|
wasmer::raise_user_trap(Box::new(RuntimeError::new(error_message))); // never returns
|
||||||
.runnable_module
|
|
||||||
.do_early_trap(Box::new(error_message)); // never returns
|
|
||||||
|
|
||||||
// cbindgen does not generate a binding for a function that
|
// cbindgen does not generate a binding for a function that
|
||||||
// returns `!`. Since we also need to error in some cases, the
|
// returns `!`. Since we also need to error in some cases, the
|
||||||
@@ -684,7 +738,6 @@ pub unsafe extern "C" fn wasmer_trap(
|
|||||||
// cbindgen, and get an acceptable clean code.
|
// cbindgen, and get an acceptable clean code.
|
||||||
#[allow(unreachable_code)]
|
#[allow(unreachable_code)]
|
||||||
wasmer_result_t::WASMER_OK
|
wasmer_result_t::WASMER_OK
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Sets the params buffer to the parameter types of the given wasmer_import_func_t
|
/// Sets the params buffer to the parameter types of the given wasmer_import_func_t
|
||||||
@@ -769,7 +822,9 @@ pub unsafe extern "C" fn wasmer_import_func_returns_arity(
|
|||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub unsafe extern "C" fn wasmer_import_func_destroy(func: Option<NonNull<wasmer_import_func_t>>) {
|
pub unsafe extern "C" fn wasmer_import_func_destroy(func: Option<NonNull<wasmer_import_func_t>>) {
|
||||||
if let Some(func) = func {
|
if let Some(func) = func {
|
||||||
Box::from_raw(func.cast::<Function>().as_ptr());
|
let function_wrapper = Box::from_raw(func.cast::<FunctionWrapper>().as_ptr());
|
||||||
|
let _legacy_env = Box::from_raw(function_wrapper.legacy_env.as_ptr());
|
||||||
|
let _function = Box::from_raw(function_wrapper.func.as_ptr());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
error::{update_last_error, CApiError},
|
error::{update_last_error, CApiError},
|
||||||
export::{wasmer_exports_t, wasmer_import_export_kind, NamedExport, NamedExports},
|
export::{wasmer_exports_t, wasmer_import_export_kind, NamedExport, NamedExports},
|
||||||
import::wasmer_import_t,
|
import::{wasmer_import_t, FunctionWrapper},
|
||||||
memory::wasmer_memory_t,
|
memory::wasmer_memory_t,
|
||||||
value::{wasmer_value, wasmer_value_t, wasmer_value_tag},
|
value::{wasmer_value, wasmer_value_t, wasmer_value_tag},
|
||||||
wasmer_result_t,
|
wasmer_result_t,
|
||||||
@@ -13,18 +13,34 @@ use std::collections::HashMap;
|
|||||||
use std::ffi::CStr;
|
use std::ffi::CStr;
|
||||||
use std::ptr::NonNull;
|
use std::ptr::NonNull;
|
||||||
use std::slice;
|
use std::slice;
|
||||||
|
use wasm_common::{entity::*, ExportIndex, MemoryIndex};
|
||||||
use wasmer::{
|
use wasmer::{
|
||||||
Exports, Extern, Function, Global, ImportObject, Instance, Memory, Module, Table, Val,
|
Exports, Extern, Function, Global, ImportObject, Instance, Memory, Module, Table, Val,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Opaque pointer to a `wasmer_runtime::Instance` value in Rust.
|
/// Opaque pointer to an Instance type plus metadata.
|
||||||
///
|
///
|
||||||
/// A `wasmer_runtime::Instance` represents a WebAssembly instance. It
|
/// This type represents a WebAssembly instance. It
|
||||||
/// is generally generated by the `wasmer_instantiate()` function, or by
|
/// is generally generated by the `wasmer_instantiate()` function, or by
|
||||||
/// the `wasmer_module_instantiate()` function for the most common paths.
|
/// the `wasmer_module_instantiate()` function for the most common paths.
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
pub struct wasmer_instance_t;
|
pub struct wasmer_instance_t;
|
||||||
|
|
||||||
|
/// A wrapper around a Wasmer instance with extra data to maintain the existing API
|
||||||
|
pub(crate) struct CAPIInstance {
|
||||||
|
/// The real wasmer `Instance`
|
||||||
|
pub(crate) instance: Instance,
|
||||||
|
/// List of pointers of memories that are imported into this Instance. This is
|
||||||
|
/// required because the old Wasmer API allowed accessing these from the Instance
|
||||||
|
/// but the new/current API does not. So we store them here to allow functions to
|
||||||
|
/// access this data for backwards compatibilty.
|
||||||
|
pub(crate) imported_memories: Vec<*mut Memory>,
|
||||||
|
/// The Instance/Ctx wide data. Previously the Ctx Instance were separate, but
|
||||||
|
/// given the internal API changes this is no longer true: this is a single global
|
||||||
|
/// void pointer like the old Wasmer API used to have.
|
||||||
|
pub(crate) ctx_data: Option<NonNull<c_void>>,
|
||||||
|
}
|
||||||
|
|
||||||
/// Opaque pointer to a `wasmer_runtime::Ctx` value in Rust.
|
/// Opaque pointer to a `wasmer_runtime::Ctx` value in Rust.
|
||||||
///
|
///
|
||||||
/// An instance context is passed to any host function (aka imported
|
/// An instance context is passed to any host function (aka imported
|
||||||
@@ -112,6 +128,8 @@ pub unsafe extern "C" fn wasmer_instantiate(
|
|||||||
});
|
});
|
||||||
return wasmer_result_t::WASMER_ERROR;
|
return wasmer_result_t::WASMER_ERROR;
|
||||||
};
|
};
|
||||||
|
let mut imported_memories = vec![];
|
||||||
|
let mut instance_pointers_to_update = vec![];
|
||||||
let imports: &[wasmer_import_t] = slice::from_raw_parts(imports, imports_len as usize);
|
let imports: &[wasmer_import_t] = slice::from_raw_parts(imports, imports_len as usize);
|
||||||
let mut import_object = ImportObject::new();
|
let mut import_object = ImportObject::new();
|
||||||
let mut namespaces = HashMap::new();
|
let mut namespaces = HashMap::new();
|
||||||
@@ -147,10 +165,14 @@ pub unsafe extern "C" fn wasmer_instantiate(
|
|||||||
let export = match import.tag {
|
let export = match import.tag {
|
||||||
wasmer_import_export_kind::WASM_MEMORY => {
|
wasmer_import_export_kind::WASM_MEMORY => {
|
||||||
let mem = import.value.memory as *mut Memory;
|
let mem = import.value.memory as *mut Memory;
|
||||||
|
// TODO: review ownership here, probably need to clone Memory for imported_meomries
|
||||||
|
imported_memories.push(mem);
|
||||||
Extern::Memory((&*mem).clone())
|
Extern::Memory((&*mem).clone())
|
||||||
}
|
}
|
||||||
wasmer_import_export_kind::WASM_FUNCTION => {
|
wasmer_import_export_kind::WASM_FUNCTION => {
|
||||||
let func_export = import.value.func as *mut Function;
|
let func_wrapper = import.value.func as *mut FunctionWrapper;
|
||||||
|
let func_export = (*func_wrapper).func.as_ptr();
|
||||||
|
instance_pointers_to_update.push((*func_wrapper).legacy_env);
|
||||||
Extern::Function((&*func_export).clone())
|
Extern::Function((&*func_export).clone())
|
||||||
}
|
}
|
||||||
wasmer_import_export_kind::WASM_GLOBAL => {
|
wasmer_import_export_kind::WASM_GLOBAL => {
|
||||||
@@ -187,7 +209,16 @@ pub unsafe extern "C" fn wasmer_instantiate(
|
|||||||
return wasmer_result_t::WASMER_ERROR;
|
return wasmer_result_t::WASMER_ERROR;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
*instance = Box::into_raw(Box::new(new_instance)) as *mut wasmer_instance_t;
|
let c_api_instance = CAPIInstance {
|
||||||
|
instance: new_instance,
|
||||||
|
imported_memories,
|
||||||
|
ctx_data: None,
|
||||||
|
};
|
||||||
|
let c_api_instance_pointer = Box::into_raw(Box::new(c_api_instance));
|
||||||
|
for mut to_update in instance_pointers_to_update {
|
||||||
|
to_update.as_mut().instance_ptr = Some(NonNull::new_unchecked(c_api_instance_pointer));
|
||||||
|
}
|
||||||
|
*instance = c_api_instance_pointer as *mut wasmer_instance_t;
|
||||||
wasmer_result_t::WASMER_OK
|
wasmer_result_t::WASMER_OK
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -207,16 +238,13 @@ pub unsafe extern "C" fn wasmer_instantiate(
|
|||||||
/// It is often useful with `wasmer_instance_context_data_set()`.
|
/// It is often useful with `wasmer_instance_context_data_set()`.
|
||||||
#[allow(clippy::cast_ptr_alignment)]
|
#[allow(clippy::cast_ptr_alignment)]
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub extern "C" fn wasmer_instance_context_get(
|
pub unsafe extern "C" fn wasmer_instance_context_get(
|
||||||
instance: Option<NonNull<wasmer_instance_t>>,
|
instance: Option<NonNull<wasmer_instance_t>>,
|
||||||
) -> Option<&'static wasmer_instance_context_t> {
|
) -> Option<&'static wasmer_instance_context_t> {
|
||||||
unimplemented!("wasmer_instance_context_get: API changed")
|
// TODO: double check that `wasmer_instance_t` can be safely cast into CAPIInstance
|
||||||
/*
|
let instance: *mut CAPIInstance = instance?.cast::<CAPIInstance>().as_ptr();
|
||||||
let instance = instance?.as_ref();
|
|
||||||
let context: *const Ctx = instance.context() as *const _;
|
|
||||||
|
|
||||||
context as *const wasmer_instance_context_t
|
Some(&*(instance as *const wasmer_instance_context_t))
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Calls an exported function of a WebAssembly instance by `name`
|
/// Calls an exported function of a WebAssembly instance by `name`
|
||||||
@@ -310,8 +338,8 @@ pub unsafe extern "C" fn wasmer_instance_call(
|
|||||||
|
|
||||||
let results: &mut [wasmer_value_t] = slice::from_raw_parts_mut(results, results_len as usize);
|
let results: &mut [wasmer_value_t] = slice::from_raw_parts_mut(results, results_len as usize);
|
||||||
|
|
||||||
let instance = &*(instance as *mut Instance);
|
let instance = &*(instance as *mut CAPIInstance);
|
||||||
let f: &Function = match instance.exports.get(func_name_r) {
|
let f: &Function = match instance.instance.exports.get(func_name_r) {
|
||||||
Ok(f) => f,
|
Ok(f) => f,
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
update_last_error(err);
|
update_last_error(err);
|
||||||
@@ -405,7 +433,7 @@ pub unsafe extern "C" fn wasmer_instance_exports(
|
|||||||
exports: *mut *mut wasmer_exports_t,
|
exports: *mut *mut wasmer_exports_t,
|
||||||
) {
|
) {
|
||||||
let instance = if let Some(instance) = instance {
|
let instance = if let Some(instance) = instance {
|
||||||
instance.cast::<Instance>()
|
instance.cast::<CAPIInstance>()
|
||||||
} else {
|
} else {
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
@@ -414,6 +442,7 @@ pub unsafe extern "C" fn wasmer_instance_exports(
|
|||||||
let instance_ref = instance_ref_copy.as_mut();
|
let instance_ref = instance_ref_copy.as_mut();
|
||||||
|
|
||||||
let exports_vec: Vec<NamedExport> = instance_ref
|
let exports_vec: Vec<NamedExport> = instance_ref
|
||||||
|
.instance
|
||||||
.module()
|
.module()
|
||||||
.exports()
|
.exports()
|
||||||
.map(|export_type| NamedExport {
|
.map(|export_type| NamedExport {
|
||||||
@@ -457,22 +486,17 @@ pub unsafe extern "C" fn wasmer_instance_exports(
|
|||||||
/// ```
|
/// ```
|
||||||
#[allow(clippy::cast_ptr_alignment)]
|
#[allow(clippy::cast_ptr_alignment)]
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub extern "C" fn wasmer_instance_context_data_set(
|
pub unsafe extern "C" fn wasmer_instance_context_data_set(
|
||||||
instance: *mut wasmer_instance_t,
|
instance: Option<NonNull<wasmer_instance_t>>,
|
||||||
data_ptr: *mut c_void,
|
data_ptr: *mut c_void,
|
||||||
) {
|
) {
|
||||||
unimplemented!(
|
let instance = if let Some(instance_inner) = instance {
|
||||||
"wasmer_instance_context_data_set: API changed in a way that this is non-obvious"
|
instance_inner
|
||||||
)
|
} else {
|
||||||
/*
|
|
||||||
if instance.is_null() {
|
|
||||||
return;
|
return;
|
||||||
}
|
};
|
||||||
|
|
||||||
let instance = unsafe { &mut *(instance as *mut Instance) };
|
instance.cast::<CAPIInstance>().as_mut().ctx_data = NonNull::new(data_ptr);
|
||||||
|
|
||||||
instance.context_mut().data = data_ptr;
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Gets the `memory_idx`th memory of the instance.
|
/// Gets the `memory_idx`th memory of the instance.
|
||||||
@@ -498,15 +522,53 @@ pub extern "C" fn wasmer_instance_context_data_set(
|
|||||||
/// ```
|
/// ```
|
||||||
#[allow(clippy::cast_ptr_alignment)]
|
#[allow(clippy::cast_ptr_alignment)]
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub extern "C" fn wasmer_instance_context_memory(
|
pub unsafe extern "C" fn wasmer_instance_context_memory(
|
||||||
ctx: *const wasmer_instance_context_t,
|
ctx: *const wasmer_instance_context_t,
|
||||||
_memory_idx: u32,
|
_memory_idx: u32,
|
||||||
) -> *const wasmer_memory_t {
|
) -> Option<&'static wasmer_memory_t> {
|
||||||
unimplemented!("wasmer_instance_context_memory: API changed")
|
let instance = &*(ctx as *const CAPIInstance);
|
||||||
/*let ctx = unsafe { &*(ctx as *const Ctx) };
|
let module = instance.instance.module();
|
||||||
let memory = ctx.memory(0);
|
let memory_index = MemoryIndex::new(0);
|
||||||
memory as *const Memory as *const wasmer_memory_t
|
if module.info().is_imported_memory(memory_index) {
|
||||||
*/
|
if let Some(memory) = instance.imported_memories.first() {
|
||||||
|
let memory: &Memory = &**memory;
|
||||||
|
return Some(&*(Box::into_raw(Box::new(memory.clone())) as *const wasmer_memory_t));
|
||||||
|
} else {
|
||||||
|
update_last_error(CApiError {
|
||||||
|
msg:
|
||||||
|
"Internal error: memory is imported but the list of imported memories is empty"
|
||||||
|
.to_string(),
|
||||||
|
});
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
let exported_memory_name = if let Some(name) = module
|
||||||
|
.info()
|
||||||
|
.exports
|
||||||
|
.iter()
|
||||||
|
.filter_map(|(name, export_index)| match export_index {
|
||||||
|
ExportIndex::Memory(idx) if *idx == memory_index => Some(name),
|
||||||
|
_ => None,
|
||||||
|
})
|
||||||
|
.next()
|
||||||
|
{
|
||||||
|
name
|
||||||
|
} else {
|
||||||
|
update_last_error(CApiError {
|
||||||
|
msg: "Could not find an exported memory".to_string(),
|
||||||
|
});
|
||||||
|
return None;
|
||||||
|
};
|
||||||
|
let memory = instance
|
||||||
|
.instance
|
||||||
|
.exports
|
||||||
|
.get_memory(exported_memory_name)
|
||||||
|
.expect(&format!(
|
||||||
|
"Module exports memory named `{}` but it's inaccessible",
|
||||||
|
&exported_memory_name
|
||||||
|
));
|
||||||
|
Some(&*(Box::into_raw(Box::new(memory.clone())) as *const wasmer_memory_t))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Gets the data that can be hold by an instance.
|
/// Gets the data that can be hold by an instance.
|
||||||
@@ -519,19 +581,11 @@ pub extern "C" fn wasmer_instance_context_memory(
|
|||||||
/// This function returns nothing if `ctx` is a null pointer.
|
/// This function returns nothing if `ctx` is a null pointer.
|
||||||
#[allow(clippy::cast_ptr_alignment)]
|
#[allow(clippy::cast_ptr_alignment)]
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub extern "C" fn wasmer_instance_context_data_get(
|
pub unsafe extern "C" fn wasmer_instance_context_data_get(
|
||||||
ctx: *const wasmer_instance_context_t,
|
ctx: Option<&'static wasmer_instance_context_t>,
|
||||||
) -> *mut c_void {
|
) -> Option<NonNull<c_void>> {
|
||||||
unimplemented!("wasmer_instance_context_data_get: API changed")
|
let instance: &'static CAPIInstance = &*(ctx? as *const _ as *const CAPIInstance);
|
||||||
/*
|
instance.ctx_data
|
||||||
if ctx.is_null() {
|
|
||||||
return ptr::null_mut() as _;
|
|
||||||
}
|
|
||||||
|
|
||||||
let ctx = unsafe { &*(ctx as *const Ctx) };
|
|
||||||
|
|
||||||
ctx.data
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Frees memory for the given `wasmer_instance_t`.
|
/// Frees memory for the given `wasmer_instance_t`.
|
||||||
@@ -555,6 +609,6 @@ pub extern "C" fn wasmer_instance_context_data_get(
|
|||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub unsafe extern "C" fn wasmer_instance_destroy(instance: Option<NonNull<wasmer_instance_t>>) {
|
pub unsafe extern "C" fn wasmer_instance_destroy(instance: Option<NonNull<wasmer_instance_t>>) {
|
||||||
if let Some(instance_inner) = instance {
|
if let Some(instance_inner) = instance {
|
||||||
Box::from_raw(instance_inner.cast::<Instance>().as_ptr());
|
Box::from_raw(instance_inner.cast::<CAPIInstance>().as_ptr());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ use crate::{
|
|||||||
error::{update_last_error, CApiError},
|
error::{update_last_error, CApiError},
|
||||||
export::wasmer_import_export_kind,
|
export::wasmer_import_export_kind,
|
||||||
import::{wasmer_import_object_t, wasmer_import_t},
|
import::{wasmer_import_object_t, wasmer_import_t},
|
||||||
instance::wasmer_instance_t,
|
instance::{wasmer_instance_t, CAPIInstance},
|
||||||
wasmer_byte_array, wasmer_result_t,
|
wasmer_byte_array, wasmer_result_t,
|
||||||
};
|
};
|
||||||
use libc::c_int;
|
use libc::c_int;
|
||||||
@@ -86,6 +86,7 @@ pub unsafe extern "C" fn wasmer_module_instantiate(
|
|||||||
imports_len: c_int,
|
imports_len: c_int,
|
||||||
) -> wasmer_result_t {
|
) -> wasmer_result_t {
|
||||||
let imports: &[wasmer_import_t] = slice::from_raw_parts(imports, imports_len as usize);
|
let imports: &[wasmer_import_t] = slice::from_raw_parts(imports, imports_len as usize);
|
||||||
|
let mut imported_memories = vec![];
|
||||||
let mut import_object = ImportObject::new();
|
let mut import_object = ImportObject::new();
|
||||||
let mut namespaces = HashMap::new();
|
let mut namespaces = HashMap::new();
|
||||||
for import in imports {
|
for import in imports {
|
||||||
@@ -119,6 +120,7 @@ pub unsafe extern "C" fn wasmer_module_instantiate(
|
|||||||
let export = match import.tag {
|
let export = match import.tag {
|
||||||
wasmer_import_export_kind::WASM_MEMORY => {
|
wasmer_import_export_kind::WASM_MEMORY => {
|
||||||
let mem = import.value.memory as *mut Memory;
|
let mem = import.value.memory as *mut Memory;
|
||||||
|
imported_memories.push(mem);
|
||||||
Extern::Memory((&*mem).clone())
|
Extern::Memory((&*mem).clone())
|
||||||
}
|
}
|
||||||
wasmer_import_export_kind::WASM_FUNCTION => {
|
wasmer_import_export_kind::WASM_FUNCTION => {
|
||||||
@@ -149,7 +151,13 @@ pub unsafe extern "C" fn wasmer_module_instantiate(
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
*instance = Box::into_raw(Box::new(new_instance)) as *mut wasmer_instance_t;
|
let c_api_instance = CAPIInstance {
|
||||||
|
instance: new_instance,
|
||||||
|
imported_memories,
|
||||||
|
ctx_data: None,
|
||||||
|
};
|
||||||
|
|
||||||
|
*instance = Box::into_raw(Box::new(c_api_instance)) as *mut wasmer_instance_t;
|
||||||
wasmer_result_t::WASMER_OK
|
wasmer_result_t::WASMER_OK
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -174,7 +182,13 @@ pub unsafe extern "C" fn wasmer_module_import_instantiate(
|
|||||||
return wasmer_result_t::WASMER_ERROR;
|
return wasmer_result_t::WASMER_ERROR;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
*instance = Box::into_raw(Box::new(new_instance)) as *mut wasmer_instance_t;
|
let imported_memories = todo!("get imported memories");
|
||||||
|
let c_api_instance = CAPIInstance {
|
||||||
|
instance: new_instance,
|
||||||
|
imported_memories,
|
||||||
|
ctx_data: None,
|
||||||
|
};
|
||||||
|
*instance = Box::into_raw(Box::new(c_api_instance)) as *mut wasmer_instance_t;
|
||||||
|
|
||||||
return wasmer_result_t::WASMER_OK;
|
return wasmer_result_t::WASMER_OK;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ project (WasmerRuntimeCApiTests)
|
|||||||
add_executable(test-exported-memory test-exported-memory.c)
|
add_executable(test-exported-memory test-exported-memory.c)
|
||||||
add_executable(test-exports test-exports.c)
|
add_executable(test-exports test-exports.c)
|
||||||
add_executable(test-globals test-globals.c)
|
add_executable(test-globals test-globals.c)
|
||||||
# functionality not yet implemented in wasmer reborn
|
# trampoline functionality not yet implemented in wasmer reborn
|
||||||
#add_executable(test-import-function test-import-function.c)
|
#add_executable(test-import-function test-import-function.c)
|
||||||
add_executable(test-import-trap test-import-trap.c)
|
add_executable(test-import-trap test-import-trap.c)
|
||||||
add_executable(test-imports test-imports.c)
|
add_executable(test-imports test-imports.c)
|
||||||
@@ -71,20 +71,18 @@ target_link_libraries(test-globals general ${WASMER_LIB})
|
|||||||
target_compile_options(test-globals PRIVATE ${COMPILER_OPTIONS})
|
target_compile_options(test-globals PRIVATE ${COMPILER_OPTIONS})
|
||||||
add_test(test-globals test-globals)
|
add_test(test-globals test-globals)
|
||||||
|
|
||||||
# functionality not yet implemented in wasmer reborn
|
# trampoline functionality not yet implemented in wasmer reborn
|
||||||
#target_link_libraries(test-import-function general ${WASMER_LIB})
|
#target_link_libraries(test-import-function general ${WASMER_LIB})
|
||||||
#target_compile_options(test-import-function PRIVATE ${COMPILER_OPTIONS})
|
#target_compile_options(test-import-function PRIVATE ${COMPILER_OPTIONS})
|
||||||
#add_test(test-import-function test-import-function)
|
#add_test(test-import-function test-import-function)
|
||||||
|
|
||||||
target_link_libraries(test-import-trap general ${WASMER_LIB})
|
target_link_libraries(test-import-trap general ${WASMER_LIB})
|
||||||
target_compile_options(test-import-trap PRIVATE ${COMPILER_OPTIONS})
|
target_compile_options(test-import-trap PRIVATE ${COMPILER_OPTIONS})
|
||||||
# TODO: reenable this test
|
add_test(test-import-trap test-import-trap)
|
||||||
#add_test(test-import-trap test-import-trap)
|
|
||||||
|
|
||||||
target_link_libraries(test-imports general ${WASMER_LIB})
|
target_link_libraries(test-imports general ${WASMER_LIB})
|
||||||
target_compile_options(test-imports PRIVATE ${COMPILER_OPTIONS})
|
target_compile_options(test-imports PRIVATE ${COMPILER_OPTIONS})
|
||||||
# TODO: reenable this test
|
add_test(test-imports test-imports)
|
||||||
#add_test(test-imports test-imports)
|
|
||||||
|
|
||||||
target_link_libraries(test-import-object general ${WASMER_LIB})
|
target_link_libraries(test-import-object general ${WASMER_LIB})
|
||||||
target_compile_options(test-import-object PRIVATE ${COMPILER_OPTIONS})
|
target_compile_options(test-import-object PRIVATE ${COMPILER_OPTIONS})
|
||||||
@@ -139,8 +137,7 @@ add_test(test-validate test-validate)
|
|||||||
|
|
||||||
target_link_libraries(test-context general ${WASMER_LIB})
|
target_link_libraries(test-context general ${WASMER_LIB})
|
||||||
target_compile_options(test-context PRIVATE ${COMPILER_OPTIONS})
|
target_compile_options(test-context PRIVATE ${COMPILER_OPTIONS})
|
||||||
# TODO: reenable this test
|
add_test(test-context test-context)
|
||||||
#add_test(test-context test-context)
|
|
||||||
|
|
||||||
target_link_libraries(test-module-import-instantiate general ${WASMER_LIB})
|
target_link_libraries(test-module-import-instantiate general ${WASMER_LIB})
|
||||||
target_compile_options(test-module-import-instantiate PRIVATE ${COMPILER_OPTIONS})
|
target_compile_options(test-module-import-instantiate PRIVATE ${COMPILER_OPTIONS})
|
||||||
|
|||||||
@@ -69,7 +69,7 @@ int main()
|
|||||||
wasmer_last_error_message(error_str, error_len);
|
wasmer_last_error_message(error_str, error_len);
|
||||||
printf("Error str: `%s`\n", error_str);
|
printf("Error str: `%s`\n", error_str);
|
||||||
|
|
||||||
assert(0 == strcmp(error_str, "Call error: \"Hello\""));
|
assert(0 == strcmp(error_str, "RuntimeError: Hello"));
|
||||||
|
|
||||||
printf("Destroying func\n");
|
printf("Destroying func\n");
|
||||||
wasmer_import_func_destroy(func);
|
wasmer_import_func_destroy(func);
|
||||||
|
|||||||
@@ -141,6 +141,10 @@ int main()
|
|||||||
wasmer_value_t results[] = {result_one};
|
wasmer_value_t results[] = {result_one};
|
||||||
wasmer_result_t call_result = wasmer_instance_call(instance, "_hello_wasm", params, 0, results, 1);
|
wasmer_result_t call_result = wasmer_instance_call(instance, "_hello_wasm", params, 0, results, 1);
|
||||||
printf("Call result: %d\n", call_result);
|
printf("Call result: %d\n", call_result);
|
||||||
|
if (compile_result != WASMER_OK)
|
||||||
|
{
|
||||||
|
print_wasmer_error();
|
||||||
|
}
|
||||||
assert(call_result == WASMER_OK);
|
assert(call_result == WASMER_OK);
|
||||||
assert(print_str_called);
|
assert(print_str_called);
|
||||||
|
|
||||||
|
|||||||
@@ -138,9 +138,9 @@ typedef struct {
|
|||||||
} wasmer_module_t;
|
} wasmer_module_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Opaque pointer to a `wasmer_runtime::Instance` value in Rust.
|
* Opaque pointer to an Instance type plus metadata.
|
||||||
*
|
*
|
||||||
* A `wasmer_runtime::Instance` represents a WebAssembly instance. It
|
* This type represents a WebAssembly instance. It
|
||||||
* is generally generated by the `wasmer_instantiate()` function, or by
|
* is generally generated by the `wasmer_instantiate()` function, or by
|
||||||
* the `wasmer_module_instantiate()` function for the most common paths.
|
* the `wasmer_module_instantiate()` function for the most common paths.
|
||||||
*/
|
*/
|
||||||
@@ -1389,7 +1389,7 @@ wasmer_result_t wasmer_table_new(wasmer_table_t **table, wasmer_limits_t limits)
|
|||||||
*
|
*
|
||||||
* This function never returns otherwise.
|
* This function never returns otherwise.
|
||||||
*/
|
*/
|
||||||
wasmer_result_t wasmer_trap(const wasmer_instance_context_t *ctx, const char *error_message);
|
wasmer_result_t wasmer_trap(const wasmer_instance_context_t *_ctx, const char *error_message);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Validates a sequence of bytes hoping it represents a valid WebAssembly module.
|
* Validates a sequence of bytes hoping it represents a valid WebAssembly module.
|
||||||
|
|||||||
@@ -100,9 +100,9 @@ struct wasmer_module_t {
|
|||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Opaque pointer to a `wasmer_runtime::Instance` value in Rust.
|
/// Opaque pointer to an Instance type plus metadata.
|
||||||
///
|
///
|
||||||
/// A `wasmer_runtime::Instance` represents a WebAssembly instance. It
|
/// This type represents a WebAssembly instance. It
|
||||||
/// is generally generated by the `wasmer_instantiate()` function, or by
|
/// is generally generated by the `wasmer_instantiate()` function, or by
|
||||||
/// the `wasmer_module_instantiate()` function for the most common paths.
|
/// the `wasmer_module_instantiate()` function for the most common paths.
|
||||||
struct wasmer_instance_t {
|
struct wasmer_instance_t {
|
||||||
@@ -1148,7 +1148,7 @@ wasmer_result_t wasmer_table_new(wasmer_table_t **table, wasmer_limits_t limits)
|
|||||||
/// `error_message` are null.
|
/// `error_message` are null.
|
||||||
///
|
///
|
||||||
/// This function never returns otherwise.
|
/// This function never returns otherwise.
|
||||||
wasmer_result_t wasmer_trap(const wasmer_instance_context_t *ctx, const char *error_message);
|
wasmer_result_t wasmer_trap(const wasmer_instance_context_t *_ctx, const char *error_message);
|
||||||
|
|
||||||
/// Validates a sequence of bytes hoping it represents a valid WebAssembly module.
|
/// Validates a sequence of bytes hoping it represents a valid WebAssembly module.
|
||||||
///
|
///
|
||||||
|
|||||||
@@ -65,15 +65,7 @@ impl Compiler for LLVMCompiler {
|
|||||||
//let data = Arc::new(Mutex::new(0));
|
//let data = Arc::new(Mutex::new(0));
|
||||||
let mut func_names = SecondaryMap::new();
|
let mut func_names = SecondaryMap::new();
|
||||||
|
|
||||||
// We're going to "link" the sections by simply appending all compatible
|
// TODO: merge constants in sections.
|
||||||
// sections, then building the new relocations.
|
|
||||||
// TODO: merge constants.
|
|
||||||
let mut used_readonly_section = false;
|
|
||||||
let mut readonly_section = CustomSection {
|
|
||||||
protection: CustomSectionProtection::Read,
|
|
||||||
bytes: SectionBody::default(),
|
|
||||||
relocations: vec![],
|
|
||||||
};
|
|
||||||
|
|
||||||
for (func_index, _) in &module.functions {
|
for (func_index, _) in &module.functions {
|
||||||
func_names[func_index] = module
|
func_names[func_index] = module
|
||||||
@@ -153,6 +145,6 @@ impl Compiler for LLVMCompiler {
|
|||||||
module: &Module,
|
module: &Module,
|
||||||
) -> Result<PrimaryMap<FunctionIndex, FunctionBody>, CompileError> {
|
) -> Result<PrimaryMap<FunctionIndex, FunctionBody>, CompileError> {
|
||||||
Ok(PrimaryMap::new())
|
Ok(PrimaryMap::new())
|
||||||
// unimplemented!("Dynamic funciton trampolines not yet implemented");
|
// unimplemented!("Dynamic function trampolines not yet implemented");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -20,18 +20,6 @@ use inkwell::{
|
|||||||
AddressSpace,
|
AddressSpace,
|
||||||
};
|
};
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
/*
|
|
||||||
use wasmer_runtime_core::{
|
|
||||||
memory::MemoryType,
|
|
||||||
module::ModuleInfo,
|
|
||||||
structures::TypedIndex,
|
|
||||||
types::{
|
|
||||||
GlobalIndex, ImportedFunctionIndex, LocalOrImport, MemoryIndex, SignatureIndex, TableIndex, Type,
|
|
||||||
},
|
|
||||||
units::Pages,
|
|
||||||
vm::{Ctx, INTERNALS_SIZE},
|
|
||||||
};
|
|
||||||
*/
|
|
||||||
use wasm_common::entity::{EntityRef, PrimaryMap};
|
use wasm_common::entity::{EntityRef, PrimaryMap};
|
||||||
use wasm_common::{
|
use wasm_common::{
|
||||||
FunctionIndex, FunctionType as FuncType, GlobalIndex, MemoryIndex, Mutability, Pages,
|
FunctionIndex, FunctionType as FuncType, GlobalIndex, MemoryIndex, Mutability, Pages,
|
||||||
@@ -271,65 +259,6 @@ impl<'ctx> Intrinsics<'ctx> {
|
|||||||
false,
|
false,
|
||||||
);
|
);
|
||||||
|
|
||||||
/*
|
|
||||||
ctx_ty.set_body(
|
|
||||||
&[
|
|
||||||
local_memory_ty
|
|
||||||
.ptr_type(AddressSpace::Generic)
|
|
||||||
.ptr_type(AddressSpace::Generic)
|
|
||||||
.as_basic_type_enum(),
|
|
||||||
local_table_ty
|
|
||||||
.ptr_type(AddressSpace::Generic)
|
|
||||||
.ptr_type(AddressSpace::Generic)
|
|
||||||
.as_basic_type_enum(),
|
|
||||||
local_global_ty
|
|
||||||
.ptr_type(AddressSpace::Generic)
|
|
||||||
.ptr_type(AddressSpace::Generic)
|
|
||||||
.as_basic_type_enum(),
|
|
||||||
local_memory_ty
|
|
||||||
.ptr_type(AddressSpace::Generic)
|
|
||||||
.ptr_type(AddressSpace::Generic)
|
|
||||||
.as_basic_type_enum(),
|
|
||||||
local_table_ty
|
|
||||||
.ptr_type(AddressSpace::Generic)
|
|
||||||
.ptr_type(AddressSpace::Generic)
|
|
||||||
.as_basic_type_enum(),
|
|
||||||
local_global_ty
|
|
||||||
.ptr_type(AddressSpace::Generic)
|
|
||||||
.ptr_type(AddressSpace::Generic)
|
|
||||||
.as_basic_type_enum(),
|
|
||||||
imported_func_ty
|
|
||||||
.ptr_type(AddressSpace::Generic)
|
|
||||||
.as_basic_type_enum(),
|
|
||||||
sigindex_ty
|
|
||||||
.ptr_type(AddressSpace::Generic)
|
|
||||||
.as_basic_type_enum(),
|
|
||||||
rt_intrinsics_ty
|
|
||||||
.ptr_type(AddressSpace::Generic)
|
|
||||||
.as_basic_type_enum(),
|
|
||||||
stack_lower_bound_ty
|
|
||||||
.ptr_type(AddressSpace::Generic)
|
|
||||||
.as_basic_type_enum(),
|
|
||||||
memory_base_ty
|
|
||||||
.ptr_type(AddressSpace::Generic)
|
|
||||||
.as_basic_type_enum(),
|
|
||||||
memory_bound_ty
|
|
||||||
.ptr_type(AddressSpace::Generic)
|
|
||||||
.as_basic_type_enum(),
|
|
||||||
internals_ty
|
|
||||||
.ptr_type(AddressSpace::Generic)
|
|
||||||
.as_basic_type_enum(),
|
|
||||||
interrupt_signal_mem_ty
|
|
||||||
.ptr_type(AddressSpace::Generic)
|
|
||||||
.as_basic_type_enum(),
|
|
||||||
local_function_ty
|
|
||||||
.ptr_type(AddressSpace::Generic)
|
|
||||||
.as_basic_type_enum(),
|
|
||||||
],
|
|
||||||
false,
|
|
||||||
);
|
|
||||||
*/
|
|
||||||
|
|
||||||
let ret_i8x16_take_i8x16_i8x16 = i8x16_ty.fn_type(&[i8x16_ty_basic, i8x16_ty_basic], false);
|
let ret_i8x16_take_i8x16_i8x16 = i8x16_ty.fn_type(&[i8x16_ty_basic, i8x16_ty_basic], false);
|
||||||
let ret_i16x8_take_i16x8_i16x8 = i16x8_ty.fn_type(&[i16x8_ty_basic, i16x8_ty_basic], false);
|
let ret_i16x8_take_i16x8_i16x8 = i16x8_ty.fn_type(&[i16x8_ty_basic, i16x8_ty_basic], false);
|
||||||
|
|
||||||
@@ -669,17 +598,10 @@ pub enum MemoryCache<'ctx> {
|
|||||||
/// The memory moves around.
|
/// The memory moves around.
|
||||||
Dynamic {
|
Dynamic {
|
||||||
ptr_to_base_ptr: PointerValue<'ctx>,
|
ptr_to_base_ptr: PointerValue<'ctx>,
|
||||||
ptr_to_bounds: PointerValue<'ctx>,
|
current_length_ptr: PointerValue<'ctx>,
|
||||||
minimum: Pages,
|
|
||||||
maximum: Option<Pages>,
|
|
||||||
},
|
},
|
||||||
/// The memory is always in the same place.
|
/// The memory is always in the same place.
|
||||||
Static {
|
Static { base_ptr: PointerValue<'ctx> },
|
||||||
base_ptr: PointerValue<'ctx>,
|
|
||||||
bounds: IntValue<'ctx>,
|
|
||||||
minimum: Pages,
|
|
||||||
maximum: Option<Pages>,
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct TableCache<'ctx> {
|
struct TableCache<'ctx> {
|
||||||
@@ -747,28 +669,7 @@ impl<'ctx, 'a> CtxType<'ctx, 'a> {
|
|||||||
pub fn basic(&self) -> BasicValueEnum<'ctx> {
|
pub fn basic(&self) -> BasicValueEnum<'ctx> {
|
||||||
self.ctx_ptr_value.as_basic_value_enum()
|
self.ctx_ptr_value.as_basic_value_enum()
|
||||||
}
|
}
|
||||||
/*
|
|
||||||
pub fn signal_mem(&mut self) -> PointerValue<'ctx> {
|
|
||||||
if let Some(x) = self.cached_signal_mem {
|
|
||||||
return x;
|
|
||||||
}
|
|
||||||
|
|
||||||
let (ctx_ptr_value, cache_builder) = (self.ctx_ptr_value, &self.cache_builder);
|
|
||||||
|
|
||||||
let ptr_ptr = unsafe {
|
|
||||||
cache_builder.build_struct_gep(
|
|
||||||
ctx_ptr_value,
|
|
||||||
offset_to_index(Ctx::offset_interrupt_signal_mem()),
|
|
||||||
"interrupt_signal_mem_ptr",
|
|
||||||
)
|
|
||||||
};
|
|
||||||
let ptr = cache_builder
|
|
||||||
.build_load(ptr_ptr, "interrupt_signal_mem")
|
|
||||||
.into_pointer_value();
|
|
||||||
self.cached_signal_mem = Some(ptr);
|
|
||||||
ptr
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
pub fn memory(
|
pub fn memory(
|
||||||
&mut self,
|
&mut self,
|
||||||
index: MemoryIndex,
|
index: MemoryIndex,
|
||||||
@@ -783,129 +684,59 @@ impl<'ctx, 'a> CtxType<'ctx, 'a> {
|
|||||||
&self.cache_builder,
|
&self.cache_builder,
|
||||||
&self.offsets,
|
&self.offsets,
|
||||||
);
|
);
|
||||||
|
let memory_plan = &memory_plans[index];
|
||||||
*cached_memories.entry(index).or_insert_with(|| {
|
*cached_memories.entry(index).or_insert_with(|| {
|
||||||
let (memory_array_ptr_ptr, index, memory_type, minimum, maximum, field_name) = {
|
let memory_definition_ptr =
|
||||||
let desc = memory_plans.get(index).unwrap();
|
if let Some(local_memory_index) = wasm_module.local_memory_index(index) {
|
||||||
if let Some(local_mem_index) = wasm_module.local_memory_index(index) {
|
let offset = offsets.vmctx_vmmemory_definition(local_memory_index);
|
||||||
let byte_offset = intrinsics.i64_ty.const_int(
|
let offset = intrinsics.i32_ty.const_int(offset.into(), false);
|
||||||
offsets
|
unsafe { cache_builder.build_gep(ctx_ptr_value, &[offset], "") }
|
||||||
.vmctx_vmmemory_definition_base(local_mem_index)
|
|
||||||
.into(),
|
|
||||||
false,
|
|
||||||
);
|
|
||||||
(
|
|
||||||
unsafe {
|
|
||||||
cache_builder.build_gep(
|
|
||||||
ctx_ptr_value,
|
|
||||||
&[byte_offset],
|
|
||||||
"memory_base_ptr_ptr",
|
|
||||||
)
|
|
||||||
},
|
|
||||||
local_mem_index.index() as u64,
|
|
||||||
desc.style.clone(),
|
|
||||||
desc.memory.minimum,
|
|
||||||
desc.memory.maximum,
|
|
||||||
"context_field_ptr_to_local_memory",
|
|
||||||
)
|
|
||||||
} else {
|
} else {
|
||||||
let byte_offset = intrinsics.i64_ty.const_int(
|
let offset = offsets.vmctx_vmmemory_import(index);
|
||||||
offsets.vmctx_vmmemory_import_definition(index).into(),
|
let offset = intrinsics.i32_ty.const_int(offset.into(), false);
|
||||||
false,
|
let memory_definition_ptr_ptr =
|
||||||
);
|
unsafe { cache_builder.build_gep(ctx_ptr_value, &[offset], "") };
|
||||||
(
|
let memory_definition_ptr_ptr = cache_builder
|
||||||
unsafe {
|
.build_bitcast(
|
||||||
cache_builder
|
memory_definition_ptr_ptr,
|
||||||
.build_struct_gep(
|
intrinsics.i8_ptr_ty.ptr_type(AddressSpace::Generic),
|
||||||
ctx_ptr_value,
|
"",
|
||||||
offset_to_index(offsets.vmctx_imported_memories_begin()),
|
)
|
||||||
"memory_array_ptr_ptr",
|
|
||||||
)
|
|
||||||
.unwrap()
|
|
||||||
},
|
|
||||||
index.index() as u64,
|
|
||||||
desc.style.clone(),
|
|
||||||
desc.memory.minimum,
|
|
||||||
desc.memory.maximum,
|
|
||||||
"context_field_ptr_to_imported_memory",
|
|
||||||
)
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
let memory_array_ptr = cache_builder
|
|
||||||
.build_load(memory_array_ptr_ptr, "memory_array_ptr")
|
|
||||||
.into_pointer_value();
|
|
||||||
tbaa_label(
|
|
||||||
module,
|
|
||||||
intrinsics,
|
|
||||||
field_name,
|
|
||||||
memory_array_ptr.as_instruction_value().unwrap(),
|
|
||||||
None,
|
|
||||||
);
|
|
||||||
let const_index = intrinsics.i32_ty.const_int(index, false);
|
|
||||||
let memory_ptr_ptr = unsafe {
|
|
||||||
cache_builder.build_in_bounds_gep(
|
|
||||||
memory_array_ptr,
|
|
||||||
&[const_index],
|
|
||||||
"memory_ptr_ptr",
|
|
||||||
)
|
|
||||||
};
|
|
||||||
let memory_ptr = cache_builder
|
|
||||||
.build_load(memory_ptr_ptr, "memory_ptr")
|
|
||||||
.into_pointer_value();
|
|
||||||
tbaa_label(
|
|
||||||
module,
|
|
||||||
intrinsics,
|
|
||||||
"memory_ptr",
|
|
||||||
memory_ptr.as_instruction_value().unwrap(),
|
|
||||||
Some(index as u32),
|
|
||||||
);
|
|
||||||
|
|
||||||
let (ptr_to_base_ptr, ptr_to_bounds) = unsafe {
|
|
||||||
(
|
|
||||||
cache_builder
|
|
||||||
.build_struct_gep(memory_ptr, 0, "base_ptr")
|
|
||||||
.unwrap(),
|
|
||||||
cache_builder
|
|
||||||
.build_struct_gep(memory_ptr, 1, "bounds_ptr")
|
|
||||||
.unwrap(),
|
|
||||||
)
|
|
||||||
};
|
|
||||||
|
|
||||||
match memory_type {
|
|
||||||
MemoryStyle::Dynamic => MemoryCache::Dynamic {
|
|
||||||
ptr_to_base_ptr,
|
|
||||||
ptr_to_bounds,
|
|
||||||
minimum,
|
|
||||||
maximum,
|
|
||||||
},
|
|
||||||
MemoryStyle::Static { bound: _ } => {
|
|
||||||
let base_ptr = cache_builder
|
|
||||||
.build_load(ptr_to_base_ptr, "base")
|
|
||||||
.into_pointer_value();
|
.into_pointer_value();
|
||||||
let bounds = cache_builder
|
cache_builder
|
||||||
.build_load(ptr_to_bounds, "bounds")
|
.build_load(memory_definition_ptr_ptr, "")
|
||||||
.into_int_value();
|
.into_pointer_value()
|
||||||
tbaa_label(
|
};
|
||||||
module,
|
let memory_definition_ptr = cache_builder
|
||||||
intrinsics,
|
.build_bitcast(
|
||||||
"static_memory_base",
|
memory_definition_ptr,
|
||||||
base_ptr.as_instruction_value().unwrap(),
|
intrinsics.vmmemory_definition_ptr_ty,
|
||||||
Some(index as u32),
|
"",
|
||||||
);
|
)
|
||||||
tbaa_label(
|
.into_pointer_value();
|
||||||
module,
|
let base_ptr = cache_builder
|
||||||
intrinsics,
|
.build_struct_gep(
|
||||||
"static_memory_bounds",
|
memory_definition_ptr,
|
||||||
bounds.as_instruction_value().unwrap(),
|
intrinsics.vmmemory_definition_base_element,
|
||||||
Some(index as u32),
|
"",
|
||||||
);
|
)
|
||||||
MemoryCache::Static {
|
.unwrap();
|
||||||
base_ptr,
|
if memory_plan.style == MemoryStyle::Dynamic {
|
||||||
bounds,
|
let current_length_ptr = cache_builder
|
||||||
minimum,
|
.build_struct_gep(
|
||||||
maximum,
|
memory_definition_ptr,
|
||||||
}
|
intrinsics.vmmemory_definition_current_length_element,
|
||||||
|
"",
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
MemoryCache::Dynamic {
|
||||||
|
ptr_to_base_ptr: base_ptr,
|
||||||
|
current_length_ptr,
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
let base_ptr = cache_builder.build_load(base_ptr, "").into_pointer_value();
|
||||||
|
// TODO: tbaa
|
||||||
|
MemoryCache::Static { base_ptr }
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -1051,27 +882,6 @@ impl<'ctx, 'a> CtxType<'ctx, 'a> {
|
|||||||
&self.offsets,
|
&self.offsets,
|
||||||
);
|
);
|
||||||
*cached_sigindices.entry(index).or_insert_with(|| {
|
*cached_sigindices.entry(index).or_insert_with(|| {
|
||||||
/*
|
|
||||||
let sigindex_array_ptr_ptr = unsafe {
|
|
||||||
cache_builder.build_struct_gep(
|
|
||||||
ctx_ptr_value,
|
|
||||||
offset_to_index(offsets.vmctx_signature_ids_begin()),
|
|
||||||
"sigindex_array_ptr_ptr",
|
|
||||||
)
|
|
||||||
};
|
|
||||||
let sigindex_array_ptr = cache_builder
|
|
||||||
.build_load(sigindex_array_ptr_ptr, "sigindex_array_ptr")
|
|
||||||
.into_pointer_value();
|
|
||||||
let const_index = intrinsics.i32_ty.const_int(index.index() as u64, false);
|
|
||||||
|
|
||||||
let sigindex_ptr = unsafe {
|
|
||||||
cache_builder.build_in_bounds_gep(
|
|
||||||
sigindex_array_ptr,
|
|
||||||
&[const_index],
|
|
||||||
"sigindex_ptr",
|
|
||||||
)
|
|
||||||
};
|
|
||||||
*/
|
|
||||||
let byte_offset = intrinsics
|
let byte_offset = intrinsics
|
||||||
.i64_ty
|
.i64_ty
|
||||||
.const_int(offsets.vmctx_vmshared_signature_id(index).into(), false);
|
.const_int(offsets.vmctx_vmshared_signature_id(index).into(), false);
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ use inkwell::{
|
|||||||
values::{BasicValue, BasicValueEnum, PhiValue},
|
values::{BasicValue, BasicValueEnum, PhiValue},
|
||||||
};
|
};
|
||||||
use smallvec::SmallVec;
|
use smallvec::SmallVec;
|
||||||
use std::cell::Cell;
|
|
||||||
use std::ops::{BitAnd, BitOr, BitOrAssign};
|
use std::ops::{BitAnd, BitOr, BitOrAssign};
|
||||||
use wasmer_compiler::CompileError;
|
use wasmer_compiler::CompileError;
|
||||||
|
|
||||||
@@ -196,7 +195,6 @@ impl BitAnd for ExtraInfo {
|
|||||||
pub struct State<'ctx> {
|
pub struct State<'ctx> {
|
||||||
pub stack: Vec<(BasicValueEnum<'ctx>, ExtraInfo)>,
|
pub stack: Vec<(BasicValueEnum<'ctx>, ExtraInfo)>,
|
||||||
control_stack: Vec<ControlFrame<'ctx>>,
|
control_stack: Vec<ControlFrame<'ctx>>,
|
||||||
value_counter: Cell<usize>,
|
|
||||||
|
|
||||||
pub reachable: bool,
|
pub reachable: bool,
|
||||||
}
|
}
|
||||||
@@ -206,7 +204,6 @@ impl<'ctx> State<'ctx> {
|
|||||||
Self {
|
Self {
|
||||||
stack: vec![],
|
stack: vec![],
|
||||||
control_stack: vec![],
|
control_stack: vec![],
|
||||||
value_counter: Cell::new(0),
|
|
||||||
reachable: true,
|
reachable: true,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -270,13 +267,6 @@ impl<'ctx> State<'ctx> {
|
|||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn var_name(&self) -> String {
|
|
||||||
let counter = self.value_counter.get();
|
|
||||||
let s = format!("s{}", counter);
|
|
||||||
self.value_counter.set(counter + 1);
|
|
||||||
s
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn push1<T: BasicValue<'ctx>>(&mut self, value: T) {
|
pub fn push1<T: BasicValue<'ctx>>(&mut self, value: T) {
|
||||||
self.push1_extra(value, Default::default());
|
self.push1_extra(value, Default::default());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -74,4 +74,12 @@ impl Compiler for SinglepassCompiler {
|
|||||||
"Singlepass trampoline compilation not supported yet".to_owned(),
|
"Singlepass trampoline compilation not supported yet".to_owned(),
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn compile_dynamic_function_trampolines(
|
||||||
|
&self,
|
||||||
|
module: &Module,
|
||||||
|
) -> Result<PrimaryMap<FunctionIndex, FunctionBody>, CompileError> {
|
||||||
|
Ok(PrimaryMap::new())
|
||||||
|
// unimplemented!("Dynamic function trampolines not yet implemented");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ use crate::x64_decl::{new_machine_state, X64Register};
|
|||||||
use smallvec::smallvec;
|
use smallvec::smallvec;
|
||||||
use smallvec::SmallVec;
|
use smallvec::SmallVec;
|
||||||
use std::collections::HashSet;
|
use std::collections::HashSet;
|
||||||
use wasmparser::Type as WpType;
|
use wasmer_compiler::wasmparser::Type as WpType;
|
||||||
|
|
||||||
struct MachineStackOffset(usize);
|
struct MachineStackOffset(usize);
|
||||||
|
|
||||||
|
|||||||
@@ -29,8 +29,8 @@ pub struct TableElements {
|
|||||||
pub elements: Box<[FunctionIndex]>,
|
pub elements: Box<[FunctionIndex]>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Implemenation styles for WebAssembly linear memory.
|
/// Implementation styles for WebAssembly linear memory.
|
||||||
#[derive(Debug, Clone, Hash, Serialize, Deserialize)]
|
#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
||||||
pub enum MemoryStyle {
|
pub enum MemoryStyle {
|
||||||
/// The actual memory can be resized and moved.
|
/// The actual memory can be resized and moved.
|
||||||
Dynamic,
|
Dynamic,
|
||||||
@@ -53,7 +53,7 @@ pub struct MemoryPlan {
|
|||||||
pub offset_guard_size: u64,
|
pub offset_guard_size: u64,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Implemenation styles for WebAssembly tables.
|
/// Implementation styles for WebAssembly tables.
|
||||||
#[derive(Debug, Clone, Hash, Serialize, Deserialize)]
|
#[derive(Debug, Clone, Hash, Serialize, Deserialize)]
|
||||||
pub enum TableStyle {
|
pub enum TableStyle {
|
||||||
/// Signatures are stored in the table and checked in the caller.
|
/// Signatures are stored in the table and checked in the caller.
|
||||||
|
|||||||
Reference in New Issue
Block a user