mirror of
https://github.com/fluencelabs/wasmer
synced 2025-06-21 12:41:32 +00:00
Merge branch 'master' into feature/singlepass-opt
This commit is contained in:
@ -5,6 +5,7 @@ All PRs to the Wasmer repository must add to this file.
|
|||||||
Blocks of changes will separated by version increments.
|
Blocks of changes will separated by version increments.
|
||||||
|
|
||||||
## **[Unreleased]**
|
## **[Unreleased]**
|
||||||
|
- [#348](https://github.com/wasmerio/wasmer/pull/348) Refactor internal runtime ↔️ backend abstraction.
|
||||||
- [#355](https://github.com/wasmerio/wasmer/pull/355) Misc changes to `Cargo.toml`s for publishing
|
- [#355](https://github.com/wasmerio/wasmer/pull/355) Misc changes to `Cargo.toml`s for publishing
|
||||||
- [#352](https://github.com/wasmerio/wasmer/pull/352) Bump version numbers to 0.3.0
|
- [#352](https://github.com/wasmerio/wasmer/pull/352) Bump version numbers to 0.3.0
|
||||||
- [#351](https://github.com/wasmerio/wasmer/pull/351) Add hidden option to specify wasm program name (can be used to improve error messages)
|
- [#351](https://github.com/wasmerio/wasmer/pull/351) Add hidden option to specify wasm program name (can be used to improve error messages)
|
||||||
|
89
Cargo.lock
generated
89
Cargo.lock
generated
@ -123,11 +123,6 @@ dependencies = [
|
|||||||
"which 2.0.1 (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 = "0.5.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bitflags"
|
name = "bitflags"
|
||||||
version = "1.0.4"
|
version = "1.0.4"
|
||||||
@ -579,18 +574,6 @@ dependencies = [
|
|||||||
"syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
"syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "env_logger"
|
|
||||||
version = "0.5.13"
|
|
||||||
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.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"termcolor 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "env_logger"
|
name = "env_logger"
|
||||||
version = "0.6.1"
|
version = "0.6.1"
|
||||||
@ -739,14 +722,6 @@ dependencies = [
|
|||||||
"typenum 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"typenum 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "getopts"
|
|
||||||
version = "0.2.18"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
dependencies = [
|
|
||||||
"unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "glob"
|
name = "glob"
|
||||||
version = "0.2.11"
|
version = "0.2.11"
|
||||||
@ -1003,16 +978,6 @@ dependencies = [
|
|||||||
"cfg-if 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
"cfg-if 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "lz4"
|
|
||||||
version = "1.22.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
dependencies = [
|
|
||||||
"libc 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"lz4-sys 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"skeptic 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "lz4"
|
name = "lz4"
|
||||||
version = "1.23.1"
|
version = "1.23.1"
|
||||||
@ -1022,15 +987,6 @@ dependencies = [
|
|||||||
"lz4-sys 1.8.3 (git+https://github.com/zboxfs/lz4-rs.git)",
|
"lz4-sys 1.8.3 (git+https://github.com/zboxfs/lz4-rs.git)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "lz4-sys"
|
|
||||||
version = "1.8.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
dependencies = [
|
|
||||||
"gcc 0.3.55 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"libc 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "lz4-sys"
|
name = "lz4-sys"
|
||||||
version = "1.8.3"
|
version = "1.8.3"
|
||||||
@ -1374,15 +1330,6 @@ dependencies = [
|
|||||||
"unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "pulldown-cmark"
|
|
||||||
version = "0.0.8"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
dependencies = [
|
|
||||||
"bitflags 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"getopts 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "quick-error"
|
name = "quick-error"
|
||||||
version = "1.2.2"
|
version = "1.2.2"
|
||||||
@ -1808,15 +1755,6 @@ name = "siphasher"
|
|||||||
version = "0.2.3"
|
version = "0.2.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "skeptic"
|
|
||||||
version = "0.9.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
dependencies = [
|
|
||||||
"pulldown-cmark 0.0.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"tempdir 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "slab"
|
name = "slab"
|
||||||
version = "0.4.2"
|
version = "0.4.2"
|
||||||
@ -2425,6 +2363,7 @@ dependencies = [
|
|||||||
"serde-bench 0.0.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
"serde-bench 0.0.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"serde_bytes 0.10.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
"serde_bytes 0.10.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"serde_derive 1.0.90 (registry+https://github.com/rust-lang/crates.io-index)",
|
"serde_derive 1.0.90 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"smallvec 0.6.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"wasmparser 0.29.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"wasmparser 0.29.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
"winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
@ -2467,7 +2406,7 @@ dependencies = [
|
|||||||
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
"rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"wasmer-runtime-core 0.3.0",
|
"wasmer-runtime-core 0.3.0",
|
||||||
"zbox 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"zbox 0.6.1 (git+https://github.com/wasmerio/zbox?branch=bundle-libsodium)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -2592,22 +2531,6 @@ dependencies = [
|
|||||||
"zip 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"zip 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "zbox"
|
|
||||||
version = "0.6.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
dependencies = [
|
|
||||||
"bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"env_logger 0.5.13 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"linked-hash-map 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"lz4 1.22.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"pkg-config 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"rmp-serde 0.13.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"serde 1.0.90 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"serde_derive 1.0.90 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "zip"
|
name = "zip"
|
||||||
version = "0.5.1"
|
version = "0.5.1"
|
||||||
@ -2663,7 +2586,6 @@ dependencies = [
|
|||||||
"checksum backtrace-sys 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)" = "797c830ac25ccc92a7f8a7b9862bde440715531514594a6154e3d4a54dd769b6"
|
"checksum backtrace-sys 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)" = "797c830ac25ccc92a7f8a7b9862bde440715531514594a6154e3d4a54dd769b6"
|
||||||
"checksum base64 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0b25d992356d2eb0ed82172f5248873db5560c4721f564b13cb5193bda5e668e"
|
"checksum base64 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0b25d992356d2eb0ed82172f5248873db5560c4721f564b13cb5193bda5e668e"
|
||||||
"checksum bindgen 0.46.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8f7f7f0701772b17de73e4f5cbcb1dd6926f4706cba4c1ab62c5367f8bdc94e1"
|
"checksum bindgen 0.46.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8f7f7f0701772b17de73e4f5cbcb1dd6926f4706cba4c1ab62c5367f8bdc94e1"
|
||||||
"checksum bitflags 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4f67931368edf3a9a51d29886d245f1c3db2f1ef0dcc9e35ff70341b78c10d23"
|
|
||||||
"checksum bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "228047a76f468627ca71776ecdebd732a3423081fcf5125585bcd7c49886ce12"
|
"checksum bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "228047a76f468627ca71776ecdebd732a3423081fcf5125585bcd7c49886ce12"
|
||||||
"checksum blake2b_simd 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ce2571a6cd634670daa2977cc894c1cc2ba57c563c498e5a82c35446f34d056e"
|
"checksum blake2b_simd 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ce2571a6cd634670daa2977cc894c1cc2ba57c563c498e5a82c35446f34d056e"
|
||||||
"checksum blob 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "19803aa44ff8b43123bbe369efaddcb638ea7dc332e543972dd95ac7cb148b92"
|
"checksum blob 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "19803aa44ff8b43123bbe369efaddcb638ea7dc332e543972dd95ac7cb148b92"
|
||||||
@ -2713,7 +2635,6 @@ dependencies = [
|
|||||||
"checksum either 1.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "5527cfe0d098f36e3f8839852688e63c8fff1c90b2b405aef730615f9a7bcf7b"
|
"checksum either 1.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "5527cfe0d098f36e3f8839852688e63c8fff1c90b2b405aef730615f9a7bcf7b"
|
||||||
"checksum encoding_rs 0.8.17 (registry+https://github.com/rust-lang/crates.io-index)" = "4155785c79f2f6701f185eb2e6b4caf0555ec03477cb4c70db67b465311620ed"
|
"checksum encoding_rs 0.8.17 (registry+https://github.com/rust-lang/crates.io-index)" = "4155785c79f2f6701f185eb2e6b4caf0555ec03477cb4c70db67b465311620ed"
|
||||||
"checksum enum-methods 0.0.8 (registry+https://github.com/rust-lang/crates.io-index)" = "7798e7da2d4cb0d6d6fc467e8d6b5bf247e9e989f786dde1732d79899c32bb10"
|
"checksum enum-methods 0.0.8 (registry+https://github.com/rust-lang/crates.io-index)" = "7798e7da2d4cb0d6d6fc467e8d6b5bf247e9e989f786dde1732d79899c32bb10"
|
||||||
"checksum env_logger 0.5.13 (registry+https://github.com/rust-lang/crates.io-index)" = "15b0a4d2e39f8420210be8b27eeda28029729e2fd4291019455016c348240c38"
|
|
||||||
"checksum env_logger 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b61fa891024a945da30a9581546e8cfaf5602c7b3f4c137a2805cf388f92075a"
|
"checksum env_logger 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b61fa891024a945da30a9581546e8cfaf5602c7b3f4c137a2805cf388f92075a"
|
||||||
"checksum errno 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "c2a071601ed01b988f896ab14b95e67335d1eeb50190932a1320f7fe3cadc84e"
|
"checksum errno 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "c2a071601ed01b988f896ab14b95e67335d1eeb50190932a1320f7fe3cadc84e"
|
||||||
"checksum errno-dragonfly 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "14ca354e36190500e1e1fb267c647932382b54053c50b14970856c0b00a35067"
|
"checksum errno-dragonfly 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "14ca354e36190500e1e1fb267c647932382b54053c50b14970856c0b00a35067"
|
||||||
@ -2733,7 +2654,6 @@ dependencies = [
|
|||||||
"checksum gcc 0.3.55 (registry+https://github.com/rust-lang/crates.io-index)" = "8f5f3913fa0bfe7ee1fd8248b6b9f42a5af4b9d65ec2dd2c3c26132b950ecfc2"
|
"checksum gcc 0.3.55 (registry+https://github.com/rust-lang/crates.io-index)" = "8f5f3913fa0bfe7ee1fd8248b6b9f42a5af4b9d65ec2dd2c3c26132b950ecfc2"
|
||||||
"checksum generational-arena 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "4024f96ffa0ebaaf36aa589cd41f2fd69f3a5e6fd02c86e11e12cdf41d5b46a3"
|
"checksum generational-arena 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "4024f96ffa0ebaaf36aa589cd41f2fd69f3a5e6fd02c86e11e12cdf41d5b46a3"
|
||||||
"checksum generic-array 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3c0f28c2f5bfb5960175af447a2da7c18900693738343dc896ffbcabd9839592"
|
"checksum generic-array 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3c0f28c2f5bfb5960175af447a2da7c18900693738343dc896ffbcabd9839592"
|
||||||
"checksum getopts 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)" = "0a7292d30132fb5424b354f5dc02512a86e4c516fe544bb7a25e7f266951b797"
|
|
||||||
"checksum glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "8be18de09a56b60ed0edf84bc9df007e30040691af7acd1c41874faac5895bfb"
|
"checksum glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "8be18de09a56b60ed0edf84bc9df007e30040691af7acd1c41874faac5895bfb"
|
||||||
"checksum goblin 0.0.20 (registry+https://github.com/rust-lang/crates.io-index)" = "84473a5302fa5094d3d9911c2f312f522f9a37462a777f195f63fae1bf7faf4d"
|
"checksum goblin 0.0.20 (registry+https://github.com/rust-lang/crates.io-index)" = "84473a5302fa5094d3d9911c2f312f522f9a37462a777f195f63fae1bf7faf4d"
|
||||||
"checksum h2 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)" = "910a5e7be6283a9c91b3982fa5188368c8719cce2a3cf3b86048673bf9d9c36b"
|
"checksum h2 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)" = "910a5e7be6283a9c91b3982fa5188368c8719cce2a3cf3b86048673bf9d9c36b"
|
||||||
@ -2762,9 +2682,7 @@ dependencies = [
|
|||||||
"checksum llvm-sys 70.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "60a9ee82fe0fa72ae6ef6d018b407296085863836451c7a97384f84ed7e26b9f"
|
"checksum llvm-sys 70.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "60a9ee82fe0fa72ae6ef6d018b407296085863836451c7a97384f84ed7e26b9f"
|
||||||
"checksum lock_api 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "62ebf1391f6acad60e5c8b43706dde4582df75c06698ab44511d15016bc2442c"
|
"checksum lock_api 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "62ebf1391f6acad60e5c8b43706dde4582df75c06698ab44511d15016bc2442c"
|
||||||
"checksum log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c84ec4b527950aa83a329754b01dbe3f58361d1c5efacd1f6d68c494d08a17c6"
|
"checksum log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c84ec4b527950aa83a329754b01dbe3f58361d1c5efacd1f6d68c494d08a17c6"
|
||||||
"checksum lz4 1.22.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fe55d2ebbc2e4fc987e6fbfc13f416d97b06d06e50bc1124d613aa790842f80c"
|
|
||||||
"checksum lz4 1.23.1 (git+https://github.com/zboxfs/lz4-rs.git)" = "<none>"
|
"checksum lz4 1.23.1 (git+https://github.com/zboxfs/lz4-rs.git)" = "<none>"
|
||||||
"checksum lz4-sys 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a59044c3ba3994f3d2aa2270ddd6c5947922219501e67efde5604d36aad462b5"
|
|
||||||
"checksum lz4-sys 1.8.3 (git+https://github.com/zboxfs/lz4-rs.git)" = "<none>"
|
"checksum lz4-sys 1.8.3 (git+https://github.com/zboxfs/lz4-rs.git)" = "<none>"
|
||||||
"checksum matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "7ffc5c5338469d4d3ea17d269fa8ea3512ad247247c30bd2df69e68309ed0a08"
|
"checksum matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "7ffc5c5338469d4d3ea17d269fa8ea3512ad247247c30bd2df69e68309ed0a08"
|
||||||
"checksum memchr 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2efc7bc57c883d4a4d6e3246905283d8dae951bb3bd32f49d6ef297f546e1c39"
|
"checksum memchr 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2efc7bc57c883d4a4d6e3246905283d8dae951bb3bd32f49d6ef297f546e1c39"
|
||||||
@ -2804,7 +2722,6 @@ dependencies = [
|
|||||||
"checksum plain 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "b4596b6d070b27117e987119b4dac604f3c58cfb0b191112e24771b2faeac1a6"
|
"checksum plain 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "b4596b6d070b27117e987119b4dac604f3c58cfb0b191112e24771b2faeac1a6"
|
||||||
"checksum podio 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "780fb4b6698bbf9cf2444ea5d22411cef2953f0824b98f33cf454ec5615645bd"
|
"checksum podio 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "780fb4b6698bbf9cf2444ea5d22411cef2953f0824b98f33cf454ec5615645bd"
|
||||||
"checksum proc-macro2 0.4.27 (registry+https://github.com/rust-lang/crates.io-index)" = "4d317f9caece796be1980837fd5cb3dfec5613ebdb04ad0956deea83ce168915"
|
"checksum proc-macro2 0.4.27 (registry+https://github.com/rust-lang/crates.io-index)" = "4d317f9caece796be1980837fd5cb3dfec5613ebdb04ad0956deea83ce168915"
|
||||||
"checksum pulldown-cmark 0.0.8 (registry+https://github.com/rust-lang/crates.io-index)" = "1058d7bb927ca067656537eec4e02c2b4b70eaaa129664c5b90c111e20326f41"
|
|
||||||
"checksum quick-error 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9274b940887ce9addde99c4eee6b5c44cc494b182b97e73dc8ffdcb3397fd3f0"
|
"checksum quick-error 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9274b940887ce9addde99c4eee6b5c44cc494b182b97e73dc8ffdcb3397fd3f0"
|
||||||
"checksum quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6e920b65c65f10b2ae65c831a81a073a89edd28c7cce89475bff467ab4167a"
|
"checksum quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6e920b65c65f10b2ae65c831a81a073a89edd28c7cce89475bff467ab4167a"
|
||||||
"checksum quote 0.6.11 (registry+https://github.com/rust-lang/crates.io-index)" = "cdd8e04bd9c52e0342b406469d494fcb033be4bdbe5c606016defbb1681411e1"
|
"checksum quote 0.6.11 (registry+https://github.com/rust-lang/crates.io-index)" = "cdd8e04bd9c52e0342b406469d494fcb033be4bdbe5c606016defbb1681411e1"
|
||||||
@ -2852,7 +2769,6 @@ dependencies = [
|
|||||||
"checksum serde_test 1.0.90 (registry+https://github.com/rust-lang/crates.io-index)" = "6ce17ed207fa61e7f4701a778a6c111da84a441ca9a8f50b92808f4223dd240b"
|
"checksum serde_test 1.0.90 (registry+https://github.com/rust-lang/crates.io-index)" = "6ce17ed207fa61e7f4701a778a6c111da84a441ca9a8f50b92808f4223dd240b"
|
||||||
"checksum serde_urlencoded 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)" = "d48f9f99cd749a2de71d29da5f948de7f2764cc5a9d7f3c97e3514d4ee6eabf2"
|
"checksum serde_urlencoded 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)" = "d48f9f99cd749a2de71d29da5f948de7f2764cc5a9d7f3c97e3514d4ee6eabf2"
|
||||||
"checksum siphasher 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "0b8de496cf83d4ed58b6be86c3a275b8602f6ffe98d3024a869e124147a9a3ac"
|
"checksum siphasher 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "0b8de496cf83d4ed58b6be86c3a275b8602f6ffe98d3024a869e124147a9a3ac"
|
||||||
"checksum skeptic 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "dd7d8dc1315094150052d0ab767840376335a98ac66ef313ff911cdf439a5b69"
|
|
||||||
"checksum slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c111b5bd5695e56cffe5129854aa230b39c93a305372fdbb2668ca2394eea9f8"
|
"checksum slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c111b5bd5695e56cffe5129854aa230b39c93a305372fdbb2668ca2394eea9f8"
|
||||||
"checksum smallvec 0.6.9 (registry+https://github.com/rust-lang/crates.io-index)" = "c4488ae950c49d403731982257768f48fada354a5203fe81f9bb6f43ca9002be"
|
"checksum smallvec 0.6.9 (registry+https://github.com/rust-lang/crates.io-index)" = "c4488ae950c49d403731982257768f48fada354a5203fe81f9bb6f43ca9002be"
|
||||||
"checksum stable_deref_trait 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "dba1a27d3efae4351c8051072d619e3ade2820635c3958d826bfea39d59b54c8"
|
"checksum stable_deref_trait 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "dba1a27d3efae4351c8051072d619e3ade2820635c3958d826bfea39d59b54c8"
|
||||||
@ -2922,7 +2838,6 @@ dependencies = [
|
|||||||
"checksum ws2_32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d59cefebd0c892fa2dd6de581e937301d8552cb44489cdff035c6187cb63fa5e"
|
"checksum ws2_32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d59cefebd0c892fa2dd6de581e937301d8552cb44489cdff035c6187cb63fa5e"
|
||||||
"checksum xattr 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "244c3741f4240ef46274860397c7c74e50eb23624996930e484c16679633a54c"
|
"checksum xattr 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "244c3741f4240ef46274860397c7c74e50eb23624996930e484c16679633a54c"
|
||||||
"checksum zbox 0.6.1 (git+https://github.com/wasmerio/zbox?branch=bundle-libsodium)" = "<none>"
|
"checksum zbox 0.6.1 (git+https://github.com/wasmerio/zbox?branch=bundle-libsodium)" = "<none>"
|
||||||
"checksum zbox 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4a969b504de4ee47ac68bbd035b0c5a53818edb1edd6737131de001de2a09e64"
|
|
||||||
"checksum zip 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1cbbddef6339155bc4fa8e2609040078ff18f3011117b55caa9f0516d544a357"
|
"checksum zip 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1cbbddef6339155bc4fa8e2609040078ff18f3011117b55caa9f0516d544a357"
|
||||||
"checksum zstd 0.4.22+zstd.1.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "6f042dd18d52854d302d3d92f66d0a63c2d520d7b7034a9d43cde7441d1b4ddd"
|
"checksum zstd 0.4.22+zstd.1.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "6f042dd18d52854d302d3d92f66d0a63c2d520d7b7034a9d43cde7441d1b4ddd"
|
||||||
"checksum zstd-safe 1.4.7+zstd.1.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "63febf0b0dcd076db81e6b3110ed254cfb8ed54378a4c3cfbb68956e839d4f59"
|
"checksum zstd-safe 1.4.7+zstd.1.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "63febf0b0dcd076db81e6b3110ed254cfb8ed54378a4c3cfbb68956e839d4f59"
|
||||||
|
4
LICENSE
4
LICENSE
@ -1,4 +1,6 @@
|
|||||||
Copyright (c) 2019 Syrus Akbary
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2019 Wasmer, Inc. and its affiliates.
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
@ -2,8 +2,9 @@ status = [
|
|||||||
"ci/circleci: lint",
|
"ci/circleci: lint",
|
||||||
"ci/circleci: test",
|
"ci/circleci: test",
|
||||||
"ci/circleci: test-macos",
|
"ci/circleci: test-macos",
|
||||||
|
"ci/circleci: test-rust-nightly",
|
||||||
"continuous-integration/appveyor/branch"
|
"continuous-integration/appveyor/branch"
|
||||||
]
|
]
|
||||||
required_approvals = 1
|
required_approvals = 1
|
||||||
timeout_sec = 900
|
timeout_sec = 900
|
||||||
delete_merged_branches = true
|
delete_merged_branches = true
|
||||||
|
@ -73,16 +73,15 @@ impl Module {
|
|||||||
handler_data.clone(),
|
handler_data.clone(),
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
let protected_caller = Caller::new(&self.info, handler_data, trampolines);
|
|
||||||
|
|
||||||
let cache_gen = Box::new(CacheGenerator::new(
|
let cache_gen = Box::new(CacheGenerator::new(
|
||||||
backend_cache,
|
backend_cache,
|
||||||
Arc::clone(&func_resolver.memory),
|
Arc::clone(&func_resolver.memory),
|
||||||
));
|
));
|
||||||
|
|
||||||
|
let runnable_module = Caller::new(handler_data, trampolines, func_resolver);
|
||||||
|
|
||||||
Ok(ModuleInner {
|
Ok(ModuleInner {
|
||||||
func_resolver: Box::new(func_resolver),
|
runnable_module: Box::new(runnable_module),
|
||||||
protected_caller: Box::new(protected_caller),
|
|
||||||
cache_gen,
|
cache_gen,
|
||||||
|
|
||||||
info: self.info,
|
info: self.info,
|
||||||
@ -103,16 +102,15 @@ impl Module {
|
|||||||
)
|
)
|
||||||
.map_err(|e| CacheError::Unknown(format!("{:?}", e)))?;
|
.map_err(|e| CacheError::Unknown(format!("{:?}", e)))?;
|
||||||
|
|
||||||
let protected_caller = Caller::new(&info, handler_data, trampolines);
|
|
||||||
|
|
||||||
let cache_gen = Box::new(CacheGenerator::new(
|
let cache_gen = Box::new(CacheGenerator::new(
|
||||||
backend_cache,
|
backend_cache,
|
||||||
Arc::clone(&func_resolver.memory),
|
Arc::clone(&func_resolver.memory),
|
||||||
));
|
));
|
||||||
|
|
||||||
|
let runnable_module = Caller::new(handler_data, trampolines, func_resolver);
|
||||||
|
|
||||||
Ok(ModuleInner {
|
Ok(ModuleInner {
|
||||||
func_resolver: Box::new(func_resolver),
|
runnable_module: Box::new(runnable_module),
|
||||||
protected_caller: Box::new(protected_caller),
|
|
||||||
cache_gen,
|
cache_gen,
|
||||||
|
|
||||||
info,
|
info,
|
||||||
|
@ -21,7 +21,6 @@ use wasmer_runtime_core::cache::Error as CacheError;
|
|||||||
use wasmer_runtime_core::{
|
use wasmer_runtime_core::{
|
||||||
self,
|
self,
|
||||||
backend::{
|
backend::{
|
||||||
self,
|
|
||||||
sys::{Memory, Protect},
|
sys::{Memory, Protect},
|
||||||
SigRegistry,
|
SigRegistry,
|
||||||
},
|
},
|
||||||
@ -357,13 +356,8 @@ pub struct FuncResolver {
|
|||||||
pub(crate) memory: Arc<Memory>,
|
pub(crate) memory: Arc<Memory>,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Implements FuncResolver trait.
|
impl FuncResolver {
|
||||||
impl backend::FuncResolver for FuncResolver {
|
pub fn lookup(&self, index: LocalFuncIndex) -> Option<NonNull<vm::Func>> {
|
||||||
fn get(
|
|
||||||
&self,
|
|
||||||
_module: &wasmer_runtime_core::module::ModuleInner,
|
|
||||||
index: LocalFuncIndex,
|
|
||||||
) -> Option<NonNull<vm::Func>> {
|
|
||||||
lookup_func(&self.map, &self.memory, index)
|
lookup_func(&self.map, &self.memory, index)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,16 +1,14 @@
|
|||||||
use crate::relocation::{TrapData, TrapSink};
|
use crate::relocation::{TrapData, TrapSink};
|
||||||
|
use crate::resolver::FuncResolver;
|
||||||
use crate::trampoline::Trampolines;
|
use crate::trampoline::Trampolines;
|
||||||
use hashbrown::HashSet;
|
|
||||||
use libc::c_void;
|
use libc::c_void;
|
||||||
use std::{any::Any, cell::Cell, ptr::NonNull, sync::Arc};
|
use std::{any::Any, cell::Cell, ptr::NonNull, sync::Arc};
|
||||||
use wasmer_runtime_core::{
|
use wasmer_runtime_core::{
|
||||||
backend::{ProtectedCaller, Token, UserTrapper},
|
backend::{RunnableModule, UserTrapper},
|
||||||
error::RuntimeResult,
|
module::ModuleInfo,
|
||||||
export::Context,
|
|
||||||
module::{ExportIndex, ModuleInfo, ModuleInner},
|
|
||||||
typed_func::{Wasm, WasmTrapInfo},
|
typed_func::{Wasm, WasmTrapInfo},
|
||||||
types::{FuncIndex, FuncSig, LocalOrImport, SigIndex, Type, Value},
|
types::{LocalFuncIndex, SigIndex},
|
||||||
vm::{self, ImportBacking},
|
vm,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[cfg(unix)]
|
#[cfg(unix)]
|
||||||
@ -39,130 +37,44 @@ impl UserTrapper for Trapper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub struct Caller {
|
pub struct Caller {
|
||||||
func_export_set: HashSet<FuncIndex>,
|
|
||||||
handler_data: HandlerData,
|
handler_data: HandlerData,
|
||||||
trampolines: Arc<Trampolines>,
|
trampolines: Arc<Trampolines>,
|
||||||
|
resolver: FuncResolver,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Caller {
|
impl Caller {
|
||||||
pub fn new(
|
pub fn new(
|
||||||
module: &ModuleInfo,
|
|
||||||
handler_data: HandlerData,
|
handler_data: HandlerData,
|
||||||
trampolines: Arc<Trampolines>,
|
trampolines: Arc<Trampolines>,
|
||||||
|
resolver: FuncResolver,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let mut func_export_set = HashSet::new();
|
|
||||||
for export_index in module.exports.values() {
|
|
||||||
if let ExportIndex::Func(func_index) = export_index {
|
|
||||||
func_export_set.insert(*func_index);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if let Some(start_func_index) = module.start_func {
|
|
||||||
func_export_set.insert(start_func_index);
|
|
||||||
}
|
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
func_export_set,
|
|
||||||
handler_data,
|
handler_data,
|
||||||
trampolines,
|
trampolines,
|
||||||
|
resolver,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ProtectedCaller for Caller {
|
impl RunnableModule for Caller {
|
||||||
fn call(
|
fn get_func(&self, _: &ModuleInfo, func_index: LocalFuncIndex) -> Option<NonNull<vm::Func>> {
|
||||||
&self,
|
self.resolver.lookup(func_index)
|
||||||
module: &ModuleInner,
|
|
||||||
func_index: FuncIndex,
|
|
||||||
params: &[Value],
|
|
||||||
import_backing: &ImportBacking,
|
|
||||||
vmctx: *mut vm::Ctx,
|
|
||||||
_: Token,
|
|
||||||
) -> RuntimeResult<Vec<Value>> {
|
|
||||||
let (func_ptr, ctx, signature, sig_index) =
|
|
||||||
get_func_from_index(&module, import_backing, func_index);
|
|
||||||
|
|
||||||
let vmctx_ptr = match ctx {
|
|
||||||
Context::External(external_vmctx) => external_vmctx,
|
|
||||||
Context::Internal => vmctx,
|
|
||||||
};
|
|
||||||
|
|
||||||
assert!(self.func_export_set.contains(&func_index));
|
|
||||||
|
|
||||||
assert!(
|
|
||||||
signature.returns().len() <= 1,
|
|
||||||
"multi-value returns not yet supported"
|
|
||||||
);
|
|
||||||
|
|
||||||
assert!(
|
|
||||||
signature.check_param_value_types(params),
|
|
||||||
"incorrect signature"
|
|
||||||
);
|
|
||||||
|
|
||||||
let param_vec: Vec<u64> = params
|
|
||||||
.iter()
|
|
||||||
.map(|val| match val {
|
|
||||||
Value::I32(x) => *x as u64,
|
|
||||||
Value::I64(x) => *x as u64,
|
|
||||||
Value::F32(x) => x.to_bits() as u64,
|
|
||||||
Value::F64(x) => x.to_bits(),
|
|
||||||
})
|
|
||||||
.collect();
|
|
||||||
|
|
||||||
let mut return_vec = vec![0; signature.returns().len()];
|
|
||||||
|
|
||||||
let trampoline = self
|
|
||||||
.trampolines
|
|
||||||
.lookup(sig_index)
|
|
||||||
.expect("that trampoline doesn't exist");
|
|
||||||
|
|
||||||
#[cfg(not(target_os = "windows"))]
|
|
||||||
call_protected(&self.handler_data, || unsafe {
|
|
||||||
// Leap of faith.
|
|
||||||
trampoline(
|
|
||||||
vmctx_ptr,
|
|
||||||
func_ptr,
|
|
||||||
param_vec.as_ptr(),
|
|
||||||
return_vec.as_mut_ptr(),
|
|
||||||
);
|
|
||||||
})?;
|
|
||||||
|
|
||||||
// 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())
|
|
||||||
.map(|(&x, ty)| match ty {
|
|
||||||
Type::I32 => Value::I32(x as i32),
|
|
||||||
Type::I64 => Value::I64(x as i64),
|
|
||||||
Type::F32 => Value::F32(f32::from_bits(x as u32)),
|
|
||||||
Type::F64 => Value::F64(f64::from_bits(x as u64)),
|
|
||||||
})
|
|
||||||
.collect())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_wasm_trampoline(&self, module: &ModuleInner, sig_index: SigIndex) -> Option<Wasm> {
|
fn get_trampoline(&self, _: &ModuleInfo, sig_index: SigIndex) -> Option<Wasm> {
|
||||||
unsafe extern "C" fn invoke(
|
unsafe extern "C" fn invoke(
|
||||||
trampoline: unsafe extern "C" fn(*mut vm::Ctx, NonNull<vm::Func>, *const u64, *mut u64),
|
trampoline: unsafe extern "C" fn(*mut vm::Ctx, NonNull<vm::Func>, *const u64, *mut u64),
|
||||||
ctx: *mut vm::Ctx,
|
ctx: *mut vm::Ctx,
|
||||||
func: NonNull<vm::Func>,
|
func: NonNull<vm::Func>,
|
||||||
args: *const u64,
|
args: *const u64,
|
||||||
rets: *mut u64,
|
rets: *mut u64,
|
||||||
trap_info: *mut WasmTrapInfo,
|
_trap_info: *mut WasmTrapInfo,
|
||||||
invoke_env: Option<NonNull<c_void>>,
|
invoke_env: Option<NonNull<c_void>>,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
let handler_data = &*invoke_env.unwrap().cast().as_ptr();
|
let handler_data = &*invoke_env.unwrap().cast().as_ptr();
|
||||||
|
|
||||||
#[cfg(not(target_os = "windows"))]
|
#[cfg(not(target_os = "windows"))]
|
||||||
let res = call_protected(handler_data, || unsafe {
|
let res = call_protected(handler_data, || {
|
||||||
// Leap of faith.
|
// Leap of faith.
|
||||||
trampoline(ctx, func, args, rets);
|
trampoline(ctx, func, args, rets);
|
||||||
})
|
})
|
||||||
@ -194,40 +106,6 @@ impl ProtectedCaller for Caller {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_func_from_index<'a>(
|
|
||||||
module: &'a ModuleInner,
|
|
||||||
import_backing: &ImportBacking,
|
|
||||||
func_index: FuncIndex,
|
|
||||||
) -> (NonNull<vm::Func>, Context, &'a FuncSig, SigIndex) {
|
|
||||||
let sig_index = *module
|
|
||||||
.info
|
|
||||||
.func_assoc
|
|
||||||
.get(func_index)
|
|
||||||
.expect("broken invariant, incorrect func index");
|
|
||||||
|
|
||||||
let (func_ptr, ctx) = match func_index.local_or_import(&module.info) {
|
|
||||||
LocalOrImport::Local(local_func_index) => (
|
|
||||||
module
|
|
||||||
.func_resolver
|
|
||||||
.get(&module, local_func_index)
|
|
||||||
.expect("broken invariant, func resolver not synced with module.exports")
|
|
||||||
.cast(),
|
|
||||||
Context::Internal,
|
|
||||||
),
|
|
||||||
LocalOrImport::Import(imported_func_index) => {
|
|
||||||
let imported_func = import_backing.imported_func(imported_func_index);
|
|
||||||
(
|
|
||||||
NonNull::new(imported_func.func as *mut _).unwrap(),
|
|
||||||
Context::External(imported_func.vmctx),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
let signature = &module.info.signatures[sig_index];
|
|
||||||
|
|
||||||
(func_ptr, ctx, signature, sig_index)
|
|
||||||
}
|
|
||||||
|
|
||||||
unsafe impl Send for HandlerData {}
|
unsafe impl Send for HandlerData {}
|
||||||
unsafe impl Sync for HandlerData {}
|
unsafe impl Sync for HandlerData {}
|
||||||
|
|
||||||
|
@ -6,7 +6,6 @@ use cranelift_codegen::{
|
|||||||
isa, Context,
|
isa, Context,
|
||||||
};
|
};
|
||||||
use hashbrown::HashMap;
|
use hashbrown::HashMap;
|
||||||
use std::ffi::c_void;
|
|
||||||
use std::{iter, mem, ptr::NonNull};
|
use std::{iter, mem, ptr::NonNull};
|
||||||
use wasmer_runtime_core::{
|
use wasmer_runtime_core::{
|
||||||
backend::sys::{Memory, Protect},
|
backend::sys::{Memory, Protect},
|
||||||
|
@ -18,15 +18,12 @@ use std::{
|
|||||||
sync::Once,
|
sync::Once,
|
||||||
};
|
};
|
||||||
use wasmer_runtime_core::{
|
use wasmer_runtime_core::{
|
||||||
backend::{FuncResolver, ProtectedCaller, Token, UserTrapper},
|
backend::{RunnableModule, UserTrapper},
|
||||||
error::{RuntimeError, RuntimeResult},
|
module::ModuleInfo,
|
||||||
export::Context,
|
|
||||||
module::{ModuleInfo, ModuleInner},
|
|
||||||
structures::TypedIndex,
|
structures::TypedIndex,
|
||||||
typed_func::{Wasm, WasmTrapInfo},
|
typed_func::{Wasm, WasmTrapInfo},
|
||||||
types::{FuncIndex, FuncSig, LocalFuncIndex, LocalOrImport, SigIndex, Type, Value},
|
types::{LocalFuncIndex, SigIndex},
|
||||||
vm::{self, ImportBacking},
|
vm, vmcalls,
|
||||||
vmcalls,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
@ -216,7 +213,7 @@ pub struct LLVMBackend {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl LLVMBackend {
|
impl LLVMBackend {
|
||||||
pub fn new(module: Module, _intrinsics: Intrinsics) -> (Self, LLVMProtectedCaller) {
|
pub fn new(module: Module, _intrinsics: Intrinsics) -> Self {
|
||||||
Target::initialize_x86(&InitializationConfig {
|
Target::initialize_x86(&InitializationConfig {
|
||||||
asm_parser: true,
|
asm_parser: true,
|
||||||
asm_printer: true,
|
asm_printer: true,
|
||||||
@ -265,16 +262,21 @@ impl LLVMBackend {
|
|||||||
panic!("failed to load object")
|
panic!("failed to load object")
|
||||||
}
|
}
|
||||||
|
|
||||||
(
|
Self {
|
||||||
Self {
|
module,
|
||||||
module,
|
memory_buffer,
|
||||||
memory_buffer,
|
}
|
||||||
},
|
|
||||||
LLVMProtectedCaller { module },
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn get_func(
|
impl Drop for LLVMBackend {
|
||||||
|
fn drop(&mut self) {
|
||||||
|
unsafe { module_delete(self.module) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl RunnableModule for LLVMBackend {
|
||||||
|
fn get_func(
|
||||||
&self,
|
&self,
|
||||||
info: &ModuleInfo,
|
info: &ModuleInfo,
|
||||||
local_func_index: LocalFuncIndex,
|
local_func_index: LocalFuncIndex,
|
||||||
@ -291,126 +293,8 @@ impl LLVMBackend {
|
|||||||
|
|
||||||
NonNull::new(ptr as _)
|
NonNull::new(ptr as _)
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
impl Drop for LLVMBackend {
|
fn get_trampoline(&self, _: &ModuleInfo, sig_index: SigIndex) -> Option<Wasm> {
|
||||||
fn drop(&mut self) {
|
|
||||||
unsafe { module_delete(self.module) }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl FuncResolver for LLVMBackend {
|
|
||||||
fn get(
|
|
||||||
&self,
|
|
||||||
module: &ModuleInner,
|
|
||||||
local_func_index: LocalFuncIndex,
|
|
||||||
) -> Option<NonNull<vm::Func>> {
|
|
||||||
self.get_func(&module.info, local_func_index)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
struct Placeholder;
|
|
||||||
|
|
||||||
unsafe impl Send for LLVMProtectedCaller {}
|
|
||||||
unsafe impl Sync for LLVMProtectedCaller {}
|
|
||||||
|
|
||||||
pub struct LLVMProtectedCaller {
|
|
||||||
module: *mut LLVMModule,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ProtectedCaller for LLVMProtectedCaller {
|
|
||||||
fn call(
|
|
||||||
&self,
|
|
||||||
module: &ModuleInner,
|
|
||||||
func_index: FuncIndex,
|
|
||||||
params: &[Value],
|
|
||||||
import_backing: &ImportBacking,
|
|
||||||
vmctx: *mut vm::Ctx,
|
|
||||||
_: Token,
|
|
||||||
) -> RuntimeResult<Vec<Value>> {
|
|
||||||
let (func_ptr, ctx, signature, sig_index) =
|
|
||||||
get_func_from_index(&module, import_backing, func_index);
|
|
||||||
|
|
||||||
let vmctx_ptr = match ctx {
|
|
||||||
Context::External(external_vmctx) => external_vmctx,
|
|
||||||
Context::Internal => vmctx,
|
|
||||||
};
|
|
||||||
|
|
||||||
assert!(
|
|
||||||
signature.returns().len() <= 1,
|
|
||||||
"multi-value returns not yet supported"
|
|
||||||
);
|
|
||||||
|
|
||||||
assert!(
|
|
||||||
signature.check_param_value_types(params),
|
|
||||||
"incorrect signature"
|
|
||||||
);
|
|
||||||
|
|
||||||
let param_vec: Vec<u64> = params
|
|
||||||
.iter()
|
|
||||||
.map(|val| match val {
|
|
||||||
Value::I32(x) => *x as u64,
|
|
||||||
Value::I64(x) => *x as u64,
|
|
||||||
Value::F32(x) => x.to_bits() as u64,
|
|
||||||
Value::F64(x) => x.to_bits(),
|
|
||||||
})
|
|
||||||
.collect();
|
|
||||||
|
|
||||||
let mut return_vec = vec![0; signature.returns().len()];
|
|
||||||
|
|
||||||
let trampoline: unsafe extern "C" fn(
|
|
||||||
*mut vm::Ctx,
|
|
||||||
NonNull<vm::Func>,
|
|
||||||
*const u64,
|
|
||||||
*mut u64,
|
|
||||||
) = unsafe {
|
|
||||||
let name = if cfg!(target_os = "macos") {
|
|
||||||
format!("_trmp{}", sig_index.index())
|
|
||||||
} else {
|
|
||||||
format!("trmp{}", sig_index.index())
|
|
||||||
};
|
|
||||||
|
|
||||||
let c_str = CString::new(name).unwrap();
|
|
||||||
let symbol = get_func_symbol(self.module, c_str.as_ptr());
|
|
||||||
assert!(!symbol.is_null());
|
|
||||||
|
|
||||||
mem::transmute(symbol)
|
|
||||||
};
|
|
||||||
|
|
||||||
let mut trap_out = WasmTrapInfo::Unknown;
|
|
||||||
|
|
||||||
// Here we go.
|
|
||||||
let success = unsafe {
|
|
||||||
invoke_trampoline(
|
|
||||||
trampoline,
|
|
||||||
vmctx_ptr,
|
|
||||||
func_ptr,
|
|
||||||
param_vec.as_ptr(),
|
|
||||||
return_vec.as_mut_ptr(),
|
|
||||||
&mut trap_out,
|
|
||||||
None,
|
|
||||||
)
|
|
||||||
};
|
|
||||||
|
|
||||||
if success {
|
|
||||||
Ok(return_vec
|
|
||||||
.iter()
|
|
||||||
.zip(signature.returns().iter())
|
|
||||||
.map(|(&x, ty)| match ty {
|
|
||||||
Type::I32 => Value::I32(x as i32),
|
|
||||||
Type::I64 => Value::I64(x as i64),
|
|
||||||
Type::F32 => Value::F32(f32::from_bits(x as u32)),
|
|
||||||
Type::F64 => Value::F64(f64::from_bits(x as u64)),
|
|
||||||
})
|
|
||||||
.collect())
|
|
||||||
} else {
|
|
||||||
Err(RuntimeError::Trap {
|
|
||||||
msg: trap_out.to_string().into(),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_wasm_trampoline(&self, _module: &ModuleInner, sig_index: SigIndex) -> Option<Wasm> {
|
|
||||||
let trampoline: unsafe extern "C" fn(
|
let trampoline: unsafe extern "C" fn(
|
||||||
*mut vm::Ctx,
|
*mut vm::Ctx,
|
||||||
NonNull<vm::Func>,
|
NonNull<vm::Func>,
|
||||||
@ -438,46 +322,14 @@ impl ProtectedCaller for LLVMProtectedCaller {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct Placeholder;
|
||||||
|
|
||||||
impl UserTrapper for Placeholder {
|
impl UserTrapper for Placeholder {
|
||||||
unsafe fn do_early_trap(&self, data: Box<dyn Any>) -> ! {
|
unsafe fn do_early_trap(&self, data: Box<dyn Any>) -> ! {
|
||||||
throw_any(Box::leak(data))
|
throw_any(Box::leak(data))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_func_from_index<'a>(
|
|
||||||
module: &'a ModuleInner,
|
|
||||||
import_backing: &ImportBacking,
|
|
||||||
func_index: FuncIndex,
|
|
||||||
) -> (NonNull<vm::Func>, Context, &'a FuncSig, SigIndex) {
|
|
||||||
let sig_index = *module
|
|
||||||
.info
|
|
||||||
.func_assoc
|
|
||||||
.get(func_index)
|
|
||||||
.expect("broken invariant, incorrect func index");
|
|
||||||
|
|
||||||
let (func_ptr, ctx) = match func_index.local_or_import(&module.info) {
|
|
||||||
LocalOrImport::Local(local_func_index) => (
|
|
||||||
module
|
|
||||||
.func_resolver
|
|
||||||
.get(&module, local_func_index)
|
|
||||||
.expect("broken invariant, func resolver not synced with module.exports")
|
|
||||||
.cast(),
|
|
||||||
Context::Internal,
|
|
||||||
),
|
|
||||||
LocalOrImport::Import(imported_func_index) => {
|
|
||||||
let imported_func = import_backing.imported_func(imported_func_index);
|
|
||||||
(
|
|
||||||
NonNull::new(imported_func.func as *mut _).unwrap(),
|
|
||||||
Context::External(imported_func.vmctx),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
let signature = &module.info.signatures[sig_index];
|
|
||||||
|
|
||||||
(func_ptr, ctx, signature, sig_index)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(feature = "disasm")]
|
#[cfg(feature = "disasm")]
|
||||||
unsafe fn disass_ptr(ptr: *const u8, size: usize, inst_count: usize) {
|
unsafe fn disass_ptr(ptr: *const u8, size: usize, inst_count: usize) {
|
||||||
use capstone::arch::BuildsCapstone;
|
use capstone::arch::BuildsCapstone;
|
||||||
|
@ -38,7 +38,7 @@ impl Compiler for LLVMCompiler {
|
|||||||
let (info, code_reader) = read_info::read_module(wasm, compiler_config).unwrap();
|
let (info, code_reader) = read_info::read_module(wasm, compiler_config).unwrap();
|
||||||
let (module, intrinsics) = code::parse_function_bodies(&info, code_reader).unwrap();
|
let (module, intrinsics) = code::parse_function_bodies(&info, code_reader).unwrap();
|
||||||
|
|
||||||
let (backend, protected_caller) = backend::LLVMBackend::new(module, intrinsics);
|
let backend = backend::LLVMBackend::new(module, intrinsics);
|
||||||
|
|
||||||
// Create placeholder values here.
|
// Create placeholder values here.
|
||||||
let cache_gen = {
|
let cache_gen = {
|
||||||
@ -61,8 +61,7 @@ impl Compiler for LLVMCompiler {
|
|||||||
};
|
};
|
||||||
|
|
||||||
Ok(ModuleInner {
|
Ok(ModuleInner {
|
||||||
func_resolver: Box::new(backend),
|
runnable_module: Box::new(backend),
|
||||||
protected_caller: Box::new(protected_caller),
|
|
||||||
cache_gen,
|
cache_gen,
|
||||||
|
|
||||||
info,
|
info,
|
||||||
@ -104,7 +103,9 @@ fn validate(bytes: &[u8]) -> Result<(), CompileError> {
|
|||||||
fn test_read_module() {
|
fn test_read_module() {
|
||||||
use std::mem::transmute;
|
use std::mem::transmute;
|
||||||
use wabt::wat2wasm;
|
use wabt::wat2wasm;
|
||||||
use wasmer_runtime_core::{structures::TypedIndex, types::LocalFuncIndex, vm, vmcalls};
|
use wasmer_runtime_core::{
|
||||||
|
backend::RunnableModule, structures::TypedIndex, types::LocalFuncIndex, vm,
|
||||||
|
};
|
||||||
// let wasm = include_bytes!("../../spectests/examples/simple/simple.wasm") as &[u8];
|
// let wasm = include_bytes!("../../spectests/examples/simple/simple.wasm") as &[u8];
|
||||||
let wat = r#"
|
let wat = r#"
|
||||||
(module
|
(module
|
||||||
@ -122,7 +123,7 @@ fn test_read_module() {
|
|||||||
|
|
||||||
let (module, intrinsics) = code::parse_function_bodies(&info, code_reader).unwrap();
|
let (module, intrinsics) = code::parse_function_bodies(&info, code_reader).unwrap();
|
||||||
|
|
||||||
let (backend, _caller) = backend::LLVMBackend::new(module, intrinsics);
|
let backend = backend::LLVMBackend::new(module, intrinsics);
|
||||||
|
|
||||||
let func_ptr = backend.get_func(&info, LocalFuncIndex::new(0)).unwrap();
|
let func_ptr = backend.get_func(&info, LocalFuncIndex::new(0)).unwrap();
|
||||||
|
|
||||||
|
@ -17,6 +17,7 @@ indexmap = "1.0.2"
|
|||||||
errno = "0.2.4"
|
errno = "0.2.4"
|
||||||
libc = "0.2.49"
|
libc = "0.2.49"
|
||||||
hex = "0.3.2"
|
hex = "0.3.2"
|
||||||
|
smallvec = "0.6.9"
|
||||||
|
|
||||||
# Dependencies for caching.
|
# Dependencies for caching.
|
||||||
[dependencies.serde]
|
[dependencies.serde]
|
||||||
|
@ -1,10 +1,8 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
backing::ImportBacking,
|
|
||||||
error::CompileResult,
|
error::CompileResult,
|
||||||
error::RuntimeResult,
|
|
||||||
module::ModuleInner,
|
module::ModuleInner,
|
||||||
typed_func::Wasm,
|
typed_func::Wasm,
|
||||||
types::{FuncIndex, LocalFuncIndex, SigIndex, Value},
|
types::{LocalFuncIndex, SigIndex},
|
||||||
vm,
|
vm,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -67,59 +65,25 @@ pub trait Compiler {
|
|||||||
unsafe fn from_cache(&self, cache: Artifact, _: Token) -> Result<ModuleInner, CacheError>;
|
unsafe fn from_cache(&self, cache: Artifact, _: Token) -> Result<ModuleInner, CacheError>;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The functionality exposed by this trait is expected to be used
|
|
||||||
/// for calling functions exported by a webassembly module from
|
|
||||||
/// host code only.
|
|
||||||
pub trait ProtectedCaller: Send + Sync {
|
|
||||||
/// This calls the exported function designated by `local_func_index`.
|
|
||||||
/// Important to note, this supports calling imported functions that are
|
|
||||||
/// then exported.
|
|
||||||
///
|
|
||||||
/// It's invalid to attempt to call a local function that isn't exported and
|
|
||||||
/// the implementation is expected to check for that. The implementation
|
|
||||||
/// is also expected to check for correct parameter types and correct
|
|
||||||
/// parameter number.
|
|
||||||
///
|
|
||||||
/// The `returns` parameter is filled with dummy values when passed in and upon function
|
|
||||||
/// return, will be filled with the return values of the wasm function, as long as the
|
|
||||||
/// call completed successfully.
|
|
||||||
///
|
|
||||||
/// The existance of the Token parameter ensures that this can only be called from
|
|
||||||
/// within the runtime crate.
|
|
||||||
///
|
|
||||||
/// TODO(lachlan): Now that `get_wasm_trampoline` exists, `ProtectedCaller::call`
|
|
||||||
/// can be removed. That should speed up calls a little bit, since sanity checks
|
|
||||||
/// would only occur once.
|
|
||||||
fn call(
|
|
||||||
&self,
|
|
||||||
module: &ModuleInner,
|
|
||||||
func_index: FuncIndex,
|
|
||||||
params: &[Value],
|
|
||||||
import_backing: &ImportBacking,
|
|
||||||
vmctx: *mut vm::Ctx,
|
|
||||||
_: Token,
|
|
||||||
) -> RuntimeResult<Vec<Value>>;
|
|
||||||
|
|
||||||
/// A wasm trampoline contains the necesarry data to dynamically call an exported wasm function.
|
|
||||||
/// Given a particular signature index, we are returned a trampoline that is matched with that
|
|
||||||
/// signature and an invoke function that can call the trampoline.
|
|
||||||
fn get_wasm_trampoline(&self, module: &ModuleInner, sig_index: SigIndex) -> Option<Wasm>;
|
|
||||||
|
|
||||||
fn get_early_trapper(&self) -> Box<dyn UserTrapper>;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub trait UserTrapper {
|
pub trait UserTrapper {
|
||||||
unsafe fn do_early_trap(&self, data: Box<dyn Any>) -> !;
|
unsafe fn do_early_trap(&self, data: Box<dyn Any>) -> !;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait FuncResolver: Send + Sync {
|
pub trait RunnableModule: Send + Sync {
|
||||||
/// This returns a pointer to the function designated by the `local_func_index`
|
/// This returns a pointer to the function designated by the `local_func_index`
|
||||||
/// parameter.
|
/// parameter.
|
||||||
fn get(
|
fn get_func(
|
||||||
&self,
|
&self,
|
||||||
module: &ModuleInner,
|
info: &ModuleInfo,
|
||||||
local_func_index: LocalFuncIndex,
|
local_func_index: LocalFuncIndex,
|
||||||
) -> Option<NonNull<vm::Func>>;
|
) -> Option<NonNull<vm::Func>>;
|
||||||
|
|
||||||
|
/// A wasm trampoline contains the necesarry data to dynamically call an exported wasm function.
|
||||||
|
/// Given a particular signature index, we are returned a trampoline that is matched with that
|
||||||
|
/// signature and an invoke function that can call the trampoline.
|
||||||
|
fn get_trampoline(&self, info: &ModuleInfo, sig_index: SigIndex) -> Option<Wasm>;
|
||||||
|
|
||||||
|
fn get_early_trapper(&self) -> Box<dyn UserTrapper>;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait CacheGen: Send + Sync {
|
pub trait CacheGen: Send + Sync {
|
||||||
|
@ -72,8 +72,8 @@ impl LocalBacking {
|
|||||||
(0..module.info.func_assoc.len() - module.info.imported_functions.len())
|
(0..module.info.func_assoc.len() - module.info.imported_functions.len())
|
||||||
.map(|index| {
|
.map(|index| {
|
||||||
module
|
module
|
||||||
.func_resolver
|
.runnable_module
|
||||||
.get(module, LocalFuncIndex::new(index))
|
.get_func(&module.info, LocalFuncIndex::new(index))
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.as_ptr() as *const _
|
.as_ptr() as *const _
|
||||||
})
|
})
|
||||||
@ -216,8 +216,8 @@ impl LocalBacking {
|
|||||||
let (func, ctx) = match func_index.local_or_import(&module.info) {
|
let (func, ctx) = match func_index.local_or_import(&module.info) {
|
||||||
LocalOrImport::Local(local_func_index) => (
|
LocalOrImport::Local(local_func_index) => (
|
||||||
module
|
module
|
||||||
.func_resolver
|
.runnable_module
|
||||||
.get(module, local_func_index)
|
.get_func(&module.info, local_func_index)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.as_ptr()
|
.as_ptr()
|
||||||
as *const vm::Func,
|
as *const vm::Func,
|
||||||
@ -255,8 +255,8 @@ impl LocalBacking {
|
|||||||
let (func, ctx) = match func_index.local_or_import(&module.info) {
|
let (func, ctx) = match func_index.local_or_import(&module.info) {
|
||||||
LocalOrImport::Local(local_func_index) => (
|
LocalOrImport::Local(local_func_index) => (
|
||||||
module
|
module
|
||||||
.func_resolver
|
.runnable_module
|
||||||
.get(module, local_func_index)
|
.get_func(&module.info, local_func_index)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.as_ptr()
|
.as_ptr()
|
||||||
as *const vm::Func,
|
as *const vm::Func,
|
||||||
|
@ -1,18 +1,19 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
backend::Token,
|
backend::RunnableModule,
|
||||||
backing::{ImportBacking, LocalBacking},
|
backing::{ImportBacking, LocalBacking},
|
||||||
error::{CallError, CallResult, ResolveError, ResolveResult, Result},
|
error::{CallError, CallResult, ResolveError, ResolveResult, Result, RuntimeError},
|
||||||
export::{Context, Export, ExportIter, FuncPointer},
|
export::{Context, Export, ExportIter, FuncPointer},
|
||||||
global::Global,
|
global::Global,
|
||||||
import::{ImportObject, LikeNamespace},
|
import::{ImportObject, LikeNamespace},
|
||||||
memory::Memory,
|
memory::Memory,
|
||||||
module::{ExportIndex, Module, ModuleInner},
|
module::{ExportIndex, Module, ModuleInfo, ModuleInner},
|
||||||
sig_registry::SigRegistry,
|
sig_registry::SigRegistry,
|
||||||
table::Table,
|
table::Table,
|
||||||
typed_func::{Func, Wasm, WasmTypeList},
|
typed_func::{Func, Wasm, WasmTrapInfo, WasmTypeList},
|
||||||
types::{FuncIndex, FuncSig, GlobalIndex, LocalOrImport, MemoryIndex, TableIndex, Value},
|
types::{FuncIndex, FuncSig, GlobalIndex, LocalOrImport, MemoryIndex, TableIndex, Type, Value},
|
||||||
vm,
|
vm,
|
||||||
};
|
};
|
||||||
|
use smallvec::{smallvec, SmallVec};
|
||||||
use std::{mem, ptr::NonNull, sync::Arc};
|
use std::{mem, ptr::NonNull, sync::Arc};
|
||||||
|
|
||||||
pub(crate) struct InstanceInner {
|
pub(crate) struct InstanceInner {
|
||||||
@ -82,7 +83,45 @@ impl Instance {
|
|||||||
};
|
};
|
||||||
|
|
||||||
if let Some(start_index) = instance.module.info.start_func {
|
if let Some(start_index) = instance.module.info.start_func {
|
||||||
instance.call_with_index(start_index, &[])?;
|
// We know that the start function takes no arguments and returns no values.
|
||||||
|
// Therefore, we can call it without doing any signature checking, etc.
|
||||||
|
|
||||||
|
let func_ptr = match start_index.local_or_import(&instance.module.info) {
|
||||||
|
LocalOrImport::Local(local_func_index) => instance
|
||||||
|
.module
|
||||||
|
.runnable_module
|
||||||
|
.get_func(&instance.module.info, local_func_index)
|
||||||
|
.unwrap(),
|
||||||
|
LocalOrImport::Import(import_func_index) => NonNull::new(
|
||||||
|
instance.inner.import_backing.vm_functions[import_func_index].func as *mut _,
|
||||||
|
)
|
||||||
|
.unwrap(),
|
||||||
|
};
|
||||||
|
|
||||||
|
let ctx_ptr = match start_index.local_or_import(&instance.module.info) {
|
||||||
|
LocalOrImport::Local(_) => instance.inner.vmctx,
|
||||||
|
LocalOrImport::Import(imported_func_index) => {
|
||||||
|
instance.inner.import_backing.vm_functions[imported_func_index].vmctx
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let sig_index = *instance
|
||||||
|
.module
|
||||||
|
.info
|
||||||
|
.func_assoc
|
||||||
|
.get(start_index)
|
||||||
|
.expect("broken invariant, incorrect func index");
|
||||||
|
|
||||||
|
let wasm_trampoline = instance
|
||||||
|
.module
|
||||||
|
.runnable_module
|
||||||
|
.get_trampoline(&instance.module.info, sig_index)
|
||||||
|
.expect("wasm trampoline");
|
||||||
|
|
||||||
|
let start_func: Func<(), (), Wasm> =
|
||||||
|
unsafe { Func::from_raw_parts(wasm_trampoline, func_ptr, ctx_ptr) };
|
||||||
|
|
||||||
|
start_func.call()?;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(instance)
|
Ok(instance)
|
||||||
@ -147,15 +186,15 @@ impl Instance {
|
|||||||
|
|
||||||
let func_wasm_inner = self
|
let func_wasm_inner = self
|
||||||
.module
|
.module
|
||||||
.protected_caller
|
.runnable_module
|
||||||
.get_wasm_trampoline(&self.module, sig_index)
|
.get_trampoline(&self.module.info, sig_index)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let func_ptr = match func_index.local_or_import(&self.module.info) {
|
let func_ptr = match func_index.local_or_import(&self.module.info) {
|
||||||
LocalOrImport::Local(local_func_index) => self
|
LocalOrImport::Local(local_func_index) => self
|
||||||
.module
|
.module
|
||||||
.func_resolver
|
.runnable_module
|
||||||
.get(&self.module, local_func_index)
|
.get_func(&self.module.info, local_func_index)
|
||||||
.unwrap(),
|
.unwrap(),
|
||||||
LocalOrImport::Import(import_func_index) => NonNull::new(
|
LocalOrImport::Import(import_func_index) => NonNull::new(
|
||||||
self.inner.import_backing.vm_functions[import_func_index].func as *mut _,
|
self.inner.import_backing.vm_functions[import_func_index].func as *mut _,
|
||||||
@ -245,7 +284,7 @@ impl Instance {
|
|||||||
/// # Ok(())
|
/// # Ok(())
|
||||||
/// # }
|
/// # }
|
||||||
/// ```
|
/// ```
|
||||||
pub fn call(&self, name: &str, args: &[Value]) -> CallResult<Vec<Value>> {
|
pub fn call(&self, name: &str, params: &[Value]) -> CallResult<Vec<Value>> {
|
||||||
let export_index =
|
let export_index =
|
||||||
self.module
|
self.module
|
||||||
.info
|
.info
|
||||||
@ -264,7 +303,19 @@ impl Instance {
|
|||||||
.into());
|
.into());
|
||||||
};
|
};
|
||||||
|
|
||||||
self.call_with_index(func_index, args)
|
let mut results = Vec::new();
|
||||||
|
|
||||||
|
call_func_with_index(
|
||||||
|
&self.module.info,
|
||||||
|
&*self.module.runnable_module,
|
||||||
|
&self.inner.import_backing,
|
||||||
|
self.inner.vmctx,
|
||||||
|
func_index,
|
||||||
|
params,
|
||||||
|
&mut results,
|
||||||
|
)?;
|
||||||
|
|
||||||
|
Ok(results)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns an immutable reference to the
|
/// Returns an immutable reference to the
|
||||||
@ -295,45 +346,6 @@ impl Instance {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Instance {
|
|
||||||
fn call_with_index(&self, func_index: FuncIndex, args: &[Value]) -> CallResult<Vec<Value>> {
|
|
||||||
let sig_index = *self
|
|
||||||
.module
|
|
||||||
.info
|
|
||||||
.func_assoc
|
|
||||||
.get(func_index)
|
|
||||||
.expect("broken invariant, incorrect func index");
|
|
||||||
let signature = &self.module.info.signatures[sig_index];
|
|
||||||
|
|
||||||
if !signature.check_param_value_types(args) {
|
|
||||||
Err(ResolveError::Signature {
|
|
||||||
expected: signature.clone(),
|
|
||||||
found: args.iter().map(|val| val.ty()).collect(),
|
|
||||||
})?
|
|
||||||
}
|
|
||||||
|
|
||||||
let vmctx = match func_index.local_or_import(&self.module.info) {
|
|
||||||
LocalOrImport::Local(_) => self.inner.vmctx,
|
|
||||||
LocalOrImport::Import(imported_func_index) => {
|
|
||||||
self.inner.import_backing.vm_functions[imported_func_index].vmctx
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
let token = Token::generate();
|
|
||||||
|
|
||||||
let returns = self.module.protected_caller.call(
|
|
||||||
&self.module,
|
|
||||||
func_index,
|
|
||||||
args,
|
|
||||||
&self.inner.import_backing,
|
|
||||||
vmctx,
|
|
||||||
token,
|
|
||||||
)?;
|
|
||||||
|
|
||||||
Ok(returns)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl InstanceInner {
|
impl InstanceInner {
|
||||||
pub(crate) fn get_export_from_index(
|
pub(crate) fn get_export_from_index(
|
||||||
&self,
|
&self,
|
||||||
@ -382,8 +394,8 @@ impl InstanceInner {
|
|||||||
let (func_ptr, ctx) = match func_index.local_or_import(&module.info) {
|
let (func_ptr, ctx) = match func_index.local_or_import(&module.info) {
|
||||||
LocalOrImport::Local(local_func_index) => (
|
LocalOrImport::Local(local_func_index) => (
|
||||||
module
|
module
|
||||||
.func_resolver
|
.runnable_module
|
||||||
.get(&module, local_func_index)
|
.get_func(&module.info, local_func_index)
|
||||||
.expect("broken invariant, func resolver not synced with module.exports")
|
.expect("broken invariant, func resolver not synced with module.exports")
|
||||||
.cast()
|
.cast()
|
||||||
.as_ptr() as *const _,
|
.as_ptr() as *const _,
|
||||||
@ -452,6 +464,128 @@ impl LikeNamespace for Instance {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[must_use]
|
||||||
|
fn call_func_with_index(
|
||||||
|
info: &ModuleInfo,
|
||||||
|
runnable: &dyn RunnableModule,
|
||||||
|
import_backing: &ImportBacking,
|
||||||
|
local_ctx: *mut vm::Ctx,
|
||||||
|
func_index: FuncIndex,
|
||||||
|
args: &[Value],
|
||||||
|
rets: &mut Vec<Value>,
|
||||||
|
) -> CallResult<()> {
|
||||||
|
rets.clear();
|
||||||
|
|
||||||
|
let sig_index = *info
|
||||||
|
.func_assoc
|
||||||
|
.get(func_index)
|
||||||
|
.expect("broken invariant, incorrect func index");
|
||||||
|
|
||||||
|
let signature = &info.signatures[sig_index];
|
||||||
|
let num_results = signature.returns().len();
|
||||||
|
rets.reserve(num_results);
|
||||||
|
|
||||||
|
if !signature.check_param_value_types(args) {
|
||||||
|
Err(ResolveError::Signature {
|
||||||
|
expected: signature.clone(),
|
||||||
|
found: args.iter().map(|val| val.ty()).collect(),
|
||||||
|
})?
|
||||||
|
}
|
||||||
|
|
||||||
|
let func_ptr = match func_index.local_or_import(info) {
|
||||||
|
LocalOrImport::Local(local_func_index) => {
|
||||||
|
runnable.get_func(info, local_func_index).unwrap()
|
||||||
|
}
|
||||||
|
LocalOrImport::Import(import_func_index) => {
|
||||||
|
NonNull::new(import_backing.vm_functions[import_func_index].func as *mut _).unwrap()
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let ctx_ptr = match func_index.local_or_import(info) {
|
||||||
|
LocalOrImport::Local(_) => local_ctx,
|
||||||
|
LocalOrImport::Import(imported_func_index) => {
|
||||||
|
import_backing.vm_functions[imported_func_index].vmctx
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let raw_args: SmallVec<[u64; 8]> = args
|
||||||
|
.iter()
|
||||||
|
.map(|v| match v {
|
||||||
|
Value::I32(i) => *i as u64,
|
||||||
|
Value::I64(i) => *i as u64,
|
||||||
|
Value::F32(f) => f.to_bits() as u64,
|
||||||
|
Value::F64(f) => f.to_bits(),
|
||||||
|
})
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
let Wasm {
|
||||||
|
trampoline,
|
||||||
|
invoke,
|
||||||
|
invoke_env,
|
||||||
|
} = runnable
|
||||||
|
.get_trampoline(info, sig_index)
|
||||||
|
.expect("wasm trampoline");
|
||||||
|
|
||||||
|
let run_wasm = |result_space: *mut u64| unsafe {
|
||||||
|
let mut trap_info = WasmTrapInfo::Unknown;
|
||||||
|
|
||||||
|
let success = invoke(
|
||||||
|
trampoline,
|
||||||
|
ctx_ptr,
|
||||||
|
func_ptr,
|
||||||
|
raw_args.as_ptr(),
|
||||||
|
result_space,
|
||||||
|
&mut trap_info,
|
||||||
|
invoke_env,
|
||||||
|
);
|
||||||
|
|
||||||
|
if success {
|
||||||
|
Ok(())
|
||||||
|
} else {
|
||||||
|
Err(RuntimeError::Trap {
|
||||||
|
msg: trap_info.to_string().into(),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let raw_to_value = |raw, ty| match ty {
|
||||||
|
Type::I32 => Value::I32(raw as i32),
|
||||||
|
Type::I64 => Value::I64(raw as i64),
|
||||||
|
Type::F32 => Value::F32(f32::from_bits(raw as u32)),
|
||||||
|
Type::F64 => Value::F64(f64::from_bits(raw)),
|
||||||
|
};
|
||||||
|
|
||||||
|
match signature.returns() {
|
||||||
|
&[] => {
|
||||||
|
run_wasm(0 as *mut u64)?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
&[ty] => {
|
||||||
|
let mut result = 0u64;
|
||||||
|
|
||||||
|
run_wasm(&mut result)?;
|
||||||
|
|
||||||
|
rets.push(raw_to_value(result, ty));
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
result_tys @ _ => {
|
||||||
|
let mut results: SmallVec<[u64; 8]> = smallvec![0; num_results];
|
||||||
|
|
||||||
|
run_wasm(results.as_mut_ptr())?;
|
||||||
|
|
||||||
|
rets.extend(
|
||||||
|
results
|
||||||
|
.iter()
|
||||||
|
.zip(result_tys.iter())
|
||||||
|
.map(|(&raw, &ty)| raw_to_value(raw, ty)),
|
||||||
|
);
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// A representation of an exported WebAssembly function.
|
/// A representation of an exported WebAssembly function.
|
||||||
pub struct DynFunc<'a> {
|
pub struct DynFunc<'a> {
|
||||||
pub(crate) signature: Arc<FuncSig>,
|
pub(crate) signature: Arc<FuncSig>,
|
||||||
@ -484,32 +618,19 @@ impl<'a> DynFunc<'a> {
|
|||||||
/// # }
|
/// # }
|
||||||
/// ```
|
/// ```
|
||||||
pub fn call(&self, params: &[Value]) -> CallResult<Vec<Value>> {
|
pub fn call(&self, params: &[Value]) -> CallResult<Vec<Value>> {
|
||||||
if !self.signature.check_param_value_types(params) {
|
let mut results = Vec::new();
|
||||||
Err(ResolveError::Signature {
|
|
||||||
expected: (*self.signature).clone(),
|
|
||||||
found: params.iter().map(|val| val.ty()).collect(),
|
|
||||||
})?
|
|
||||||
}
|
|
||||||
|
|
||||||
let vmctx = match self.func_index.local_or_import(&self.module.info) {
|
call_func_with_index(
|
||||||
LocalOrImport::Local(_) => self.instance_inner.vmctx,
|
&self.module.info,
|
||||||
LocalOrImport::Import(imported_func_index) => {
|
&*self.module.runnable_module,
|
||||||
self.instance_inner.import_backing.vm_functions[imported_func_index].vmctx
|
&self.instance_inner.import_backing,
|
||||||
}
|
self.instance_inner.vmctx,
|
||||||
};
|
|
||||||
|
|
||||||
let token = Token::generate();
|
|
||||||
|
|
||||||
let returns = self.module.protected_caller.call(
|
|
||||||
&self.module,
|
|
||||||
self.func_index,
|
self.func_index,
|
||||||
params,
|
params,
|
||||||
&self.instance_inner.import_backing,
|
&mut results,
|
||||||
vmctx,
|
|
||||||
token,
|
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
Ok(returns)
|
Ok(results)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn signature(&self) -> &FuncSig {
|
pub fn signature(&self) -> &FuncSig {
|
||||||
@ -520,8 +641,8 @@ impl<'a> DynFunc<'a> {
|
|||||||
match self.func_index.local_or_import(&self.module.info) {
|
match self.func_index.local_or_import(&self.module.info) {
|
||||||
LocalOrImport::Local(local_func_index) => self
|
LocalOrImport::Local(local_func_index) => self
|
||||||
.module
|
.module
|
||||||
.func_resolver
|
.runnable_module
|
||||||
.get(self.module, local_func_index)
|
.get_func(&self.module.info, local_func_index)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.as_ptr(),
|
.as_ptr(),
|
||||||
LocalOrImport::Import(import_func_index) => {
|
LocalOrImport::Import(import_func_index) => {
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
backend::{Backend, FuncResolver, ProtectedCaller},
|
backend::{Backend, RunnableModule},
|
||||||
cache::{Artifact, Error as CacheError},
|
cache::{Artifact, Error as CacheError},
|
||||||
error,
|
error,
|
||||||
import::ImportObject,
|
import::ImportObject,
|
||||||
@ -22,9 +22,7 @@ use std::sync::Arc;
|
|||||||
/// This is used to instantiate a new WebAssembly module.
|
/// This is used to instantiate a new WebAssembly module.
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
pub struct ModuleInner {
|
pub struct ModuleInner {
|
||||||
pub func_resolver: Box<dyn FuncResolver>,
|
pub runnable_module: Box<dyn RunnableModule>,
|
||||||
pub protected_caller: Box<dyn ProtectedCaller>,
|
|
||||||
|
|
||||||
pub cache_gen: Box<dyn CacheGen>,
|
pub cache_gen: Box<dyn CacheGen>,
|
||||||
|
|
||||||
pub info: ModuleInfo,
|
pub info: ModuleInfo,
|
||||||
@ -96,7 +94,7 @@ impl Module {
|
|||||||
pub(crate) fn new(inner: Arc<ModuleInner>) -> Self {
|
pub(crate) fn new(inner: Arc<ModuleInner>) -> Self {
|
||||||
unsafe {
|
unsafe {
|
||||||
EARLY_TRAPPER
|
EARLY_TRAPPER
|
||||||
.with(|ucell| *ucell.get() = Some(inner.protected_caller.get_early_trapper()));
|
.with(|ucell| *ucell.get() = Some(inner.runnable_module.get_early_trapper()));
|
||||||
}
|
}
|
||||||
Module { inner }
|
Module { inner }
|
||||||
}
|
}
|
||||||
|
@ -71,9 +71,9 @@ pub type Invoke = unsafe extern "C" fn(
|
|||||||
/// as well as the environment that the invoke function may or may not require.
|
/// as well as the environment that the invoke function may or may not require.
|
||||||
#[derive(Copy, Clone)]
|
#[derive(Copy, Clone)]
|
||||||
pub struct Wasm {
|
pub struct Wasm {
|
||||||
trampoline: Trampoline,
|
pub(crate) trampoline: Trampoline,
|
||||||
invoke: Invoke,
|
pub(crate) invoke: Invoke,
|
||||||
invoke_env: Option<NonNull<c_void>>,
|
pub(crate) invoke_env: Option<NonNull<c_void>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Wasm {
|
impl Wasm {
|
||||||
|
@ -544,42 +544,23 @@ mod vm_ctx_tests {
|
|||||||
|
|
||||||
fn generate_module() -> ModuleInner {
|
fn generate_module() -> ModuleInner {
|
||||||
use super::Func;
|
use super::Func;
|
||||||
use crate::backend::{
|
use crate::backend::{sys::Memory, Backend, CacheGen, RunnableModule, UserTrapper};
|
||||||
sys::Memory, Backend, CacheGen, FuncResolver, ProtectedCaller, Token, UserTrapper,
|
|
||||||
};
|
|
||||||
use crate::cache::Error as CacheError;
|
use crate::cache::Error as CacheError;
|
||||||
use crate::error::RuntimeResult;
|
|
||||||
use crate::typed_func::Wasm;
|
use crate::typed_func::Wasm;
|
||||||
use crate::types::{FuncIndex, LocalFuncIndex, SigIndex, Value};
|
use crate::types::{LocalFuncIndex, SigIndex};
|
||||||
use hashbrown::HashMap;
|
use hashbrown::HashMap;
|
||||||
use std::ptr::NonNull;
|
use std::ptr::NonNull;
|
||||||
struct Placeholder;
|
struct Placeholder;
|
||||||
impl FuncResolver for Placeholder {
|
impl RunnableModule for Placeholder {
|
||||||
fn get(
|
fn get_func(
|
||||||
&self,
|
&self,
|
||||||
_module: &ModuleInner,
|
_module: &ModuleInfo,
|
||||||
_local_func_index: LocalFuncIndex,
|
_local_func_index: LocalFuncIndex,
|
||||||
) -> Option<NonNull<Func>> {
|
) -> Option<NonNull<Func>> {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
}
|
|
||||||
impl ProtectedCaller for Placeholder {
|
fn get_trampoline(&self, _module: &ModuleInfo, _sig_index: SigIndex) -> Option<Wasm> {
|
||||||
fn call(
|
|
||||||
&self,
|
|
||||||
_module: &ModuleInner,
|
|
||||||
_func_index: FuncIndex,
|
|
||||||
_params: &[Value],
|
|
||||||
_import_backing: &ImportBacking,
|
|
||||||
_vmctx: *mut Ctx,
|
|
||||||
_: Token,
|
|
||||||
) -> RuntimeResult<Vec<Value>> {
|
|
||||||
Ok(vec![])
|
|
||||||
}
|
|
||||||
fn get_wasm_trampoline(
|
|
||||||
&self,
|
|
||||||
_module: &ModuleInner,
|
|
||||||
_sig_index: SigIndex,
|
|
||||||
) -> Option<Wasm> {
|
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
fn get_early_trapper(&self) -> Box<dyn UserTrapper> {
|
fn get_early_trapper(&self) -> Box<dyn UserTrapper> {
|
||||||
@ -596,8 +577,7 @@ mod vm_ctx_tests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ModuleInner {
|
ModuleInner {
|
||||||
func_resolver: Box::new(Placeholder),
|
runnable_module: Box::new(Placeholder),
|
||||||
protected_caller: Box::new(Placeholder),
|
|
||||||
cache_gen: Box::new(Placeholder),
|
cache_gen: Box::new(Placeholder),
|
||||||
info: ModuleInfo {
|
info: ModuleInfo {
|
||||||
memories: Map::new(),
|
memories: Map::new(),
|
||||||
|
@ -1,24 +1,17 @@
|
|||||||
use wasmer_runtime_core::{
|
use wasmer_runtime_core::{
|
||||||
backend::{FuncResolver, ProtectedCaller},
|
backend::RunnableModule,
|
||||||
module::ModuleInfo,
|
module::ModuleInfo,
|
||||||
structures::Map,
|
structures::Map,
|
||||||
types::{FuncIndex, FuncSig, SigIndex},
|
types::{FuncIndex, FuncSig, SigIndex},
|
||||||
};
|
};
|
||||||
use wasmparser::{Operator, Type as WpType};
|
use wasmparser::{Operator, Type as WpType};
|
||||||
|
|
||||||
/// The module-scope code generator trait.
|
pub trait ModuleCodeGenerator<FCG: FunctionCodeGenerator, RM: RunnableModule> {
|
||||||
pub trait ModuleCodeGenerator<FCG: FunctionCodeGenerator, PC: ProtectedCaller, FR: FuncResolver> {
|
|
||||||
/// Verifies that the module satisfies a precondition before generating code for it.
|
|
||||||
/// This method is called just before the first call to `next_function`.
|
|
||||||
fn check_precondition(&mut self, module_info: &ModuleInfo) -> Result<(), CodegenError>;
|
fn check_precondition(&mut self, module_info: &ModuleInfo) -> Result<(), CodegenError>;
|
||||||
|
|
||||||
/// Creates a new function and returns the function-scope code generator for it.
|
/// Creates a new function and returns the function-scope code generator for it.
|
||||||
fn next_function(&mut self) -> Result<&mut FCG, CodegenError>;
|
fn next_function(&mut self) -> Result<&mut FCG, CodegenError>;
|
||||||
|
fn finalize(self, module_info: &ModuleInfo) -> Result<RM, CodegenError>;
|
||||||
/// Finalizes code generation, returning runtime structures.
|
|
||||||
fn finalize(self, module_info: &ModuleInfo) -> Result<(PC, FR), CodegenError>;
|
|
||||||
|
|
||||||
/// Sets signatures.
|
|
||||||
fn feed_signatures(&mut self, signatures: Map<SigIndex, FuncSig>) -> Result<(), CodegenError>;
|
fn feed_signatures(&mut self, signatures: Map<SigIndex, FuncSig>) -> Result<(), CodegenError>;
|
||||||
|
|
||||||
/// Sets function signatures.
|
/// Sets function signatures.
|
||||||
|
@ -11,17 +11,16 @@ use smallvec::SmallVec;
|
|||||||
use std::ptr::NonNull;
|
use std::ptr::NonNull;
|
||||||
use std::{any::Any, collections::HashMap, sync::Arc};
|
use std::{any::Any, collections::HashMap, sync::Arc};
|
||||||
use wasmer_runtime_core::{
|
use wasmer_runtime_core::{
|
||||||
backend::{FuncResolver, ProtectedCaller, Token, UserTrapper},
|
backend::{RunnableModule, UserTrapper},
|
||||||
error::RuntimeResult,
|
|
||||||
memory::MemoryType,
|
memory::MemoryType,
|
||||||
module::{ModuleInfo, ModuleInner},
|
module::ModuleInfo,
|
||||||
structures::{Map, TypedIndex},
|
structures::{Map, TypedIndex},
|
||||||
typed_func::Wasm,
|
typed_func::Wasm,
|
||||||
types::{
|
types::{
|
||||||
FuncIndex, FuncSig, GlobalIndex, LocalFuncIndex, LocalOrImport, MemoryIndex, SigIndex,
|
FuncIndex, FuncSig, GlobalIndex, LocalFuncIndex, LocalOrImport, MemoryIndex, SigIndex,
|
||||||
TableIndex, Type, Value,
|
TableIndex, Type,
|
||||||
},
|
},
|
||||||
vm::{self, ImportBacking, LocalGlobal, LocalMemory, LocalTable},
|
vm::{self, LocalGlobal, LocalMemory, LocalTable},
|
||||||
vmcalls,
|
vmcalls,
|
||||||
};
|
};
|
||||||
use wasmparser::{Operator, Type as WpType};
|
use wasmparser::{Operator, Type as WpType};
|
||||||
@ -133,7 +132,6 @@ pub struct X64FunctionCode {
|
|||||||
signatures: Arc<Map<SigIndex, FuncSig>>,
|
signatures: Arc<Map<SigIndex, FuncSig>>,
|
||||||
function_signatures: Arc<Map<FuncIndex, SigIndex>>,
|
function_signatures: Arc<Map<FuncIndex, SigIndex>>,
|
||||||
|
|
||||||
begin_offset: AssemblyOffset,
|
|
||||||
assembler: Option<Assembler>,
|
assembler: Option<Assembler>,
|
||||||
function_labels: Option<HashMap<usize, (DynamicLabel, Option<AssemblyOffset>)>>,
|
function_labels: Option<HashMap<usize, (DynamicLabel, Option<AssemblyOffset>)>>,
|
||||||
br_table_data: Option<Vec<Vec<usize>>>,
|
br_table_data: Option<Vec<Vec<usize>>>,
|
||||||
@ -155,7 +153,9 @@ unsafe impl Send for FuncPtr {}
|
|||||||
unsafe impl Sync for FuncPtr {}
|
unsafe impl Sync for FuncPtr {}
|
||||||
|
|
||||||
pub struct X64ExecutionContext {
|
pub struct X64ExecutionContext {
|
||||||
|
#[allow(dead_code)]
|
||||||
code: ExecutableBuffer,
|
code: ExecutableBuffer,
|
||||||
|
#[allow(dead_code)]
|
||||||
functions: Vec<X64FunctionCode>,
|
functions: Vec<X64FunctionCode>,
|
||||||
function_pointers: Vec<FuncPtr>,
|
function_pointers: Vec<FuncPtr>,
|
||||||
signatures: Arc<Map<SigIndex, FuncSig>>,
|
signatures: Arc<Map<SigIndex, FuncSig>>,
|
||||||
@ -163,10 +163,6 @@ pub struct X64ExecutionContext {
|
|||||||
func_import_count: usize,
|
func_import_count: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct X64RuntimeResolver {
|
|
||||||
local_function_pointers: Vec<FuncPtr>,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct ControlFrame {
|
pub struct ControlFrame {
|
||||||
pub label: DynamicLabel,
|
pub label: DynamicLabel,
|
||||||
@ -183,86 +179,33 @@ pub enum IfElseState {
|
|||||||
Else,
|
Else,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl X64ExecutionContext {
|
impl RunnableModule for X64ExecutionContext {
|
||||||
fn get_runtime_resolver(
|
fn get_func(
|
||||||
&self,
|
&self,
|
||||||
_module_info: &ModuleInfo,
|
_: &ModuleInfo,
|
||||||
) -> Result<X64RuntimeResolver, CodegenError> {
|
local_func_index: LocalFuncIndex,
|
||||||
Ok(X64RuntimeResolver {
|
|
||||||
local_function_pointers: self.function_pointers[self.func_import_count..].to_vec(),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl FuncResolver for X64RuntimeResolver {
|
|
||||||
fn get(
|
|
||||||
&self,
|
|
||||||
_module: &ModuleInner,
|
|
||||||
_local_func_index: LocalFuncIndex,
|
|
||||||
) -> Option<NonNull<vm::Func>> {
|
) -> Option<NonNull<vm::Func>> {
|
||||||
NonNull::new(
|
self.function_pointers[self.func_import_count..]
|
||||||
self.local_function_pointers[_local_func_index.index() as usize].0 as *mut vm::Func,
|
.get(local_func_index.index())
|
||||||
)
|
.and_then(|ptr| NonNull::new(ptr.0 as *mut vm::Func))
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ProtectedCaller for X64ExecutionContext {
|
|
||||||
fn call(
|
|
||||||
&self,
|
|
||||||
_module: &ModuleInner,
|
|
||||||
_func_index: FuncIndex,
|
|
||||||
_params: &[Value],
|
|
||||||
_import_backing: &ImportBacking,
|
|
||||||
_vmctx: *mut vm::Ctx,
|
|
||||||
_: Token,
|
|
||||||
) -> RuntimeResult<Vec<Value>> {
|
|
||||||
let index = _func_index.index() - self.func_import_count;
|
|
||||||
let ptr = self.code.ptr(self.functions[index].begin_offset);
|
|
||||||
let return_ty = self.functions[index].returns.last().cloned();
|
|
||||||
let buffer: Vec<u64> = _params
|
|
||||||
.iter()
|
|
||||||
.rev()
|
|
||||||
.map(|x| match *x {
|
|
||||||
Value::I32(x) => x as u32 as u64,
|
|
||||||
Value::I64(x) => x as u64,
|
|
||||||
Value::F32(x) => f32::to_bits(x) as u64,
|
|
||||||
Value::F64(x) => f64::to_bits(x),
|
|
||||||
})
|
|
||||||
.collect();
|
|
||||||
let ret = unsafe {
|
|
||||||
protect_unix::call_protected(|| {
|
|
||||||
CONSTRUCT_STACK_AND_CALL_WASM(
|
|
||||||
buffer.as_ptr(),
|
|
||||||
buffer.as_ptr().offset(buffer.len() as isize),
|
|
||||||
_vmctx,
|
|
||||||
ptr as _,
|
|
||||||
)
|
|
||||||
})
|
|
||||||
}?;
|
|
||||||
Ok(if let Some(ty) = return_ty {
|
|
||||||
vec![match ty {
|
|
||||||
WpType::I32 => Value::I32(ret as i32),
|
|
||||||
WpType::I64 => Value::I64(ret as i64),
|
|
||||||
WpType::F32 => Value::F32(f32::from_bits(ret as u32)),
|
|
||||||
WpType::F64 => Value::F64(f64::from_bits(ret as u64)),
|
|
||||||
_ => unreachable!(),
|
|
||||||
}]
|
|
||||||
} else {
|
|
||||||
vec![]
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_wasm_trampoline(&self, module: &ModuleInner, sig_index: SigIndex) -> Option<Wasm> {
|
fn get_trampoline(&self, _: &ModuleInfo, sig_index: SigIndex) -> Option<Wasm> {
|
||||||
use std::ffi::c_void;
|
use std::ffi::c_void;
|
||||||
use wasmer_runtime_core::typed_func::WasmTrapInfo;
|
use wasmer_runtime_core::typed_func::WasmTrapInfo;
|
||||||
|
|
||||||
unsafe extern "C" fn invoke(
|
unsafe extern "C" fn invoke(
|
||||||
trampoline: unsafe extern "C" fn(*mut vm::Ctx, NonNull<vm::Func>, *const u64, *mut u64),
|
_trampoline: unsafe extern "C" fn(
|
||||||
|
*mut vm::Ctx,
|
||||||
|
NonNull<vm::Func>,
|
||||||
|
*const u64,
|
||||||
|
*mut u64,
|
||||||
|
),
|
||||||
ctx: *mut vm::Ctx,
|
ctx: *mut vm::Ctx,
|
||||||
func: NonNull<vm::Func>,
|
func: NonNull<vm::Func>,
|
||||||
args: *const u64,
|
args: *const u64,
|
||||||
rets: *mut u64,
|
rets: *mut u64,
|
||||||
trap_info: *mut WasmTrapInfo,
|
_trap_info: *mut WasmTrapInfo,
|
||||||
num_params_plus_one: Option<NonNull<c_void>>,
|
num_params_plus_one: Option<NonNull<c_void>>,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
let args = ::std::slice::from_raw_parts(
|
let args = ::std::slice::from_raw_parts(
|
||||||
@ -279,7 +222,9 @@ impl ProtectedCaller for X64ExecutionContext {
|
|||||||
)
|
)
|
||||||
}) {
|
}) {
|
||||||
Ok(x) => {
|
Ok(x) => {
|
||||||
*rets = x;
|
if !rets.is_null() {
|
||||||
|
*rets = x;
|
||||||
|
}
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
Err(_) => false,
|
Err(_) => false,
|
||||||
@ -331,9 +276,7 @@ impl X64ModuleCodeGenerator {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ModuleCodeGenerator<X64FunctionCode, X64ExecutionContext, X64RuntimeResolver>
|
impl ModuleCodeGenerator<X64FunctionCode, X64ExecutionContext> for X64ModuleCodeGenerator {
|
||||||
for X64ModuleCodeGenerator
|
|
||||||
{
|
|
||||||
fn check_precondition(&mut self, _module_info: &ModuleInfo) -> Result<(), CodegenError> {
|
fn check_precondition(&mut self, _module_info: &ModuleInfo) -> Result<(), CodegenError> {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@ -368,7 +311,6 @@ impl ModuleCodeGenerator<X64FunctionCode, X64ExecutionContext, X64RuntimeResolve
|
|||||||
signatures: self.signatures.as_ref().unwrap().clone(),
|
signatures: self.signatures.as_ref().unwrap().clone(),
|
||||||
function_signatures: self.function_signatures.as_ref().unwrap().clone(),
|
function_signatures: self.function_signatures.as_ref().unwrap().clone(),
|
||||||
|
|
||||||
begin_offset: begin_offset,
|
|
||||||
assembler: Some(assembler),
|
assembler: Some(assembler),
|
||||||
function_labels: Some(function_labels),
|
function_labels: Some(function_labels),
|
||||||
br_table_data: Some(br_table_data),
|
br_table_data: Some(br_table_data),
|
||||||
@ -385,10 +327,7 @@ impl ModuleCodeGenerator<X64FunctionCode, X64ExecutionContext, X64RuntimeResolve
|
|||||||
Ok(self.functions.last_mut().unwrap())
|
Ok(self.functions.last_mut().unwrap())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn finalize(
|
fn finalize(mut self, _: &ModuleInfo) -> Result<X64ExecutionContext, CodegenError> {
|
||||||
mut self,
|
|
||||||
module_info: &ModuleInfo,
|
|
||||||
) -> Result<(X64ExecutionContext, X64RuntimeResolver), CodegenError> {
|
|
||||||
let (assembler, mut br_table_data) = match self.functions.last_mut() {
|
let (assembler, mut br_table_data) = match self.functions.last_mut() {
|
||||||
Some(x) => (x.assembler.take().unwrap(), x.br_table_data.take().unwrap()),
|
Some(x) => (x.assembler.take().unwrap(), x.br_table_data.take().unwrap()),
|
||||||
None => {
|
None => {
|
||||||
@ -432,17 +371,14 @@ impl ModuleCodeGenerator<X64FunctionCode, X64ExecutionContext, X64RuntimeResolve
|
|||||||
out_labels.push(FuncPtr(output.ptr(*offset) as _));
|
out_labels.push(FuncPtr(output.ptr(*offset) as _));
|
||||||
}
|
}
|
||||||
|
|
||||||
let ctx = X64ExecutionContext {
|
Ok(X64ExecutionContext {
|
||||||
code: output,
|
code: output,
|
||||||
functions: self.functions,
|
functions: self.functions,
|
||||||
signatures: self.signatures.as_ref().unwrap().clone(),
|
signatures: self.signatures.as_ref().unwrap().clone(),
|
||||||
_br_table_data: br_table_data,
|
_br_table_data: br_table_data,
|
||||||
func_import_count: self.func_import_count,
|
func_import_count: self.func_import_count,
|
||||||
function_pointers: out_labels,
|
function_pointers: out_labels,
|
||||||
};
|
})
|
||||||
let resolver = ctx.get_runtime_resolver(module_info)?;
|
|
||||||
|
|
||||||
Ok((ctx, resolver))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn feed_signatures(&mut self, signatures: Map<SigIndex, FuncSig>) -> Result<(), CodegenError> {
|
fn feed_signatures(&mut self, signatures: Map<SigIndex, FuncSig>) -> Result<(), CodegenError> {
|
||||||
|
@ -62,11 +62,10 @@ impl Compiler for SinglePassCompiler {
|
|||||||
) -> CompileResult<ModuleInner> {
|
) -> CompileResult<ModuleInner> {
|
||||||
let mut mcg = codegen_x64::X64ModuleCodeGenerator::new();
|
let mut mcg = codegen_x64::X64ModuleCodeGenerator::new();
|
||||||
let info = parse::read_module(wasm, Backend::Singlepass, &mut mcg, &compiler_config)?;
|
let info = parse::read_module(wasm, Backend::Singlepass, &mut mcg, &compiler_config)?;
|
||||||
let (ec, resolver) = mcg.finalize(&info)?;
|
let exec_context = mcg.finalize(&info)?;
|
||||||
Ok(ModuleInner {
|
Ok(ModuleInner {
|
||||||
cache_gen: Box::new(Placeholder),
|
cache_gen: Box::new(Placeholder),
|
||||||
func_resolver: Box::new(resolver),
|
runnable_module: Box::new(exec_context),
|
||||||
protected_caller: Box::new(ec),
|
|
||||||
info: info,
|
info: info,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
use crate::codegen::{CodegenError, FunctionCodeGenerator, ModuleCodeGenerator};
|
use crate::codegen::{CodegenError, FunctionCodeGenerator, ModuleCodeGenerator};
|
||||||
use hashbrown::HashMap;
|
use hashbrown::HashMap;
|
||||||
use wasmer_runtime_core::{
|
use wasmer_runtime_core::{
|
||||||
backend::{Backend, CompilerConfig, FuncResolver, ProtectedCaller},
|
backend::{Backend, CompilerConfig, RunnableModule},
|
||||||
module::{
|
module::{
|
||||||
DataInitializer, ExportIndex, ImportName, ModuleInfo, StringTable, StringTableBuilder,
|
DataInitializer, ExportIndex, ImportName, ModuleInfo, StringTable, StringTableBuilder,
|
||||||
TableInitializer,
|
TableInitializer,
|
||||||
@ -39,10 +39,9 @@ impl From<CodegenError> for LoadError {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn read_module<
|
pub fn read_module<
|
||||||
MCG: ModuleCodeGenerator<FCG, PC, FR>,
|
MCG: ModuleCodeGenerator<FCG, RM>,
|
||||||
FCG: FunctionCodeGenerator,
|
FCG: FunctionCodeGenerator,
|
||||||
PC: ProtectedCaller,
|
RM: RunnableModule,
|
||||||
FR: FuncResolver,
|
|
||||||
>(
|
>(
|
||||||
wasm: &[u8],
|
wasm: &[u8],
|
||||||
backend: Backend,
|
backend: Backend,
|
||||||
|
Reference in New Issue
Block a user