externref: Address review feedback

This commit is contained in:
Nick Fitzgerald
2020-06-12 17:22:54 -07:00
parent 618c278e41
commit 7e167cae10
20 changed files with 422 additions and 589 deletions

265
Cargo.lock generated
View File

@@ -11,9 +11,9 @@ dependencies = [
[[package]]
name = "adler32"
version = "1.0.4"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5d2e7343e7fc9de883d1b0341e0b13970f764c14101234857d2ddafa1cb1cac2"
checksum = "567b077b825e468cc974f0020d4082ee6e03132512f207ef1a02fd5d00d1f32d"
[[package]]
name = "ahash"
@@ -50,9 +50,9 @@ dependencies = [
[[package]]
name = "anyhow"
version = "1.0.28"
version = "1.0.31"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d9a60d744a80c30fcb657dfe2c1b22bcb3e814c1a1e3674f32bf5820b570fbff"
checksum = "85bb70cc08ec97ca5450e6eba421deeea5f172c0fc61f78b5357b2a8e8be195f"
[[package]]
name = "arbitrary"
@@ -100,14 +100,15 @@ checksum = "f8aac770f1885fd7e387acedd76065302551364496e46b3dd00860b2f8359b9d"
[[package]]
name = "backtrace"
version = "0.3.48"
source = "git+https://github.com/rust-lang/backtrace-rs.git#05319f46dd4126a4d4a3b2bbf8c378c4cf9fd902"
version = "0.3.49"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "05100821de9e028f12ae3d189176b41ee198341eb8f369956407fea2f5cc666c"
dependencies = [
"addr2line",
"cfg-if",
"libc",
"miniz_oxide",
"object 0.19.0",
"object 0.20.0",
"rustc-demangle",
]
@@ -119,9 +120,9 @@ checksum = "b41b7ea54a0c9d92199de89e20e58d49f02f8e699814ef3fdf266f6f748d15c7"
[[package]]
name = "base64"
version = "0.12.0"
version = "0.12.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7d5ca2cd0adc3f48f9e9ea5a6bbdf9ccc0bfade884847e484d452414c7ccffb3"
checksum = "53d1ccbaf7d9ec9537465a97bf19edc1a4e158ecb49fc16178202238c569cc42"
[[package]]
name = "binaryen"
@@ -156,18 +157,18 @@ dependencies = [
[[package]]
name = "bit-set"
version = "0.5.1"
version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e84c238982c4b1e1ee668d136c510c67a13465279c0cb367ea6baf6310620a80"
checksum = "6e11e16035ea35e4e5997b393eacbf6f63983188f7a2ad25bfb13465f5ad59de"
dependencies = [
"bit-vec",
]
[[package]]
name = "bit-vec"
version = "0.5.1"
version = "0.6.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f59bbe95d4e52a6398ec21238d31577f2b28a9d86807f06ca59d191d8440d0bb"
checksum = "5f0dc55f2d8a1a85650ac47858bb001b4c0dd73d79e3c455a842925e68d29cd3"
[[package]]
name = "bitflags"
@@ -209,9 +210,9 @@ dependencies = [
[[package]]
name = "bumpalo"
version = "3.3.0"
version = "3.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5356f1d23ee24a1f785a56d1d1a5f0fd5b0f6a0c0fb2412ce11da71649ab78f6"
checksum = "2e8c087f005730276d1096a652e92a8bacee2e2472bcc9715a74d2bec38b5820"
[[package]]
name = "byte-tools"
@@ -245,9 +246,9 @@ dependencies = [
[[package]]
name = "cc"
version = "1.0.52"
version = "1.0.54"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c3d87b23d6a92cd03af510a5ade527033f6aa6fa92161e2d5863a907d4c5e31d"
checksum = "7bbb73db36c1246e9034e307d0fba23f9a2e251faa47ade70c1bd252220c8311"
dependencies = [
"jobserver",
]
@@ -271,9 +272,9 @@ dependencies = [
[[package]]
name = "clap"
version = "2.33.0"
version = "2.33.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5067f5bb2d80ef5d68b4c87db81601f0b75bca627bc2ef76b141d7b846a3c6d9"
checksum = "bdfa80d47f954d53a35a64987ca1422f495b8d6483c0fe9f7117b36c2a792129"
dependencies = [
"ansi_term",
"atty",
@@ -295,18 +296,18 @@ dependencies = [
[[package]]
name = "cmake"
version = "0.1.42"
version = "0.1.44"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "81fb25b677f8bf1eb325017cb6bb8452f87969db0fedb4f757b297bee78a7c62"
checksum = "0e56268c17a6248366d66d4a47a3381369d068cce8409bb1716ed77ea32163bb"
dependencies = [
"cc",
]
[[package]]
name = "console"
version = "0.11.2"
version = "0.11.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dea0f3e2e8d7dba335e913b97f9e1992c86c4399d54f8be1d31c8727d0652064"
checksum = "8c0994e656bba7b922d8dd1245db90672ffb701e684e45be58f20719d69abc5a"
dependencies = [
"encode_unicode",
"lazy_static",
@@ -499,7 +500,7 @@ dependencies = [
"anyhow",
"cranelift-codegen",
"cranelift-module",
"object 0.18.0",
"object 0.19.0",
"target-lexicon",
]
@@ -639,12 +640,13 @@ dependencies = [
[[package]]
name = "crossbeam-queue"
version = "0.2.1"
version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c695eeca1e7173472a32221542ae469b3e9aac3a4fc81f7696bcad82029493db"
checksum = "774ba60a54c213d409d5353bda12d49cd68d14e45036a285234c8d6f91f92570"
dependencies = [
"cfg-if",
"crossbeam-utils",
"maybe-uninit",
]
[[package]]
@@ -680,9 +682,9 @@ dependencies = [
[[package]]
name = "derive_more"
version = "0.99.5"
version = "0.99.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e2323f3f47db9a0e77ce7a300605d8d2098597fc451ed1a97bb1f6411bb550a7"
checksum = "2127768764f1556535c01b5326ef94bd60ff08dcfbdc544d53e69ed155610f5d"
dependencies = [
"proc-macro2",
"quote",
@@ -691,9 +693,9 @@ dependencies = [
[[package]]
name = "derive_utils"
version = "0.9.1"
version = "0.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "114aa287358087a616096186f3de19525d8083f83d437dc6b583f895316b02e6"
checksum = "3df5480412da86cdf5d6b7f3b682422c84359ff7399aa658df1d15ee83244b1d"
dependencies = [
"proc-macro2",
"quote",
@@ -783,19 +785,6 @@ version = "0.3.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f"
[[package]]
name = "env_logger"
version = "0.6.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "aafcde04e90a5226a6443b7aabdb016ba2f8307c847d524724bd9b346dd1a2d3"
dependencies = [
"atty",
"humantime",
"log",
"regex",
"termcolor",
]
[[package]]
name = "env_logger"
version = "0.7.1"
@@ -867,11 +856,11 @@ checksum = "4443176a9f2c162692bd3d352d745ef9413eec5782a80d8fd6f8a1ac692a07f7"
[[package]]
name = "file-per-thread-logger"
version = "0.1.2"
version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8505b75b31ef7285168dd237c4a7db3c1f3e0927e7d314e670bc98e854272fe9"
checksum = "8b3937f028664bd0e13df401ba49a4567ccda587420365823242977f06609ed1"
dependencies = [
"env_logger 0.6.2",
"env_logger",
"log",
]
@@ -887,9 +876,9 @@ dependencies = [
[[package]]
name = "filetime"
version = "0.2.9"
version = "0.2.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f59efc38004c988e4201d11d263b8171f49a2e7ec0bdbb71773433f271504a5e"
checksum = "affc17579b132fc2461adf7c575cc6e8b134ebca52c51f5411388965227dc695"
dependencies = [
"cfg-if",
"libc",
@@ -899,15 +888,15 @@ dependencies = [
[[package]]
name = "fnv"
version = "1.0.6"
version = "1.0.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2fad85553e09a6f881f739c29f0b00b0f01357c743266d478b68951ce23285f3"
checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
[[package]]
name = "fst"
version = "0.4.3"
version = "0.4.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "81f9cac32c1741cdf6b66be7dcf0d9c7f25ccf12f8aa84c16cfa31f9f14513b3"
checksum = "a7293de202dbfe786c0b3fe6110a027836c5438ed06db7b715c9955ff4bfea51"
[[package]]
name = "fuchsia-cprng"
@@ -1000,9 +989,9 @@ dependencies = [
[[package]]
name = "hermit-abi"
version = "0.1.12"
version = "0.1.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "61565ff7aaace3525556587bd2dc31d4a07071957be715e63ce7b1eccf51a8f4"
checksum = "b9586eedd4ce6b3c498bc3b4dd92fc9f11166aa908a914071953768066c67909"
dependencies = [
"libc",
]
@@ -1018,9 +1007,9 @@ dependencies = [
[[package]]
name = "indexmap"
version = "1.3.2"
version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "076f042c5b7b98f31d205f1249267e12a6518c1481e9dae9764af19b707d2292"
checksum = "c398b2b113b55809ceb9ee3e753fcbac793f1956663f3c36549c1346015c2afe"
dependencies = [
"autocfg 1.0.0",
]
@@ -1039,9 +1028,9 @@ dependencies = [
[[package]]
name = "iter-enum"
version = "0.2.3"
version = "0.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "58107b833f974ca7bc9f98e032881967613dc214b6ab7ececb45b1ab9f0e7008"
checksum = "2cdea9771bec3d95893f6c665a4fcd477af7858446a46bc2772f560534eee43b"
dependencies = [
"derive_utils",
"quote",
@@ -1057,6 +1046,15 @@ dependencies = [
"either",
]
[[package]]
name = "itertools"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "284f18f85651fe11e8a991b2adb42cb078325c996ed026d994719efcfca1d54b"
dependencies = [
"either",
]
[[package]]
name = "itoa"
version = "0.4.5"
@@ -1095,9 +1093,9 @@ checksum = "3576a87f2ba00f6f106fdfcd16db1d698d648a26ad8e0573cad8537c3c362d2a"
[[package]]
name = "libc"
version = "0.2.70"
version = "0.2.71"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3baa92041a6fec78c687fa0cc2b3fae8884f743d672cf551bed1d6dac6988d0f"
checksum = "9457b06509d27052635f90d6466700c65095fdf75409b3fbdd903e988b886f49"
[[package]]
name = "libfuzzer-sys"
@@ -1120,7 +1118,7 @@ dependencies = [
"dynasm",
"dynasmrt",
"iter-enum",
"itertools",
"itertools 0.8.2",
"lazy_static",
"memoffset",
"more-asserts",
@@ -1144,9 +1142,9 @@ dependencies = [
[[package]]
name = "mach"
version = "0.2.3"
version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "86dd2487cdfea56def77b88438a2c915fb45113c5319bfe7e14306ca4cd0b0e1"
checksum = "b823e83b2affd8f40a9ee8c29dbc56404c1e34cd2710921f2801e2cf29527afa"
dependencies = [
"libc",
]
@@ -1208,9 +1206,9 @@ checksum = "0debeb9fcf88823ea64d64e4a815ab1643f33127d995978e099942ce38f25238"
[[package]]
name = "num-integer"
version = "0.1.42"
version = "0.1.43"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3f6ea62e9d81a77cd3ee9a2a5b9b609447857f3d358704331e4ef39eb247fcba"
checksum = "8d59457e662d541ba17869cf51cf177c0b5f0cbf476c66bdc90bf1edac4f875b"
dependencies = [
"autocfg 1.0.0",
"num-traits",
@@ -1218,9 +1216,9 @@ dependencies = [
[[package]]
name = "num-traits"
version = "0.2.11"
version = "0.2.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c62be47e61d1842b9170f0fdeec8eba98e60e90e5446449a0545e5152acd7096"
checksum = "ac267bcc07f48ee5f8935ab0d24f316fb722d7a1292e2913f0cc196b29ffd611"
dependencies = [
"autocfg 1.0.0",
]
@@ -1253,14 +1251,15 @@ dependencies = [
[[package]]
name = "object"
version = "0.19.0"
source = "git+https://github.com/gimli-rs/object.git#2ad508810e5470f5bcb7ede8d866c8b1eda4c4d3"
version = "0.20.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1ab52be62400ca80aa00285d25253d7f7c437b7375c4de678f5405d3afe82ca5"
[[package]]
name = "once_cell"
version = "1.3.1"
version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b1c601810575c99596d4afc46f78a678c80105117c379eb3650cf99b8a21ce5b"
checksum = "0b631f7e854af39a1739f401cf34a8a013dfe09eac4fa4dba91e9768bd28168d"
[[package]]
name = "opaque-debug"
@@ -1270,9 +1269,9 @@ checksum = "2839e79665f131bdb5782e51f2c6c9599c133c6098982a54c794358bf432529c"
[[package]]
name = "os_pipe"
version = "0.9.1"
version = "0.9.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "db4d06355a7090ce852965b2d08e11426c315438462638c6d721448d0b47aa22"
checksum = "fb233f06c2307e1f5ce2ecad9f8121cffbbee2c95428f44ea85222e460d0d213"
dependencies = [
"libc",
"winapi",
@@ -1312,7 +1311,7 @@ version = "0.2.0"
dependencies = [
"arbitrary",
"bincode",
"env_logger 0.7.1",
"env_logger",
"fst",
"log",
"peepmatic",
@@ -1351,7 +1350,7 @@ dependencies = [
name = "peepmatic-test"
version = "0.2.0"
dependencies = [
"env_logger 0.7.1",
"env_logger",
"log",
"peepmatic",
"peepmatic-runtime",
@@ -1365,9 +1364,9 @@ checksum = "b4596b6d070b27117e987119b4dac604f3c58cfb0b191112e24771b2faeac1a6"
[[package]]
name = "ppv-lite86"
version = "0.2.6"
version = "0.2.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "74490b50b9fbe561ac330df47c08f3f33073d2d00c150f719147d7c54522fa1b"
checksum = "237a5ed80e274dbc66f86bd59c1e25edc039660be53194b5fe0a482e0f2612ea"
[[package]]
name = "pretty_env_logger"
@@ -1375,7 +1374,7 @@ version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "926d36b9553851b8b0005f1275891b392ee4d2d833852c417ed025477350fb9d"
dependencies = [
"env_logger 0.7.1",
"env_logger",
"log",
]
@@ -1407,15 +1406,15 @@ dependencies = [
[[package]]
name = "proc-macro-hack"
version = "0.5.15"
version = "0.5.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0d659fe7c6d27f25e9d80a1a094c223f5246f6a6596453e09d7229bf42750b63"
checksum = "7e0456befd48169b9f13ef0f0ad46d492cf9d2dbb918bcf38e01eed4ce3ec5e4"
[[package]]
name = "proc-macro2"
version = "1.0.10"
version = "1.0.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "df246d292ff63439fea9bc8c0a270bed0e390d5ebd4db4ba15aba81111b5abe3"
checksum = "beae6331a816b1f65d04c45b078fd8e6c93e8071771f41b8163255bbd8d7c8fa"
dependencies = [
"unicode-xid",
]
@@ -1452,7 +1451,7 @@ version = "0.9.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a44883e74aa97ad63db83c4bf8ca490f02b2fc02f92575e720c8551e843c945f"
dependencies = [
"env_logger 0.7.1",
"env_logger",
"log",
"rand 0.7.3",
"rand_core 0.5.1",
@@ -1637,10 +1636,11 @@ dependencies = [
[[package]]
name = "rayon"
version = "1.3.0"
version = "1.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "db6ce3297f9c85e16621bb8cca38a06779ffc31bb8184e1be4bed2be4678a098"
checksum = "62f02856753d04e03e26929f820d0a0a337ebe71f849801eea335d464b349080"
dependencies = [
"autocfg 1.0.0",
"crossbeam-deque",
"either",
"rayon-core",
@@ -1648,9 +1648,9 @@ dependencies = [
[[package]]
name = "rayon-core"
version = "1.7.0"
version = "1.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "08a89b46efaf957e52b18062fb2f4660f8b8a4dde1807ca002690868ef2c85a9"
checksum = "e92e15d89083484e11353891f1af602cc661426deb9564c298b270c726973280"
dependencies = [
"crossbeam-deque",
"crossbeam-queue",
@@ -1699,9 +1699,9 @@ dependencies = [
[[package]]
name = "regex"
version = "1.3.7"
version = "1.3.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a6020f034922e3194c711b82a627453881bc4682166cabb07134a10c26ba7692"
checksum = "9c3780fcf44b193bc4d09f36d2a3c87b251da4a046c87795a0d35f4f927ad8e6"
dependencies = [
"aho-corasick",
"memchr",
@@ -1721,15 +1721,15 @@ dependencies = [
[[package]]
name = "regex-syntax"
version = "0.6.17"
version = "0.6.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7fe5bd57d1d7414c6b5ed48563a2c855d995ff777729dcd91c369ec7fea395ae"
checksum = "26412eb97c6b088a6997e05f69403a802a92d520de2f8e63c2b65f9e0f47c4e8"
[[package]]
name = "region"
version = "2.1.2"
version = "2.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "448e868c6e4cfddfa49b6a72c95906c04e8547465e9536575b95c70a4044f856"
checksum = "877e54ea2adcd70d80e9179344c97f93ef0dffd6b03e1f4529e6e83ab2fa9ae0"
dependencies = [
"bitflags",
"libc",
@@ -1739,9 +1739,9 @@ dependencies = [
[[package]]
name = "remove_dir_all"
version = "0.5.2"
version = "0.5.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4a83fa3702a688b9359eccba92d153ac33fd2e8462f9e0e3fdf155239ea7792e"
checksum = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7"
dependencies = [
"winapi",
]
@@ -1800,9 +1800,9 @@ dependencies = [
[[package]]
name = "ryu"
version = "1.0.4"
version = "1.0.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ed3d612bc64430efeb3f7ee6ef26d590dce0c43249217bddc62112540c7941e1"
checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e"
[[package]]
name = "same-file"
@@ -1830,9 +1830,9 @@ dependencies = [
[[package]]
name = "scroll_derive"
version = "0.10.1"
version = "0.10.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f8584eea9b9ff42825b46faf46a8c24d2cff13ec152fa2a50df788b87c07ee28"
checksum = "e367622f934864ffa1c704ba2b82280aab856e3d8213c84c5720257eb34b15b9"
dependencies = [
"proc-macro2",
"quote",
@@ -1856,18 +1856,18 @@ checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3"
[[package]]
name = "serde"
version = "1.0.106"
version = "1.0.112"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "36df6ac6412072f67cf767ebbde4133a5b2e88e76dc6187fa7104cd16f783399"
checksum = "736aac72d1eafe8e5962d1d1c3d99b0df526015ba40915cb3c49d042e92ec243"
dependencies = [
"serde_derive",
]
[[package]]
name = "serde_derive"
version = "1.0.106"
version = "1.0.112"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9e549e3abf4fb8621bd1609f11dfc9f5e50320802273b12f3811a67e6716ea6c"
checksum = "bf0343ce212ac0d3d6afd9391ac8e9c9efe06b533c8d33f660f6390cc4093f57"
dependencies = [
"proc-macro2",
"quote",
@@ -1876,9 +1876,9 @@ dependencies = [
[[package]]
name = "serde_json"
version = "1.0.52"
version = "1.0.55"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a7894c8ed05b7a3a279aeb79025fdec1d3158080b75b98a08faf2806bb799edd"
checksum = "ec2c5d7e739bc07a3e73381a39d61fdb5f671c60c1df26a130690665803d8226"
dependencies = [
"itoa",
"ryu",
@@ -1887,9 +1887,9 @@ dependencies = [
[[package]]
name = "sha2"
version = "0.8.1"
version = "0.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "27044adfd2e1f077f649f59deb9490d3941d674002f7d062870a60ebe9bd47a0"
checksum = "a256f46ea78a0c0d9ff00077504903ac881a1dafdc20da66545699e7776b3e69"
dependencies = [
"block-buffer",
"digest",
@@ -1965,9 +1965,9 @@ dependencies = [
[[package]]
name = "syn"
version = "1.0.18"
version = "1.0.31"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "410a7488c0a728c7ceb4ad59b9567eb4053d02e8cc7f5c0e0eeeb39518369213"
checksum = "b5304cfdf27365b7585c25d4af91b35016ed21ef88f17ced89c7093b43dba8b6"
dependencies = [
"proc-macro2",
"quote",
@@ -2070,18 +2070,18 @@ dependencies = [
[[package]]
name = "thiserror"
version = "1.0.16"
version = "1.0.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d12a1dae4add0f0d568eebc7bf142f145ba1aa2544cafb195c76f0f409091b60"
checksum = "b13f926965ad00595dd129fa12823b04bbf866e9085ab0a5f2b05b850fbfc344"
dependencies = [
"thiserror-impl",
]
[[package]]
name = "thiserror-impl"
version = "1.0.16"
version = "1.0.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3f34e0c1caaa462fd840ec6b768946ea1e7842620d94fe29d5b847138f521269"
checksum = "893582086c2f98cde18f906265a65b5030a074b1046c674ae898be6519a7f479"
dependencies = [
"proc-macro2",
"quote",
@@ -2239,15 +2239,15 @@ dependencies = [
[[package]]
name = "vec_map"
version = "0.8.1"
version = "0.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "05c78687fb1a80548ae3250346c3db86a80a7cdd77bda190189f2d0a0987c81a"
checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191"
[[package]]
name = "version_check"
version = "0.9.1"
version = "0.9.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "078775d0255232fb988e6fccf26ddc9d1ac274299aaedcedce21c6f72cc533ce"
checksum = "b5a972e5669d67ba988ce3dc826706fb0a8b01471c088cb0b6110b805cc36aed"
[[package]]
name = "wait-timeout"
@@ -2345,7 +2345,7 @@ name = "wasmtime-c-api"
version = "0.18.0"
dependencies = [
"anyhow",
"env_logger 0.7.1",
"env_logger",
"once_cell",
"wasi-common",
"wasmtime",
@@ -2367,14 +2367,14 @@ name = "wasmtime-cli"
version = "0.18.0"
dependencies = [
"anyhow",
"env_logger 0.7.1",
"env_logger",
"file-per-thread-logger",
"filecheck",
"humantime",
"libc",
"log",
"more-asserts",
"object 0.18.0",
"object 0.19.0",
"pretty_env_logger",
"rayon",
"structopt",
@@ -2401,7 +2401,7 @@ dependencies = [
"anyhow",
"gimli",
"more-asserts",
"object 0.18.0",
"object 0.19.0",
"target-lexicon",
"thiserror",
"wasmparser 0.57.0",
@@ -2413,7 +2413,7 @@ name = "wasmtime-environ"
version = "0.18.0"
dependencies = [
"anyhow",
"base64 0.12.0",
"base64 0.12.1",
"bincode",
"cranelift-codegen",
"cranelift-entity",
@@ -2461,7 +2461,7 @@ dependencies = [
"anyhow",
"arbitrary",
"binaryen",
"env_logger 0.7.1",
"env_logger",
"log",
"rayon",
"wasmparser 0.57.0",
@@ -2502,7 +2502,7 @@ version = "0.18.0"
dependencies = [
"anyhow",
"more-asserts",
"object 0.18.0",
"object 0.19.0",
"wasmtime-environ",
]
@@ -2516,7 +2516,7 @@ dependencies = [
"ittapi-rs",
"lazy_static",
"libc",
"object 0.18.0",
"object 0.19.0",
"scroll",
"serde",
"target-lexicon",
@@ -2678,7 +2678,7 @@ dependencies = [
name = "wiggle-test"
version = "0.18.0"
dependencies = [
"env_logger 0.7.1",
"env_logger",
"proptest",
"thiserror",
"tracing",
@@ -2772,18 +2772,18 @@ dependencies = [
[[package]]
name = "zstd"
version = "0.5.1+zstd.1.4.4"
version = "0.5.3+zstd.1.4.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5c5d978b793ae64375b80baf652919b148f6a496ac8802922d9999f5a553194f"
checksum = "01b32eaf771efa709e8308605bbf9319bf485dc1503179ec0469b611937c0cd8"
dependencies = [
"zstd-safe",
]
[[package]]
name = "zstd-safe"
version = "2.0.3+zstd.1.4.4"
version = "2.0.5+zstd.1.4.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bee25eac9753cfedd48133fa1736cbd23b774e253d89badbeac7d12b23848d3f"
checksum = "1cfb642e0d27f64729a639c52db457e0ae906e7bc6f5fe8f5c453230400f1055"
dependencies = [
"libc",
"zstd-sys",
@@ -2791,11 +2791,12 @@ dependencies = [
[[package]]
name = "zstd-sys"
version = "1.4.15+zstd.1.4.4"
version = "1.4.17+zstd.1.4.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "89719b034dc22d240d5b407fb0a3fe6d29952c181cff9a9f95c0bd40b4f8f7d8"
checksum = "b89249644df056b522696b1bb9e7c18c87e8ffa3e2f0dc3b0155875d6498f01b"
dependencies = [
"cc",
"glob",
"itertools 0.9.0",
"libc",
]

View File

@@ -88,5 +88,5 @@ maintenance = { status = "actively-developed" }
name = "host_segfault"
harness = false
[patch.crates-io]
backtrace = { git = "https://github.com/rust-lang/backtrace-rs.git" }
[profile.dev.package.backtrace]
debug = false # FIXME(#1813)

View File

@@ -100,5 +100,6 @@ fn new_module_cache_data() -> Result<ModuleCacheDataTupleType, ()> {
PrimaryMap::new(),
PrimaryMap::new(),
PrimaryMap::new(),
PrimaryMap::new(),
))
}

View File

@@ -221,7 +221,7 @@ impl binemit::StackmapSink for StackMapSink {
impl StackMapSink {
fn finish(mut self) -> Vec<StackMapInformation> {
self.infos.sort_by_key(|info| info.code_offset);
self.infos.sort_unstable_by_key(|info| info.code_offset);
self.infos
}
}

View File

@@ -134,7 +134,7 @@ impl CodeMemory {
if !m.is_empty() {
unsafe {
region::protect(m.as_mut_ptr(), m.len(), region::Protection::ReadExecute)
region::protect(m.as_mut_ptr(), m.len(), region::Protection::READ_EXECUTE)
}
.expect("unable to make memory readonly and executable");
}

View File

@@ -10,7 +10,6 @@ use crate::link::link_module;
use crate::resolver::Resolver;
use std::any::Any;
use std::collections::HashMap;
use std::rc::Rc;
use std::sync::Arc;
use thiserror::Error;
use wasmtime_debug::{read_debuginfo, write_debugsections_image, DwarfSection};
@@ -173,8 +172,8 @@ impl CompiledModule {
mem_creator: Option<&dyn RuntimeMemoryCreator>,
interrupts: Arc<VMInterrupts>,
host_state: Box<dyn Any>,
externref_activations_table: Rc<VMExternRefActivationsTable>,
stack_map_registry: Arc<StackMapRegistry>,
externref_activations_table: *mut VMExternRefActivationsTable,
stack_map_registry: *mut StackMapRegistry,
) -> Result<InstanceHandle, InstantiationError> {
// Compute indices into the shared signature table.
let signatures = {

View File

@@ -21,7 +21,7 @@ indexmap = "1.0.2"
thiserror = "1.0.4"
more-asserts = "0.2.1"
cfg-if = "0.1.9"
backtrace = "0.3.42"
backtrace = "0.3.49"
lazy_static = "1.3.0"
[target.'cfg(target_os = "windows")'.dependencies]

View File

@@ -105,11 +105,11 @@ use std::cell::{Cell, RefCell, UnsafeCell};
use std::cmp::Ordering;
use std::collections::BTreeMap;
use std::collections::HashSet;
use std::hash::Hasher;
use std::hash::{Hash, Hasher};
use std::mem;
use std::ops::Deref;
use std::ptr::{self, NonNull};
use std::sync::{Arc, RwLock};
use std::rc::Rc;
use wasmtime_environ::{ir::Stackmap, StackMapInformation};
/// An external reference to some opaque data.
@@ -337,37 +337,6 @@ impl VMExternRef {
}
}
// /// Turn this `VMExternRef` into a raw, untyped pointer.
// ///
// /// This forgets `self` and does *not* decrement the reference count on the
// /// pointed-to data.
// ///
// /// This `VMExternRef` may be recovered with `VMExternRef::from_raw`.
// pub fn into_raw(self) -> *mut u8 {
// let ptr = self.as_raw();
// mem::forget(self);
// ptr
// }
// /// Recreate a `VMExternRef` from a pointer returned from a previous call to
// /// `VMExternRef::into_raw`.
// ///
// /// # Safety
// ///
// /// Wildly unsafe to use with anything other than the result of a previous
// /// `into_raw` call!
// ///
// /// This method does *not* increment the reference count on the pointed-to
// /// data, so `from_raw` must be called at most *once* on the result of a
// /// previous `into_raw` call. (Ideally, every `into_raw` is later followed
// /// by a `from_raw`, but it is technically memory safe to never call
// /// `from_raw` after `into_raw`: it will leak the pointed-to value, which is
// /// memory safe).
// pub unsafe fn from_raw(ptr: *mut u8) -> Self {
// debug_assert!(!ptr.is_null());
// VMExternRef(NonNull::new_unchecked(ptr).cast())
// }
/// Turn this `VMExternRef` into a raw, untyped pointer.
///
/// Unlike `into_raw`, this does not consume and forget `self`. It is *not*
@@ -379,7 +348,6 @@ impl VMExternRef {
/// `clone_from_raw` is called.
pub fn as_raw(&self) -> *mut u8 {
let ptr = self.0.cast::<u8>().as_ptr();
mem::forget(self);
ptr
}
@@ -401,8 +369,8 @@ impl VMExternRef {
x
}
/// Get the reference count for this `VMExternRef`.
pub fn get_reference_count(&self) -> usize {
/// Get the strong reference count for this `VMExternRef`.
pub fn strong_count(&self) -> usize {
self.extern_data().get_ref_count()
}
@@ -461,6 +429,31 @@ impl Deref for VMExternRef {
}
}
/// A wrapper around a `VMExternRef` that implements `Eq` and `Hash` with
/// pointer semantics.
///
/// We use this so that we can morally put `VMExternRef`s inside of `HashSet`s
/// even though they don't implement `Eq` and `Hash` to avoid foot guns.
#[derive(Clone)]
struct VMExternRefWithTraits(VMExternRef);
impl Hash for VMExternRefWithTraits {
fn hash<H>(&self, hasher: &mut H)
where
H: Hasher,
{
VMExternRef::hash(&self.0, hasher)
}
}
impl PartialEq for VMExternRefWithTraits {
fn eq(&self, other: &Self) -> bool {
VMExternRef::eq(&self.0, &other.0)
}
}
impl Eq for VMExternRefWithTraits {}
type TableElem = UnsafeCell<Option<VMExternRef>>;
/// A table that over-approximizes the set of `VMExternRef`s that any Wasm
@@ -470,35 +463,37 @@ type TableElem = UnsafeCell<Option<VMExternRef>>;
/// entries. Deduplication happens at GC time.
#[repr(C)]
pub struct VMExternRefActivationsTable {
/// Bump-allocation finger within the current chunk.
/// Bump-allocation finger within the `chunk`.
///
/// NB: this is an `UnsafeCell` because it is read from and written to by
/// compiled Wasm code.
/// NB: this is an `UnsafeCell` because it is written to by compiled Wasm
/// code.
next: UnsafeCell<NonNull<TableElem>>,
/// Pointer to just after the current chunk.
/// Pointer to just after the `chunk`.
///
/// This is *not* within the current chunk and therefore is not a valid
/// place to insert a reference!
///
/// This is only updated from host code.
end: Cell<NonNull<TableElem>>,
end: NonNull<TableElem>,
/// The chunks within which we are bump allocating.
/// Bump allocation chunk that stores fast-path insertions.
chunk: Box<[TableElem]>,
/// When unioned with `chunk`, this is an over-approximation of the GC roots
/// on the stack, inside Wasm frames.
///
/// This is only updated from host code.
chunks: RefCell<Vec<Box<[TableElem]>>>,
/// This is used by slow-path insertion, and when a GC cycle finishes, is
/// re-initialized to the just-discovered precise set of stack roots (which
/// immediately becomes an over-approximation again as soon as Wasm runs and
/// potentially drops references).
over_approximated_stack_roots: RefCell<HashSet<VMExternRefWithTraits>>,
/// The precise set of on-stack, inside-Wasm GC roots that we discover via
/// walking the stack and interpreting stack maps.
///
/// That is, this is the precise set that the bump allocation table is
/// over-approximating.
///
/// This is *only* used inside the `gc` function, and is empty otherwise. It
/// is just part of this struct so that we can reuse the allocation, rather
/// than create a new hash set every GC.
precise_stack_roots: RefCell<HashSet<NonNull<VMExternData>>>,
precise_stack_roots: RefCell<HashSet<VMExternRefWithTraits>>,
/// A pointer to a `u8` on the youngest host stack frame before we called
/// into Wasm for the first time. When walking the stack in garbage
@@ -510,119 +505,107 @@ pub struct VMExternRefActivationsTable {
}
impl VMExternRefActivationsTable {
const INITIAL_CHUNK_SIZE: usize = 4096 / mem::size_of::<usize>();
const CHUNK_SIZE: usize = 4096 / mem::size_of::<usize>();
/// Create a new `VMExternRefActivationsTable`.
pub fn new() -> Self {
let chunk = Self::new_chunk(Self::INITIAL_CHUNK_SIZE);
let chunk = Self::new_chunk(Self::CHUNK_SIZE);
let next = chunk.as_ptr() as *mut TableElem;
let end = unsafe { next.add(chunk.len()) };
VMExternRefActivationsTable {
next: UnsafeCell::new(NonNull::new(next).unwrap()),
end: Cell::new(NonNull::new(end).unwrap()),
chunks: RefCell::new(vec![chunk]),
precise_stack_roots: RefCell::new(HashSet::with_capacity(Self::INITIAL_CHUNK_SIZE)),
end: NonNull::new(end).unwrap(),
chunk,
over_approximated_stack_roots: RefCell::new(HashSet::with_capacity(Self::CHUNK_SIZE)),
precise_stack_roots: RefCell::new(HashSet::with_capacity(Self::CHUNK_SIZE)),
stack_canary: Cell::new(None),
}
}
fn new_chunk(size: usize) -> Box<[UnsafeCell<Option<VMExternRef>>]> {
assert!(size >= Self::INITIAL_CHUNK_SIZE);
let mut chunk = Vec::with_capacity(size);
for _ in 0..size {
chunk.push(UnsafeCell::new(None));
}
chunk.into_boxed_slice()
assert!(size >= Self::CHUNK_SIZE);
(0..size).map(|_| UnsafeCell::new(None)).collect()
}
/// Try and insert a `VMExternRef` into this table.
///
/// This is a fast path that only succeeds when the current chunk has the
/// This is a fast path that only succeeds when the bump chunk has the
/// capacity for the requested insertion.
///
/// If the insertion fails, then the `VMExternRef` is given back. Callers
/// may attempt a GC to free up space and try again, or may call
/// `insert_slow_path` to allocate a new bump chunk for this insertion.
/// `insert_slow_path` to infallibly insert the reference (potentially
/// allocating additional space in the table to hold it).
#[inline]
pub fn try_insert(&self, externref: VMExternRef) -> Result<(), VMExternRef> {
unsafe {
let next = *self.next.get();
let end = self.end.get();
if next == end {
if next == self.end {
return Err(externref);
}
debug_assert!((*next.as_ref().get()).is_none());
ptr::write(next.as_ptr(), UnsafeCell::new(Some(externref)));
let next = NonNull::new_unchecked(next.as_ptr().add(1));
debug_assert!(next <= end);
debug_assert!(next <= self.end);
*self.next.get() = next;
Ok(())
}
}
/// This is a slow path for inserting a reference into the table when the
/// current bump chunk is full.
/// Insert a reference into the table, falling back on a GC to clear up
/// space if the table is already full.
///
/// This method is infallible, and will allocate an additional bump chunk if
/// necessary.
#[inline(never)]
pub fn insert_slow_path(&self, externref: VMExternRef) {
let externref = match self.try_insert(externref) {
Ok(()) => return,
Err(x) => x,
};
{
let mut chunks = self.chunks.borrow_mut();
let new_size = chunks.last().unwrap().len() * 2;
let new_chunk = Self::new_chunk(new_size);
unsafe {
let next = new_chunk.as_ptr() as *mut TableElem;
debug_assert!(!next.is_null());
*self.next.get() = NonNull::new_unchecked(next);
let end = next.add(new_chunk.len());
debug_assert!(!end.is_null());
self.end.set(NonNull::new_unchecked(end));
}
chunks.push(new_chunk);
/// # Unsafety
///
/// The same as `gc`.
#[inline]
pub unsafe fn insert_with_gc(
&self,
externref: VMExternRef,
stack_maps_registry: &StackMapRegistry,
) {
if let Err(externref) = self.try_insert(externref) {
self.gc_and_insert_slow(externref, stack_maps_registry);
}
self.try_insert(externref)
.expect("insertion should always succeed after we allocate a new chunk");
}
fn num_filled_in_last_chunk(&self, chunks: &[Box<[TableElem]>]) -> usize {
let last_chunk = chunks.last().unwrap();
#[inline(never)]
unsafe fn gc_and_insert_slow(
&self,
externref: VMExternRef,
stack_maps_registry: &StackMapRegistry,
) {
gc(stack_maps_registry, self);
// Might as well insert right into the hash set, rather than the bump
// chunk, since we are already on a slow path and we get de-duplication
// this way.
let mut roots = self.over_approximated_stack_roots.borrow_mut();
roots.insert(VMExternRefWithTraits(externref));
}
fn num_filled_in_bump_chunk(&self) -> usize {
let next = unsafe { *self.next.get() };
let end = self.end.get();
let num_unused_in_last_chunk =
((end.as_ptr() as usize) - (next.as_ptr() as usize)) / mem::size_of::<usize>();
last_chunk.len().saturating_sub(num_unused_in_last_chunk)
let bytes_unused = (self.end.as_ptr() as usize) - (next.as_ptr() as usize);
let slots_unused = bytes_unused / mem::size_of::<TableElem>();
self.chunk.len().saturating_sub(slots_unused)
}
fn elements(&self, mut f: impl FnMut(&VMExternRef)) {
// Every chunk except the last one is full, so we can simply iterate
// over all of their elements.
let chunks = self.chunks.borrow();
for chunk in chunks.iter().take(chunks.len() - 1) {
for elem in chunk.iter() {
if let Some(elem) = unsafe { &*elem.get() } {
f(elem);
}
}
let roots = self.over_approximated_stack_roots.borrow();
for elem in roots.iter() {
f(&elem.0);
}
// The last chunk is not all the way full, so we only iterate over its
// full parts.
let num_filled_in_last_chunk = self.num_filled_in_last_chunk(&chunks);
for elem in chunks.last().unwrap().iter().take(num_filled_in_last_chunk) {
if let Some(elem) = unsafe { &*elem.get() } {
// The bump chunk is not all the way full, so we only iterate over its
// filled-in slots.
let num_filled = self.num_filled_in_bump_chunk();
for slot in self.chunk.iter().take(num_filled) {
if let Some(elem) = unsafe { &*slot.get() } {
f(elem);
}
}
@@ -630,94 +613,43 @@ impl VMExternRefActivationsTable {
fn insert_precise_stack_root(&self, root: NonNull<VMExternData>) {
let mut precise_stack_roots = self.precise_stack_roots.borrow_mut();
if precise_stack_roots.insert(root) {
// If this root was not already in the set, then we need to
// increment its reference count, so that it doesn't get freed in
// `reset` when we're overwriting old bump allocation table entries
// with new ones.
unsafe {
root.as_ref().increment_ref_count();
}
}
let root = unsafe { VMExternRef::clone_from_raw(root.as_ptr() as *mut _) };
precise_stack_roots.insert(VMExternRefWithTraits(root));
}
/// Refill the bump allocation table with our precise stack roots, and sweep
/// away everything else.
fn reset(&self) {
let mut chunks = self.chunks.borrow_mut();
let mut precise_roots = self.precise_stack_roots.borrow_mut();
if precise_roots.is_empty() {
// Get rid of all but our first bump chunk, and set our `next` and
// `end` bump allocation fingers into it.
unsafe {
let chunk = chunks.first().unwrap();
let next = chunk.as_ptr() as *mut TableElem;
debug_assert!(!next.is_null());
*self.next.get() = NonNull::new_unchecked(next);
let end = next.add(chunk.len());
debug_assert!(!end.is_null());
self.end.set(NonNull::new_unchecked(end));
}
chunks.truncate(1);
} else {
// Drain our precise stack roots into the bump allocation table.
//
// This overwrites old entries, which drops them and decrements their
// reference counts. Safety relies on the reference count increment in
// `insert_precise_stack_root` to avoid over-eagerly dropping references
// that are in `self.precise_stack_roots` but haven't been inserted into
// the bump allocation table yet.
let mut precise_roots = precise_roots.drain();
'outer: for (chunk_index, chunk) in chunks.iter().enumerate() {
for (slot_index, slot) in chunk.iter().enumerate() {
if let Some(root) = precise_roots.next() {
unsafe {
// NB: there is no reference count increment here
// because everything in `self.precise_stack_roots`
// already had its reference count incremented for us,
// and this is logically a move out from there, rather
// than a clone.
*slot.get() = Some(VMExternRef(root));
}
} else {
// We've inserted all of our precise, on-stack roots back
// into the bump allocation table. Update our `next` and
// `end` bump pointer members for the new current chunk, and
// free any excess chunks.
let start = chunk.as_ptr() as *mut TableElem;
unsafe {
let next = start.add(slot_index + 1);
debug_assert!(!next.is_null());
*self.next.get() = NonNull::new_unchecked(next);
let end = start.add(chunk.len());
debug_assert!(!end.is_null());
self.end.set(NonNull::new_unchecked(end));
}
chunks.truncate(chunk_index + 1);
break 'outer;
}
}
}
debug_assert!(
precise_roots.next().is_none(),
"should always have enough capacity in the bump allocations table \
to hold all of our precise, on-stack roots"
);
}
// Finally, sweep away excess capacity within our new last/current
// chunk, so that old, no-longer-live roots get dropped.
let num_filled_in_last_chunk = self.num_filled_in_last_chunk(&chunks);
for slot in chunks.last().unwrap().iter().skip(num_filled_in_last_chunk) {
/// Sweep the bump allocation table after we've discovered our precise stack
/// roots.
fn sweep(&self) {
// Sweep our bump chunk.
let num_filled = self.num_filled_in_bump_chunk();
for slot in self.chunk.iter().take(num_filled) {
unsafe {
*slot.get() = None;
}
}
debug_assert!(
self.chunk
.iter()
.all(|slot| unsafe { (*slot.get()).as_ref().is_none() }),
"after sweeping the bump chunk, all slots should be `None`"
);
// Reset our `next` bump allocation finger.
unsafe {
let next = self.chunk.as_ptr() as *mut TableElem;
debug_assert!(!next.is_null());
*self.next.get() = NonNull::new_unchecked(next);
}
// The current `precise_roots` becomes our new over-appoximated set for
// the next GC cycle.
let mut precise_roots = self.precise_stack_roots.borrow_mut();
let mut over_approximated = self.over_approximated_stack_roots.borrow_mut();
mem::swap(&mut *precise_roots, &mut *over_approximated);
// And finally, the new `precise_roots` should be cleared and remain
// empty until the next GC cycle.
precise_roots.clear();
}
/// Set the stack canary around a call into Wasm.
@@ -739,7 +671,7 @@ impl VMExternRefActivationsTable {
/// ```no_run
/// use wasmtime_runtime::*;
///
/// #let get_table_from_somewhere = || unimplemented!();
/// # let get_table_from_somewhere = || unimplemented!();
/// let table: &VMExternRefActivationsTable = get_table_from_somewhere();
///
/// // Set the canary before a Wasm call. The canary should always be a
@@ -748,7 +680,7 @@ impl VMExternRefActivationsTable {
/// let auto_reset_canary = table.set_stack_canary(&canary);
///
/// // Do the call into Wasm.
/// #let call_into_wasm = || unimplemented!();
/// # let call_into_wasm = || unimplemented!();
/// call_into_wasm();
///
/// // Only drop the value returned by `set_stack_canary` after the Wasm
@@ -791,7 +723,7 @@ impl VMExternRefActivationsTable {
/// A registry of stack maps for currently active Wasm modules.
#[derive(Default)]
pub struct StackMapRegistry {
inner: RwLock<StackMapRegistryInner>,
inner: RefCell<StackMapRegistryInner>,
}
#[derive(Default)]
@@ -804,13 +736,13 @@ struct StackMapRegistryInner {
#[derive(Debug)]
struct ModuleStackMaps {
/// The range of PCs that this module covers. Different modules should
/// always have distinct ranges.
/// The range of PCs that this module covers. Different modules must always
/// have distinct ranges.
range: std::ops::Range<usize>,
/// A map from a PC in this module (that is a GC safepoint) to its
/// associated stack map.
pc_to_stack_map: Vec<(usize, Arc<Stackmap>)>,
pc_to_stack_map: Vec<(usize, Rc<Stackmap>)>,
}
impl StackMapRegistry {
@@ -820,22 +752,10 @@ impl StackMapRegistry {
/// in memory (that is, where the JIT actually allocated and emitted the
/// function's code at), and the stack maps and code offsets within that
/// range for each of its GC safepoints.
///
/// The return value is an RAII registration for the stack maps. The
/// registration should not be dropped until its associated module is
/// dropped. Dropping the registration will unregister its stack
/// maps.
///
/// # Safety
///
/// Dropping the returned registration before the module is dropped, or when
/// there are still active frames from the module on the stack, means we
/// will no longer be able to find GC roots for the module's frames anymore,
/// which could lead to freeing still-in-use objects and use-after-free!
pub unsafe fn register_stack_maps<'a>(
self: &Arc<Self>,
pub fn register_stack_maps<'a>(
&self,
stack_maps: impl IntoIterator<Item = (std::ops::Range<usize>, &'a [StackMapInformation])>,
) -> Option<StackMapRegistration> {
) {
let mut min = usize::max_value();
let mut max = 0;
let mut pc_to_stack_map = vec![];
@@ -850,14 +770,14 @@ impl StackMapRegistry {
assert!((info.code_offset as usize) < len);
pc_to_stack_map.push((
range.start + (info.code_offset as usize),
Arc::new(info.stack_map.clone()),
Rc::new(info.stack_map.clone()),
));
}
}
if pc_to_stack_map.is_empty() {
// Nothing to register.
return None;
return;
}
let module_stack_maps = ModuleStackMaps {
@@ -865,7 +785,17 @@ impl StackMapRegistry {
pc_to_stack_map,
};
let mut inner = self.inner.write().unwrap();
let mut inner = self.inner.borrow_mut();
// Check if we've already registered this module.
if let Some(existing_module) = inner.ranges.get(&max) {
assert_eq!(existing_module.range, module_stack_maps.range);
debug_assert_eq!(
existing_module.pc_to_stack_map,
module_stack_maps.pc_to_stack_map,
);
return;
}
// Assert that this chunk of ranges doesn't collide with any other known
// chunks.
@@ -878,16 +808,11 @@ impl StackMapRegistry {
let old = inner.ranges.insert(max, module_stack_maps);
assert!(old.is_none());
Some(StackMapRegistration {
key: max,
registry: self.clone(),
})
}
/// Lookup the stack map for the given PC, if any.
pub fn lookup_stack_map(&self, pc: usize) -> Option<Arc<Stackmap>> {
let inner = self.inner.read().unwrap();
pub fn lookup_stack_map(&self, pc: usize) -> Option<Rc<Stackmap>> {
let inner = self.inner.borrow();
let stack_maps = inner.module_stack_maps(pc)?;
// Do a binary search to find the stack map for the given PC.
@@ -968,64 +893,36 @@ impl StackMapRegistryInner {
}
}
/// The registration for a module's stack maps.
///
/// Unsafe to drop earlier than its module is dropped. See
/// `StackMapRegistry::register_stack_maps` for details.
pub struct StackMapRegistration {
key: usize,
registry: Arc<StackMapRegistry>,
}
impl Drop for StackMapRegistration {
fn drop(&mut self) {
if let Ok(mut inner) = self.registry.inner.write() {
inner.ranges.remove(&self.key);
}
}
}
#[cfg(debug_assertions)]
#[derive(Debug, Default)]
struct DebugOnly<T> {
inner: T,
}
#[cfg(debug_assertions)]
impl<T> std::ops::Deref for DebugOnly<T> {
type Target = T;
fn deref(&self) -> &T {
&self.inner
if cfg!(debug_assertions) {
&self.inner
} else {
panic!(
"only deref `DebugOnly` when `cfg(debug_assertions)` or \
inside a `debug_assert!(..)`"
)
}
}
}
#[cfg(debug_assertions)]
impl<T> std::ops::DerefMut for DebugOnly<T> {
fn deref_mut(&mut self) -> &mut T {
&mut self.inner
}
}
#[cfg(not(debug_assertions))]
#[derive(Debug, Default)]
struct DebugOnly<T> {
_phantom: PhantomData<T>,
}
#[cfg(not(debug_assertions))]
impl<T> std::ops::Deref for DebugOnly<T> {
type Target = T;
fn deref(&self) -> &T {
panic!("only deref `DebugOnly` inside `debug_assert!`s")
}
}
#[cfg(not(debug_assertions))]
impl<T> std::ops::DerefMut for DebugOnly<T> {
fn deref_mut(&mut self) -> &mut T {
panic!("only deref `DebugOnly` inside `debug_assert!`s")
if cfg!(debug_assertions) {
&mut self.inner
} else {
panic!(
"only deref `DebugOnly` when `cfg(debug_assertions)` or \
inside a `debug_assert!(..)`"
)
}
}
}
@@ -1037,6 +934,9 @@ impl<T> std::ops::DerefMut for DebugOnly<T> {
/// least the oldest host-->Wasm stack frame transition on this thread's stack
/// (it is idempotent to call it more than once) and keep its return value alive
/// across the duration of that host-->Wasm call.
///
/// Additionally, you must have registered the stack maps for every Wasm module
/// that has frames on the stack with the given `stack_maps_registry`.
pub unsafe fn gc(
stack_maps_registry: &StackMapRegistry,
externref_activations_table: &VMExternRefActivationsTable,
@@ -1068,7 +968,7 @@ pub unsafe fn gc(
true
});
}
externref_activations_table.reset();
externref_activations_table.sweep();
log::debug!("end GC");
return;
}
@@ -1086,7 +986,7 @@ pub unsafe fn gc(
// * resetting our bump-allocated table's over-approximation to the
// newly-discovered precise set.
// The SP of the previous frame we processed.
// The SP of the previous (younger) frame we processed.
let mut last_sp = None;
// Whether we have found our stack canary or not yet.
@@ -1109,6 +1009,8 @@ pub unsafe fn gc(
let sp = frame.sp() as usize;
if let Some(stack_map) = stack_maps_registry.lookup_stack_map(pc) {
debug_assert!(sp != 0, "we should always get a valid SP for Wasm frames");
for i in 0..(stack_map.mapped_words() as usize) {
if stack_map.get_bit(i) {
// Stack maps have one bit per word in the frame, and the
@@ -1144,14 +1046,16 @@ pub unsafe fn gc(
!found_canary
});
// Only reset the table if we found the stack canary, and therefore know
// that we discovered all the on-stack, inside-a-Wasm-frame roots. If we did
// *not* find the stack canary, then `libunwind` failed to walk the whole
// stack, and we might be missing roots. Reseting the table would free those
// missing roots while they are still in use, leading to use-after-free.
// Only sweep and reset the table if we found the stack canary, and
// therefore know that we discovered all the on-stack, inside-a-Wasm-frame
// roots. If we did *not* find the stack canary, then `libunwind` failed to
// walk the whole stack, and we might be missing roots. Reseting the table
// would free those missing roots while they are still in use, leading to
// use-after-free.
if found_canary {
externref_activations_table.reset();
externref_activations_table.sweep();
} else {
log::warn!("did not find stack canary; skipping GC sweep");
let mut roots = externref_activations_table.precise_stack_roots.borrow_mut();
roots.clear();
}
@@ -1221,7 +1125,10 @@ mod tests {
num_defined_memories: 0,
num_defined_globals: 0,
};
assert_eq!(offsets.vm_extern_ref_activation_table_next(), actual_offset);
assert_eq!(
offsets.vm_extern_ref_activation_table_next() as usize,
actual_offset
);
}
#[test]
@@ -1244,21 +1151,9 @@ mod tests {
num_defined_memories: 0,
num_defined_globals: 0,
};
assert_eq!(offsets.vm_extern_ref_activation_table_end(), actual_offset);
}
fn assert_is_send<T: Send>() {}
fn assert_is_sync<T: Send>() {}
#[test]
fn stack_map_registry_is_send_sync() {
assert_is_send::<StackMapRegistry>();
assert_is_sync::<StackMapRegistry>();
}
#[test]
fn stack_map_registration_is_send_sync() {
assert_is_send::<StackMapRegistration>();
assert_is_sync::<StackMapRegistration>();
assert_eq!(
offsets.vm_extern_ref_activation_table_end() as usize,
actual_offset
);
}
}

View File

@@ -21,7 +21,6 @@ use std::any::Any;
use std::cell::RefCell;
use std::collections::HashMap;
use std::convert::TryFrom;
use std::rc::Rc;
use std::sync::Arc;
use std::{mem, ptr, slice};
use thiserror::Error;
@@ -74,19 +73,6 @@ pub(crate) struct Instance {
/// interrupted.
pub(crate) interrupts: Arc<VMInterrupts>,
/// A handle to the (over-approximized) set of `externref`s that Wasm code
/// is using.
///
/// The `vmctx` also holds a raw pointer to the table and relies on this
/// member to keep it alive.
pub(crate) externref_activations_table: Rc<VMExternRefActivationsTable>,
/// A handle to the stack map registry for this thread.
///
/// The `vmctx` also holds a raw pointer to the registry and relies on this
/// member to keep it alive.
pub(crate) stack_map_registry: Arc<StackMapRegistry>,
/// Additional context used by compiled wasm code. This field is last, and
/// represents a dynamically-sized array that extends beyond the nominal
/// end of the struct (similar to a flexible array member).
@@ -799,6 +785,10 @@ impl InstanceHandle {
/// internally if you'd like to do so. If possible it's recommended to use
/// the `wasmtime` crate API rather than this type since that is vetted for
/// safety.
///
/// It is your responsibility to ensure that the given raw
/// `externref_activations_table` and `stack_map_registry` outlive this
/// instance.
pub unsafe fn new(
module: Arc<Module>,
code: Arc<dyn Any>,
@@ -809,9 +799,12 @@ impl InstanceHandle {
vmshared_signatures: BoxedSlice<SignatureIndex, VMSharedSignatureIndex>,
host_state: Box<dyn Any>,
interrupts: Arc<VMInterrupts>,
externref_activations_table: Rc<VMExternRefActivationsTable>,
stack_map_registry: Arc<StackMapRegistry>,
externref_activations_table: *mut VMExternRefActivationsTable,
stack_map_registry: *mut StackMapRegistry,
) -> Result<Self, InstantiationError> {
debug_assert!(!externref_activations_table.is_null());
debug_assert!(!stack_map_registry.is_null());
let tables = create_tables(&module);
let memories = create_memories(&module, mem_creator.unwrap_or(&DefaultMemoryCreator {}))?;
@@ -846,8 +839,6 @@ impl InstanceHandle {
trampolines,
host_state,
interrupts,
externref_activations_table,
stack_map_registry,
vmctx: VMContext {},
};
let layout = instance.alloc_layout();
@@ -907,9 +898,8 @@ impl InstanceHandle {
VMBuiltinFunctionsArray::initialized(),
);
*instance.interrupts() = &*instance.interrupts;
*instance.externref_activations_table() =
&*instance.externref_activations_table as *const _ as *mut _;
*instance.stack_map_registry() = &*instance.stack_map_registry as *const _ as *mut _;
*instance.externref_activations_table() = externref_activations_table;
*instance.stack_map_registry() = stack_map_registry;
// Perform infallible initialization in this constructor, while fallible
// initialization is deferred to the `initialize` method.

View File

@@ -182,7 +182,7 @@ impl Mmap {
// Commit the accessible size.
let ptr = self.ptr as *const u8;
unsafe { region::protect(ptr.add(start), len, region::Protection::ReadWrite) }
unsafe { region::protect(ptr.add(start), len, region::Protection::READ_WRITE) }
.map_err(|e| e.to_string())
}

View File

@@ -195,16 +195,9 @@ macro_rules! getters {
let mut ret = None;
$(let $args = $args.into_abi();)*
{
let canary = 0;
let _auto_reset = instance
.store
.externref_activations_table()
.set_stack_canary(&canary);
catch_traps(export.vmctx, &instance.store, || {
ret = Some(fnptr(export.vmctx, ptr::null_mut(), $($args,)*));
})?;
}
invoke_wasm_and_catch_traps(export.vmctx, &instance.store, || {
ret = Some(fnptr(export.vmctx, ptr::null_mut(), $($args,)*));
})?;
Ok(ret.unwrap())
}
@@ -560,23 +553,14 @@ impl Func {
}
// Call the trampoline.
{
let canary = 0;
let _auto_reset = self
.instance
.store
.externref_activations_table()
.set_stack_canary(&canary);
catch_traps(self.export.vmctx, &self.instance.store, || unsafe {
(self.trampoline)(
self.export.vmctx,
ptr::null_mut(),
self.export.address,
values_vec.as_mut_ptr(),
)
})?;
}
invoke_wasm_and_catch_traps(self.export.vmctx, &self.instance.store, || unsafe {
(self.trampoline)(
self.export.vmctx,
ptr::null_mut(),
self.export.address,
values_vec.as_mut_ptr(),
)
})?;
// Load the return values out of `values_vec`.
let mut results = Vec::with_capacity(my_ty.results().len());
@@ -746,13 +730,18 @@ impl fmt::Debug for Func {
}
}
pub(crate) fn catch_traps(
pub(crate) fn invoke_wasm_and_catch_traps(
vmctx: *mut VMContext,
store: &Store,
closure: impl FnMut(),
) -> Result<(), Trap> {
let signalhandler = store.signal_handler();
unsafe {
let canary = 0;
let _auto_reset_canary = store
.externref_activations_table()
.set_stack_canary(&canary);
wasmtime_runtime::catch_traps(
vmctx,
store.engine().config().max_wasm_stack,

View File

@@ -3,13 +3,9 @@ use crate::{Engine, Export, Extern, Func, Global, Memory, Module, Store, Table,
use anyhow::{bail, Error, Result};
use std::any::Any;
use std::mem;
use std::rc::Rc;
use std::sync::Arc;
use wasmtime_environ::EntityIndex;
use wasmtime_jit::{CompiledModule, Resolver};
use wasmtime_runtime::{
InstantiationError, StackMapRegistry, VMContext, VMExternRefActivationsTable, VMFunctionBody,
};
use wasmtime_runtime::{InstantiationError, VMContext, VMFunctionBody};
struct SimpleResolver<'a> {
imports: &'a [Extern],
@@ -28,8 +24,6 @@ fn instantiate(
compiled_module: &CompiledModule,
imports: &[Extern],
host: Box<dyn Any>,
externref_activations_table: Rc<VMExternRefActivationsTable>,
stack_map_registry: Arc<StackMapRegistry>,
) -> Result<StoreInstanceHandle, Error> {
// For now we have a restriction that the `Store` that we're working
// with is the same for everything involved here.
@@ -56,8 +50,8 @@ fn instantiate(
config.memory_creator.as_ref().map(|a| a as _),
store.interrupts().clone(),
host,
externref_activations_table,
stack_map_registry,
&*store.externref_activations_table() as *const _ as *mut _,
&*store.stack_map_registry() as *const _ as *mut _,
)?;
// After we've created the `InstanceHandle` we still need to run
@@ -97,7 +91,7 @@ fn instantiate(
};
let vmctx_ptr = instance.handle.vmctx_ptr();
unsafe {
super::func::catch_traps(vmctx_ptr, store, || {
super::func::invoke_wasm_and_catch_traps(vmctx_ptr, store, || {
mem::transmute::<
*const VMFunctionBody,
unsafe extern "C" fn(*mut VMContext, *mut VMContext),
@@ -194,24 +188,11 @@ impl Instance {
let host_info = Box::new({
let frame_info_registration = module.register_frame_info();
store.register_jit_code(module.compiled_module().jit_code_ranges());
// We need to make sure that we keep this alive as long as the instance
// is alive, or else we could miss GC roots, reclaim objects too early,
// and get user-after-frees.
let stack_map_registration =
unsafe { module.register_stack_maps(&*store.stack_map_registry()) };
(frame_info_registration, stack_map_registration)
store.register_stack_maps(&module);
frame_info_registration
});
let handle = instantiate(
store,
module.compiled_module(),
imports,
host_info,
store.externref_activations_table().clone(),
store.stack_map_registry().clone(),
)?;
let handle = instantiate(store, module.compiled_module(), imports, host_info)?;
Ok(Instance {
handle,

View File

@@ -6,7 +6,6 @@ use std::path::Path;
use std::sync::{Arc, Mutex};
use wasmparser::validate;
use wasmtime_jit::CompiledModule;
use wasmtime_runtime::{StackMapRegistration, StackMapRegistry};
/// A compiled WebAssembly module, ready to be instantiated.
///
@@ -81,7 +80,6 @@ pub struct Module {
engine: Engine,
compiled: Arc<CompiledModule>,
frame_info_registration: Arc<Mutex<Option<Option<Arc<GlobalFrameInfoRegistration>>>>>,
stack_map_registration: Arc<Mutex<Option<Option<Arc<StackMapRegistration>>>>>,
}
impl Module {
@@ -309,7 +307,6 @@ impl Module {
engine: engine.clone(),
compiled: Arc::new(compiled),
frame_info_registration: Arc::new(Mutex::new(None)),
stack_map_registration: Arc::new(Mutex::new(None)),
})
}
@@ -537,41 +534,6 @@ impl Module {
*info = Some(ret.clone());
return ret;
}
/// Register this module's stack maps.
///
/// # Safety
///
/// The same as `wasmtime_runtime::StackMapRegistry::register_stack_maps`.
pub(crate) unsafe fn register_stack_maps(
&self,
registry: &Arc<StackMapRegistry>,
) -> Option<Arc<StackMapRegistration>> {
let mut registration = self.stack_map_registration.lock().unwrap();
if let Some(registration) = &*registration {
return registration.clone();
}
let module = &self.compiled;
let ret = registry
.register_stack_maps(
module
.finished_functions()
.values()
.zip(module.stack_maps().values())
.map(|(func, stack_maps)| {
let ptr = (**func).as_ptr();
let len = (**func).len();
let start = ptr as usize;
let end = ptr as usize + len;
let range = start..end;
(range, &stack_maps[..])
}),
)
.map(Arc::new);
*registration = Some(ret.clone());
ret
}
}
fn _assert_send_sync() {

6
crates/wasmtime/src/ref.rs Executable file → Normal file
View File

@@ -36,9 +36,9 @@ impl ExternRef {
&*self.inner
}
/// Get the reference count for this `ExternRef`.
pub fn get_reference_count(&self) -> usize {
self.inner.get_reference_count()
/// Get the strong reference count for this `ExternRef`.
pub fn strong_count(&self) -> usize {
self.inner.strong_count()
}
/// Does this `ExternRef` point to the same inner value as `other`?0

View File

@@ -1,6 +1,7 @@
use crate::externals::MemoryCreator;
use crate::r#ref::ExternRef;
use crate::trampoline::{MemoryCreatorProxy, StoreInstanceHandle};
use crate::Module;
use anyhow::{bail, Result};
use std::any::Any;
use std::cell::RefCell;
@@ -14,7 +15,7 @@ use std::rc::{Rc, Weak};
use std::sync::Arc;
use wasmparser::{OperatorValidatorConfig, ValidatingParserConfig};
use wasmtime_environ::settings::{self, Configurable};
use wasmtime_environ::{ir, wasm, CacheConfig, Tunables};
use wasmtime_environ::{ir, isa::TargetIsa, wasm, CacheConfig, Tunables};
use wasmtime_jit::{native, CompilationStrategy, Compiler};
use wasmtime_profiling::{JitDumpAgent, NullProfilerAgent, ProfilingAgent, VTuneAgent};
use wasmtime_runtime::{
@@ -195,6 +196,7 @@ impl Config {
self.validating_config
.operator_config
.enable_reference_types = enable;
self.flags
.set("enable_safepoints", if enable { "true" } else { "false" })
.unwrap();
@@ -597,8 +599,12 @@ impl Config {
self
}
pub(crate) fn target_isa(&self) -> Box<dyn TargetIsa> {
native::builder().finish(settings::Flags::new(self.flags.clone()))
}
fn build_compiler(&self) -> Compiler {
let isa = native::builder().finish(settings::Flags::new(self.flags.clone()));
let isa = self.target_isa();
Compiler::new(
isa,
self.strategy,
@@ -730,7 +736,6 @@ pub struct Engine {
struct EngineInner {
config: Config,
compiler: Compiler,
stack_map_registry: Arc<StackMapRegistry>,
}
impl Engine {
@@ -742,7 +747,6 @@ impl Engine {
inner: Arc::new(EngineInner {
config: config.clone(),
compiler: config.build_compiler(),
stack_map_registry: Arc::new(StackMapRegistry::default()),
}),
}
}
@@ -801,7 +805,7 @@ pub(crate) struct StoreInner {
jit_code_ranges: RefCell<Vec<(usize, usize)>>,
host_info: RefCell<HashMap<HostInfoKey, Rc<RefCell<dyn Any>>>>,
externref_activations_table: Rc<VMExternRefActivationsTable>,
stack_map_registry: Arc<StackMapRegistry>,
stack_map_registry: Rc<StackMapRegistry>,
}
struct HostInfoKey(VMExternRef);
@@ -843,7 +847,7 @@ impl Store {
jit_code_ranges: RefCell::new(Vec::new()),
host_info: RefCell::new(HashMap::new()),
externref_activations_table: Rc::new(VMExternRefActivationsTable::new()),
stack_map_registry: engine.inner.stack_map_registry.clone(),
stack_map_registry: Rc::new(StackMapRegistry::default()),
}),
}
}
@@ -916,6 +920,24 @@ impl Store {
}
}
pub(crate) fn register_stack_maps(&self, module: &Module) {
let module = &module.compiled_module();
self.stack_map_registry().register_stack_maps(
module
.finished_functions()
.values()
.zip(module.stack_maps().values())
.map(|(func, stack_maps)| unsafe {
let ptr = (**func).as_ptr();
let len = (**func).len();
let start = ptr as usize;
let end = ptr as usize + len;
let range = start..end;
(range, &stack_maps[..])
}),
);
}
pub(crate) unsafe fn add_instance(&self, handle: InstanceHandle) -> StoreInstanceHandle {
self.inner.instances.borrow_mut().push(handle.clone());
StoreInstanceHandle {
@@ -1091,14 +1113,15 @@ impl Store {
&self.inner.externref_activations_table
}
pub(crate) fn stack_map_registry(&self) -> &Arc<StackMapRegistry> {
&self.inner.engine.inner.stack_map_registry
pub(crate) fn stack_map_registry(&self) -> &Rc<StackMapRegistry> {
&self.inner.stack_map_registry
}
/// Perform garbage collection of `ExternRef`s.
pub fn gc(&self) {
// For this crate's API, we ensure that `set_stack_canary` invariants
// are upheld for all host-->Wasm calls.
// are upheld for all host-->Wasm calls, and we register every module
// used with this store in `self.inner.stack_map_registry`.
unsafe {
wasmtime_runtime::gc(
&*self.inner.stack_map_registry,

View File

@@ -46,8 +46,8 @@ pub(crate) fn create_handle(
signatures.into_boxed_slice(),
state,
store.interrupts().clone(),
store.externref_activations_table().clone(),
store.stack_map_registry().clone(),
&*store.externref_activations_table() as *const _ as *mut _,
&*store.stack_map_registry() as *const _ as *mut _,
)?;
Ok(store.add_instance(handle))
}

View File

@@ -2,7 +2,7 @@
use super::create_handle::create_handle;
use crate::trampoline::StoreInstanceHandle;
use crate::{FuncType, Store, Trap, ValType};
use crate::{FuncType, Store, Trap};
use anyhow::{bail, Result};
use std::any::Any;
use std::cmp;
@@ -11,9 +11,7 @@ use std::mem;
use std::panic::{self, AssertUnwindSafe};
use wasmtime_environ::entity::PrimaryMap;
use wasmtime_environ::isa::TargetIsa;
use wasmtime_environ::{
ir, settings, settings::Configurable, CompiledFunction, EntityIndex, Module,
};
use wasmtime_environ::{ir, settings, CompiledFunction, EntityIndex, Module};
use wasmtime_jit::trampoline::ir::{
ExternalName, Function, InstBuilder, MemFlags, StackSlotData, StackSlotKind,
};
@@ -210,18 +208,7 @@ pub fn create_handle_with_function(
func: Box<dyn Fn(*mut VMContext, *mut u128) -> Result<(), Trap>>,
store: &Store,
) -> Result<(StoreInstanceHandle, VMTrampoline)> {
let isa = {
let isa_builder = native::builder();
let mut flag_builder = settings::builder();
if ft.params().iter().any(|p| *p == ValType::ExternRef)
|| ft.results().iter().any(|r| *r == ValType::ExternRef)
{
flag_builder.set("enable_safepoints", "true").unwrap();
}
isa_builder.finish(settings::Flags::new(flag_builder))
};
let isa = store.engine().config().target_isa();
let pointer_type = isa.pointer_type();
let sig = match ft.get_wasmtime_signature(pointer_type) {

View File

@@ -106,7 +106,10 @@ impl ValType {
ValType::F32 => Some(ir::types::F32),
ValType::F64 => Some(ir::types::F64),
ValType::V128 => Some(ir::types::I8X16),
#[cfg(target_pointer_width = "64")]
ValType::ExternRef => Some(ir::types::R64),
#[cfg(target_pointer_width = "32")]
ValType::ExternRef => Some(ir::types::R32),
_ => None,
}
}
@@ -118,7 +121,10 @@ impl ValType {
ir::types::F32 => Some(ValType::F32),
ir::types::F64 => Some(ValType::F64),
ir::types::I8X16 => Some(ValType::V128),
#[cfg(target_pointer_width = "64")]
ir::types::R64 => Some(ValType::ExternRef),
#[cfg(target_pointer_width = "32")]
ir::types::R32 => Some(ValType::ExternRef),
_ => None,
}
}

View File

@@ -89,10 +89,9 @@ impl Val {
Val::ExternRef(None) => ptr::write(p, 0),
Val::ExternRef(Some(x)) => {
let externref_ptr = x.inner.as_raw();
if let Err(inner) = store.externref_activations_table().try_insert(x.inner) {
store.gc();
store.externref_activations_table().insert_slow_path(inner);
}
store
.externref_activations_table()
.insert_with_gc(x.inner, store.stack_map_registry());
ptr::write(p as *mut *mut u8, externref_ptr)
}
_ => unimplemented!("Val::write_value_to"),

View File

@@ -59,12 +59,12 @@ fn smoke_test_gc() -> anyhow::Result<()> {
// Still held alive by the `VMExternRefActivationsTable` (potentially in
// multiple slots within the table) and by this `r` local.
assert!(r.get_reference_count() >= 2);
assert!(r.strong_count() >= 2);
// Doing a GC should see that there aren't any `externref`s on the stack in
// Wasm frames anymore.
store.gc();
assert_eq!(r.get_reference_count(), 1);
assert_eq!(r.strong_count(), 1);
// Dropping `r` should drop the inner `SetFlagOnDrop` value.
drop(r);