mirror of
https://github.com/fluencelabs/wasmer
synced 2025-06-23 13:41:32 +00:00
Add importable memories and dynamic memories
This commit is contained in:
120
Cargo.lock
generated
120
Cargo.lock
generated
@ -55,6 +55,14 @@ dependencies = [
|
|||||||
"vec_map 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"vec_map 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "cloudabi"
|
||||||
|
version = "0.0.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cmake"
|
name = "cmake"
|
||||||
version = "0.1.35"
|
version = "0.1.35"
|
||||||
@ -176,6 +184,20 @@ name = "field-offset"
|
|||||||
version = "0.1.1"
|
version = "0.1.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "fuchsia-zircon"
|
||||||
|
version = "0.3.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "fuchsia-zircon-sys"
|
||||||
|
version = "0.3.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "gcc"
|
name = "gcc"
|
||||||
version = "0.3.55"
|
version = "0.3.55"
|
||||||
@ -227,6 +249,15 @@ name = "libc"
|
|||||||
version = "0.2.44"
|
version = "0.2.44"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "lock_api"
|
||||||
|
version = "0.1.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"owning_ref 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "log"
|
name = "log"
|
||||||
version = "0.4.5"
|
version = "0.4.5"
|
||||||
@ -247,6 +278,14 @@ dependencies = [
|
|||||||
"void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "owning_ref"
|
||||||
|
version = "0.4.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"stable_deref_trait 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "page_size"
|
name = "page_size"
|
||||||
version = "0.4.1"
|
version = "0.4.1"
|
||||||
@ -257,6 +296,27 @@ dependencies = [
|
|||||||
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "parking_lot"
|
||||||
|
version = "0.6.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"lock_api 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"parking_lot_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "parking_lot_core"
|
||||||
|
version = "0.3.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"libc 0.2.44 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"rand 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"smallvec 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "proc-macro2"
|
name = "proc-macro2"
|
||||||
version = "0.4.20"
|
version = "0.4.20"
|
||||||
@ -273,6 +333,31 @@ dependencies = [
|
|||||||
"proc-macro2 0.4.20 (registry+https://github.com/rust-lang/crates.io-index)",
|
"proc-macro2 0.4.20 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rand"
|
||||||
|
version = "0.5.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"libc 0.2.44 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"rand_core 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rand_core"
|
||||||
|
version = "0.2.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"rand_core 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rand_core"
|
||||||
|
version = "0.3.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "raw-cpuid"
|
name = "raw-cpuid"
|
||||||
version = "6.1.0"
|
version = "6.1.0"
|
||||||
@ -352,6 +437,19 @@ dependencies = [
|
|||||||
"serde 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)",
|
"serde 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "smallvec"
|
||||||
|
version = "0.6.8"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"unreachable 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "stable_deref_trait"
|
||||||
|
version = "1.1.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "strsim"
|
name = "strsim"
|
||||||
version = "0.7.0"
|
version = "0.7.0"
|
||||||
@ -451,6 +549,14 @@ name = "unicode-xid"
|
|||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "unreachable"
|
||||||
|
version = "1.0.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "vec_map"
|
name = "vec_map"
|
||||||
version = "0.8.1"
|
version = "0.8.1"
|
||||||
@ -542,6 +648,7 @@ dependencies = [
|
|||||||
"hashbrown 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
"hashbrown 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"nix 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"nix 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"page_size 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"page_size 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"parking_lot 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"wabt 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"wabt 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"wasmer-clif-backend 0.1.1",
|
"wasmer-clif-backend 0.1.1",
|
||||||
"wasmparser 0.23.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"wasmparser 0.23.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
@ -596,6 +703,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
"checksum cc 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)" = "f159dfd43363c4d08055a07703eb7a3406b0dac4d0584d96965a3262db3c9d16"
|
"checksum cc 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)" = "f159dfd43363c4d08055a07703eb7a3406b0dac4d0584d96965a3262db3c9d16"
|
||||||
"checksum cfg-if 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "0c4e7bb64a8ebb0d856483e1e682ea3422f883c5f5615a90d51a2c82fe87fdd3"
|
"checksum cfg-if 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "0c4e7bb64a8ebb0d856483e1e682ea3422f883c5f5615a90d51a2c82fe87fdd3"
|
||||||
"checksum clap 2.32.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b957d88f4b6a63b9d70d5f454ac8011819c6efa7727858f458ab71c756ce2d3e"
|
"checksum clap 2.32.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b957d88f4b6a63b9d70d5f454ac8011819c6efa7727858f458ab71c756ce2d3e"
|
||||||
|
"checksum cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f"
|
||||||
"checksum cmake 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)" = "6ec65ee4f9c9d16f335091d23693457ed4928657ba4982289d7fafee03bc614a"
|
"checksum cmake 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)" = "6ec65ee4f9c9d16f335091d23693457ed4928657ba4982289d7fafee03bc614a"
|
||||||
"checksum cranelift-bforest 0.26.0 (registry+https://github.com/rust-lang/crates.io-index)" = "40f8ff24e9a6c89b8a846b14df9a34d2cac17cea7bdb5c81ed6b4744ee0e38bf"
|
"checksum cranelift-bforest 0.26.0 (registry+https://github.com/rust-lang/crates.io-index)" = "40f8ff24e9a6c89b8a846b14df9a34d2cac17cea7bdb5c81ed6b4744ee0e38bf"
|
||||||
"checksum cranelift-codegen 0.26.0 (registry+https://github.com/rust-lang/crates.io-index)" = "42f5b809bd885c368e01aeec8fe04f21dcb07569834b907d75b4a7bed8d067eb"
|
"checksum cranelift-codegen 0.26.0 (registry+https://github.com/rust-lang/crates.io-index)" = "42f5b809bd885c368e01aeec8fe04f21dcb07569834b907d75b4a7bed8d067eb"
|
||||||
@ -609,6 +717,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
"checksum failure 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "6dd377bcc1b1b7ce911967e3ec24fa19c3224394ec05b54aa7b083d498341ac7"
|
"checksum failure 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "6dd377bcc1b1b7ce911967e3ec24fa19c3224394ec05b54aa7b083d498341ac7"
|
||||||
"checksum failure_derive 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "64c2d913fe8ed3b6c6518eedf4538255b989945c14c2a7d5cbff62a5e2120596"
|
"checksum failure_derive 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "64c2d913fe8ed3b6c6518eedf4538255b989945c14c2a7d5cbff62a5e2120596"
|
||||||
"checksum field-offset 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "64e9bc339e426139e02601fa69d101e96a92aee71b58bc01697ec2a63a5c9e68"
|
"checksum field-offset 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "64e9bc339e426139e02601fa69d101e96a92aee71b58bc01697ec2a63a5c9e68"
|
||||||
|
"checksum fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82"
|
||||||
|
"checksum fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7"
|
||||||
"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 glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "8be18de09a56b60ed0edf84bc9df007e30040691af7acd1c41874faac5895bfb"
|
"checksum glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "8be18de09a56b60ed0edf84bc9df007e30040691af7acd1c41874faac5895bfb"
|
||||||
"checksum hashbrown 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "64b7d419d0622ae02fe5da6b9a5e1964b610a65bb37923b976aeebb6dbb8f86e"
|
"checksum hashbrown 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "64b7d419d0622ae02fe5da6b9a5e1964b610a65bb37923b976aeebb6dbb8f86e"
|
||||||
@ -617,11 +727,18 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
"checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d"
|
"checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d"
|
||||||
"checksum libc 0.2.44 (git+https://github.com/rust-lang/libc)" = "<none>"
|
"checksum libc 0.2.44 (git+https://github.com/rust-lang/libc)" = "<none>"
|
||||||
"checksum libc 0.2.44 (registry+https://github.com/rust-lang/crates.io-index)" = "10923947f84a519a45c8fefb7dd1b3e8c08747993381adee176d7a82b4195311"
|
"checksum libc 0.2.44 (registry+https://github.com/rust-lang/crates.io-index)" = "10923947f84a519a45c8fefb7dd1b3e8c08747993381adee176d7a82b4195311"
|
||||||
|
"checksum lock_api 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "62ebf1391f6acad60e5c8b43706dde4582df75c06698ab44511d15016bc2442c"
|
||||||
"checksum log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)" = "d4fcce5fa49cc693c312001daf1d13411c4a5283796bac1084299ea3e567113f"
|
"checksum log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)" = "d4fcce5fa49cc693c312001daf1d13411c4a5283796bac1084299ea3e567113f"
|
||||||
"checksum nix 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = "921f61dc817b379d0834e45d5ec45beaacfae97082090a49c2cf30dcbc30206f"
|
"checksum nix 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = "921f61dc817b379d0834e45d5ec45beaacfae97082090a49c2cf30dcbc30206f"
|
||||||
|
"checksum owning_ref 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "49a4b8ea2179e6a2e27411d3bca09ca6dd630821cf6894c6c7c8467a8ee7ef13"
|
||||||
"checksum page_size 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f89ef58b3d32420dbd1a43d2f38ae92f6239ef12bb556ab09ca55445f5a67242"
|
"checksum page_size 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f89ef58b3d32420dbd1a43d2f38ae92f6239ef12bb556ab09ca55445f5a67242"
|
||||||
|
"checksum parking_lot 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)" = "f0802bff09003b291ba756dc7e79313e51cc31667e94afbe847def490424cde5"
|
||||||
|
"checksum parking_lot_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ad7f7e6ebdc79edff6fdcb87a55b620174f7a989e3eb31b65231f4af57f00b8c"
|
||||||
"checksum proc-macro2 0.4.20 (registry+https://github.com/rust-lang/crates.io-index)" = "3d7b7eaaa90b4a90a932a9ea6666c95a389e424eff347f0f793979289429feee"
|
"checksum proc-macro2 0.4.20 (registry+https://github.com/rust-lang/crates.io-index)" = "3d7b7eaaa90b4a90a932a9ea6666c95a389e424eff347f0f793979289429feee"
|
||||||
"checksum quote 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)" = "dd636425967c33af890042c483632d33fa7a18f19ad1d7ea72e8998c6ef8dea5"
|
"checksum quote 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)" = "dd636425967c33af890042c483632d33fa7a18f19ad1d7ea72e8998c6ef8dea5"
|
||||||
|
"checksum rand 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)" = "e464cd887e869cddcae8792a4ee31d23c7edd516700695608f5b98c67ee0131c"
|
||||||
|
"checksum rand_core 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1961a422c4d189dfb50ffa9320bf1f2a9bd54ecb92792fb9477f99a1045f3372"
|
||||||
|
"checksum rand_core 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0905b6b7079ec73b314d4c748701f6931eb79fd97c668caa3f1899b22b32c6db"
|
||||||
"checksum raw-cpuid 6.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "30a9d219c32c9132f7be513c18be77c9881c7107d2ab5569d205a6a0f0e6dc7d"
|
"checksum raw-cpuid 6.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "30a9d219c32c9132f7be513c18be77c9881c7107d2ab5569d205a6a0f0e6dc7d"
|
||||||
"checksum redox_syscall 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)" = "c214e91d3ecf43e9a4e41e578973adeb14b474f2bee858742d127af75a0112b1"
|
"checksum redox_syscall 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)" = "c214e91d3ecf43e9a4e41e578973adeb14b474f2bee858742d127af75a0112b1"
|
||||||
"checksum redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7e891cfe48e9100a70a3b6eb652fef28920c117d366339687bd5576160db0f76"
|
"checksum redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7e891cfe48e9100a70a3b6eb652fef28920c117d366339687bd5576160db0f76"
|
||||||
@ -633,6 +750,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
"checksum serde 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)" = "84257ccd054dc351472528c8587b4de2dbf0dc0fe2e634030c1a90bfdacebaa9"
|
"checksum serde 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)" = "84257ccd054dc351472528c8587b4de2dbf0dc0fe2e634030c1a90bfdacebaa9"
|
||||||
"checksum serde_derive 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)" = "31569d901045afbff7a9479f793177fe9259819aff10ab4f89ef69bbc5f567fe"
|
"checksum serde_derive 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)" = "31569d901045afbff7a9479f793177fe9259819aff10ab4f89ef69bbc5f567fe"
|
||||||
"checksum serde_json 1.0.32 (registry+https://github.com/rust-lang/crates.io-index)" = "43344e7ce05d0d8280c5940cabb4964bea626aa58b1ec0e8c73fa2a8512a38ce"
|
"checksum serde_json 1.0.32 (registry+https://github.com/rust-lang/crates.io-index)" = "43344e7ce05d0d8280c5940cabb4964bea626aa58b1ec0e8c73fa2a8512a38ce"
|
||||||
|
"checksum smallvec 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)" = "88aea073965ab29f6edb5493faf96ad662fb18aa9eeb186a3b7057951605ed15"
|
||||||
|
"checksum stable_deref_trait 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "dba1a27d3efae4351c8051072d619e3ade2820635c3958d826bfea39d59b54c8"
|
||||||
"checksum strsim 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bb4f380125926a99e52bc279241539c018323fab05ad6368b56f93d9369ff550"
|
"checksum strsim 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bb4f380125926a99e52bc279241539c018323fab05ad6368b56f93d9369ff550"
|
||||||
"checksum structopt 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)" = "670ad348dc73012fcf78c71f06f9d942232cdd4c859d4b6975e27836c3efc0c3"
|
"checksum structopt 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)" = "670ad348dc73012fcf78c71f06f9d942232cdd4c859d4b6975e27836c3efc0c3"
|
||||||
"checksum structopt-derive 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)" = "ef98172b1a00b0bec738508d3726540edcbd186d50dfd326f2b1febbb3559f04"
|
"checksum structopt-derive 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)" = "ef98172b1a00b0bec738508d3726540edcbd186d50dfd326f2b1febbb3559f04"
|
||||||
@ -645,6 +764,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
"checksum unicode-segmentation 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "aa6024fc12ddfd1c6dbc14a80fa2324d4568849869b779f6bd37e5e4c03344d1"
|
"checksum unicode-segmentation 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "aa6024fc12ddfd1c6dbc14a80fa2324d4568849869b779f6bd37e5e4c03344d1"
|
||||||
"checksum unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "882386231c45df4700b275c7ff55b6f3698780a650026380e72dabe76fa46526"
|
"checksum unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "882386231c45df4700b275c7ff55b6f3698780a650026380e72dabe76fa46526"
|
||||||
"checksum unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc"
|
"checksum unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc"
|
||||||
|
"checksum unreachable 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "382810877fe448991dfc7f0dd6e3ae5d58088fd0ea5e35189655f84e6814fa56"
|
||||||
"checksum vec_map 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "05c78687fb1a80548ae3250346c3db86a80a7cdd77bda190189f2d0a0987c81a"
|
"checksum vec_map 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "05c78687fb1a80548ae3250346c3db86a80a7cdd77bda190189f2d0a0987c81a"
|
||||||
"checksum void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d"
|
"checksum void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d"
|
||||||
"checksum wabt 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "8ff1f0f87e467255240c1faf5cf13a04410723407840d7733e75967224e191a5"
|
"checksum wabt 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "8ff1f0f87e467255240c1faf5cf13a04410723407840d7733e75967224e191a5"
|
||||||
|
@ -1,17 +1,20 @@
|
|||||||
use crate::{module::Converter, module_env::ModuleEnv};
|
use crate::{module::Converter, module_env::ModuleEnv, relocation::call_names};
|
||||||
use cranelift_codegen::{
|
use cranelift_codegen::{
|
||||||
cursor::FuncCursor,
|
cursor::FuncCursor,
|
||||||
ir::{self, InstBuilder},
|
ir::{self, InstBuilder},
|
||||||
isa,
|
isa,
|
||||||
};
|
};
|
||||||
use cranelift_wasm::{self, FuncEnvironment, ModuleEnvironment};
|
use cranelift_wasm::{self, FuncEnvironment, ModuleEnvironment};
|
||||||
|
use std::mem;
|
||||||
use wasmer_runtime_core::{
|
use wasmer_runtime_core::{
|
||||||
memory::LinearMemory,
|
memory::MemoryType,
|
||||||
structures::TypedIndex,
|
structures::TypedIndex,
|
||||||
types::{FuncIndex, GlobalIndex, LocalOrImport, MemoryIndex, TableIndex},
|
types::{FuncIndex, GlobalIndex, LocalOrImport, MemoryIndex, TableIndex},
|
||||||
vm,
|
vm,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const WASM_PAGE_SIZE: usize = 65_536;
|
||||||
|
|
||||||
pub struct FuncEnv<'env, 'module, 'isa> {
|
pub struct FuncEnv<'env, 'module, 'isa> {
|
||||||
env: &'env ModuleEnv<'module, 'isa>,
|
env: &'env ModuleEnv<'module, 'isa>,
|
||||||
}
|
}
|
||||||
@ -140,7 +143,7 @@ impl<'env, 'module, 'isa> FuncEnvironment for FuncEnv<'env, 'module, 'isa> {
|
|||||||
let vmctx = func.create_global_value(ir::GlobalValueData::VMContext);
|
let vmctx = func.create_global_value(ir::GlobalValueData::VMContext);
|
||||||
let ptr_type = self.pointer_type();
|
let ptr_type = self.pointer_type();
|
||||||
|
|
||||||
match mem_index.local_or_import(self.env.module) {
|
let (local_memory_ptr_ptr, description) = match mem_index.local_or_import(self.env.module) {
|
||||||
LocalOrImport::Local(local_mem_index) => {
|
LocalOrImport::Local(local_mem_index) => {
|
||||||
let memories_base_addr = func.create_global_value(ir::GlobalValueData::Load {
|
let memories_base_addr = func.create_global_value(ir::GlobalValueData::Load {
|
||||||
base: vmctx,
|
base: vmctx,
|
||||||
@ -149,75 +152,88 @@ impl<'env, 'module, 'isa> FuncEnvironment for FuncEnv<'env, 'module, 'isa> {
|
|||||||
readonly: true,
|
readonly: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
let memory_offset = local_mem_index.index() * vm::LocalMemory::size() as usize;
|
let local_memory_ptr_offset =
|
||||||
|
local_mem_index.index() * mem::size_of::<*mut vm::LocalMemory>();
|
||||||
|
|
||||||
let memory_struct_addr = func.create_global_value(ir::GlobalValueData::IAddImm {
|
(
|
||||||
base: memories_base_addr,
|
func.create_global_value(ir::GlobalValueData::IAddImm {
|
||||||
offset: (memory_offset as i64).into(),
|
base: memories_base_addr,
|
||||||
global_type: ptr_type,
|
offset: (local_memory_ptr_offset as i64).into(),
|
||||||
});
|
global_type: ptr_type,
|
||||||
|
}),
|
||||||
let memory_base_addr = func.create_global_value(ir::GlobalValueData::Load {
|
self.env.module.memories[local_mem_index],
|
||||||
base: memory_struct_addr,
|
)
|
||||||
offset: (vm::LocalMemory::offset_base() as i32).into(),
|
|
||||||
global_type: ptr_type,
|
|
||||||
readonly: true,
|
|
||||||
});
|
|
||||||
|
|
||||||
func.create_heap(ir::HeapData {
|
|
||||||
base: memory_base_addr,
|
|
||||||
min_size: (self.env.module.memories[local_mem_index].min as u64).into(),
|
|
||||||
offset_guard_size: (LinearMemory::DEFAULT_GUARD_SIZE as u64).into(),
|
|
||||||
style: ir::HeapStyle::Static {
|
|
||||||
bound: (LinearMemory::DEFAULT_HEAP_SIZE as u64).into(),
|
|
||||||
},
|
|
||||||
index_type: ir::types::I32,
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
LocalOrImport::Import(imported_mem_index) => {
|
LocalOrImport::Import(import_mem_index) => {
|
||||||
let imported_memories_base = func.create_global_value(ir::GlobalValueData::Load {
|
let memories_base_addr = func.create_global_value(ir::GlobalValueData::Load {
|
||||||
base: vmctx,
|
base: vmctx,
|
||||||
offset: (vm::Ctx::offset_imported_memories() as i32).into(),
|
offset: (vm::Ctx::offset_imported_memories() as i32).into(),
|
||||||
global_type: ptr_type,
|
global_type: ptr_type,
|
||||||
readonly: true,
|
readonly: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
let imported_memory_offset =
|
let local_memory_ptr_offset =
|
||||||
imported_mem_index.index() * vm::ImportedMemory::size() as usize;
|
import_mem_index.index() * mem::size_of::<*mut vm::LocalMemory>();
|
||||||
|
|
||||||
let imported_memory_struct_addr =
|
(
|
||||||
func.create_global_value(ir::GlobalValueData::IAddImm {
|
func.create_global_value(ir::GlobalValueData::IAddImm {
|
||||||
base: imported_memories_base,
|
base: memories_base_addr,
|
||||||
offset: (imported_memory_offset as i64).into(),
|
offset: (local_memory_ptr_offset as i64).into(),
|
||||||
global_type: ptr_type,
|
global_type: ptr_type,
|
||||||
});
|
}),
|
||||||
|
self.env.module.imported_memories[import_mem_index].1,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
let local_memory_struct_addr =
|
let (local_memory_ptr, local_memory_base) = {
|
||||||
func.create_global_value(ir::GlobalValueData::Load {
|
let local_memory_ptr = func.create_global_value(ir::GlobalValueData::Load {
|
||||||
base: imported_memory_struct_addr,
|
base: local_memory_ptr_ptr,
|
||||||
offset: (vm::ImportedMemory::offset_memory() as i32).into(),
|
offset: 0.into(),
|
||||||
global_type: ptr_type,
|
global_type: ptr_type,
|
||||||
readonly: true,
|
readonly: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
let local_memory_base = func.create_global_value(ir::GlobalValueData::Load {
|
(
|
||||||
base: local_memory_struct_addr,
|
local_memory_ptr,
|
||||||
|
func.create_global_value(ir::GlobalValueData::Load {
|
||||||
|
base: local_memory_ptr,
|
||||||
offset: (vm::LocalMemory::offset_base() as i32).into(),
|
offset: (vm::LocalMemory::offset_base() as i32).into(),
|
||||||
global_type: ptr_type,
|
global_type: ptr_type,
|
||||||
readonly: true,
|
readonly: false,
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
};
|
||||||
|
|
||||||
|
match description.memory_type() {
|
||||||
|
mem_type @ MemoryType::Dynamic => {
|
||||||
|
let local_memory_bound = func.create_global_value(ir::GlobalValueData::Load {
|
||||||
|
base: local_memory_ptr,
|
||||||
|
offset: (vm::LocalMemory::offset_bound() as i32).into(),
|
||||||
|
global_type: ptr_type,
|
||||||
|
readonly: false,
|
||||||
});
|
});
|
||||||
|
|
||||||
func.create_heap(ir::HeapData {
|
func.create_heap(ir::HeapData {
|
||||||
base: local_memory_base,
|
base: local_memory_base,
|
||||||
min_size: (self.env.module.imported_memories[imported_mem_index].1.min as u64)
|
min_size: ((description.min as u64) * (WASM_PAGE_SIZE as u64)).into(),
|
||||||
.into(),
|
offset_guard_size: mem_type.guard_size().into(),
|
||||||
offset_guard_size: (LinearMemory::DEFAULT_GUARD_SIZE as u64).into(),
|
style: ir::HeapStyle::Dynamic {
|
||||||
style: ir::HeapStyle::Static {
|
bound_gv: local_memory_bound,
|
||||||
bound: (LinearMemory::DEFAULT_HEAP_SIZE as u64).into(),
|
|
||||||
},
|
},
|
||||||
index_type: ir::types::I32,
|
index_type: ir::types::I32,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
mem_type @ MemoryType::Static | mem_type @ MemoryType::SharedStatic => func
|
||||||
|
.create_heap(ir::HeapData {
|
||||||
|
base: local_memory_base,
|
||||||
|
min_size: ((description.min as u64) * (WASM_PAGE_SIZE as u64)).into(),
|
||||||
|
offset_guard_size: mem_type.guard_size().into(),
|
||||||
|
style: ir::HeapStyle::Static {
|
||||||
|
bound: mem_type.bounds().unwrap().into(),
|
||||||
|
},
|
||||||
|
index_type: ir::types::I32,
|
||||||
|
}),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -539,23 +555,27 @@ impl<'env, 'module, 'isa> FuncEnvironment for FuncEnv<'env, 'module, 'isa> {
|
|||||||
|
|
||||||
let mem_index: MemoryIndex = Converter(clif_mem_index).into();
|
let mem_index: MemoryIndex = Converter(clif_mem_index).into();
|
||||||
|
|
||||||
let (name, mem_index) = match mem_index.local_or_import(self.env.module) {
|
let (namespace, mem_index, description) = match mem_index.local_or_import(self.env.module) {
|
||||||
LocalOrImport::Local(local_mem_index) => {
|
LocalOrImport::Local(local_mem_index) => (
|
||||||
(
|
call_names::LOCAL_NAMESPACE,
|
||||||
// local_static_memory_grow
|
local_mem_index.index(),
|
||||||
ir::ExternalName::user(1, 0),
|
self.env.module.memories[local_mem_index],
|
||||||
local_mem_index.index(),
|
),
|
||||||
)
|
LocalOrImport::Import(import_mem_index) => (
|
||||||
}
|
call_names::IMPORT_NAMESPACE,
|
||||||
LocalOrImport::Import(imported_mem_index) => {
|
import_mem_index.index(),
|
||||||
(
|
self.env.module.imported_memories[import_mem_index].1,
|
||||||
// imported_static_memory_grow
|
),
|
||||||
ir::ExternalName::user(1, 2),
|
|
||||||
imported_mem_index.index(),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let name_index = match description.memory_type() {
|
||||||
|
MemoryType::Dynamic => call_names::DYNAMIC_MEM_GROW,
|
||||||
|
MemoryType::Static => call_names::STATIC_MEM_GROW,
|
||||||
|
MemoryType::SharedStatic => call_names::SHARED_STATIC_MEM_GROW,
|
||||||
|
};
|
||||||
|
|
||||||
|
let name = ir::ExternalName::user(namespace, name_index);
|
||||||
|
|
||||||
let mem_grow_func = pos.func.import_function(ir::ExtFuncData {
|
let mem_grow_func = pos.func.import_function(ir::ExtFuncData {
|
||||||
name,
|
name,
|
||||||
signature,
|
signature,
|
||||||
@ -587,37 +607,6 @@ impl<'env, 'module, 'isa> FuncEnvironment for FuncEnv<'env, 'module, 'isa> {
|
|||||||
clif_mem_index: cranelift_wasm::MemoryIndex,
|
clif_mem_index: cranelift_wasm::MemoryIndex,
|
||||||
_heap: ir::Heap,
|
_heap: ir::Heap,
|
||||||
) -> cranelift_wasm::WasmResult<ir::Value> {
|
) -> cranelift_wasm::WasmResult<ir::Value> {
|
||||||
// let signature = pos.func.import_signature(ir::Signature {
|
|
||||||
// call_conv: self.target_config().default_call_conv,
|
|
||||||
// params: vec![
|
|
||||||
// ir::AbiParam::new(ir::types::I32),
|
|
||||||
// ir::AbiParam::special(self.pointer_type(), ir::ArgumentPurpose::VMContext),
|
|
||||||
// ],
|
|
||||||
// returns: vec![ir::AbiParam::new(ir::types::I32)],
|
|
||||||
// });
|
|
||||||
|
|
||||||
// let size_mem_func = pos.func.import_function(ir::ExtFuncData {
|
|
||||||
// // `ir::ExternalName` for static_grow_memory`
|
|
||||||
// name: ir::ExternalName::user(1, 1),
|
|
||||||
// signature,
|
|
||||||
// colocated: false,
|
|
||||||
// });
|
|
||||||
|
|
||||||
// // Create a memory index value.
|
|
||||||
// let memory_index = pos.ins().iconst(ir::types::I32, index.index() as i64);
|
|
||||||
|
|
||||||
// // Create a VMContext value.
|
|
||||||
// let vmctx = pos
|
|
||||||
// .func
|
|
||||||
// .special_param(ir::ArgumentPurpose::VMContext)
|
|
||||||
// .expect("missing vmctx parameter");
|
|
||||||
|
|
||||||
// // Insert call instructions for `grow_memory`.
|
|
||||||
// let call_inst = pos.ins().call(size_mem_func, &[memory_index, vmctx]);
|
|
||||||
|
|
||||||
// // Return value.
|
|
||||||
// Ok(*pos.func.dfg.inst_results(call_inst).first().unwrap())
|
|
||||||
|
|
||||||
let signature = pos.func.import_signature(ir::Signature {
|
let signature = pos.func.import_signature(ir::Signature {
|
||||||
call_conv: self.target_config().default_call_conv,
|
call_conv: self.target_config().default_call_conv,
|
||||||
params: vec![
|
params: vec![
|
||||||
@ -629,23 +618,27 @@ impl<'env, 'module, 'isa> FuncEnvironment for FuncEnv<'env, 'module, 'isa> {
|
|||||||
|
|
||||||
let mem_index: MemoryIndex = Converter(clif_mem_index).into();
|
let mem_index: MemoryIndex = Converter(clif_mem_index).into();
|
||||||
|
|
||||||
let (name, mem_index) = match mem_index.local_or_import(self.env.module) {
|
let (namespace, mem_index, description) = match mem_index.local_or_import(self.env.module) {
|
||||||
LocalOrImport::Local(local_mem_index) => {
|
LocalOrImport::Local(local_mem_index) => (
|
||||||
(
|
call_names::LOCAL_NAMESPACE,
|
||||||
// local_static_memory_size
|
local_mem_index.index(),
|
||||||
ir::ExternalName::user(1, 1),
|
self.env.module.memories[local_mem_index],
|
||||||
local_mem_index.index(),
|
),
|
||||||
)
|
LocalOrImport::Import(import_mem_index) => (
|
||||||
}
|
call_names::IMPORT_NAMESPACE,
|
||||||
LocalOrImport::Import(imported_mem_index) => {
|
import_mem_index.index(),
|
||||||
(
|
self.env.module.imported_memories[import_mem_index].1,
|
||||||
// imported_static_memory_size
|
),
|
||||||
ir::ExternalName::user(1, 3),
|
|
||||||
imported_mem_index.index(),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let name_index = match description.memory_type() {
|
||||||
|
MemoryType::Dynamic => call_names::DYNAMIC_MEM_SIZE,
|
||||||
|
MemoryType::Static => call_names::STATIC_MEM_SIZE,
|
||||||
|
MemoryType::SharedStatic => call_names::SHARED_STATIC_MEM_SIZE,
|
||||||
|
};
|
||||||
|
|
||||||
|
let name = ir::ExternalName::user(namespace, name_index);
|
||||||
|
|
||||||
let mem_grow_func = pos.func.import_function(ir::ExtFuncData {
|
let mem_grow_func = pos.func.import_function(ir::ExtFuncData {
|
||||||
name,
|
name,
|
||||||
signature,
|
signature,
|
||||||
|
@ -10,7 +10,7 @@ use wasmer_runtime_core::{
|
|||||||
structures::{Map, TypedIndex},
|
structures::{Map, TypedIndex},
|
||||||
types::{
|
types::{
|
||||||
ElementType, Global, GlobalDesc, GlobalIndex, Initializer, LocalFuncIndex, LocalOrImport,
|
ElementType, Global, GlobalDesc, GlobalIndex, Initializer, LocalFuncIndex, LocalOrImport,
|
||||||
Memory, SigIndex, Table, Value,
|
MemoryDesc, SigIndex, TableDesc, Value,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -160,7 +160,7 @@ impl<'module, 'isa, 'data> ModuleEnvironment<'data> for ModuleEnv<'module, 'isa>
|
|||||||
fn declare_table(&mut self, table: cranelift_wasm::Table) {
|
fn declare_table(&mut self, table: cranelift_wasm::Table) {
|
||||||
use cranelift_wasm::TableElementType;
|
use cranelift_wasm::TableElementType;
|
||||||
// Add table ir to the list of tables
|
// Add table ir to the list of tables
|
||||||
self.module.tables.push(Table {
|
self.module.tables.push(TableDesc {
|
||||||
ty: match table.ty {
|
ty: match table.ty {
|
||||||
TableElementType::Func => ElementType::Anyfunc,
|
TableElementType::Func => ElementType::Anyfunc,
|
||||||
_ => unimplemented!(),
|
_ => unimplemented!(),
|
||||||
@ -184,7 +184,7 @@ impl<'module, 'isa, 'data> ModuleEnvironment<'data> for ModuleEnv<'module, 'isa>
|
|||||||
name: name.to_string(),
|
name: name.to_string(),
|
||||||
};
|
};
|
||||||
|
|
||||||
let imported_table = Table {
|
let imported_table = TableDesc {
|
||||||
ty: match table.ty {
|
ty: match table.ty {
|
||||||
TableElementType::Func => ElementType::Anyfunc,
|
TableElementType::Func => ElementType::Anyfunc,
|
||||||
_ => unimplemented!(),
|
_ => unimplemented!(),
|
||||||
@ -235,7 +235,7 @@ impl<'module, 'isa, 'data> ModuleEnvironment<'data> for ModuleEnv<'module, 'isa>
|
|||||||
|
|
||||||
/// Declares a memory to the environment
|
/// Declares a memory to the environment
|
||||||
fn declare_memory(&mut self, memory: cranelift_wasm::Memory) {
|
fn declare_memory(&mut self, memory: cranelift_wasm::Memory) {
|
||||||
self.module.memories.push(Memory {
|
self.module.memories.push(MemoryDesc {
|
||||||
min: memory.minimum,
|
min: memory.minimum,
|
||||||
max: memory.maximum,
|
max: memory.maximum,
|
||||||
shared: memory.shared,
|
shared: memory.shared,
|
||||||
@ -254,7 +254,7 @@ impl<'module, 'isa, 'data> ModuleEnvironment<'data> for ModuleEnv<'module, 'isa>
|
|||||||
name: name.to_string(),
|
name: name.to_string(),
|
||||||
};
|
};
|
||||||
|
|
||||||
let memory = Memory {
|
let memory = MemoryDesc {
|
||||||
min: memory.minimum,
|
min: memory.minimum,
|
||||||
max: memory.maximum,
|
max: memory.maximum,
|
||||||
shared: memory.shared,
|
shared: memory.shared,
|
||||||
|
@ -8,6 +8,18 @@ use cranelift_codegen::ir::{self, ExternalName, LibCall, SourceLoc, TrapCode};
|
|||||||
use hashbrown::HashMap;
|
use hashbrown::HashMap;
|
||||||
use wasmer_runtime_core::{structures::TypedIndex, types::LocalFuncIndex};
|
use wasmer_runtime_core::{structures::TypedIndex, types::LocalFuncIndex};
|
||||||
|
|
||||||
|
pub mod call_names {
|
||||||
|
pub const LOCAL_NAMESPACE: u32 = 1;
|
||||||
|
pub const IMPORT_NAMESPACE: u32 = 2;
|
||||||
|
|
||||||
|
pub const STATIC_MEM_GROW: u32 = 0;
|
||||||
|
pub const STATIC_MEM_SIZE: u32 = 1;
|
||||||
|
pub const SHARED_STATIC_MEM_GROW: u32 = 2;
|
||||||
|
pub const SHARED_STATIC_MEM_SIZE: u32 = 3;
|
||||||
|
pub const DYNAMIC_MEM_GROW: u32 = 4;
|
||||||
|
pub const DYNAMIC_MEM_SIZE: u32 = 5;
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct Relocation {
|
pub struct Relocation {
|
||||||
/// The relocation code.
|
/// The relocation code.
|
||||||
@ -20,12 +32,22 @@ pub struct Relocation {
|
|||||||
pub target: RelocationType,
|
pub target: RelocationType,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Copy)]
|
||||||
|
pub enum VmCallKind {
|
||||||
|
StaticMemoryGrow,
|
||||||
|
StaticMemorySize,
|
||||||
|
|
||||||
|
SharedStaticMemoryGrow,
|
||||||
|
SharedStaticMemorySize,
|
||||||
|
|
||||||
|
DynamicMemoryGrow,
|
||||||
|
DynamicMemorySize,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy)]
|
#[derive(Debug, Clone, Copy)]
|
||||||
pub enum VmCall {
|
pub enum VmCall {
|
||||||
LocalStaticMemoryGrow,
|
Local(VmCallKind),
|
||||||
LocalStaticMemorySize,
|
Import(VmCallKind),
|
||||||
ImportedStaticMemoryGrow,
|
|
||||||
ImportedStaticMemorySize,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Specify the type of relocation
|
/// Specify the type of relocation
|
||||||
@ -72,15 +94,31 @@ impl binemit::RelocSink for RelocSink {
|
|||||||
target: RelocationType::Normal(LocalFuncIndex::new(index as usize)),
|
target: RelocationType::Normal(LocalFuncIndex::new(index as usize)),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
ExternalName::User {
|
ExternalName::User { namespace, index } => {
|
||||||
namespace: 1,
|
use self::call_names::*;
|
||||||
index,
|
let target = RelocationType::VmCall(match namespace {
|
||||||
} => {
|
LOCAL_NAMESPACE => VmCall::Local(match index {
|
||||||
let target = RelocationType::VmCall(match index {
|
STATIC_MEM_GROW => VmCallKind::StaticMemoryGrow,
|
||||||
0 => VmCall::LocalStaticMemoryGrow,
|
STATIC_MEM_SIZE => VmCallKind::StaticMemorySize,
|
||||||
1 => VmCall::LocalStaticMemorySize,
|
|
||||||
2 => VmCall::ImportedStaticMemoryGrow,
|
SHARED_STATIC_MEM_GROW => VmCallKind::SharedStaticMemoryGrow,
|
||||||
3 => VmCall::ImportedStaticMemorySize,
|
SHARED_STATIC_MEM_SIZE => VmCallKind::SharedStaticMemorySize,
|
||||||
|
|
||||||
|
DYNAMIC_MEM_GROW => VmCallKind::DynamicMemoryGrow,
|
||||||
|
DYNAMIC_MEM_SIZE => VmCallKind::DynamicMemorySize,
|
||||||
|
_ => unimplemented!(),
|
||||||
|
}),
|
||||||
|
IMPORT_NAMESPACE => VmCall::Import(match index {
|
||||||
|
STATIC_MEM_GROW => VmCallKind::StaticMemoryGrow,
|
||||||
|
STATIC_MEM_SIZE => VmCallKind::StaticMemorySize,
|
||||||
|
|
||||||
|
SHARED_STATIC_MEM_GROW => VmCallKind::SharedStaticMemoryGrow,
|
||||||
|
SHARED_STATIC_MEM_SIZE => VmCallKind::SharedStaticMemorySize,
|
||||||
|
|
||||||
|
DYNAMIC_MEM_GROW => VmCallKind::DynamicMemoryGrow,
|
||||||
|
DYNAMIC_MEM_SIZE => VmCallKind::DynamicMemorySize,
|
||||||
|
_ => unimplemented!(),
|
||||||
|
}),
|
||||||
_ => unimplemented!(),
|
_ => unimplemented!(),
|
||||||
});
|
});
|
||||||
self.func_relocs.push(Relocation {
|
self.func_relocs.push(Relocation {
|
||||||
@ -109,9 +147,6 @@ impl binemit::RelocSink for RelocSink {
|
|||||||
target: relocation_type,
|
target: relocation_type,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
_ => {
|
|
||||||
unimplemented!();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn reloc_jt(
|
fn reloc_jt(
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
use crate::call::HandlerData;
|
use crate::call::HandlerData;
|
||||||
use crate::libcalls;
|
use crate::libcalls;
|
||||||
use crate::relocation::{
|
use crate::relocation::{
|
||||||
LocalTrapSink, Reloc, RelocSink, Relocation, RelocationType, TrapSink, VmCall,
|
LocalTrapSink, Reloc, RelocSink, Relocation, RelocationType, TrapSink, VmCall, VmCallKind,
|
||||||
};
|
};
|
||||||
use byteorder::{ByteOrder, LittleEndian};
|
use byteorder::{ByteOrder, LittleEndian};
|
||||||
use cranelift_codegen::{ir, isa, Context};
|
use cranelift_codegen::{ir, isa, Context};
|
||||||
@ -133,14 +133,38 @@ impl FuncResolverBuilder {
|
|||||||
msg: format!("unexpected intrinsic: {}", name),
|
msg: format!("unexpected intrinsic: {}", name),
|
||||||
})?,
|
})?,
|
||||||
RelocationType::VmCall(vmcall) => match vmcall {
|
RelocationType::VmCall(vmcall) => match vmcall {
|
||||||
VmCall::LocalStaticMemoryGrow => vmcalls::local_static_memory_grow as _,
|
VmCall::Local(kind) => match kind {
|
||||||
VmCall::LocalStaticMemorySize => vmcalls::local_static_memory_size as _,
|
VmCallKind::StaticMemoryGrow => vmcalls::local_static_memory_grow as _,
|
||||||
VmCall::ImportedStaticMemoryGrow => {
|
VmCallKind::StaticMemorySize => vmcalls::local_static_memory_size as _,
|
||||||
vmcalls::imported_static_memory_grow as _
|
|
||||||
}
|
VmCallKind::SharedStaticMemoryGrow => unimplemented!(),
|
||||||
VmCall::ImportedStaticMemorySize => {
|
VmCallKind::SharedStaticMemorySize => unimplemented!(),
|
||||||
vmcalls::imported_static_memory_size as _
|
|
||||||
}
|
VmCallKind::DynamicMemoryGrow => {
|
||||||
|
vmcalls::local_dynamic_memory_grow as _
|
||||||
|
}
|
||||||
|
VmCallKind::DynamicMemorySize => {
|
||||||
|
vmcalls::local_dynamic_memory_size as _
|
||||||
|
}
|
||||||
|
},
|
||||||
|
VmCall::Import(kind) => match kind {
|
||||||
|
VmCallKind::StaticMemoryGrow => {
|
||||||
|
vmcalls::imported_static_memory_grow as _
|
||||||
|
}
|
||||||
|
VmCallKind::StaticMemorySize => {
|
||||||
|
vmcalls::imported_static_memory_size as _
|
||||||
|
}
|
||||||
|
|
||||||
|
VmCallKind::SharedStaticMemoryGrow => unimplemented!(),
|
||||||
|
VmCallKind::SharedStaticMemorySize => unimplemented!(),
|
||||||
|
|
||||||
|
VmCallKind::DynamicMemoryGrow => {
|
||||||
|
vmcalls::imported_dynamic_memory_grow as _
|
||||||
|
}
|
||||||
|
VmCallKind::DynamicMemorySize => {
|
||||||
|
vmcalls::imported_dynamic_memory_size as _
|
||||||
|
}
|
||||||
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -7,7 +7,7 @@ use std::mem;
|
|||||||
use wasmer_runtime_core::{
|
use wasmer_runtime_core::{
|
||||||
export::{Context, Export, FuncPointer, GlobalPointer},
|
export::{Context, Export, FuncPointer, GlobalPointer},
|
||||||
import::{ImportObject, Namespace},
|
import::{ImportObject, Namespace},
|
||||||
memory::LinearMemory,
|
memory::Memory,
|
||||||
types::{
|
types::{
|
||||||
FuncSig, GlobalDesc,
|
FuncSig, GlobalDesc,
|
||||||
Type::{self, *},
|
Type::{self, *},
|
||||||
@ -74,7 +74,7 @@ fn dynamictop_ptr(static_bump: u32) -> u32 {
|
|||||||
// pub jumps: Vec<UnsafeCell<[c_int; 27]>>,
|
// pub jumps: Vec<UnsafeCell<[c_int; 27]>>,
|
||||||
//}
|
//}
|
||||||
|
|
||||||
pub fn emscripten_set_up_memory(memory: &mut LinearMemory) {
|
pub fn emscripten_set_up_memory(memory: &mut Memory) {
|
||||||
let dynamictop_ptr = dynamictop_ptr(STATIC_BUMP) as usize;
|
let dynamictop_ptr = dynamictop_ptr(STATIC_BUMP) as usize;
|
||||||
let dynamictop_ptr_offset = dynamictop_ptr + mem::size_of::<u32>();
|
let dynamictop_ptr_offset = dynamictop_ptr + mem::size_of::<u32>();
|
||||||
|
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
// use crate::webassembly::LinearMemory;
|
// use crate::webassembly::Memory;
|
||||||
|
|
||||||
pub fn align_memory(ptr: u32) -> u32 {
|
pub fn align_memory(ptr: u32) -> u32 {
|
||||||
(ptr + 15) & !15
|
(ptr + 15) & !15
|
||||||
}
|
}
|
||||||
|
|
||||||
// pub fn static_alloc(size: u32, static_top: &mut u32, memory: &LinearMemory) -> u32 {
|
// pub fn static_alloc(size: u32, static_top: &mut u32, memory: &Memory) -> u32 {
|
||||||
// let old_static_top = *static_top;
|
// let old_static_top = *static_top;
|
||||||
// let total_memory = memory.maximum_size() * LinearMemory::PAGE_SIZE;
|
// let total_memory = memory.maximum_size() * Memory::PAGE_SIZE;
|
||||||
// // NOTE: The `4294967280` is a u32 conversion of -16 as gotten from emscripten.
|
// // NOTE: The `4294967280` is a u32 conversion of -16 as gotten from emscripten.
|
||||||
// *static_top = (*static_top + size + 15) & 4294967280;
|
// *static_top = (*static_top + size + 15) & 4294967280;
|
||||||
// assert!(
|
// assert!(
|
||||||
|
@ -13,6 +13,7 @@ hashbrown = "0.1"
|
|||||||
nix = "0.12.0"
|
nix = "0.12.0"
|
||||||
page_size = "0.4.1"
|
page_size = "0.4.1"
|
||||||
wasmparser = "0.23.0"
|
wasmparser = "0.23.0"
|
||||||
|
parking_lot = "0.6"
|
||||||
|
|
||||||
[target.'cfg(windows)'.dependencies]
|
[target.'cfg(windows)'.dependencies]
|
||||||
winapi = { version = "0.3", features = ["memoryapi"] }
|
winapi = { version = "0.3", features = ["memoryapi"] }
|
||||||
|
@ -36,6 +36,7 @@ extern "C" fn print_num(n: i32, _vmctx: &mut vm::Ctx) -> i32 {
|
|||||||
static IMPORT_MODULE: &str = r#"
|
static IMPORT_MODULE: &str = r#"
|
||||||
(module
|
(module
|
||||||
(type $t0 (func (param i32) (result i32)))
|
(type $t0 (func (param i32) (result i32)))
|
||||||
|
;; (import "env" "memory" (memory 0 1))
|
||||||
(import "env" "print_i32" (func $print_i32 (type $t0)))
|
(import "env" "print_i32" (func $print_i32 (type $t0)))
|
||||||
(func $print_num (export "print_num") (type $t0) (param $p0 i32) (result i32)
|
(func $print_num (export "print_num") (type $t0) (param $p0 i32) (result i32)
|
||||||
get_local $p0
|
get_local $p0
|
||||||
|
@ -2,7 +2,7 @@ use crate::{
|
|||||||
error::{LinkError, LinkResult},
|
error::{LinkError, LinkResult},
|
||||||
export::{Context, Export},
|
export::{Context, Export},
|
||||||
import::ImportObject,
|
import::ImportObject,
|
||||||
memory::LinearMemory,
|
memory::{Memory, WASM_PAGE_SIZE},
|
||||||
module::{ImportName, ModuleInner},
|
module::{ImportName, ModuleInner},
|
||||||
structures::{BoxedMap, Map, SliceMap, TypedIndex},
|
structures::{BoxedMap, Map, SliceMap, TypedIndex},
|
||||||
table::{TableBacking, TableElements},
|
table::{TableBacking, TableElements},
|
||||||
@ -17,23 +17,23 @@ use std::{mem, slice};
|
|||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct LocalBacking {
|
pub struct LocalBacking {
|
||||||
pub(crate) memories: BoxedMap<LocalMemoryIndex, LinearMemory>,
|
pub(crate) memories: BoxedMap<LocalMemoryIndex, Memory>,
|
||||||
pub(crate) tables: BoxedMap<LocalTableIndex, TableBacking>,
|
pub(crate) tables: BoxedMap<LocalTableIndex, TableBacking>,
|
||||||
|
|
||||||
pub(crate) vm_memories: BoxedMap<LocalMemoryIndex, vm::LocalMemory>,
|
pub(crate) vm_memories: BoxedMap<LocalMemoryIndex, *mut vm::LocalMemory>,
|
||||||
pub(crate) vm_tables: BoxedMap<LocalTableIndex, vm::LocalTable>,
|
pub(crate) vm_tables: BoxedMap<LocalTableIndex, vm::LocalTable>,
|
||||||
pub(crate) vm_globals: BoxedMap<LocalGlobalIndex, vm::LocalGlobal>,
|
pub(crate) vm_globals: BoxedMap<LocalGlobalIndex, vm::LocalGlobal>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl LocalBacking {
|
// impl LocalBacking {
|
||||||
pub fn memory(&mut self, local_memory_index: LocalMemoryIndex) -> &mut LinearMemory {
|
// pub fn memory(&mut self, local_memory_index: LocalMemoryIndex) -> &mut Memory {
|
||||||
&mut self.memories[local_memory_index]
|
// &mut self.memories[local_memory_index]
|
||||||
}
|
// }
|
||||||
|
|
||||||
pub fn table(&mut self, local_table_index: LocalTableIndex) -> &mut TableBacking {
|
// pub fn table(&mut self, local_table_index: LocalTableIndex) -> &mut TableBacking {
|
||||||
&mut self.tables[local_table_index]
|
// &mut self.tables[local_table_index]
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
impl LocalBacking {
|
impl LocalBacking {
|
||||||
pub(crate) fn new(module: &ModuleInner, imports: &ImportBacking, vmctx: *mut vm::Ctx) -> Self {
|
pub(crate) fn new(module: &ModuleInner, imports: &ImportBacking, vmctx: *mut vm::Ctx) -> Self {
|
||||||
@ -55,20 +55,20 @@ impl LocalBacking {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn generate_memories(module: &ModuleInner) -> BoxedMap<LocalMemoryIndex, LinearMemory> {
|
fn generate_memories(module: &ModuleInner) -> BoxedMap<LocalMemoryIndex, Memory> {
|
||||||
let mut memories = Map::with_capacity(module.memories.len());
|
let mut memories = Map::with_capacity(module.memories.len());
|
||||||
|
|
||||||
for (_, mem) in &module.memories {
|
for (_, &desc) in &module.memories {
|
||||||
// If we use emscripten, we set a fixed initial and maximum
|
// If we use emscripten, we set a fixed initial and maximum
|
||||||
// let memory = if options.abi == InstanceABI::Emscripten {
|
// let memory = if options.abi == InstanceABI::Emscripten {
|
||||||
// // We use MAX_PAGES, so at the end the result is:
|
// // We use MAX_PAGES, so at the end the result is:
|
||||||
// // (initial * LinearMemory::PAGE_SIZE) == LinearMemory::DEFAULT_HEAP_SIZE
|
// // (initial * Memory::PAGE_SIZE) == Memory::DEFAULT_HEAP_SIZE
|
||||||
// // However, it should be: (initial * LinearMemory::PAGE_SIZE) == 16777216
|
// // However, it should be: (initial * Memory::PAGE_SIZE) == 16777216
|
||||||
// LinearMemory::new(LinearMemory::MAX_PAGES, None)
|
// Memory::new(Memory::MAX_PAGES, None)
|
||||||
// } else {
|
// } else {
|
||||||
// LinearMemory::new(memory.minimum, memory.maximum.map(|m| m as u32))
|
// Memory::new(memory.minimum, memory.maximum.map(|m| m as u32))
|
||||||
// };
|
// };
|
||||||
let memory = LinearMemory::new(mem);
|
let memory = Memory::new(desc).expect("unable to create memory");
|
||||||
memories.push(memory);
|
memories.push(memory);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -78,8 +78,8 @@ impl LocalBacking {
|
|||||||
fn finalize_memories(
|
fn finalize_memories(
|
||||||
module: &ModuleInner,
|
module: &ModuleInner,
|
||||||
imports: &ImportBacking,
|
imports: &ImportBacking,
|
||||||
memories: &mut SliceMap<LocalMemoryIndex, LinearMemory>,
|
memories: &mut SliceMap<LocalMemoryIndex, Memory>,
|
||||||
) -> BoxedMap<LocalMemoryIndex, vm::LocalMemory> {
|
) -> BoxedMap<LocalMemoryIndex, *mut vm::LocalMemory> {
|
||||||
// For each init that has some data...
|
// For each init that has some data...
|
||||||
for init in module
|
for init in module
|
||||||
.data_initializers
|
.data_initializers
|
||||||
@ -91,7 +91,7 @@ impl LocalBacking {
|
|||||||
Initializer::Const(_) => panic!("a const initializer must be the i32 type"),
|
Initializer::Const(_) => panic!("a const initializer must be the i32 type"),
|
||||||
Initializer::GetGlobal(imported_global_index) => {
|
Initializer::GetGlobal(imported_global_index) => {
|
||||||
if module.imported_globals[imported_global_index].1.ty == Type::I32 {
|
if module.imported_globals[imported_global_index].1.ty == Type::I32 {
|
||||||
unsafe { (*imports.globals[imported_global_index].global).data as u32 }
|
unsafe { (*imports.vm_globals[imported_global_index].global).data as u32 }
|
||||||
} else {
|
} else {
|
||||||
panic!("unsupported global type for initialzer")
|
panic!("unsupported global type for initialzer")
|
||||||
}
|
}
|
||||||
@ -100,20 +100,23 @@ impl LocalBacking {
|
|||||||
|
|
||||||
match init.memory_index.local_or_import(module) {
|
match init.memory_index.local_or_import(module) {
|
||||||
LocalOrImport::Local(local_memory_index) => {
|
LocalOrImport::Local(local_memory_index) => {
|
||||||
let memory_desc = &module.memories[local_memory_index];
|
let memory_desc = module.memories[local_memory_index];
|
||||||
let data_top = init_base + init.data.len();
|
let data_top = init_base + init.data.len();
|
||||||
assert!((memory_desc.min * LinearMemory::PAGE_SIZE) as usize >= data_top);
|
assert!(memory_desc.min as usize * WASM_PAGE_SIZE >= data_top);
|
||||||
let mem: &mut LinearMemory = &mut memories[local_memory_index];
|
|
||||||
|
let mem: &mut Memory = &mut memories[local_memory_index];
|
||||||
|
let mem_init_view =
|
||||||
|
&mut mem.as_slice_mut()[init_base..init_base + init.data.len()];
|
||||||
|
|
||||||
let mem_init_view = &mut mem[init_base..init_base + init.data.len()];
|
|
||||||
mem_init_view.copy_from_slice(&init.data);
|
mem_init_view.copy_from_slice(&init.data);
|
||||||
}
|
}
|
||||||
LocalOrImport::Import(imported_memory_index) => {
|
LocalOrImport::Import(imported_memory_index) => {
|
||||||
let vm_imported_memory = imports.imported_memory(imported_memory_index);
|
// Write the initialization data to the memory that
|
||||||
|
// we think the imported memory is.
|
||||||
unsafe {
|
unsafe {
|
||||||
let local_memory = &(*vm_imported_memory.memory);
|
let local_memory = &*imports.vm_memories[imported_memory_index];
|
||||||
let memory_slice =
|
let memory_slice =
|
||||||
slice::from_raw_parts_mut(local_memory.base, local_memory.size);
|
slice::from_raw_parts_mut(local_memory.base, local_memory.bound);
|
||||||
|
|
||||||
let mem_init_view =
|
let mem_init_view =
|
||||||
&mut memory_slice[init_base..init_base + init.data.len()];
|
&mut memory_slice[init_base..init_base + init.data.len()];
|
||||||
@ -125,7 +128,7 @@ impl LocalBacking {
|
|||||||
|
|
||||||
memories
|
memories
|
||||||
.iter_mut()
|
.iter_mut()
|
||||||
.map(|(index, mem)| mem.into_vm_memory(index))
|
.map(|(_, mem)| mem.vm_local_memory())
|
||||||
.collect::<Map<_, _>>()
|
.collect::<Map<_, _>>()
|
||||||
.into_boxed_map()
|
.into_boxed_map()
|
||||||
}
|
}
|
||||||
@ -133,7 +136,7 @@ impl LocalBacking {
|
|||||||
fn generate_tables(module: &ModuleInner) -> BoxedMap<LocalTableIndex, TableBacking> {
|
fn generate_tables(module: &ModuleInner) -> BoxedMap<LocalTableIndex, TableBacking> {
|
||||||
let mut tables = Map::with_capacity(module.tables.len());
|
let mut tables = Map::with_capacity(module.tables.len());
|
||||||
|
|
||||||
for (_, table) in &module.tables {
|
for (_, &table) in &module.tables {
|
||||||
let table_backing = TableBacking::new(table);
|
let table_backing = TableBacking::new(table);
|
||||||
tables.push(table_backing);
|
tables.push(table_backing);
|
||||||
}
|
}
|
||||||
@ -154,7 +157,7 @@ impl LocalBacking {
|
|||||||
Initializer::Const(_) => panic!("a const initializer must be the i32 type"),
|
Initializer::Const(_) => panic!("a const initializer must be the i32 type"),
|
||||||
Initializer::GetGlobal(imported_global_index) => {
|
Initializer::GetGlobal(imported_global_index) => {
|
||||||
if module.imported_globals[imported_global_index].1.ty == Type::I32 {
|
if module.imported_globals[imported_global_index].1.ty == Type::I32 {
|
||||||
unsafe { (*imports.globals[imported_global_index].global).data as u32 }
|
unsafe { (*imports.vm_globals[imported_global_index].global).data as u32 }
|
||||||
} else {
|
} else {
|
||||||
panic!("unsupported global type for initialzer")
|
panic!("unsupported global type for initialzer")
|
||||||
}
|
}
|
||||||
@ -186,7 +189,7 @@ impl LocalBacking {
|
|||||||
vmctx,
|
vmctx,
|
||||||
},
|
},
|
||||||
LocalOrImport::Import(imported_func_index) => {
|
LocalOrImport::Import(imported_func_index) => {
|
||||||
imports.functions[imported_func_index].clone()
|
imports.vm_functions[imported_func_index].clone()
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -199,7 +202,7 @@ impl LocalBacking {
|
|||||||
let (_, table_description) = module.imported_tables[imported_table_index];
|
let (_, table_description) = module.imported_tables[imported_table_index];
|
||||||
match table_description.ty {
|
match table_description.ty {
|
||||||
ElementType::Anyfunc => {
|
ElementType::Anyfunc => {
|
||||||
let imported_table = &imports.tables[imported_table_index];
|
let imported_table = &imports.vm_tables[imported_table_index];
|
||||||
let imported_local_table = (*imported_table).table;
|
let imported_local_table = (*imported_table).table;
|
||||||
|
|
||||||
let mut elements = unsafe {
|
let mut elements = unsafe {
|
||||||
@ -237,7 +240,7 @@ impl LocalBacking {
|
|||||||
vmctx,
|
vmctx,
|
||||||
},
|
},
|
||||||
LocalOrImport::Import(imported_func_index) => {
|
LocalOrImport::Import(imported_func_index) => {
|
||||||
imports.functions[imported_func_index].clone()
|
imports.vm_functions[imported_func_index].clone()
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -283,7 +286,7 @@ impl LocalBacking {
|
|||||||
Value::F64(x) => x.to_bits(),
|
Value::F64(x) => x.to_bits(),
|
||||||
},
|
},
|
||||||
Initializer::GetGlobal(imported_global_index) => unsafe {
|
Initializer::GetGlobal(imported_global_index) => unsafe {
|
||||||
(*imports.globals[imported_global_index].global).data
|
(*imports.vm_globals[imported_global_index].global).data
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -294,10 +297,12 @@ impl LocalBacking {
|
|||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct ImportBacking {
|
pub struct ImportBacking {
|
||||||
pub(crate) functions: BoxedMap<ImportedFuncIndex, vm::ImportedFunc>,
|
pub(crate) memories: BoxedMap<ImportedMemoryIndex, Memory>,
|
||||||
pub(crate) memories: BoxedMap<ImportedMemoryIndex, vm::ImportedMemory>,
|
|
||||||
pub(crate) tables: BoxedMap<ImportedTableIndex, vm::ImportedTable>,
|
pub(crate) vm_functions: BoxedMap<ImportedFuncIndex, vm::ImportedFunc>,
|
||||||
pub(crate) globals: BoxedMap<ImportedGlobalIndex, vm::ImportedGlobal>,
|
pub(crate) vm_memories: BoxedMap<ImportedMemoryIndex, *mut vm::LocalMemory>,
|
||||||
|
pub(crate) vm_tables: BoxedMap<ImportedTableIndex, vm::ImportedTable>,
|
||||||
|
pub(crate) vm_globals: BoxedMap<ImportedGlobalIndex, vm::ImportedGlobal>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ImportBacking {
|
impl ImportBacking {
|
||||||
@ -309,25 +314,25 @@ impl ImportBacking {
|
|||||||
let mut failed = false;
|
let mut failed = false;
|
||||||
let mut link_errors = vec![];
|
let mut link_errors = vec![];
|
||||||
|
|
||||||
let functions = import_functions(module, imports, vmctx).unwrap_or_else(|le| {
|
let vm_functions = import_functions(module, imports, vmctx).unwrap_or_else(|le| {
|
||||||
failed = true;
|
failed = true;
|
||||||
link_errors.extend(le);
|
link_errors.extend(le);
|
||||||
Map::new().into_boxed_map()
|
Map::new().into_boxed_map()
|
||||||
});
|
});
|
||||||
|
|
||||||
let memories = import_memories(module, imports, vmctx).unwrap_or_else(|le| {
|
let (vm_memories, memories) = import_memories(module, imports).unwrap_or_else(|le| {
|
||||||
|
failed = true;
|
||||||
|
link_errors.extend(le);
|
||||||
|
(Map::new().into_boxed_map(), Map::new().into_boxed_map())
|
||||||
|
});
|
||||||
|
|
||||||
|
let vm_tables = import_tables(module, imports, vmctx).unwrap_or_else(|le| {
|
||||||
failed = true;
|
failed = true;
|
||||||
link_errors.extend(le);
|
link_errors.extend(le);
|
||||||
Map::new().into_boxed_map()
|
Map::new().into_boxed_map()
|
||||||
});
|
});
|
||||||
|
|
||||||
let tables = import_tables(module, imports, vmctx).unwrap_or_else(|le| {
|
let vm_globals = import_globals(module, imports).unwrap_or_else(|le| {
|
||||||
failed = true;
|
|
||||||
link_errors.extend(le);
|
|
||||||
Map::new().into_boxed_map()
|
|
||||||
});
|
|
||||||
|
|
||||||
let globals = import_globals(module, imports).unwrap_or_else(|le| {
|
|
||||||
failed = true;
|
failed = true;
|
||||||
link_errors.extend(le);
|
link_errors.extend(le);
|
||||||
Map::new().into_boxed_map()
|
Map::new().into_boxed_map()
|
||||||
@ -337,20 +342,18 @@ impl ImportBacking {
|
|||||||
Err(link_errors)
|
Err(link_errors)
|
||||||
} else {
|
} else {
|
||||||
Ok(ImportBacking {
|
Ok(ImportBacking {
|
||||||
functions,
|
|
||||||
memories,
|
memories,
|
||||||
tables,
|
|
||||||
globals,
|
vm_functions,
|
||||||
|
vm_memories,
|
||||||
|
vm_tables,
|
||||||
|
vm_globals,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn imported_func(&self, func_index: ImportedFuncIndex) -> vm::ImportedFunc {
|
pub fn imported_func(&self, index: ImportedFuncIndex) -> vm::ImportedFunc {
|
||||||
self.functions[func_index].clone()
|
self.vm_functions[index].clone()
|
||||||
}
|
|
||||||
|
|
||||||
pub fn imported_memory(&self, memory_index: ImportedMemoryIndex) -> vm::ImportedMemory {
|
|
||||||
self.memories[memory_index].clone()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -424,36 +427,30 @@ fn import_functions(
|
|||||||
fn import_memories(
|
fn import_memories(
|
||||||
module: &ModuleInner,
|
module: &ModuleInner,
|
||||||
imports: &mut ImportObject,
|
imports: &mut ImportObject,
|
||||||
vmctx: *mut vm::Ctx,
|
) -> LinkResult<(
|
||||||
) -> LinkResult<BoxedMap<ImportedMemoryIndex, vm::ImportedMemory>> {
|
BoxedMap<ImportedMemoryIndex, *mut vm::LocalMemory>,
|
||||||
|
BoxedMap<ImportedMemoryIndex, Memory>,
|
||||||
|
)> {
|
||||||
let mut link_errors = vec![];
|
let mut link_errors = vec![];
|
||||||
let mut memories = Map::with_capacity(module.imported_memories.len());
|
let mut memories = Map::with_capacity(module.imported_memories.len());
|
||||||
|
let mut vm_memories = Map::with_capacity(module.imported_memories.len());
|
||||||
for (_index, (ImportName { namespace, name }, expected_memory_desc)) in
|
for (_index, (ImportName { namespace, name }, expected_memory_desc)) in
|
||||||
&module.imported_memories
|
&module.imported_memories
|
||||||
{
|
{
|
||||||
let memory_import = imports
|
let memory_import = imports
|
||||||
.get_namespace(namespace)
|
.get_namespace(&namespace)
|
||||||
.and_then(|namespace| namespace.get_export(name));
|
.and_then(|namespace| namespace.get_export(&name));
|
||||||
match memory_import {
|
match memory_import {
|
||||||
Some(Export::Memory {
|
Some(Export::Memory(mut memory)) => {
|
||||||
local,
|
if expected_memory_desc.fits_in_imported(memory.description()) {
|
||||||
ctx,
|
memories.push(memory.clone());
|
||||||
memory: memory_desc,
|
vm_memories.push(memory.vm_local_memory());
|
||||||
}) => {
|
|
||||||
if expected_memory_desc.fits_in_imported(&memory_desc) {
|
|
||||||
memories.push(vm::ImportedMemory {
|
|
||||||
memory: local.inner(),
|
|
||||||
vmctx: match ctx {
|
|
||||||
Context::External(ctx) => ctx,
|
|
||||||
Context::Internal => vmctx,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
} else {
|
} else {
|
||||||
link_errors.push(LinkError::IncorrectMemoryDescription {
|
link_errors.push(LinkError::IncorrectMemoryDescription {
|
||||||
namespace: namespace.clone(),
|
namespace: namespace.clone(),
|
||||||
name: name.clone(),
|
name: name.clone(),
|
||||||
expected: expected_memory_desc.clone(),
|
expected: *expected_memory_desc,
|
||||||
found: memory_desc.clone(),
|
found: memory.description(),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -484,7 +481,7 @@ fn import_memories(
|
|||||||
if link_errors.len() > 0 {
|
if link_errors.len() > 0 {
|
||||||
Err(link_errors)
|
Err(link_errors)
|
||||||
} else {
|
} else {
|
||||||
Ok(memories.into_boxed_map())
|
Ok((vm_memories.into_boxed_map(), memories.into_boxed_map()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -497,13 +494,13 @@ fn import_tables(
|
|||||||
let mut tables = Map::with_capacity(module.imported_tables.len());
|
let mut tables = Map::with_capacity(module.imported_tables.len());
|
||||||
for (_index, (ImportName { namespace, name }, expected_table_desc)) in &module.imported_tables {
|
for (_index, (ImportName { namespace, name }, expected_table_desc)) in &module.imported_tables {
|
||||||
let table_import = imports
|
let table_import = imports
|
||||||
.get_namespace(namespace)
|
.get_namespace(&namespace)
|
||||||
.and_then(|namespace| namespace.get_export(name));
|
.and_then(|namespace| namespace.get_export(&name));
|
||||||
match table_import {
|
match table_import {
|
||||||
Some(Export::Table {
|
Some(Export::Table {
|
||||||
local,
|
local,
|
||||||
ctx,
|
ctx,
|
||||||
table: table_desc,
|
desc: table_desc,
|
||||||
}) => {
|
}) => {
|
||||||
if expected_table_desc.fits_in_imported(&table_desc) {
|
if expected_table_desc.fits_in_imported(&table_desc) {
|
||||||
tables.push(vm::ImportedTable {
|
tables.push(vm::ImportedTable {
|
||||||
@ -564,8 +561,8 @@ fn import_globals(
|
|||||||
.get_namespace(namespace)
|
.get_namespace(namespace)
|
||||||
.and_then(|namespace| namespace.get_export(name));
|
.and_then(|namespace| namespace.get_export(name));
|
||||||
match import {
|
match import {
|
||||||
Some(Export::Global { local, global }) => {
|
Some(Export::Global { local, desc }) => {
|
||||||
if global == *imported_global_desc {
|
if desc == *imported_global_desc {
|
||||||
globals.push(vm::ImportedGlobal {
|
globals.push(vm::ImportedGlobal {
|
||||||
global: local.inner(),
|
global: local.inner(),
|
||||||
});
|
});
|
||||||
@ -574,7 +571,7 @@ fn import_globals(
|
|||||||
namespace: namespace.clone(),
|
namespace: namespace.clone(),
|
||||||
name: name.clone(),
|
name: name.clone(),
|
||||||
expected: imported_global_desc.clone(),
|
expected: imported_global_desc.clone(),
|
||||||
found: global.clone(),
|
found: desc.clone(),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
use crate::types::{FuncSig, GlobalDesc, Memory, MemoryIndex, Table, TableIndex, Type};
|
use crate::types::{FuncSig, GlobalDesc, MemoryDesc, MemoryIndex, TableDesc, TableIndex, Type};
|
||||||
|
|
||||||
pub type Result<T> = std::result::Result<T, Box<Error>>;
|
pub type Result<T> = std::result::Result<T, Box<Error>>;
|
||||||
pub type CompileResult<T> = std::result::Result<T, Box<CompileError>>;
|
pub type CompileResult<T> = std::result::Result<T, Box<CompileError>>;
|
||||||
@ -49,14 +49,14 @@ pub enum LinkError {
|
|||||||
IncorrectMemoryDescription {
|
IncorrectMemoryDescription {
|
||||||
namespace: String,
|
namespace: String,
|
||||||
name: String,
|
name: String,
|
||||||
expected: Memory,
|
expected: MemoryDesc,
|
||||||
found: Memory,
|
found: MemoryDesc,
|
||||||
},
|
},
|
||||||
IncorrectTableDescription {
|
IncorrectTableDescription {
|
||||||
namespace: String,
|
namespace: String,
|
||||||
name: String,
|
name: String,
|
||||||
expected: Table,
|
expected: TableDesc,
|
||||||
found: Table,
|
found: TableDesc,
|
||||||
},
|
},
|
||||||
IncorrectGlobalDescription {
|
IncorrectGlobalDescription {
|
||||||
namespace: String,
|
namespace: String,
|
||||||
|
@ -1,8 +1,9 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
instance::InstanceInner,
|
instance::InstanceInner,
|
||||||
|
memory::Memory,
|
||||||
module::ExportIndex,
|
module::ExportIndex,
|
||||||
module::ModuleInner,
|
module::ModuleInner,
|
||||||
types::{FuncSig, GlobalDesc, Memory, Table},
|
types::{FuncSig, GlobalDesc, TableDesc},
|
||||||
vm,
|
vm,
|
||||||
};
|
};
|
||||||
use hashbrown::hash_map;
|
use hashbrown::hash_map;
|
||||||
@ -20,19 +21,15 @@ pub enum Export {
|
|||||||
ctx: Context,
|
ctx: Context,
|
||||||
signature: FuncSig,
|
signature: FuncSig,
|
||||||
},
|
},
|
||||||
Memory {
|
Memory(Memory),
|
||||||
local: MemoryPointer,
|
|
||||||
ctx: Context,
|
|
||||||
memory: Memory,
|
|
||||||
},
|
|
||||||
Table {
|
Table {
|
||||||
local: TablePointer,
|
local: TablePointer,
|
||||||
ctx: Context,
|
ctx: Context,
|
||||||
table: Table,
|
desc: TableDesc,
|
||||||
},
|
},
|
||||||
Global {
|
Global {
|
||||||
local: GlobalPointer,
|
local: GlobalPointer,
|
||||||
global: GlobalDesc,
|
desc: GlobalDesc,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -52,22 +49,6 @@ impl FuncPointer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
|
||||||
pub struct MemoryPointer(*mut vm::LocalMemory);
|
|
||||||
|
|
||||||
impl MemoryPointer {
|
|
||||||
/// This needs to be unsafe because there is
|
|
||||||
/// no way to check whether the passed function
|
|
||||||
/// is valid and has the right signature.
|
|
||||||
pub unsafe fn new(f: *mut vm::LocalMemory) -> Self {
|
|
||||||
MemoryPointer(f)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) fn inner(&self) -> *mut vm::LocalMemory {
|
|
||||||
self.0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct TablePointer(*mut vm::LocalTable);
|
pub struct TablePointer(*mut vm::LocalTable);
|
||||||
|
|
||||||
|
@ -5,6 +5,16 @@ pub trait LikeNamespace {
|
|||||||
fn get_export(&mut self, name: &str) -> Option<Export>;
|
fn get_export(&mut self, name: &str) -> Option<Export>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub trait IsExport {
|
||||||
|
fn to_export(&mut self) -> Export;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl IsExport for Export {
|
||||||
|
fn to_export(&mut self) -> Export {
|
||||||
|
self.clone()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// All of the import data used when instantiating.
|
/// All of the import data used when instantiating.
|
||||||
///
|
///
|
||||||
/// It's suggested that you use the [`imports!`] macro
|
/// It's suggested that you use the [`imports!`] macro
|
||||||
@ -74,7 +84,7 @@ impl ImportObject {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub struct Namespace {
|
pub struct Namespace {
|
||||||
map: HashMap<String, Export>,
|
map: HashMap<String, Box<dyn IsExport>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Namespace {
|
impl Namespace {
|
||||||
@ -84,13 +94,19 @@ impl Namespace {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn insert(&mut self, name: impl Into<String>, export: Export) -> Option<Export> {
|
pub fn insert<S, E>(&mut self, name: S, export: E) -> Option<Box<dyn IsExport>>
|
||||||
self.map.insert(name.into(), export)
|
where
|
||||||
|
S: Into<String>,
|
||||||
|
E: IsExport + 'static,
|
||||||
|
{
|
||||||
|
self.map.insert(name.into(), Box::new(export))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl LikeNamespace for Namespace {
|
impl LikeNamespace for Namespace {
|
||||||
fn get_export(&mut self, name: &str) -> Option<Export> {
|
fn get_export(&mut self, name: &str) -> Option<Export> {
|
||||||
self.map.get(name).cloned()
|
self.map
|
||||||
|
.get_mut(name)
|
||||||
|
.map(|is_export| is_export.to_export())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,13 +2,12 @@ use crate::{
|
|||||||
backend::Token,
|
backend::Token,
|
||||||
backing::{ImportBacking, LocalBacking},
|
backing::{ImportBacking, LocalBacking},
|
||||||
error::{CallError, CallResult, ResolveError, ResolveResult, Result},
|
error::{CallError, CallResult, ResolveError, ResolveResult, Result},
|
||||||
export::{
|
export::{Context, Export, ExportIter, FuncPointer, GlobalPointer, TablePointer},
|
||||||
Context, Export, ExportIter, FuncPointer, GlobalPointer, MemoryPointer, TablePointer,
|
|
||||||
},
|
|
||||||
import::{ImportObject, LikeNamespace},
|
import::{ImportObject, LikeNamespace},
|
||||||
|
memory::Memory,
|
||||||
module::{ExportIndex, Module, ModuleInner},
|
module::{ExportIndex, Module, ModuleInner},
|
||||||
types::{
|
types::{
|
||||||
FuncIndex, FuncSig, GlobalDesc, GlobalIndex, LocalOrImport, Memory, MemoryIndex, Table,
|
FuncIndex, FuncSig, GlobalDesc, GlobalIndex, LocalOrImport, MemoryIndex, TableDesc,
|
||||||
TableIndex, Value,
|
TableIndex, Value,
|
||||||
},
|
},
|
||||||
vm,
|
vm,
|
||||||
@ -206,7 +205,7 @@ impl Instance {
|
|||||||
let vmctx = match func_index.local_or_import(&self.module) {
|
let vmctx = match func_index.local_or_import(&self.module) {
|
||||||
LocalOrImport::Local(_) => &mut *self.inner.vmctx,
|
LocalOrImport::Local(_) => &mut *self.inner.vmctx,
|
||||||
LocalOrImport::Import(imported_func_index) => {
|
LocalOrImport::Import(imported_func_index) => {
|
||||||
self.inner.import_backing.functions[imported_func_index].vmctx
|
self.inner.import_backing.vm_functions[imported_func_index].vmctx
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -245,29 +244,22 @@ impl InstanceInner {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
ExportIndex::Memory(memory_index) => {
|
ExportIndex::Memory(memory_index) => {
|
||||||
let (local, ctx, memory) = self.get_memory_from_index(module, *memory_index);
|
let memory = self.get_memory_from_index(module, *memory_index);
|
||||||
Export::Memory {
|
Export::Memory(memory)
|
||||||
local,
|
|
||||||
ctx: match ctx {
|
|
||||||
Context::Internal => Context::External(&mut *self.vmctx),
|
|
||||||
ctx @ Context::External(_) => ctx,
|
|
||||||
},
|
|
||||||
memory,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
ExportIndex::Global(global_index) => {
|
ExportIndex::Global(global_index) => {
|
||||||
let (local, global) = self.get_global_from_index(module, *global_index);
|
let (local, desc) = self.get_global_from_index(module, *global_index);
|
||||||
Export::Global { local, global }
|
Export::Global { local, desc }
|
||||||
}
|
}
|
||||||
ExportIndex::Table(table_index) => {
|
ExportIndex::Table(table_index) => {
|
||||||
let (local, ctx, table) = self.get_table_from_index(module, *table_index);
|
let (local, ctx, desc) = self.get_table_from_index(module, *table_index);
|
||||||
Export::Table {
|
Export::Table {
|
||||||
local,
|
local,
|
||||||
ctx: match ctx {
|
ctx: match ctx {
|
||||||
Context::Internal => Context::External(&mut *self.vmctx),
|
Context::Internal => Context::External(&mut *self.vmctx),
|
||||||
ctx @ Context::External(_) => ctx,
|
ctx @ Context::External(_) => ctx,
|
||||||
},
|
},
|
||||||
table,
|
desc,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -294,7 +286,7 @@ impl InstanceInner {
|
|||||||
Context::Internal,
|
Context::Internal,
|
||||||
),
|
),
|
||||||
LocalOrImport::Import(imported_func_index) => {
|
LocalOrImport::Import(imported_func_index) => {
|
||||||
let imported_func = &self.import_backing.functions[imported_func_index];
|
let imported_func = &self.import_backing.vm_functions[imported_func_index];
|
||||||
(
|
(
|
||||||
imported_func.func as *const _,
|
imported_func.func as *const _,
|
||||||
Context::External(imported_func.vmctx),
|
Context::External(imported_func.vmctx),
|
||||||
@ -307,35 +299,11 @@ impl InstanceInner {
|
|||||||
(unsafe { FuncPointer::new(func_ptr) }, ctx, signature)
|
(unsafe { FuncPointer::new(func_ptr) }, ctx, signature)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_memory_from_index(
|
fn get_memory_from_index(&mut self, module: &ModuleInner, mem_index: MemoryIndex) -> Memory {
|
||||||
&mut self,
|
|
||||||
module: &ModuleInner,
|
|
||||||
mem_index: MemoryIndex,
|
|
||||||
) -> (MemoryPointer, Context, Memory) {
|
|
||||||
match mem_index.local_or_import(module) {
|
match mem_index.local_or_import(module) {
|
||||||
LocalOrImport::Local(local_mem_index) => {
|
LocalOrImport::Local(local_mem_index) => self.backing.memories[local_mem_index].clone(),
|
||||||
let vm_mem = &mut self.backing.vm_memories[local_mem_index];
|
|
||||||
(
|
|
||||||
unsafe { MemoryPointer::new(vm_mem) },
|
|
||||||
Context::Internal,
|
|
||||||
*module
|
|
||||||
.memories
|
|
||||||
.get(local_mem_index)
|
|
||||||
.expect("broken invariant, memories"),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
LocalOrImport::Import(imported_mem_index) => {
|
LocalOrImport::Import(imported_mem_index) => {
|
||||||
let &(_, mem) = &module
|
self.import_backing.memories[imported_mem_index].clone()
|
||||||
.imported_memories
|
|
||||||
.get(imported_mem_index)
|
|
||||||
.expect("missing imported memory index");
|
|
||||||
let vm::ImportedMemory { memory, vmctx } =
|
|
||||||
&self.import_backing.memories[imported_mem_index];
|
|
||||||
(
|
|
||||||
unsafe { MemoryPointer::new(*memory) },
|
|
||||||
Context::External(*vmctx),
|
|
||||||
*mem,
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -363,7 +331,7 @@ impl InstanceInner {
|
|||||||
.get(imported_global_index)
|
.get(imported_global_index)
|
||||||
.expect("missing imported global index");
|
.expect("missing imported global index");
|
||||||
let vm::ImportedGlobal { global } =
|
let vm::ImportedGlobal { global } =
|
||||||
&self.import_backing.globals[imported_global_index];
|
&self.import_backing.vm_globals[imported_global_index];
|
||||||
(
|
(
|
||||||
unsafe { GlobalPointer::new(*global) },
|
unsafe { GlobalPointer::new(*global) },
|
||||||
*imported_global_desc,
|
*imported_global_desc,
|
||||||
@ -376,7 +344,7 @@ impl InstanceInner {
|
|||||||
&mut self,
|
&mut self,
|
||||||
module: &ModuleInner,
|
module: &ModuleInner,
|
||||||
table_index: TableIndex,
|
table_index: TableIndex,
|
||||||
) -> (TablePointer, Context, Table) {
|
) -> (TablePointer, Context, TableDesc) {
|
||||||
match table_index.local_or_import(module) {
|
match table_index.local_or_import(module) {
|
||||||
LocalOrImport::Local(local_table_index) => {
|
LocalOrImport::Local(local_table_index) => {
|
||||||
let vm_table = &mut self.backing.vm_tables[local_table_index];
|
let vm_table = &mut self.backing.vm_tables[local_table_index];
|
||||||
@ -390,16 +358,16 @@ impl InstanceInner {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
LocalOrImport::Import(imported_table_index) => {
|
LocalOrImport::Import(imported_table_index) => {
|
||||||
let &(_, tab) = &module
|
let &(_, desc) = &module
|
||||||
.imported_tables
|
.imported_tables
|
||||||
.get(imported_table_index)
|
.get(imported_table_index)
|
||||||
.expect("missing imported table index");
|
.expect("missing imported table index");
|
||||||
let vm::ImportedTable { table, vmctx } =
|
let vm::ImportedTable { table, vmctx } =
|
||||||
&self.import_backing.tables[imported_table_index];
|
&self.import_backing.vm_tables[imported_table_index];
|
||||||
(
|
(
|
||||||
unsafe { TablePointer::new(*table) },
|
unsafe { TablePointer::new(*table) },
|
||||||
Context::External(*vmctx),
|
Context::External(*vmctx),
|
||||||
*tab,
|
*desc,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -456,7 +424,7 @@ impl<'a> Function<'a> {
|
|||||||
let vmctx = match self.func_index.local_or_import(self.module) {
|
let vmctx = match self.func_index.local_or_import(self.module) {
|
||||||
LocalOrImport::Local(_) => &mut *self.instance_inner.vmctx,
|
LocalOrImport::Local(_) => &mut *self.instance_inner.vmctx,
|
||||||
LocalOrImport::Import(imported_func_index) => {
|
LocalOrImport::Import(imported_func_index) => {
|
||||||
self.instance_inner.import_backing.functions[imported_func_index].vmctx
|
self.instance_inner.import_backing.vm_functions[imported_func_index].vmctx
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -487,7 +455,7 @@ impl<'a> Function<'a> {
|
|||||||
.unwrap()
|
.unwrap()
|
||||||
.as_ptr(),
|
.as_ptr(),
|
||||||
LocalOrImport::Import(import_func_index) => {
|
LocalOrImport::Import(import_func_index) => {
|
||||||
self.instance_inner.import_backing.functions[import_func_index].func
|
self.instance_inner.import_backing.vm_functions[import_func_index].func
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
#![allow(unused)]
|
||||||
|
|
||||||
macro_rules! debug {
|
macro_rules! debug {
|
||||||
($fmt:expr) => (if cfg!(any(debug_assertions, feature="debug")) { println!(concat!("wasmer-runtime(:{})::", $fmt), line!()) });
|
($fmt:expr) => (if cfg!(any(debug_assertions, feature="debug")) { println!(concat!("wasmer-runtime(:{})::", $fmt), line!()) });
|
||||||
($fmt:expr, $($arg:tt)*) => (if cfg!(any(debug_assertions, feature="debug")) { println!(concat!("wasmer-runtime(:{})::", $fmt, "\n"), line!(), $($arg)*) });
|
($fmt:expr, $($arg:tt)*) => (if cfg!(any(debug_assertions, feature="debug")) { println!(concat!("wasmer-runtime(:{})::", $fmt, "\n"), line!(), $($arg)*) });
|
||||||
|
@ -1,224 +0,0 @@
|
|||||||
use std::ops::{Deref, DerefMut};
|
|
||||||
|
|
||||||
use crate::{
|
|
||||||
sys,
|
|
||||||
types::{LocalMemoryIndex, Memory},
|
|
||||||
vm,
|
|
||||||
};
|
|
||||||
|
|
||||||
/// A linear memory instance.
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub struct LinearMemory {
|
|
||||||
/// The actual memory allocation.
|
|
||||||
memory: sys::Memory,
|
|
||||||
|
|
||||||
/// The current number of wasm pages.
|
|
||||||
current: u32,
|
|
||||||
|
|
||||||
// The maximum size the WebAssembly Memory is allowed to grow
|
|
||||||
// to, in units of WebAssembly pages. When present, the maximum
|
|
||||||
// parameter acts as a hint to the engine to reserve memory up
|
|
||||||
// front. However, the engine may ignore or clamp this reservation
|
|
||||||
// request. In general, most WebAssembly modules shouldn't need
|
|
||||||
// to set a maximum.
|
|
||||||
max: Option<u32>,
|
|
||||||
|
|
||||||
// The size of the extra guard pages after the end.
|
|
||||||
// Is used to optimize loads and stores with constant offsets.
|
|
||||||
offset_guard_size: usize,
|
|
||||||
|
|
||||||
/// Requires exception catching to handle out-of-bounds accesses.
|
|
||||||
requires_signal_catch: bool,
|
|
||||||
}
|
|
||||||
|
|
||||||
/// It holds the raw bytes of memory accessed by a WebAssembly Instance
|
|
||||||
impl LinearMemory {
|
|
||||||
pub(crate) const PAGE_SIZE: u32 = 65_536;
|
|
||||||
pub(crate) const MAX_PAGES: u32 = 65_536;
|
|
||||||
#[doc(hidden)]
|
|
||||||
pub const DEFAULT_HEAP_SIZE: usize = 1 << 32; // 4 GiB
|
|
||||||
#[doc(hidden)]
|
|
||||||
pub const DEFAULT_GUARD_SIZE: usize = 1 << 31; // 2 GiB
|
|
||||||
pub(crate) const DEFAULT_SIZE: usize = Self::DEFAULT_HEAP_SIZE + Self::DEFAULT_GUARD_SIZE; // 6 GiB
|
|
||||||
|
|
||||||
/// Create a new linear memory instance with specified initial and maximum number of pages.
|
|
||||||
///
|
|
||||||
/// `maximum` cannot be set to more than `65536` pages.
|
|
||||||
pub(crate) fn new(mem: &Memory) -> Self {
|
|
||||||
assert!(mem.min <= Self::MAX_PAGES);
|
|
||||||
assert!(mem.max.is_none() || mem.max.unwrap() <= Self::MAX_PAGES);
|
|
||||||
|
|
||||||
let (mmap_size, initial_pages, offset_guard_size, requires_signal_catch) = if
|
|
||||||
/*mem.is_static_heap()*/
|
|
||||||
true {
|
|
||||||
(Self::DEFAULT_SIZE, mem.min, Self::DEFAULT_GUARD_SIZE, true)
|
|
||||||
// This is a static heap
|
|
||||||
} else {
|
|
||||||
// this is a dynamic heap
|
|
||||||
assert!(!mem.shared, "shared memories must have a maximum size.");
|
|
||||||
|
|
||||||
(
|
|
||||||
mem.min as usize * Self::PAGE_SIZE as usize,
|
|
||||||
mem.min,
|
|
||||||
0,
|
|
||||||
false,
|
|
||||||
)
|
|
||||||
};
|
|
||||||
|
|
||||||
let mut memory = sys::Memory::with_size(mmap_size).unwrap();
|
|
||||||
|
|
||||||
// map initial pages as readwrite since the inital mmap is mapped as not accessible.
|
|
||||||
if initial_pages != 0 {
|
|
||||||
unsafe {
|
|
||||||
memory
|
|
||||||
.protect(
|
|
||||||
0..(initial_pages as usize * Self::PAGE_SIZE as usize),
|
|
||||||
sys::Protect::ReadWrite,
|
|
||||||
)
|
|
||||||
.expect("unable to make memory accessible");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Self {
|
|
||||||
memory,
|
|
||||||
current: initial_pages,
|
|
||||||
max: mem.max,
|
|
||||||
offset_guard_size,
|
|
||||||
requires_signal_catch,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns an base address of this linear memory.
|
|
||||||
fn base(&mut self) -> *mut u8 {
|
|
||||||
self.memory.as_ptr()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns the size in bytes
|
|
||||||
pub(crate) fn size(&self) -> usize {
|
|
||||||
self.current as usize * Self::PAGE_SIZE as usize
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn pages(&self) -> u32 {
|
|
||||||
self.current
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns the maximum number of wasm pages allowed.
|
|
||||||
pub fn max(&self) -> u32 {
|
|
||||||
self.max.unwrap_or(Self::MAX_PAGES)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) fn into_vm_memory(&mut self, index: LocalMemoryIndex) -> vm::LocalMemory {
|
|
||||||
vm::LocalMemory {
|
|
||||||
base: self.base(),
|
|
||||||
size: self.size(),
|
|
||||||
index,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Grow memory by the specified amount of pages.
|
|
||||||
///
|
|
||||||
/// Returns `None` if memory can't be grown by the specified amount
|
|
||||||
/// of pages.
|
|
||||||
pub(crate) fn grow_dynamic(&mut self, add_pages: u32) -> Option<i32> {
|
|
||||||
debug!("grow_memory_dynamic called!");
|
|
||||||
assert!(self.max.is_none());
|
|
||||||
if add_pages == 0 {
|
|
||||||
return Some(self.current as _);
|
|
||||||
}
|
|
||||||
|
|
||||||
let prev_pages = self.current;
|
|
||||||
|
|
||||||
let new_pages = match self.current.checked_add(add_pages) {
|
|
||||||
Some(new_pages) => new_pages,
|
|
||||||
None => return None,
|
|
||||||
};
|
|
||||||
|
|
||||||
if let Some(val) = self.max {
|
|
||||||
if new_pages > val {
|
|
||||||
return None;
|
|
||||||
}
|
|
||||||
// Wasm linear memories are never allowed to grow beyond what is
|
|
||||||
// indexable. If the memory has no maximum, enforce the greatest
|
|
||||||
// limit here.
|
|
||||||
} else if new_pages >= Self::MAX_PAGES {
|
|
||||||
return None;
|
|
||||||
}
|
|
||||||
|
|
||||||
let new_bytes = (new_pages * Self::PAGE_SIZE) as usize;
|
|
||||||
|
|
||||||
if new_bytes > self.memory.size() - self.offset_guard_size {
|
|
||||||
let memory_size = new_bytes.checked_add(self.offset_guard_size)?;
|
|
||||||
let mut new_memory = sys::Memory::with_size(memory_size).ok()?;
|
|
||||||
|
|
||||||
unsafe {
|
|
||||||
new_memory
|
|
||||||
.protect(0..new_bytes, sys::Protect::ReadWrite)
|
|
||||||
.ok()?;
|
|
||||||
}
|
|
||||||
|
|
||||||
let copy_size = self.memory.size() - self.offset_guard_size;
|
|
||||||
unsafe {
|
|
||||||
new_memory.as_slice_mut()[..copy_size]
|
|
||||||
.copy_from_slice(&self.memory.as_slice()[..copy_size]);
|
|
||||||
}
|
|
||||||
|
|
||||||
self.memory = new_memory;
|
|
||||||
}
|
|
||||||
|
|
||||||
self.current = new_pages;
|
|
||||||
|
|
||||||
Some(prev_pages as i32)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) fn grow_static(&mut self, add_pages: u32) -> Option<i32> {
|
|
||||||
// debug!("grow_memory_static called!");
|
|
||||||
// assert!(self.max.is_some());
|
|
||||||
if add_pages == 0 {
|
|
||||||
return Some(self.current as _);
|
|
||||||
}
|
|
||||||
|
|
||||||
let prev_pages = self.current;
|
|
||||||
|
|
||||||
let new_pages = match self.current.checked_add(add_pages) {
|
|
||||||
Some(new_pages) => new_pages,
|
|
||||||
None => return None,
|
|
||||||
};
|
|
||||||
|
|
||||||
if let Some(val) = self.max {
|
|
||||||
if new_pages > val {
|
|
||||||
return None;
|
|
||||||
}
|
|
||||||
// Wasm linear memories are never allowed to grow beyond what is
|
|
||||||
// indexable. If the memory has no maximum, enforce the greatest
|
|
||||||
// limit here.
|
|
||||||
} else if new_pages >= Self::MAX_PAGES {
|
|
||||||
return None;
|
|
||||||
}
|
|
||||||
|
|
||||||
let prev_bytes = (prev_pages * Self::PAGE_SIZE) as usize;
|
|
||||||
let new_bytes = (new_pages * Self::PAGE_SIZE) as usize;
|
|
||||||
|
|
||||||
unsafe {
|
|
||||||
self.memory
|
|
||||||
.protect(prev_bytes..new_bytes, sys::Protect::ReadWrite)
|
|
||||||
.ok()?;
|
|
||||||
}
|
|
||||||
|
|
||||||
self.current = new_pages;
|
|
||||||
|
|
||||||
Some(prev_pages as i32)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Deref for LinearMemory {
|
|
||||||
type Target = [u8];
|
|
||||||
fn deref(&self) -> &[u8] {
|
|
||||||
unsafe { self.memory.as_slice() }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl DerefMut for LinearMemory {
|
|
||||||
fn deref_mut(&mut self) -> &mut [u8] {
|
|
||||||
unsafe { self.memory.as_slice_mut() }
|
|
||||||
}
|
|
||||||
}
|
|
105
lib/runtime-core/src/memory/dynamic.rs
Normal file
105
lib/runtime-core/src/memory/dynamic.rs
Normal file
@ -0,0 +1,105 @@
|
|||||||
|
use crate::{
|
||||||
|
memory::{WASM_MAX_PAGES, WASM_PAGE_SIZE},
|
||||||
|
sys,
|
||||||
|
types::MemoryDesc,
|
||||||
|
vm,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub const DYNAMIC_GUARD_SIZE: usize = 4096;
|
||||||
|
|
||||||
|
pub struct DynamicMemory {
|
||||||
|
memory: sys::Memory,
|
||||||
|
current: u32,
|
||||||
|
max: Option<u32>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl DynamicMemory {
|
||||||
|
pub(super) fn new(desc: MemoryDesc, local: &mut vm::LocalMemory) -> Option<Box<Self>> {
|
||||||
|
let memory = {
|
||||||
|
let mut memory =
|
||||||
|
sys::Memory::with_size((desc.min as usize * WASM_PAGE_SIZE) + DYNAMIC_GUARD_SIZE)
|
||||||
|
.ok()?;
|
||||||
|
if desc.min != 0 {
|
||||||
|
unsafe {
|
||||||
|
memory
|
||||||
|
.protect(
|
||||||
|
0..(desc.min as usize * WASM_PAGE_SIZE),
|
||||||
|
sys::Protect::ReadWrite,
|
||||||
|
)
|
||||||
|
.ok()?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
memory
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut storage = Box::new(DynamicMemory {
|
||||||
|
memory,
|
||||||
|
current: desc.min,
|
||||||
|
max: desc.max,
|
||||||
|
});
|
||||||
|
let storage_ptr: *mut DynamicMemory = &mut *storage;
|
||||||
|
|
||||||
|
local.base = storage.memory.as_ptr();
|
||||||
|
local.bound = desc.min as usize * WASM_PAGE_SIZE;
|
||||||
|
local.memory = storage_ptr as *mut ();
|
||||||
|
println!("local: {:?}", local);
|
||||||
|
|
||||||
|
Some(storage)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn current(&self) -> u32 {
|
||||||
|
self.current
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn grow(&mut self, delta: u32, local: &mut vm::LocalMemory) -> Option<u32> {
|
||||||
|
if delta == 0 {
|
||||||
|
return Some(self.current);
|
||||||
|
}
|
||||||
|
|
||||||
|
let new_pages = self.current.checked_add(delta)?;
|
||||||
|
|
||||||
|
if let Some(max) = self.max {
|
||||||
|
if new_pages > max {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if new_pages as usize > WASM_MAX_PAGES {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut new_memory =
|
||||||
|
sys::Memory::with_size((new_pages as usize * WASM_PAGE_SIZE) + DYNAMIC_GUARD_SIZE)
|
||||||
|
.ok()?;
|
||||||
|
|
||||||
|
unsafe {
|
||||||
|
new_memory
|
||||||
|
.protect(
|
||||||
|
0..(new_pages as usize * WASM_PAGE_SIZE),
|
||||||
|
sys::Protect::ReadWrite,
|
||||||
|
)
|
||||||
|
.ok()?;
|
||||||
|
|
||||||
|
new_memory.as_slice_mut()[..self.current as usize * WASM_PAGE_SIZE]
|
||||||
|
.copy_from_slice(&self.memory.as_slice()[..self.current as usize * WASM_PAGE_SIZE]);
|
||||||
|
}
|
||||||
|
|
||||||
|
self.memory = new_memory; //The old memory gets dropped.
|
||||||
|
|
||||||
|
local.base = self.memory.as_ptr();
|
||||||
|
local.bound = new_pages as usize * WASM_PAGE_SIZE;
|
||||||
|
|
||||||
|
let old_pages = self.current;
|
||||||
|
self.current = new_pages;
|
||||||
|
Some(old_pages)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn as_slice(&self) -> &[u8] {
|
||||||
|
unsafe { &self.memory.as_slice()[0..self.current as usize * WASM_PAGE_SIZE] }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn as_slice_mut(&mut self) -> &mut [u8] {
|
||||||
|
unsafe { &mut self.memory.as_slice_mut()[0..self.current as usize * WASM_PAGE_SIZE] }
|
||||||
|
}
|
||||||
|
}
|
156
lib/runtime-core/src/memory/mod.rs
Normal file
156
lib/runtime-core/src/memory/mod.rs
Normal file
@ -0,0 +1,156 @@
|
|||||||
|
use crate::{
|
||||||
|
export::Export,
|
||||||
|
import::IsExport,
|
||||||
|
memory::dynamic::DYNAMIC_GUARD_SIZE,
|
||||||
|
memory::static_::{SAFE_STATIC_GUARD_SIZE, SAFE_STATIC_HEAP_SIZE},
|
||||||
|
types::MemoryDesc,
|
||||||
|
vm,
|
||||||
|
};
|
||||||
|
use std::{cell::UnsafeCell, fmt, ptr, rc::Rc};
|
||||||
|
|
||||||
|
pub use self::dynamic::DynamicMemory;
|
||||||
|
pub use self::static_::{SharedStaticMemory, StaticMemory};
|
||||||
|
|
||||||
|
mod dynamic;
|
||||||
|
mod static_;
|
||||||
|
|
||||||
|
pub const WASM_PAGE_SIZE: usize = 65_536;
|
||||||
|
pub const WASM_MAX_PAGES: usize = 65_536;
|
||||||
|
|
||||||
|
pub struct Memory {
|
||||||
|
desc: MemoryDesc,
|
||||||
|
storage: Rc<UnsafeCell<(MemoryStorage, Box<vm::LocalMemory>)>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Memory {
|
||||||
|
pub fn new(desc: MemoryDesc) -> Option<Self> {
|
||||||
|
let mut vm_local_memory = Box::new(vm::LocalMemory {
|
||||||
|
base: ptr::null_mut(),
|
||||||
|
bound: 0,
|
||||||
|
memory: ptr::null_mut(),
|
||||||
|
});
|
||||||
|
|
||||||
|
let memory_storage = match desc.memory_type() {
|
||||||
|
MemoryType::Dynamic => {
|
||||||
|
MemoryStorage::Dynamic(DynamicMemory::new(desc, &mut vm_local_memory)?)
|
||||||
|
}
|
||||||
|
MemoryType::Static => {
|
||||||
|
MemoryStorage::Static(StaticMemory::new(desc, &mut vm_local_memory)?)
|
||||||
|
}
|
||||||
|
MemoryType::SharedStatic => unimplemented!(),
|
||||||
|
};
|
||||||
|
|
||||||
|
Some(Memory {
|
||||||
|
desc,
|
||||||
|
storage: Rc::new(UnsafeCell::new((memory_storage, vm_local_memory))),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn description(&self) -> MemoryDesc {
|
||||||
|
self.desc
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn grow(&mut self, delta: u32) -> Option<u32> {
|
||||||
|
match unsafe { &mut *self.storage.get() } {
|
||||||
|
(MemoryStorage::Dynamic(dynamic_memory), local) => dynamic_memory.grow(delta, local),
|
||||||
|
(MemoryStorage::Static(static_memory), local) => static_memory.grow(delta, local),
|
||||||
|
(MemoryStorage::SharedStatic(_), _) => unimplemented!(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// This returns the number of pages in the memory.
|
||||||
|
pub fn current_pages(&self) -> u32 {
|
||||||
|
match unsafe { &*self.storage.get() } {
|
||||||
|
(MemoryStorage::Dynamic(dynamic_memory), _) => dynamic_memory.current(),
|
||||||
|
(MemoryStorage::Static(static_memory), _) => static_memory.current(),
|
||||||
|
(MemoryStorage::SharedStatic(_), _) => unimplemented!(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn as_slice(&self) -> &[u8] {
|
||||||
|
match unsafe { &*self.storage.get() } {
|
||||||
|
(MemoryStorage::Dynamic(dynamic_memory), _) => dynamic_memory.as_slice(),
|
||||||
|
(MemoryStorage::Static(static_memory), _) => static_memory.as_slice(),
|
||||||
|
(MemoryStorage::SharedStatic(_), _) => panic!("cannot slice a shared memory"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn as_slice_mut(&mut self) -> &mut [u8] {
|
||||||
|
match unsafe { &mut *self.storage.get() } {
|
||||||
|
(MemoryStorage::Dynamic(dynamic_memory), _) => dynamic_memory.as_slice_mut(),
|
||||||
|
(MemoryStorage::Static(static_memory), _) => static_memory.as_slice_mut(),
|
||||||
|
(MemoryStorage::SharedStatic(_), _) => panic!("cannot slice a shared memory"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn vm_local_memory(&mut self) -> *mut vm::LocalMemory {
|
||||||
|
&mut *unsafe { &mut *self.storage.get() }.1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl IsExport for Memory {
|
||||||
|
fn to_export(&mut self) -> Export {
|
||||||
|
Export::Memory(self.clone())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Clone for Memory {
|
||||||
|
fn clone(&self) -> Self {
|
||||||
|
Self {
|
||||||
|
desc: self.desc,
|
||||||
|
storage: Rc::clone(&self.storage),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub enum MemoryStorage {
|
||||||
|
Dynamic(Box<DynamicMemory>),
|
||||||
|
Static(Box<StaticMemory>),
|
||||||
|
SharedStatic(Box<SharedStaticMemory>),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl MemoryStorage {
|
||||||
|
pub fn to_type(&self) -> MemoryType {
|
||||||
|
match self {
|
||||||
|
MemoryStorage::Dynamic(_) => MemoryType::Dynamic,
|
||||||
|
MemoryStorage::Static(_) => MemoryType::Static,
|
||||||
|
MemoryStorage::SharedStatic(_) => MemoryType::SharedStatic,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||||
|
pub enum MemoryType {
|
||||||
|
Dynamic,
|
||||||
|
Static,
|
||||||
|
SharedStatic,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl MemoryType {
|
||||||
|
#[doc(hidden)]
|
||||||
|
pub fn guard_size(self) -> u64 {
|
||||||
|
match self {
|
||||||
|
MemoryType::Dynamic => DYNAMIC_GUARD_SIZE as u64,
|
||||||
|
MemoryType::Static => SAFE_STATIC_GUARD_SIZE as u64,
|
||||||
|
MemoryType::SharedStatic => SAFE_STATIC_GUARD_SIZE as u64,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[doc(hidden)]
|
||||||
|
pub fn bounds(self) -> Option<u64> {
|
||||||
|
match self {
|
||||||
|
MemoryType::Dynamic => None,
|
||||||
|
MemoryType::Static => Some(SAFE_STATIC_HEAP_SIZE as u64),
|
||||||
|
MemoryType::SharedStatic => Some(SAFE_STATIC_HEAP_SIZE as u64),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl fmt::Debug for Memory {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
f.debug_struct("Memory")
|
||||||
|
.field("desc", &self.desc)
|
||||||
|
.field("size", &(self.current_pages() as usize * WASM_PAGE_SIZE))
|
||||||
|
.finish()
|
||||||
|
}
|
||||||
|
}
|
10
lib/runtime-core/src/memory/static_/mod.rs
Normal file
10
lib/runtime-core/src/memory/static_/mod.rs
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
#[doc(hidden)]
|
||||||
|
pub const SAFE_STATIC_HEAP_SIZE: usize = 1 << 32; // 4 GiB
|
||||||
|
#[doc(hidden)]
|
||||||
|
pub const SAFE_STATIC_GUARD_SIZE: usize = 1 << 31; // 2 GiB
|
||||||
|
|
||||||
|
mod shared;
|
||||||
|
mod unshared;
|
||||||
|
|
||||||
|
pub use self::shared::SharedStaticMemory;
|
||||||
|
pub use self::unshared::StaticMemory;
|
11
lib/runtime-core/src/memory/static_/shared.rs
Normal file
11
lib/runtime-core/src/memory/static_/shared.rs
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
use crate::sys;
|
||||||
|
use parking_lot::Mutex;
|
||||||
|
use std::sync::atomic::AtomicUsize;
|
||||||
|
|
||||||
|
// Remove this attribute once this is used.
|
||||||
|
#[allow(dead_code)]
|
||||||
|
pub struct SharedStaticMemory {
|
||||||
|
memory: sys::Memory,
|
||||||
|
current: AtomicUsize,
|
||||||
|
lock: Mutex<()>,
|
||||||
|
}
|
99
lib/runtime-core/src/memory/static_/unshared.rs
Normal file
99
lib/runtime-core/src/memory/static_/unshared.rs
Normal file
@ -0,0 +1,99 @@
|
|||||||
|
use crate::{
|
||||||
|
memory::{
|
||||||
|
static_::{SAFE_STATIC_GUARD_SIZE, SAFE_STATIC_HEAP_SIZE},
|
||||||
|
WASM_MAX_PAGES, WASM_PAGE_SIZE,
|
||||||
|
},
|
||||||
|
sys,
|
||||||
|
types::MemoryDesc,
|
||||||
|
vm,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub struct StaticMemory {
|
||||||
|
memory: sys::Memory,
|
||||||
|
current: u32,
|
||||||
|
max: Option<u32>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl StaticMemory {
|
||||||
|
pub(in crate::memory) fn new(
|
||||||
|
desc: MemoryDesc,
|
||||||
|
local: &mut vm::LocalMemory,
|
||||||
|
) -> Option<Box<Self>> {
|
||||||
|
let memory = {
|
||||||
|
let mut memory =
|
||||||
|
sys::Memory::with_size(SAFE_STATIC_HEAP_SIZE + SAFE_STATIC_GUARD_SIZE).ok()?;
|
||||||
|
if desc.min != 0 {
|
||||||
|
unsafe {
|
||||||
|
memory
|
||||||
|
.protect(
|
||||||
|
0..(desc.min as usize * WASM_PAGE_SIZE),
|
||||||
|
sys::Protect::ReadWrite,
|
||||||
|
)
|
||||||
|
.ok()?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
memory
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut storage = Box::new(StaticMemory {
|
||||||
|
memory,
|
||||||
|
current: desc.min,
|
||||||
|
max: desc.max,
|
||||||
|
});
|
||||||
|
let storage_ptr: *mut StaticMemory = &mut *storage;
|
||||||
|
|
||||||
|
local.base = storage.memory.as_ptr();
|
||||||
|
local.bound = desc.min as usize * WASM_PAGE_SIZE;
|
||||||
|
local.memory = storage_ptr as *mut ();
|
||||||
|
|
||||||
|
Some(storage)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn current(&self) -> u32 {
|
||||||
|
self.current
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn grow(&mut self, delta: u32, local: &mut vm::LocalMemory) -> Option<u32> {
|
||||||
|
if delta == 0 {
|
||||||
|
return Some(self.current);
|
||||||
|
}
|
||||||
|
|
||||||
|
let new_pages = self.current.checked_add(delta)?;
|
||||||
|
|
||||||
|
if let Some(max) = self.max {
|
||||||
|
if new_pages > max {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if new_pages as usize > WASM_MAX_PAGES {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsafe {
|
||||||
|
self.memory
|
||||||
|
.protect(
|
||||||
|
self.current as usize * WASM_PAGE_SIZE..new_pages as usize * WASM_PAGE_SIZE,
|
||||||
|
sys::Protect::ReadWrite,
|
||||||
|
)
|
||||||
|
.ok()?;
|
||||||
|
}
|
||||||
|
|
||||||
|
local.bound = new_pages as usize * WASM_PAGE_SIZE;
|
||||||
|
|
||||||
|
let old_pages = self.current;
|
||||||
|
|
||||||
|
self.current = new_pages;
|
||||||
|
|
||||||
|
Some(old_pages)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn as_slice(&self) -> &[u8] {
|
||||||
|
unsafe { &self.memory.as_slice()[0..self.current as usize * WASM_PAGE_SIZE] }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn as_slice_mut(&mut self) -> &mut [u8] {
|
||||||
|
unsafe { &mut self.memory.as_slice_mut()[0..self.current as usize * WASM_PAGE_SIZE] }
|
||||||
|
}
|
||||||
|
}
|
@ -7,7 +7,7 @@ use crate::{
|
|||||||
types::{
|
types::{
|
||||||
FuncIndex, Global, GlobalDesc, GlobalIndex, ImportedFuncIndex, ImportedGlobalIndex,
|
FuncIndex, Global, GlobalDesc, GlobalIndex, ImportedFuncIndex, ImportedGlobalIndex,
|
||||||
ImportedMemoryIndex, ImportedTableIndex, Initializer, LocalGlobalIndex, LocalMemoryIndex,
|
ImportedMemoryIndex, ImportedTableIndex, Initializer, LocalGlobalIndex, LocalMemoryIndex,
|
||||||
LocalTableIndex, Memory, MemoryIndex, SigIndex, Table, TableIndex,
|
LocalTableIndex, MemoryDesc, MemoryIndex, SigIndex, TableDesc, TableIndex,
|
||||||
},
|
},
|
||||||
Instance,
|
Instance,
|
||||||
};
|
};
|
||||||
@ -21,14 +21,14 @@ pub struct ModuleInner {
|
|||||||
pub protected_caller: Box<dyn ProtectedCaller>,
|
pub protected_caller: Box<dyn ProtectedCaller>,
|
||||||
|
|
||||||
// This are strictly local and the typsystem ensures that.
|
// This are strictly local and the typsystem ensures that.
|
||||||
pub memories: Map<LocalMemoryIndex, Memory>,
|
pub memories: Map<LocalMemoryIndex, MemoryDesc>,
|
||||||
pub globals: Map<LocalGlobalIndex, Global>,
|
pub globals: Map<LocalGlobalIndex, Global>,
|
||||||
pub tables: Map<LocalTableIndex, Table>,
|
pub tables: Map<LocalTableIndex, TableDesc>,
|
||||||
|
|
||||||
// These are strictly imported and the typesystem ensures that.
|
// These are strictly imported and the typesystem ensures that.
|
||||||
pub imported_functions: Map<ImportedFuncIndex, ImportName>,
|
pub imported_functions: Map<ImportedFuncIndex, ImportName>,
|
||||||
pub imported_memories: Map<ImportedMemoryIndex, (ImportName, Memory)>,
|
pub imported_memories: Map<ImportedMemoryIndex, (ImportName, MemoryDesc)>,
|
||||||
pub imported_tables: Map<ImportedTableIndex, (ImportName, Table)>,
|
pub imported_tables: Map<ImportedTableIndex, (ImportName, TableDesc)>,
|
||||||
pub imported_globals: Map<ImportedGlobalIndex, (ImportName, GlobalDesc)>,
|
pub imported_globals: Map<ImportedGlobalIndex, (ImportName, GlobalDesc)>,
|
||||||
|
|
||||||
pub exports: HashMap<String, ExportIndex>,
|
pub exports: HashMap<String, ExportIndex>,
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
use super::vm;
|
use super::vm;
|
||||||
use crate::types::{ElementType, Table};
|
use crate::types::{ElementType, TableDesc};
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub enum TableElements {
|
pub enum TableElements {
|
||||||
@ -14,7 +14,7 @@ pub struct TableBacking {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl TableBacking {
|
impl TableBacking {
|
||||||
pub fn new(table: &Table) -> Self {
|
pub fn new(table: TableDesc) -> Self {
|
||||||
match table.ty {
|
match table.ty {
|
||||||
ElementType::Anyfunc => {
|
ElementType::Anyfunc => {
|
||||||
let initial_table_backing_len = match table.max {
|
let initial_table_backing_len = match table.max {
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
use crate::{module::ModuleInner, structures::TypedIndex};
|
use crate::{memory::MemoryType, module::ModuleInner, structures::TypedIndex};
|
||||||
|
|
||||||
/// Represents a WebAssembly type.
|
/// Represents a WebAssembly type.
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
||||||
@ -71,7 +71,7 @@ pub enum ElementType {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy)]
|
#[derive(Debug, Clone, Copy)]
|
||||||
pub struct Table {
|
pub struct TableDesc {
|
||||||
/// Type of data stored in this table.
|
/// Type of data stored in this table.
|
||||||
pub ty: ElementType,
|
pub ty: ElementType,
|
||||||
/// The minimum number of elements that must be stored in this table.
|
/// The minimum number of elements that must be stored in this table.
|
||||||
@ -80,8 +80,8 @@ pub struct Table {
|
|||||||
pub max: Option<u32>,
|
pub max: Option<u32>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Table {
|
impl TableDesc {
|
||||||
pub(crate) fn fits_in_imported(&self, imported: &Table) -> bool {
|
pub(crate) fn fits_in_imported(&self, imported: &TableDesc) -> bool {
|
||||||
// TODO: We should define implementation limits.
|
// TODO: We should define implementation limits.
|
||||||
let imported_max = imported.max.unwrap_or(u32::max_value());
|
let imported_max = imported.max.unwrap_or(u32::max_value());
|
||||||
let self_max = self.max.unwrap_or(u32::max_value());
|
let self_max = self.max.unwrap_or(u32::max_value());
|
||||||
@ -115,7 +115,7 @@ pub struct Global {
|
|||||||
|
|
||||||
/// A wasm memory.
|
/// A wasm memory.
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||||
pub struct Memory {
|
pub struct MemoryDesc {
|
||||||
/// The minimum number of allowed pages.
|
/// The minimum number of allowed pages.
|
||||||
pub min: u32,
|
pub min: u32,
|
||||||
/// The maximum number of allowed pages.
|
/// The maximum number of allowed pages.
|
||||||
@ -124,12 +124,17 @@ pub struct Memory {
|
|||||||
pub shared: bool,
|
pub shared: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Memory {
|
impl MemoryDesc {
|
||||||
pub fn is_static_heap(&self) -> bool {
|
pub fn memory_type(self) -> MemoryType {
|
||||||
self.max.is_some()
|
match (self.max.is_some(), self.shared) {
|
||||||
|
(true, true) => MemoryType::SharedStatic,
|
||||||
|
(true, false) => MemoryType::Static,
|
||||||
|
(false, false) => MemoryType::Dynamic,
|
||||||
|
(false, true) => panic!("shared memory without a max is not allowed"),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn fits_in_imported(&self, imported: &Memory) -> bool {
|
pub(crate) fn fits_in_imported(&self, imported: MemoryDesc) -> bool {
|
||||||
let imported_max = imported.max.unwrap_or(65_536);
|
let imported_max = imported.max.unwrap_or(65_536);
|
||||||
let self_max = self.max.unwrap_or(65_536);
|
let self_max = self.max.unwrap_or(65_536);
|
||||||
|
|
||||||
|
@ -2,7 +2,7 @@ pub use crate::backing::{ImportBacking, LocalBacking};
|
|||||||
use crate::{
|
use crate::{
|
||||||
module::ModuleInner,
|
module::ModuleInner,
|
||||||
structures::TypedIndex,
|
structures::TypedIndex,
|
||||||
types::{LocalMemoryIndex, LocalOrImport, MemoryIndex},
|
types::{LocalOrImport, MemoryIndex},
|
||||||
};
|
};
|
||||||
use std::{ffi::c_void, mem, ptr, slice};
|
use std::{ffi::c_void, mem, ptr, slice};
|
||||||
|
|
||||||
@ -13,7 +13,7 @@ use std::{ffi::c_void, mem, ptr, slice};
|
|||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
pub struct Ctx {
|
pub struct Ctx {
|
||||||
/// A pointer to an array of locally-defined memories, indexed by `MemoryIndex`.
|
/// A pointer to an array of locally-defined memories, indexed by `MemoryIndex`.
|
||||||
pub(crate) memories: *mut LocalMemory,
|
pub(crate) memories: *mut *mut LocalMemory,
|
||||||
|
|
||||||
/// A pointer to an array of locally-defined tables, indexed by `TableIndex`.
|
/// A pointer to an array of locally-defined tables, indexed by `TableIndex`.
|
||||||
pub(crate) tables: *mut LocalTable,
|
pub(crate) tables: *mut LocalTable,
|
||||||
@ -22,7 +22,7 @@ pub struct Ctx {
|
|||||||
pub(crate) globals: *mut LocalGlobal,
|
pub(crate) globals: *mut LocalGlobal,
|
||||||
|
|
||||||
/// A pointer to an array of imported memories, indexed by `MemoryIndex,
|
/// A pointer to an array of imported memories, indexed by `MemoryIndex,
|
||||||
pub(crate) imported_memories: *mut ImportedMemory,
|
pub(crate) imported_memories: *mut *mut LocalMemory,
|
||||||
|
|
||||||
/// A pointer to an array of imported tables, indexed by `TableIndex`.
|
/// A pointer to an array of imported tables, indexed by `TableIndex`.
|
||||||
pub(crate) imported_tables: *mut ImportedTable,
|
pub(crate) imported_tables: *mut ImportedTable,
|
||||||
@ -33,8 +33,8 @@ pub struct Ctx {
|
|||||||
/// A pointer to an array of imported functions, indexed by `FuncIndex`.
|
/// A pointer to an array of imported functions, indexed by `FuncIndex`.
|
||||||
pub(crate) imported_funcs: *mut ImportedFunc,
|
pub(crate) imported_funcs: *mut ImportedFunc,
|
||||||
|
|
||||||
pub(crate) local_backing: *mut LocalBacking,
|
// pub(crate) local_backing: *mut LocalBacking,
|
||||||
pub(crate) import_backing: *mut ImportBacking,
|
// pub(crate) import_backing: *mut ImportBacking,
|
||||||
module: *const ModuleInner,
|
module: *const ModuleInner,
|
||||||
|
|
||||||
pub data: *mut c_void,
|
pub data: *mut c_void,
|
||||||
@ -53,13 +53,13 @@ impl Ctx {
|
|||||||
tables: local_backing.vm_tables.as_mut_ptr(),
|
tables: local_backing.vm_tables.as_mut_ptr(),
|
||||||
globals: local_backing.vm_globals.as_mut_ptr(),
|
globals: local_backing.vm_globals.as_mut_ptr(),
|
||||||
|
|
||||||
imported_memories: import_backing.memories.as_mut_ptr(),
|
imported_memories: import_backing.vm_memories.as_mut_ptr(),
|
||||||
imported_tables: import_backing.tables.as_mut_ptr(),
|
imported_tables: import_backing.vm_tables.as_mut_ptr(),
|
||||||
imported_globals: import_backing.globals.as_mut_ptr(),
|
imported_globals: import_backing.vm_globals.as_mut_ptr(),
|
||||||
imported_funcs: import_backing.functions.as_mut_ptr(),
|
imported_funcs: import_backing.vm_functions.as_mut_ptr(),
|
||||||
|
|
||||||
local_backing,
|
// local_backing,
|
||||||
import_backing,
|
// import_backing,
|
||||||
module,
|
module,
|
||||||
|
|
||||||
data: ptr::null_mut(),
|
data: ptr::null_mut(),
|
||||||
@ -80,13 +80,13 @@ impl Ctx {
|
|||||||
tables: local_backing.vm_tables.as_mut_ptr(),
|
tables: local_backing.vm_tables.as_mut_ptr(),
|
||||||
globals: local_backing.vm_globals.as_mut_ptr(),
|
globals: local_backing.vm_globals.as_mut_ptr(),
|
||||||
|
|
||||||
imported_memories: import_backing.memories.as_mut_ptr(),
|
imported_memories: import_backing.vm_memories.as_mut_ptr(),
|
||||||
imported_tables: import_backing.tables.as_mut_ptr(),
|
imported_tables: import_backing.vm_tables.as_mut_ptr(),
|
||||||
imported_globals: import_backing.globals.as_mut_ptr(),
|
imported_globals: import_backing.vm_globals.as_mut_ptr(),
|
||||||
imported_funcs: import_backing.functions.as_mut_ptr(),
|
imported_funcs: import_backing.vm_functions.as_mut_ptr(),
|
||||||
|
|
||||||
local_backing,
|
// local_backing,
|
||||||
import_backing,
|
// import_backing,
|
||||||
module,
|
module,
|
||||||
|
|
||||||
data,
|
data,
|
||||||
@ -116,19 +116,14 @@ impl Ctx {
|
|||||||
let module = unsafe { &*self.module };
|
let module = unsafe { &*self.module };
|
||||||
let mem_index = MemoryIndex::new(mem_index as usize);
|
let mem_index = MemoryIndex::new(mem_index as usize);
|
||||||
match mem_index.local_or_import(module) {
|
match mem_index.local_or_import(module) {
|
||||||
LocalOrImport::Local(local_mem_index) => {
|
LocalOrImport::Local(local_mem_index) => unsafe {
|
||||||
let local_backing = unsafe { &*self.local_backing };
|
let local_memory = &**self.memories.add(local_mem_index.index());
|
||||||
&local_backing.memories[local_mem_index][..]
|
slice::from_raw_parts(local_memory.base, local_memory.bound)
|
||||||
}
|
},
|
||||||
LocalOrImport::Import(import_mem_index) => {
|
LocalOrImport::Import(import_mem_index) => unsafe {
|
||||||
let import_backing = unsafe { &mut *self.import_backing };
|
let local_memory = &**self.imported_memories.add(import_mem_index.index());
|
||||||
let vm_memory_import = import_backing.memories[import_mem_index].clone();
|
slice::from_raw_parts(local_memory.base, local_memory.bound)
|
||||||
unsafe {
|
},
|
||||||
let memory = &*vm_memory_import.memory;
|
|
||||||
|
|
||||||
slice::from_raw_parts(memory.base, memory.size)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -155,19 +150,14 @@ impl Ctx {
|
|||||||
let module = unsafe { &*self.module };
|
let module = unsafe { &*self.module };
|
||||||
let mem_index = MemoryIndex::new(mem_index as usize);
|
let mem_index = MemoryIndex::new(mem_index as usize);
|
||||||
match mem_index.local_or_import(module) {
|
match mem_index.local_or_import(module) {
|
||||||
LocalOrImport::Local(local_mem_index) => {
|
LocalOrImport::Local(local_mem_index) => unsafe {
|
||||||
let local_backing = unsafe { &mut *self.local_backing };
|
let local_memory = &**self.memories.add(local_mem_index.index());
|
||||||
&mut local_backing.memories[local_mem_index][..]
|
slice::from_raw_parts_mut(local_memory.base, local_memory.bound)
|
||||||
}
|
},
|
||||||
LocalOrImport::Import(import_mem_index) => {
|
LocalOrImport::Import(import_mem_index) => unsafe {
|
||||||
let import_backing = unsafe { &mut *self.import_backing };
|
let local_memory = &**self.imported_memories.add(import_mem_index.index());
|
||||||
let vm_memory_import = import_backing.memories[import_mem_index].clone();
|
slice::from_raw_parts_mut(local_memory.base, local_memory.bound)
|
||||||
unsafe {
|
},
|
||||||
let memory = &*vm_memory_import.memory;
|
|
||||||
|
|
||||||
slice::from_raw_parts_mut(memory.base, memory.size)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -295,9 +285,11 @@ pub struct LocalMemory {
|
|||||||
/// Pointer to the bottom of this linear memory.
|
/// Pointer to the bottom of this linear memory.
|
||||||
pub base: *mut u8,
|
pub base: *mut u8,
|
||||||
/// Current size of this linear memory in bytes.
|
/// Current size of this linear memory in bytes.
|
||||||
pub size: usize,
|
pub bound: usize,
|
||||||
/// The local memory index.
|
/// The actual memory that this represents.
|
||||||
pub index: LocalMemoryIndex,
|
/// This is either `*mut DynamicMemory`, `*mut StaticMemory`,
|
||||||
|
/// or `*mut SharedStaticMemory`.
|
||||||
|
pub memory: *mut (),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl LocalMemory {
|
impl LocalMemory {
|
||||||
@ -306,7 +298,7 @@ impl LocalMemory {
|
|||||||
0 * (mem::size_of::<usize>() as u8)
|
0 * (mem::size_of::<usize>() as u8)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn offset_size() -> u8 {
|
pub fn offset_bound() -> u8 {
|
||||||
1 * (mem::size_of::<usize>() as u8)
|
1 * (mem::size_of::<usize>() as u8)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -315,28 +307,28 @@ impl LocalMemory {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
// #[derive(Debug, Clone)]
|
||||||
#[repr(C)]
|
// #[repr(C)]
|
||||||
pub struct ImportedMemory {
|
// pub struct ImportedMemory {
|
||||||
/// A pointer to the memory definition.
|
// /// A pointer to the memory definition.
|
||||||
pub memory: *mut LocalMemory,
|
// pub memory: *mut LocalMemory,
|
||||||
pub vmctx: *mut Ctx,
|
// pub vmctx: *mut Ctx,
|
||||||
}
|
// }
|
||||||
|
|
||||||
impl ImportedMemory {
|
// impl ImportedMemory {
|
||||||
#[allow(clippy::erasing_op)] // TODO
|
// #[allow(clippy::erasing_op)] // TODO
|
||||||
pub fn offset_memory() -> u8 {
|
// pub fn offset_memory() -> u8 {
|
||||||
0 * (mem::size_of::<usize>() as u8)
|
// 0 * (mem::size_of::<usize>() as u8)
|
||||||
}
|
// }
|
||||||
|
|
||||||
pub fn offset_vmctx() -> u8 {
|
// pub fn offset_vmctx() -> u8 {
|
||||||
1 * (mem::size_of::<usize>() as u8)
|
// 1 * (mem::size_of::<usize>() as u8)
|
||||||
}
|
// }
|
||||||
|
|
||||||
pub fn size() -> u8 {
|
// pub fn size() -> u8 {
|
||||||
mem::size_of::<Self>() as u8
|
// mem::size_of::<Self>() as u8
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
/// Definition of a global used by the VM.
|
/// Definition of a global used by the VM.
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
@ -421,8 +413,8 @@ impl Anyfunc {
|
|||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod vm_offset_tests {
|
mod vm_offset_tests {
|
||||||
use super::{
|
use super::{
|
||||||
Anyfunc, Ctx, ImportedFunc, ImportedGlobal, ImportedMemory, ImportedTable, LocalGlobal,
|
Anyfunc, Ctx, ImportedFunc, ImportedGlobal, ImportedTable, LocalGlobal, LocalMemory,
|
||||||
LocalMemory, LocalTable,
|
LocalTable,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -510,21 +502,8 @@ mod vm_offset_tests {
|
|||||||
);
|
);
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
LocalMemory::offset_size() as usize,
|
LocalMemory::offset_bound() as usize,
|
||||||
offset_of!(LocalMemory => size).get_byte_offset(),
|
offset_of!(LocalMemory => bound).get_byte_offset(),
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn imported_memory() {
|
|
||||||
assert_eq!(
|
|
||||||
ImportedMemory::offset_memory() as usize,
|
|
||||||
offset_of!(ImportedMemory => memory).get_byte_offset(),
|
|
||||||
);
|
|
||||||
|
|
||||||
assert_eq!(
|
|
||||||
ImportedMemory::offset_vmctx() as usize,
|
|
||||||
offset_of!(ImportedMemory => vmctx).get_byte_offset(),
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -600,10 +579,12 @@ mod vm_ctx_tests {
|
|||||||
vm_globals: Map::new().into_boxed_map(),
|
vm_globals: Map::new().into_boxed_map(),
|
||||||
};
|
};
|
||||||
let mut import_backing = ImportBacking {
|
let mut import_backing = ImportBacking {
|
||||||
functions: Map::new().into_boxed_map(),
|
|
||||||
memories: Map::new().into_boxed_map(),
|
memories: Map::new().into_boxed_map(),
|
||||||
tables: Map::new().into_boxed_map(),
|
|
||||||
globals: Map::new().into_boxed_map(),
|
vm_functions: Map::new().into_boxed_map(),
|
||||||
|
vm_memories: Map::new().into_boxed_map(),
|
||||||
|
vm_tables: Map::new().into_boxed_map(),
|
||||||
|
vm_globals: Map::new().into_boxed_map(),
|
||||||
};
|
};
|
||||||
let module = generate_module();
|
let module = generate_module();
|
||||||
let data = &mut data as *mut _ as *mut c_void;
|
let data = &mut data as *mut _ as *mut c_void;
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
memory::LinearMemory,
|
memory::{DynamicMemory, StaticMemory},
|
||||||
structures::TypedIndex,
|
structures::TypedIndex,
|
||||||
types::{ImportedMemoryIndex, LocalMemoryIndex, LocalTableIndex},
|
types::{ImportedMemoryIndex, LocalMemoryIndex, LocalTableIndex},
|
||||||
vm,
|
vm,
|
||||||
@ -11,17 +11,14 @@ use crate::{
|
|||||||
|
|
||||||
pub unsafe extern "C" fn local_static_memory_grow(
|
pub unsafe extern "C" fn local_static_memory_grow(
|
||||||
memory_index: LocalMemoryIndex,
|
memory_index: LocalMemoryIndex,
|
||||||
by_pages: u32,
|
delta: u32,
|
||||||
ctx: *mut vm::Ctx,
|
ctx: &mut vm::Ctx,
|
||||||
) -> i32 {
|
) -> i32 {
|
||||||
if let Some(old) = (*(*ctx).local_backing)
|
let local_memory = *ctx.memories.add(memory_index.index());
|
||||||
.memory(memory_index)
|
let memory = (*local_memory).memory as *mut StaticMemory;
|
||||||
.grow_static(by_pages)
|
|
||||||
{
|
if let Some(old) = (*memory).grow(delta, &mut *local_memory) {
|
||||||
// Store the new size back into the vmctx.
|
old as i32
|
||||||
(*(*ctx).memories.add(memory_index.index())).size =
|
|
||||||
(old as usize + by_pages as usize) * LinearMemory::PAGE_SIZE as usize;
|
|
||||||
old
|
|
||||||
} else {
|
} else {
|
||||||
-1
|
-1
|
||||||
}
|
}
|
||||||
@ -29,71 +26,91 @@ pub unsafe extern "C" fn local_static_memory_grow(
|
|||||||
|
|
||||||
pub unsafe extern "C" fn local_static_memory_size(
|
pub unsafe extern "C" fn local_static_memory_size(
|
||||||
memory_index: LocalMemoryIndex,
|
memory_index: LocalMemoryIndex,
|
||||||
ctx: *mut vm::Ctx,
|
ctx: &vm::Ctx,
|
||||||
) -> u32 {
|
) -> u32 {
|
||||||
(*(*ctx).local_backing).memory(memory_index).pages()
|
let local_memory = *ctx.memories.add(memory_index.index());
|
||||||
|
let memory = (*local_memory).memory as *mut StaticMemory;
|
||||||
|
|
||||||
|
(*memory).current()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub unsafe extern "C" fn local_dynamic_memory_grow(
|
pub unsafe extern "C" fn local_dynamic_memory_grow(
|
||||||
memory_index: LocalMemoryIndex,
|
memory_index: LocalMemoryIndex,
|
||||||
by_pages: u32,
|
delta: u32,
|
||||||
ctx: *mut vm::Ctx,
|
ctx: &mut vm::Ctx,
|
||||||
) -> i32 {
|
) -> i32 {
|
||||||
if let Some(old) = (*(*ctx).local_backing)
|
let local_memory = *ctx.memories.add(memory_index.index());
|
||||||
.memory(memory_index)
|
let memory = (*local_memory).memory as *mut DynamicMemory;
|
||||||
.grow_dynamic(by_pages)
|
|
||||||
{
|
if let Some(old) = (*memory).grow(delta, &mut *local_memory) {
|
||||||
// Store the new size back into the vmctx.
|
old as i32
|
||||||
(*(*ctx).memories.add(memory_index.index())).size =
|
|
||||||
(old as usize + by_pages as usize) * LinearMemory::PAGE_SIZE as usize;
|
|
||||||
old
|
|
||||||
} else {
|
} else {
|
||||||
-1
|
-1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub unsafe extern "C" fn local_dynamic_memory_size(
|
||||||
|
memory_index: LocalMemoryIndex,
|
||||||
|
ctx: &vm::Ctx,
|
||||||
|
) -> u32 {
|
||||||
|
let local_memory = *ctx.memories.add(memory_index.index());
|
||||||
|
let memory = (*local_memory).memory as *mut DynamicMemory;
|
||||||
|
|
||||||
|
(*memory).current()
|
||||||
|
}
|
||||||
|
|
||||||
// +*****************************+
|
// +*****************************+
|
||||||
// | IMPORTED MEMORIES |
|
// | IMPORTED MEMORIES |
|
||||||
// +****************************+
|
// +****************************+
|
||||||
|
|
||||||
pub unsafe extern "C" fn imported_static_memory_grow(
|
pub unsafe extern "C" fn imported_static_memory_grow(
|
||||||
imported_mem_index: ImportedMemoryIndex,
|
import_memory_index: ImportedMemoryIndex,
|
||||||
by_pages: u32,
|
delta: u32,
|
||||||
caller_ctx: *mut vm::Ctx,
|
ctx: &mut vm::Ctx,
|
||||||
) -> i32 {
|
) -> i32 {
|
||||||
let import_backing = &*(*caller_ctx).import_backing;
|
let local_memory = *ctx.imported_memories.add(import_memory_index.index());
|
||||||
let vm_imported_mem = import_backing.imported_memory(imported_mem_index);
|
let memory = (*local_memory).memory as *mut StaticMemory;
|
||||||
|
|
||||||
// We can assume that the memory here is local to the callee ctx.
|
if let Some(old) = (*memory).grow(delta, &mut *local_memory) {
|
||||||
let local_mem_index = (*vm_imported_mem.memory).index;
|
old as i32
|
||||||
|
|
||||||
if let Some(old) = (*(*vm_imported_mem.vmctx).local_backing)
|
|
||||||
.memory(local_mem_index)
|
|
||||||
.grow_dynamic(by_pages)
|
|
||||||
{
|
|
||||||
// Store the new size back into the vmctx.
|
|
||||||
(*(*vm_imported_mem.vmctx)
|
|
||||||
.memories
|
|
||||||
.add(local_mem_index.index()))
|
|
||||||
.size = (old as usize + by_pages as usize) * LinearMemory::PAGE_SIZE as usize;
|
|
||||||
old
|
|
||||||
} else {
|
} else {
|
||||||
-1
|
-1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub unsafe extern "C" fn imported_static_memory_size(
|
pub unsafe extern "C" fn imported_static_memory_size(
|
||||||
imported_memory_index: ImportedMemoryIndex,
|
import_memory_index: ImportedMemoryIndex,
|
||||||
caller_ctx: *mut vm::Ctx,
|
ctx: &vm::Ctx,
|
||||||
) -> u32 {
|
) -> u32 {
|
||||||
let import_backing = &*(*caller_ctx).import_backing;
|
let local_memory = *ctx.imported_memories.add(import_memory_index.index());
|
||||||
let vm_imported_mem = import_backing.imported_memory(imported_memory_index);
|
let memory = (*local_memory).memory as *mut StaticMemory;
|
||||||
|
|
||||||
// We can assume that the memory here is local to the callee ctx.
|
(*memory).current()
|
||||||
let local_mem_index = (*vm_imported_mem.memory).index;
|
}
|
||||||
(*(*vm_imported_mem.vmctx).local_backing)
|
|
||||||
.memory(local_mem_index)
|
pub unsafe extern "C" fn imported_dynamic_memory_grow(
|
||||||
.pages()
|
memory_index: ImportedMemoryIndex,
|
||||||
|
delta: u32,
|
||||||
|
ctx: &mut vm::Ctx,
|
||||||
|
) -> i32 {
|
||||||
|
let local_memory = *ctx.imported_memories.add(memory_index.index());
|
||||||
|
let memory = (*local_memory).memory as *mut DynamicMemory;
|
||||||
|
|
||||||
|
if let Some(old) = (*memory).grow(delta, &mut *local_memory) {
|
||||||
|
old as i32
|
||||||
|
} else {
|
||||||
|
-1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub unsafe extern "C" fn imported_dynamic_memory_size(
|
||||||
|
memory_index: ImportedMemoryIndex,
|
||||||
|
ctx: &vm::Ctx,
|
||||||
|
) -> u32 {
|
||||||
|
let local_memory = *ctx.imported_memories.add(memory_index.index());
|
||||||
|
let memory = (*local_memory).memory as *mut DynamicMemory;
|
||||||
|
|
||||||
|
(*memory).current()
|
||||||
}
|
}
|
||||||
|
|
||||||
// +*****************************+
|
// +*****************************+
|
||||||
@ -102,16 +119,16 @@ pub unsafe extern "C" fn imported_static_memory_size(
|
|||||||
|
|
||||||
pub unsafe extern "C" fn local_table_grow(
|
pub unsafe extern "C" fn local_table_grow(
|
||||||
table_index: LocalTableIndex,
|
table_index: LocalTableIndex,
|
||||||
by_elems: u32,
|
delta: u32,
|
||||||
ctx: *mut vm::Ctx,
|
ctx: &mut vm::Ctx,
|
||||||
) -> i32 {
|
) -> i32 {
|
||||||
let _ = table_index;
|
let _ = table_index;
|
||||||
let _ = by_elems;
|
let _ = delta;
|
||||||
let _ = ctx;
|
let _ = ctx;
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub unsafe extern "C" fn local_table_size(table_index: LocalTableIndex, ctx: *mut vm::Ctx) -> u32 {
|
pub unsafe extern "C" fn local_table_size(table_index: LocalTableIndex, ctx: &vm::Ctx) -> u32 {
|
||||||
let _ = table_index;
|
let _ = table_index;
|
||||||
let _ = ctx;
|
let _ = ctx;
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
|
Reference in New Issue
Block a user