Bug 1608941 - Bump cranelift to b01bee7c5269f72196b42e8bdd874425166bf429. r=bbouvier

Differential Revision: https://phabricator.services.mozilla.com/D60271

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Ryan Hunt 2020-01-20 13:21:55 +00:00
Родитель 1aa9918367
Коммит 6dd534025d
97 изменённых файлов: 7228 добавлений и 2995 удалений

Просмотреть файл

@ -40,7 +40,7 @@ rev = "8069f8f4189982e0b38fa6dc8993dd4fab41f728"
[source."https://github.com/bytecodealliance/cranelift"]
git = "https://github.com/bytecodealliance/cranelift"
replace-with = "vendored-sources"
rev = "ec787eb281bb2e18e191508c17abe694e91f0677"
rev = "b01bee7c5269f72196b42e8bdd874425166bf429"
[source."https://github.com/badboy/failure"]
git = "https://github.com/badboy/failure"

84
Cargo.lock сгенерированный
Просмотреть файл

@ -178,8 +178,8 @@ name = "baldrdash"
version = "0.1.0"
dependencies = [
"bindgen 0.51.1 (registry+https://github.com/rust-lang/crates.io-index)",
"cranelift-codegen 0.51.0 (git+https://github.com/bytecodealliance/cranelift?rev=ec787eb281bb2e18e191508c17abe694e91f0677)",
"cranelift-wasm 0.51.0 (git+https://github.com/bytecodealliance/cranelift?rev=ec787eb281bb2e18e191508c17abe694e91f0677)",
"cranelift-codegen 0.55.0 (git+https://github.com/bytecodealliance/cranelift?rev=b01bee7c5269f72196b42e8bdd874425166bf429)",
"cranelift-wasm 0.55.0 (git+https://github.com/bytecodealliance/cranelift?rev=b01bee7c5269f72196b42e8bdd874425166bf429)",
"env_logger 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
"smallvec 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
@ -635,41 +635,41 @@ dependencies = [
[[package]]
name = "cranelift-bforest"
version = "0.51.0"
source = "git+https://github.com/bytecodealliance/cranelift?rev=ec787eb281bb2e18e191508c17abe694e91f0677#ec787eb281bb2e18e191508c17abe694e91f0677"
version = "0.55.0"
source = "git+https://github.com/bytecodealliance/cranelift?rev=b01bee7c5269f72196b42e8bdd874425166bf429#b01bee7c5269f72196b42e8bdd874425166bf429"
dependencies = [
"cranelift-entity 0.51.0 (git+https://github.com/bytecodealliance/cranelift?rev=ec787eb281bb2e18e191508c17abe694e91f0677)",
"cranelift-entity 0.55.0 (git+https://github.com/bytecodealliance/cranelift?rev=b01bee7c5269f72196b42e8bdd874425166bf429)",
]
[[package]]
name = "cranelift-codegen"
version = "0.51.0"
source = "git+https://github.com/bytecodealliance/cranelift?rev=ec787eb281bb2e18e191508c17abe694e91f0677#ec787eb281bb2e18e191508c17abe694e91f0677"
version = "0.55.0"
source = "git+https://github.com/bytecodealliance/cranelift?rev=b01bee7c5269f72196b42e8bdd874425166bf429#b01bee7c5269f72196b42e8bdd874425166bf429"
dependencies = [
"byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
"cranelift-bforest 0.51.0 (git+https://github.com/bytecodealliance/cranelift?rev=ec787eb281bb2e18e191508c17abe694e91f0677)",
"cranelift-codegen-meta 0.51.0 (git+https://github.com/bytecodealliance/cranelift?rev=ec787eb281bb2e18e191508c17abe694e91f0677)",
"cranelift-codegen-shared 0.51.0 (git+https://github.com/bytecodealliance/cranelift?rev=ec787eb281bb2e18e191508c17abe694e91f0677)",
"cranelift-entity 0.51.0 (git+https://github.com/bytecodealliance/cranelift?rev=ec787eb281bb2e18e191508c17abe694e91f0677)",
"cranelift-bforest 0.55.0 (git+https://github.com/bytecodealliance/cranelift?rev=b01bee7c5269f72196b42e8bdd874425166bf429)",
"cranelift-codegen-meta 0.55.0 (git+https://github.com/bytecodealliance/cranelift?rev=b01bee7c5269f72196b42e8bdd874425166bf429)",
"cranelift-codegen-shared 0.55.0 (git+https://github.com/bytecodealliance/cranelift?rev=b01bee7c5269f72196b42e8bdd874425166bf429)",
"cranelift-entity 0.55.0 (git+https://github.com/bytecodealliance/cranelift?rev=b01bee7c5269f72196b42e8bdd874425166bf429)",
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
"smallvec 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"target-lexicon 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
"target-lexicon 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)",
"thiserror 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "cranelift-codegen-meta"
version = "0.51.0"
source = "git+https://github.com/bytecodealliance/cranelift?rev=ec787eb281bb2e18e191508c17abe694e91f0677#ec787eb281bb2e18e191508c17abe694e91f0677"
version = "0.55.0"
source = "git+https://github.com/bytecodealliance/cranelift?rev=b01bee7c5269f72196b42e8bdd874425166bf429#b01bee7c5269f72196b42e8bdd874425166bf429"
dependencies = [
"cranelift-codegen-shared 0.51.0 (git+https://github.com/bytecodealliance/cranelift?rev=ec787eb281bb2e18e191508c17abe694e91f0677)",
"cranelift-entity 0.51.0 (git+https://github.com/bytecodealliance/cranelift?rev=ec787eb281bb2e18e191508c17abe694e91f0677)",
"cranelift-codegen-shared 0.55.0 (git+https://github.com/bytecodealliance/cranelift?rev=b01bee7c5269f72196b42e8bdd874425166bf429)",
"cranelift-entity 0.55.0 (git+https://github.com/bytecodealliance/cranelift?rev=b01bee7c5269f72196b42e8bdd874425166bf429)",
]
[[package]]
name = "cranelift-codegen-shared"
version = "0.51.0"
source = "git+https://github.com/bytecodealliance/cranelift?rev=ec787eb281bb2e18e191508c17abe694e91f0677#ec787eb281bb2e18e191508c17abe694e91f0677"
version = "0.55.0"
source = "git+https://github.com/bytecodealliance/cranelift?rev=b01bee7c5269f72196b42e8bdd874425166bf429#b01bee7c5269f72196b42e8bdd874425166bf429"
[[package]]
name = "cranelift-entity"
@ -678,31 +678,31 @@ source = "git+https://github.com/PLSysSec/lucet_sandbox_compiler?rev=58498599272
[[package]]
name = "cranelift-entity"
version = "0.51.0"
source = "git+https://github.com/bytecodealliance/cranelift?rev=ec787eb281bb2e18e191508c17abe694e91f0677#ec787eb281bb2e18e191508c17abe694e91f0677"
version = "0.55.0"
source = "git+https://github.com/bytecodealliance/cranelift?rev=b01bee7c5269f72196b42e8bdd874425166bf429#b01bee7c5269f72196b42e8bdd874425166bf429"
[[package]]
name = "cranelift-frontend"
version = "0.51.0"
source = "git+https://github.com/bytecodealliance/cranelift?rev=ec787eb281bb2e18e191508c17abe694e91f0677#ec787eb281bb2e18e191508c17abe694e91f0677"
version = "0.55.0"
source = "git+https://github.com/bytecodealliance/cranelift?rev=b01bee7c5269f72196b42e8bdd874425166bf429#b01bee7c5269f72196b42e8bdd874425166bf429"
dependencies = [
"cranelift-codegen 0.51.0 (git+https://github.com/bytecodealliance/cranelift?rev=ec787eb281bb2e18e191508c17abe694e91f0677)",
"cranelift-codegen 0.55.0 (git+https://github.com/bytecodealliance/cranelift?rev=b01bee7c5269f72196b42e8bdd874425166bf429)",
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
"smallvec 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"target-lexicon 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
"target-lexicon 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "cranelift-wasm"
version = "0.51.0"
source = "git+https://github.com/bytecodealliance/cranelift?rev=ec787eb281bb2e18e191508c17abe694e91f0677#ec787eb281bb2e18e191508c17abe694e91f0677"
version = "0.55.0"
source = "git+https://github.com/bytecodealliance/cranelift?rev=b01bee7c5269f72196b42e8bdd874425166bf429#b01bee7c5269f72196b42e8bdd874425166bf429"
dependencies = [
"cranelift-codegen 0.51.0 (git+https://github.com/bytecodealliance/cranelift?rev=ec787eb281bb2e18e191508c17abe694e91f0677)",
"cranelift-entity 0.51.0 (git+https://github.com/bytecodealliance/cranelift?rev=ec787eb281bb2e18e191508c17abe694e91f0677)",
"cranelift-frontend 0.51.0 (git+https://github.com/bytecodealliance/cranelift?rev=ec787eb281bb2e18e191508c17abe694e91f0677)",
"cranelift-codegen 0.55.0 (git+https://github.com/bytecodealliance/cranelift?rev=b01bee7c5269f72196b42e8bdd874425166bf429)",
"cranelift-entity 0.55.0 (git+https://github.com/bytecodealliance/cranelift?rev=b01bee7c5269f72196b42e8bdd874425166bf429)",
"cranelift-frontend 0.55.0 (git+https://github.com/bytecodealliance/cranelift?rev=b01bee7c5269f72196b42e8bdd874425166bf429)",
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
"thiserror 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
"wasmparser 0.39.2 (registry+https://github.com/rust-lang/crates.io-index)",
"wasmparser 0.47.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@ -3800,6 +3800,11 @@ name = "target-lexicon"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "target-lexicon"
version = "0.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "tempfile"
version = "3.1.0"
@ -4291,7 +4296,7 @@ dependencies = [
[[package]]
name = "wasmparser"
version = "0.39.2"
version = "0.47.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
@ -4695,14 +4700,14 @@ dependencies = [
"checksum coreaudio-sys-utils 0.1.0 (git+https://github.com/ChunMinChang/cubeb-coreaudio-rs?rev=acb90e9bf36e6e035ac6bbe51efa0a8825b5b6be)" = "<none>"
"checksum cose 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "72fa26cb151d3ae4b70f63d67d0fed57ce04220feafafbae7f503bef7aae590d"
"checksum cose-c 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "49726015ab0ca765144fcca61e4a7a543a16b795a777fa53f554da2fffff9a94"
"checksum cranelift-bforest 0.51.0 (git+https://github.com/bytecodealliance/cranelift?rev=ec787eb281bb2e18e191508c17abe694e91f0677)" = "<none>"
"checksum cranelift-codegen 0.51.0 (git+https://github.com/bytecodealliance/cranelift?rev=ec787eb281bb2e18e191508c17abe694e91f0677)" = "<none>"
"checksum cranelift-codegen-meta 0.51.0 (git+https://github.com/bytecodealliance/cranelift?rev=ec787eb281bb2e18e191508c17abe694e91f0677)" = "<none>"
"checksum cranelift-codegen-shared 0.51.0 (git+https://github.com/bytecodealliance/cranelift?rev=ec787eb281bb2e18e191508c17abe694e91f0677)" = "<none>"
"checksum cranelift-bforest 0.55.0 (git+https://github.com/bytecodealliance/cranelift?rev=b01bee7c5269f72196b42e8bdd874425166bf429)" = "<none>"
"checksum cranelift-codegen 0.55.0 (git+https://github.com/bytecodealliance/cranelift?rev=b01bee7c5269f72196b42e8bdd874425166bf429)" = "<none>"
"checksum cranelift-codegen-meta 0.55.0 (git+https://github.com/bytecodealliance/cranelift?rev=b01bee7c5269f72196b42e8bdd874425166bf429)" = "<none>"
"checksum cranelift-codegen-shared 0.55.0 (git+https://github.com/bytecodealliance/cranelift?rev=b01bee7c5269f72196b42e8bdd874425166bf429)" = "<none>"
"checksum cranelift-entity 0.41.0 (git+https://github.com/PLSysSec/lucet_sandbox_compiler?rev=58498599272e23ef797bb4304d0f181d7455ca57)" = "<none>"
"checksum cranelift-entity 0.51.0 (git+https://github.com/bytecodealliance/cranelift?rev=ec787eb281bb2e18e191508c17abe694e91f0677)" = "<none>"
"checksum cranelift-frontend 0.51.0 (git+https://github.com/bytecodealliance/cranelift?rev=ec787eb281bb2e18e191508c17abe694e91f0677)" = "<none>"
"checksum cranelift-wasm 0.51.0 (git+https://github.com/bytecodealliance/cranelift?rev=ec787eb281bb2e18e191508c17abe694e91f0677)" = "<none>"
"checksum cranelift-entity 0.55.0 (git+https://github.com/bytecodealliance/cranelift?rev=b01bee7c5269f72196b42e8bdd874425166bf429)" = "<none>"
"checksum cranelift-frontend 0.55.0 (git+https://github.com/bytecodealliance/cranelift?rev=b01bee7c5269f72196b42e8bdd874425166bf429)" = "<none>"
"checksum cranelift-wasm 0.55.0 (git+https://github.com/bytecodealliance/cranelift?rev=b01bee7c5269f72196b42e8bdd874425166bf429)" = "<none>"
"checksum crc32fast 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ba125de2af0df55319f41944744ad91c71113bf74a4646efff39afe1f6842db1"
"checksum crossbeam-deque 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c3aa945d63861bfe624b55d153a39684da1e8c0bc8fba932f7ee3a3c16cea3ca"
"checksum crossbeam-epoch 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5064ebdbf05ce3cb95e45c8b086f72263f4166b29b97f6baff7ef7fe047b55ac"
@ -4966,6 +4971,7 @@ dependencies = [
"checksum svg_fmt 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c666f0fed8e1e20e057af770af9077d72f3d5a33157b8537c1475dd8ffd6d32b"
"checksum syn 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "66850e97125af79138385e9b88339cbcd037e3f28ceab8c5ad98e64f0f1f80bf"
"checksum synstructure 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3f085a5855930c0441ca1288cf044ea4aecf4f43a91668abdb870b4ba546a203"
"checksum target-lexicon 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ab0e7238dcc7b40a7be719a25365910f6807bd864f4cce6b2e6b873658e2b19d"
"checksum target-lexicon 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6f4c118a7a38378f305a9e111fcb2f7f838c0be324bfb31a77ea04f7f6e684b4"
"checksum tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6e24d9338a0a5be79593e2fa15a648add6138caa803e2d5bc782c371732ca9"
"checksum term_size 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e2b6b55df3198cc93372e85dd2ed817f0e38ce8cc0f22eb32391bfad9c4bf209"
@ -5018,7 +5024,7 @@ dependencies = [
"checksum walkdir 2.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "63636bd0eb3d00ccb8b9036381b526efac53caf112b7783b730ab3f8e44da369"
"checksum want 0.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "797464475f30ddb8830cc529aaaae648d581f99e2036a928877dfde027ddf6b3"
"checksum warp 0.1.19 (registry+https://github.com/rust-lang/crates.io-index)" = "33857527c63bc514452f885d0a57019f28139c58fef2b3566016ecc0d44e5d24"
"checksum wasmparser 0.39.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e5083b449454f7de0b15f131eee17de54b5a71dcb9adcf11df2b2f78fad0cd82"
"checksum wasmparser 0.47.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1add8db5a53a2f64f13418b241982c4ab533d7a9e1e8a5dcadccce633d8d393b"
"checksum webrtc-sdp 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "75fb1417c7262d8bdc0f0a2b0e32607675c9315dcbb6fccfdf75ece04e01326a"
"checksum weedle 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "26a4c67f132386d965390b8a734d5d10adbcd30eb5cc74bd9229af8b83f10044"
"checksum winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a"

Просмотреть файл

@ -71,8 +71,8 @@ failure_derive = { git = "https://github.com/badboy/failure", rev = "64af847bc5f
[patch.crates-io.cranelift-codegen]
git = "https://github.com/bytecodealliance/cranelift"
rev = "ec787eb281bb2e18e191508c17abe694e91f0677"
rev = "b01bee7c5269f72196b42e8bdd874425166bf429"
[patch.crates-io.cranelift-wasm]
git = "https://github.com/bytecodealliance/cranelift"
rev = "ec787eb281bb2e18e191508c17abe694e91f0677"
rev = "b01bee7c5269f72196b42e8bdd874425166bf429"

Просмотреть файл

@ -13,8 +13,8 @@ name = "baldrdash"
# cranelift-wasm to pinned commits. If you want to update Cranelift in Gecko,
# you should update the following $TOP_LEVEL/Cargo.toml file: look for the
# revision (rev) hashes of both cranelift dependencies (codegen and wasm).
cranelift-codegen = { version = "0.51", default-features = false }
cranelift-wasm = "0.51"
cranelift-codegen = { version = "0.55", default-features = false }
cranelift-wasm = "0.55"
log = { version = "0.4.6", default-features = false, features = ["release_max_level_info"] }
env_logger = "0.6"
smallvec = "1.0"

Просмотреть файл

@ -1 +1 @@
{"files":{"Cargo.toml":"abc61ed8d3d7e08b1d8f5f92e60bb76d1917d2db5b797f82b9b9ff144e6ae4c4","LICENSE":"268872b9816f90fd8e85db5a28d33f8150ebb8dd016653fb39ef1f94f2686bc5","README.md":"af367c67340fa7f6fb9a35b0aa637dcf303957f7ae7427a5f4f6356801c8bb04","src/lib.rs":"59933214e5213d003d98c6fa5f22c3c863557640189588d989ff0335b006af9a","src/map.rs":"a3b7f64cae7ec9c2a8038def315bcf90e8751552b1bc1c20b62fbb8c763866c4","src/node.rs":"28f7edd979f7b9712bc4ab30b0d2a1b8ad5485a4b1e8c09f3dcaf501b9b5ccd1","src/path.rs":"a86ee1c882c173e8af96fd53a416a0fb485dd3f045ac590ef313a9d9ecf90f56","src/pool.rs":"f6337b5417f7772e6878a160c1a40629199ff09997bdff18eb2a0ba770158600","src/set.rs":"281eb8b5ead1ffd395946464d881f9bb0e7fb61092aed701d72d2314b5f80994"},"package":null}
{"files":{"Cargo.toml":"d47e794d642207dbd9f09c345a5d35382cd0a426c510fded00422bde9f1c5fb7","LICENSE":"268872b9816f90fd8e85db5a28d33f8150ebb8dd016653fb39ef1f94f2686bc5","README.md":"af367c67340fa7f6fb9a35b0aa637dcf303957f7ae7427a5f4f6356801c8bb04","src/lib.rs":"59933214e5213d003d98c6fa5f22c3c863557640189588d989ff0335b006af9a","src/map.rs":"a3b7f64cae7ec9c2a8038def315bcf90e8751552b1bc1c20b62fbb8c763866c4","src/node.rs":"28f7edd979f7b9712bc4ab30b0d2a1b8ad5485a4b1e8c09f3dcaf501b9b5ccd1","src/path.rs":"a86ee1c882c173e8af96fd53a416a0fb485dd3f045ac590ef313a9d9ecf90f56","src/pool.rs":"f6337b5417f7772e6878a160c1a40629199ff09997bdff18eb2a0ba770158600","src/set.rs":"281eb8b5ead1ffd395946464d881f9bb0e7fb61092aed701d72d2314b5f80994"},"package":null}

Просмотреть файл

@ -1,7 +1,7 @@
[package]
authors = ["The Cranelift Project Developers"]
name = "cranelift-bforest"
version = "0.51.0"
version = "0.55.0"
description = "A forest of B+-trees"
license = "Apache-2.0 WITH LLVM-exception"
documentation = "https://cranelift.readthedocs.io/"
@ -12,7 +12,7 @@ keywords = ["btree", "forest", "set", "map"]
edition = "2018"
[dependencies]
cranelift-entity = { path = "../cranelift-entity", version = "0.51.0", default-features = false }
cranelift-entity = { path = "../cranelift-entity", version = "0.55.0", default-features = false }
[badges]
maintenance = { status = "experimental" }

Просмотреть файл

@ -1 +1 @@
{"files":{"Cargo.toml":"65c94041eeaee1397206bacf6777b9f51cedae6e5309e6a0ceaf3a1a3c82f4ea","LICENSE":"268872b9816f90fd8e85db5a28d33f8150ebb8dd016653fb39ef1f94f2686bc5","README.md":"b123f056d0d458396679c5f7f2a16d2762af0258fcda4ac14b6655a95e5a0022","src/cdsl/ast.rs":"8fdd17d9d8c4bd0cf535599a40d7da0e5bf27fdcef817cd55ab7c580c8eb6a6c","src/cdsl/cpu_modes.rs":"7ceb99df347faf5e69b34a7e0d691e9c148d15587df09e99d46a7d37238d8d06","src/cdsl/encodings.rs":"d884a564815a03c23369bcf31d13b122ae5ba84d0c80eda9312f0c0a829bf794","src/cdsl/formats.rs":"63e638305aa3ca6dd409ddf0e5e9605eeac1cc2631103e42fc6cbc87703d9b63","src/cdsl/instructions.rs":"6ad4c75e2bf634475b6a57feb1582f39dd8e670680f68f66218274ad96b6b3f4","src/cdsl/isa.rs":"ccabd6848b69eb069c10db61c7e7f86080777495714bb53d03e663c40541be94","src/cdsl/mod.rs":"0aa827923bf4c45e5ee2359573bd863e00f474acd532739f49dcd74a27553882","src/cdsl/operands.rs":"1c3411504de9c83112ff48e0ff1cfbb2e4ba5a9a15c1716f411ef31a4df59899","src/cdsl/recipes.rs":"a3b4c49488762864856f9fb181df70650fceea07219d093f3c952229c67d35e1","src/cdsl/regs.rs":"05f93ab8504ee82d7cc9811a5b40e5cd004c327577b4c0b3dd957fc422f3c013","src/cdsl/settings.rs":"e6fd9a31925743b93b11f09c9c8271bab6aa2430aa053a2601957b4487df7d77","src/cdsl/type_inference.rs":"1efca8a095ffc899b7527bda6b9d9378c73d7283f8dceaa4819e8af599f8be21","src/cdsl/types.rs":"763cb82b1d8ceb6be682ed6c71c8c98cab686151d177aad6d8f8ef92a37c5639","src/cdsl/typevar.rs":"52f7242a35805a82baf2c788c3eb392e2fba0fcbf47f047f32eba81f34487c7e","src/cdsl/xform.rs":"55da0c3f2403147b535ab6ae5d69c623fbe839edecf2a3af1de84420cd58402d","src/default_map.rs":"101bb0282a124f9c921f6bd095f529e8753621450d783c3273b0b0394c2c5c03","src/error.rs":"e9b11b2feb2d867b94c8810fdc5a6c4e0d9131604a0bfa5340ff2639a55100b4","src/gen_binemit.rs":"515e243420b30d1e01f8ea630282d9b6d78a715e1951f3f20392e19a48164442","src/gen_encodings.rs":"f00cded6b68a9b48c9e3cd39a8b6f0ba136f4062c8f8666109158a72c62c3ed1","src/gen_inst.rs":"fac99641622591c0529c0ef789dd83290a624fc674c91a959f426696f82044de","src/gen_legalizer.rs":"7a68c2b9fd77b6420ecb10539d9af0520374e4f2e30d5a345d98dafde157e6bd","src/gen_registers.rs":"3628949229c1cb5179ec5f655b9a1ddd0504ba74ffb9fb23741c85c9154b696f","src/gen_settings.rs":"f3cc3d31f6cc898f30606caf084f0de220db2d3b1b5e5e4145fa7c9a9a1597e2","src/gen_types.rs":"f6c090e1646a43bf2fe81ae0a7029cc6f7dc6d43285368f56d86c35a21c469a6","src/isa/arm32/mod.rs":"8e09ec1b3caf2d22dce8517b37c356047bfce9a6dea712467d867ed05c4bedaf","src/isa/arm64/mod.rs":"b01f030925d3f2af37d7df1b4a800eb7f0d24f74a46e9154fd8b6752643eb2d5","src/isa/mod.rs":"136141f99f217ba42b9e3f7f47238ab19cc974bb3bef2e2df7f7b5a683989d46","src/isa/riscv/encodings.rs":"8abb1968d917588bc5fc5f5be6dd66bdec23ac456ba65f8138237c8e891e843c","src/isa/riscv/mod.rs":"a7b461a30bbfbc1e3b33645422ff40d5b1761c30cb5d4a8aa12e9a3b7f7aee51","src/isa/riscv/recipes.rs":"c9424cffed54cc4d328879a4613b9f6a2c2b7cde7e6e17b4fccd5f661aaf92f2","src/isa/x86/encodings.rs":"71ba4d1cca1480437baecf1fe55ef8f9d759e540a697b5e09a2489567dfa8c26","src/isa/x86/instructions.rs":"e4a92f2b707e0a9af0317041eb9a8bc58a8bedcdbbe35f54dcfaf05699a50675","src/isa/x86/legalize.rs":"0624341293bc91f77a2bdc69c04a89a483ba18cc263058b92879b88127035c79","src/isa/x86/mod.rs":"49f0bc05898d1d8565e692ec2550855de15fd6cffa3b5b6e0f8d502cd813e306","src/isa/x86/opcodes.rs":"643bae64cd4050814adfb856046cf650979bec5d251a9d9a6e11bafb5a603c43","src/isa/x86/recipes.rs":"971277543466e91be6b41c1735d81ca2752c175ac079d7c7ab8694c87cab56fd","src/isa/x86/registers.rs":"e24c9487f4c257b1089dac6bca0106cc673db77292cd000ca8e0c7e0d0103f63","src/isa/x86/settings.rs":"7f6266cd5098115ac24caea3be07a18c590c07b8cfe5f0912af3ed1d0d288330","src/lib.rs":"2491b0e74078914cb89d1778fa8174daf723fe76aaf7fed18741237d68f6df32","src/shared/entities.rs":"911b396da11188bd510de004956596f150e27540edd351c74028f99f5f3c79c5","src/shared/formats.rs":"d8cf211c392ec3c54d0101ef31b700c3222bc8e80b69a04b244953e449770336","src/shared/immediates.rs":"e4a57657f6af9853794804eb41c01204a2c13a632f44f55d90e156a4b98c5f65","src/shared/instructions.rs":"cef3be79dfe3d1c2d0c4eef91cca2852ec5454c1e6bc326d8b64ade622da0ef2","src/shared/legalize.rs":"73e1b42743c324104f5a34120e1598146ce4ee7393137ecb5391b768c61f2605","src/shared/mod.rs":"bc497c14d083c29eefe4935cff9cd1bd138c071bc50f787248727a3858dc69f3","src/shared/settings.rs":"5775bb6b760ed9f54370b2ab0ae6bc020cafc6ad1369e90fec6144375641c27f","src/shared/types.rs":"4702df132f4b5d70cc9411ec5221ba0b1bd4479252274e0223ae57b6d0331247","src/srcgen.rs":"dcfc159c8599270f17e6a978c4be255abca51556b5ef0da497faec4a4a1e62ce","src/unique_table.rs":"31aa54330ca4786af772d32e8cb6158b6504b88fa93fe177bf0c6cbe545a8d35"},"package":null}
{"files":{"Cargo.toml":"eecaf15fdc0f1a78dce08dae1fc6c529da7638f1bb2ea7c007741df27973b6d7","LICENSE":"268872b9816f90fd8e85db5a28d33f8150ebb8dd016653fb39ef1f94f2686bc5","README.md":"b123f056d0d458396679c5f7f2a16d2762af0258fcda4ac14b6655a95e5a0022","src/cdsl/ast.rs":"8fdd17d9d8c4bd0cf535599a40d7da0e5bf27fdcef817cd55ab7c580c8eb6a6c","src/cdsl/cpu_modes.rs":"7ceb99df347faf5e69b34a7e0d691e9c148d15587df09e99d46a7d37238d8d06","src/cdsl/encodings.rs":"d884a564815a03c23369bcf31d13b122ae5ba84d0c80eda9312f0c0a829bf794","src/cdsl/formats.rs":"63e638305aa3ca6dd409ddf0e5e9605eeac1cc2631103e42fc6cbc87703d9b63","src/cdsl/instructions.rs":"6ad4c75e2bf634475b6a57feb1582f39dd8e670680f68f66218274ad96b6b3f4","src/cdsl/isa.rs":"ccabd6848b69eb069c10db61c7e7f86080777495714bb53d03e663c40541be94","src/cdsl/mod.rs":"0aa827923bf4c45e5ee2359573bd863e00f474acd532739f49dcd74a27553882","src/cdsl/operands.rs":"1c3411504de9c83112ff48e0ff1cfbb2e4ba5a9a15c1716f411ef31a4df59899","src/cdsl/recipes.rs":"80b7cd87332229b569e38086ceee8d557e679b9a32ad2e50bdb15c33337c3418","src/cdsl/regs.rs":"05f93ab8504ee82d7cc9811a5b40e5cd004c327577b4c0b3dd957fc422f3c013","src/cdsl/settings.rs":"e6fd9a31925743b93b11f09c9c8271bab6aa2430aa053a2601957b4487df7d77","src/cdsl/type_inference.rs":"1efca8a095ffc899b7527bda6b9d9378c73d7283f8dceaa4819e8af599f8be21","src/cdsl/types.rs":"763cb82b1d8ceb6be682ed6c71c8c98cab686151d177aad6d8f8ef92a37c5639","src/cdsl/typevar.rs":"52f7242a35805a82baf2c788c3eb392e2fba0fcbf47f047f32eba81f34487c7e","src/cdsl/xform.rs":"55da0c3f2403147b535ab6ae5d69c623fbe839edecf2a3af1de84420cd58402d","src/default_map.rs":"101bb0282a124f9c921f6bd095f529e8753621450d783c3273b0b0394c2c5c03","src/error.rs":"e9b11b2feb2d867b94c8810fdc5a6c4e0d9131604a0bfa5340ff2639a55100b4","src/gen_binemit.rs":"515e243420b30d1e01f8ea630282d9b6d78a715e1951f3f20392e19a48164442","src/gen_encodings.rs":"f00cded6b68a9b48c9e3cd39a8b6f0ba136f4062c8f8666109158a72c62c3ed1","src/gen_inst.rs":"fac99641622591c0529c0ef789dd83290a624fc674c91a959f426696f82044de","src/gen_legalizer.rs":"7a68c2b9fd77b6420ecb10539d9af0520374e4f2e30d5a345d98dafde157e6bd","src/gen_registers.rs":"3628949229c1cb5179ec5f655b9a1ddd0504ba74ffb9fb23741c85c9154b696f","src/gen_settings.rs":"f3cc3d31f6cc898f30606caf084f0de220db2d3b1b5e5e4145fa7c9a9a1597e2","src/gen_types.rs":"f6c090e1646a43bf2fe81ae0a7029cc6f7dc6d43285368f56d86c35a21c469a6","src/isa/arm32/mod.rs":"8e09ec1b3caf2d22dce8517b37c356047bfce9a6dea712467d867ed05c4bedaf","src/isa/arm64/mod.rs":"b01f030925d3f2af37d7df1b4a800eb7f0d24f74a46e9154fd8b6752643eb2d5","src/isa/mod.rs":"136141f99f217ba42b9e3f7f47238ab19cc974bb3bef2e2df7f7b5a683989d46","src/isa/riscv/encodings.rs":"8abb1968d917588bc5fc5f5be6dd66bdec23ac456ba65f8138237c8e891e843c","src/isa/riscv/mod.rs":"a7b461a30bbfbc1e3b33645422ff40d5b1761c30cb5d4a8aa12e9a3b7f7aee51","src/isa/riscv/recipes.rs":"c9424cffed54cc4d328879a4613b9f6a2c2b7cde7e6e17b4fccd5f661aaf92f2","src/isa/x86/encodings.rs":"ddb3b4c6f9b742ac5fb67136acd60062e16cdffb4dbdd2a309c2155feb63e23d","src/isa/x86/instructions.rs":"e4a92f2b707e0a9af0317041eb9a8bc58a8bedcdbbe35f54dcfaf05699a50675","src/isa/x86/legalize.rs":"fca4a2729fbefded71effb7517c63a3da3648f8ab68968ef014cfc5d5f631cc7","src/isa/x86/mod.rs":"49f0bc05898d1d8565e692ec2550855de15fd6cffa3b5b6e0f8d502cd813e306","src/isa/x86/opcodes.rs":"643bae64cd4050814adfb856046cf650979bec5d251a9d9a6e11bafb5a603c43","src/isa/x86/recipes.rs":"02cff98d27e852410bea7fb035510f78b15e77d133f745d4f052dbbc54a32e44","src/isa/x86/registers.rs":"e24c9487f4c257b1089dac6bca0106cc673db77292cd000ca8e0c7e0d0103f63","src/isa/x86/settings.rs":"9087cd57da2852b689bddc296639f9b9e1caa30e8185798891079da8d9340b53","src/lib.rs":"2491b0e74078914cb89d1778fa8174daf723fe76aaf7fed18741237d68f6df32","src/shared/entities.rs":"911b396da11188bd510de004956596f150e27540edd351c74028f99f5f3c79c5","src/shared/formats.rs":"d8cf211c392ec3c54d0101ef31b700c3222bc8e80b69a04b244953e449770336","src/shared/immediates.rs":"e4a57657f6af9853794804eb41c01204a2c13a632f44f55d90e156a4b98c5f65","src/shared/instructions.rs":"3eaa255634ae32a653fa16be82573d6a5912c766ce92589f13b81867b774a74e","src/shared/legalize.rs":"73e1b42743c324104f5a34120e1598146ce4ee7393137ecb5391b768c61f2605","src/shared/mod.rs":"bc497c14d083c29eefe4935cff9cd1bd138c071bc50f787248727a3858dc69f3","src/shared/settings.rs":"cda96c9599d49b82e5cd43c7d0fd53a197fa8dadcc56dc33566ac47fdd6da607","src/shared/types.rs":"4702df132f4b5d70cc9411ec5221ba0b1bd4479252274e0223ae57b6d0331247","src/srcgen.rs":"dcfc159c8599270f17e6a978c4be255abca51556b5ef0da497faec4a4a1e62ce","src/unique_table.rs":"31aa54330ca4786af772d32e8cb6158b6504b88fa93fe177bf0c6cbe545a8d35"},"package":null}

Просмотреть файл

@ -1,7 +1,7 @@
[package]
name = "cranelift-codegen-meta"
authors = ["The Cranelift Project Developers"]
version = "0.51.0"
version = "0.55.0"
description = "Metaprogram for cranelift-codegen code generator library"
license = "Apache-2.0 WITH LLVM-exception"
repository = "https://github.com/bytecodealliance/cranelift"
@ -9,8 +9,8 @@ readme = "README.md"
edition = "2018"
[dependencies]
cranelift-codegen-shared = { path = "../shared", version = "0.51.0" }
cranelift-entity = { path = "../../cranelift-entity", version = "0.51.0" }
cranelift-codegen-shared = { path = "../shared", version = "0.55.0" }
cranelift-entity = { path = "../../cranelift-entity", version = "0.55.0" }
[badges]
maintenance = { status = "experimental" }

Просмотреть файл

@ -172,7 +172,7 @@ pub(crate) struct EncodingRecipeBuilder {
pub base_size: u64,
pub operands_in: Option<Vec<OperandConstraint>>,
pub operands_out: Option<Vec<OperandConstraint>>,
compute_size: Option<&'static str>,
pub compute_size: Option<&'static str>,
pub branch_range: Option<BranchRange>,
pub emit: Option<String>,
clobbers_flags: Option<bool>,

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -40,7 +40,6 @@ pub(crate) fn define(shared: &mut SharedDefinitions, x86_instructions: &Instruct
let fmax = insts.by_name("fmax");
let fmin = insts.by_name("fmin");
let fneg = insts.by_name("fneg");
let fsub = insts.by_name("fsub");
let iadd = insts.by_name("iadd");
let icmp = insts.by_name("icmp");
let iconst = insts.by_name("iconst");
@ -48,6 +47,7 @@ pub(crate) fn define(shared: &mut SharedDefinitions, x86_instructions: &Instruct
let ineg = insts.by_name("ineg");
let insertlane = insts.by_name("insertlane");
let ishl = insts.by_name("ishl");
let ishl_imm = insts.by_name("ishl_imm");
let isub = insts.by_name("isub");
let popcnt = insts.by_name("popcnt");
let raw_bitcast = insts.by_name("raw_bitcast");
@ -335,6 +335,7 @@ pub(crate) fn define(shared: &mut SharedDefinitions, x86_instructions: &Instruct
let uimm8_zero = Literal::constant(&imm.uimm8, 0x00);
let uimm8_one = Literal::constant(&imm.uimm8, 0x01);
let u128_zeroes = constant(vec![0x00; 16]);
let u128_ones = constant(vec![0xff; 16]);
let b = var("b");
let c = var("c");
let d = var("d");
@ -405,12 +406,11 @@ pub(crate) fn define(shared: &mut SharedDefinitions, x86_instructions: &Instruct
}
// SIMD bnot
let ones = constant(vec![0xff; 16]);
for ty in ValueType::all_lane_types().filter(allowed_simd_type) {
let bnot = bnot.bind(vector(ty, sse_vector_size));
narrow.legalize(
def!(y = bnot(x)),
vec![def!(a = vconst(ones)), def!(y = bxor(a, x))],
vec![def!(a = vconst(u128_ones)), def!(y = bxor(a, x))],
);
}
@ -524,7 +524,11 @@ pub(crate) fn define(shared: &mut SharedDefinitions, x86_instructions: &Instruct
let icmp_ = icmp.bind(vector(*ty, sse_vector_size));
narrow.legalize(
def!(c = icmp_(ugt, a, b)),
vec![def!(x = x86_pmaxu(a, b)), def!(c = icmp(eq, a, x))],
vec![
def!(x = x86_pmaxu(a, b)),
def!(y = icmp(eq, x, b)),
def!(c = bnot(y)),
],
);
let icmp_ = icmp.bind(vector(*ty, sse_vector_size));
narrow.legalize(
@ -548,11 +552,40 @@ pub(crate) fn define(shared: &mut SharedDefinitions, x86_instructions: &Instruct
narrow.legalize(def!(c = icmp_(ule, a, b)), vec![def!(c = icmp(uge, b, a))]);
}
// SIMD fcmp greater-/less-than
let gt = Literal::enumerator_for(&imm.floatcc, "gt");
let lt = Literal::enumerator_for(&imm.floatcc, "lt");
let ge = Literal::enumerator_for(&imm.floatcc, "ge");
let le = Literal::enumerator_for(&imm.floatcc, "le");
let ugt = Literal::enumerator_for(&imm.floatcc, "ugt");
let ult = Literal::enumerator_for(&imm.floatcc, "ult");
let uge = Literal::enumerator_for(&imm.floatcc, "uge");
let ule = Literal::enumerator_for(&imm.floatcc, "ule");
for ty in &[F32, F64] {
let fcmp_ = fcmp.bind(vector(*ty, sse_vector_size));
narrow.legalize(def!(c = fcmp_(gt, a, b)), vec![def!(c = fcmp(lt, b, a))]);
let fcmp_ = fcmp.bind(vector(*ty, sse_vector_size));
narrow.legalize(def!(c = fcmp_(ge, a, b)), vec![def!(c = fcmp(le, b, a))]);
let fcmp_ = fcmp.bind(vector(*ty, sse_vector_size));
narrow.legalize(def!(c = fcmp_(ult, a, b)), vec![def!(c = fcmp(ugt, b, a))]);
let fcmp_ = fcmp.bind(vector(*ty, sse_vector_size));
narrow.legalize(def!(c = fcmp_(ule, a, b)), vec![def!(c = fcmp(uge, b, a))]);
}
for ty in &[F32, F64] {
let fneg = fneg.bind(vector(*ty, sse_vector_size));
let lane_type_as_int = LaneType::int_from_bits(LaneType::from(*ty).lane_bits() as u16);
let uimm8_shift = Literal::constant(&imm.uimm8, lane_type_as_int.lane_bits() as i64 - 1);
let vconst = vconst.bind(vector(lane_type_as_int, sse_vector_size));
let bitcast_to_float = raw_bitcast.bind(vector(*ty, sse_vector_size));
narrow.legalize(
def!(b = fneg(a)),
vec![def!(c = vconst(u128_zeroes)), def!(b = fsub(c, a))],
vec![
def!(c = vconst(u128_ones)),
def!(d = ishl_imm(c, uimm8_shift)), // Create a mask of all 0s except the MSB.
def!(e = bitcast_to_float(d)), // Cast mask to the floating-point type.
def!(b = bxor(a, e)), // Flip the MSB.
],
);
}
@ -565,7 +598,7 @@ pub(crate) fn define(shared: &mut SharedDefinitions, x86_instructions: &Instruct
narrow.legalize(
def!(b = fabs(a)),
vec![
def!(c = vconst(ones)),
def!(c = vconst(u128_ones)),
def!(d = ushr_imm(c, uimm8_one)), // Create a mask of all 1s except the MSB.
def!(e = bitcast_to_float(d)), // Cast mask to the floating-point type.
def!(b = band(a, e)), // Unset the MSB.

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -59,16 +59,16 @@ pub(crate) fn define(shared: &SettingGroup) -> SettingGroup {
// back in the shared SettingGroup, and use it in x86 instruction predicates.
let is_pic = shared.get_bool("is_pic");
let allones_funcaddrs = shared.get_bool("allones_funcaddrs");
let emit_all_ones_funcaddrs = shared.get_bool("emit_all_ones_funcaddrs");
settings.add_predicate("is_pic", predicate!(is_pic));
settings.add_predicate("not_is_pic", predicate!(!is_pic));
settings.add_predicate(
"all_ones_funcaddrs_and_not_is_pic",
predicate!(allones_funcaddrs && !is_pic),
predicate!(emit_all_ones_funcaddrs && !is_pic),
);
settings.add_predicate(
"not_all_ones_funcaddrs_and_not_is_pic",
predicate!(!allones_funcaddrs && !is_pic),
predicate!(!emit_all_ones_funcaddrs && !is_pic),
);
// Presets corresponding to x86 CPUs.

Просмотреть файл

@ -11,6 +11,476 @@ use crate::shared::formats::Formats;
use crate::shared::types;
use crate::shared::{entities::EntityRefs, immediates::Immediates};
#[inline(never)]
fn define_control_flow(
ig: &mut InstructionGroupBuilder,
formats: &Formats,
imm: &Immediates,
entities: &EntityRefs,
) {
let EBB = &Operand::new("EBB", &entities.ebb).with_doc("Destination extended basic block");
let args = &Operand::new("args", &entities.varargs).with_doc("EBB arguments");
ig.push(
Inst::new(
"jump",
r#"
Jump.
Unconditionally jump to an extended basic block, passing the specified
EBB arguments. The number and types of arguments must match the
destination EBB.
"#,
&formats.jump,
)
.operands_in(vec![EBB, args])
.is_terminator(true)
.is_branch(true),
);
ig.push(
Inst::new(
"fallthrough",
r#"
Fall through to the next EBB.
This is the same as `jump`, except the destination EBB must be
the next one in the layout.
Jumps are turned into fall-through instructions by the branch
relaxation pass. There is no reason to use this instruction outside
that pass.
"#,
&formats.jump,
)
.operands_in(vec![EBB, args])
.is_terminator(true)
.is_branch(true),
);
let Testable = &TypeVar::new(
"Testable",
"A scalar boolean or integer type",
TypeSetBuilder::new()
.ints(Interval::All)
.bools(Interval::All)
.build(),
);
{
let c = &Operand::new("c", Testable).with_doc("Controlling value to test");
ig.push(
Inst::new(
"brz",
r#"
Branch when zero.
If ``c`` is a `b1` value, take the branch when ``c`` is false. If
``c`` is an integer value, take the branch when ``c = 0``.
"#,
&formats.branch,
)
.operands_in(vec![c, EBB, args])
.is_branch(true),
);
ig.push(
Inst::new(
"brnz",
r#"
Branch when non-zero.
If ``c`` is a `b1` value, take the branch when ``c`` is true. If
``c`` is an integer value, take the branch when ``c != 0``.
"#,
&formats.branch,
)
.operands_in(vec![c, EBB, args])
.is_branch(true),
);
}
let iB = &TypeVar::new(
"iB",
"A scalar integer type",
TypeSetBuilder::new().ints(Interval::All).build(),
);
let iflags: &TypeVar = &ValueType::Special(types::Flag::IFlags.into()).into();
let fflags: &TypeVar = &ValueType::Special(types::Flag::FFlags.into()).into();
{
let Cond = &Operand::new("Cond", &imm.intcc);
let x = &Operand::new("x", iB);
let y = &Operand::new("y", iB);
ig.push(
Inst::new(
"br_icmp",
r#"
Compare scalar integers and branch.
Compare ``x`` and ``y`` in the same way as the `icmp` instruction
and take the branch if the condition is true:
```text
br_icmp ugt v1, v2, ebb4(v5, v6)
```
is semantically equivalent to:
```text
v10 = icmp ugt, v1, v2
brnz v10, ebb4(v5, v6)
```
Some RISC architectures like MIPS and RISC-V provide instructions that
implement all or some of the condition codes. The instruction can also
be used to represent *macro-op fusion* on architectures like Intel's.
"#,
&formats.branch_icmp,
)
.operands_in(vec![Cond, x, y, EBB, args])
.is_branch(true),
);
let f = &Operand::new("f", iflags);
ig.push(
Inst::new(
"brif",
r#"
Branch when condition is true in integer CPU flags.
"#,
&formats.branch_int,
)
.operands_in(vec![Cond, f, EBB, args])
.is_branch(true),
);
}
{
let Cond = &Operand::new("Cond", &imm.floatcc);
let f = &Operand::new("f", fflags);
ig.push(
Inst::new(
"brff",
r#"
Branch when condition is true in floating point CPU flags.
"#,
&formats.branch_float,
)
.operands_in(vec![Cond, f, EBB, args])
.is_branch(true),
);
}
{
let x = &Operand::new("x", iB).with_doc("index into jump table");
let JT = &Operand::new("JT", &entities.jump_table);
ig.push(
Inst::new(
"br_table",
r#"
Indirect branch via jump table.
Use ``x`` as an unsigned index into the jump table ``JT``. If a jump
table entry is found, branch to the corresponding EBB. If no entry was
found or the index is out-of-bounds, branch to the given default EBB.
Note that this branch instruction can't pass arguments to the targeted
blocks. Split critical edges as needed to work around this.
Do not confuse this with "tables" in WebAssembly. ``br_table`` is for
jump tables with destinations within the current function only -- think
of a ``match`` in Rust or a ``switch`` in C. If you want to call a
function in a dynamic library, that will typically use
``call_indirect``.
"#,
&formats.branch_table,
)
.operands_in(vec![x, EBB, JT])
.is_terminator(true)
.is_branch(true),
);
}
let iAddr = &TypeVar::new(
"iAddr",
"An integer address type",
TypeSetBuilder::new().ints(32..64).build(),
);
{
let x = &Operand::new("x", iAddr).with_doc("index into jump table");
let addr = &Operand::new("addr", iAddr);
let Size = &Operand::new("Size", &imm.uimm8).with_doc("Size in bytes");
let JT = &Operand::new("JT", &entities.jump_table);
let entry = &Operand::new("entry", iAddr).with_doc("entry of jump table");
ig.push(
Inst::new(
"jump_table_entry",
r#"
Get an entry from a jump table.
Load a serialized ``entry`` from a jump table ``JT`` at a given index
``addr`` with a specific ``Size``. The retrieved entry may need to be
decoded after loading, depending upon the jump table type used.
Currently, the only type supported is entries which are relative to the
base of the jump table.
"#,
&formats.branch_table_entry,
)
.operands_in(vec![x, addr, Size, JT])
.operands_out(vec![entry])
.can_load(true),
);
ig.push(
Inst::new(
"jump_table_base",
r#"
Get the absolute base address of a jump table.
This is used for jump tables wherein the entries are stored relative to
the base of jump table. In order to use these, generated code should first
load an entry using ``jump_table_entry``, then use this instruction to add
the relative base back to it.
"#,
&formats.branch_table_base,
)
.operands_in(vec![JT])
.operands_out(vec![addr]),
);
ig.push(
Inst::new(
"indirect_jump_table_br",
r#"
Branch indirectly via a jump table entry.
Unconditionally jump via a jump table entry that was previously loaded
with the ``jump_table_entry`` instruction.
"#,
&formats.indirect_jump,
)
.operands_in(vec![addr, JT])
.is_indirect_branch(true)
.is_terminator(true)
.is_branch(true),
);
}
ig.push(
Inst::new(
"debugtrap",
r#"
Encodes an assembly debug trap.
"#,
&formats.nullary,
)
.other_side_effects(true)
.can_load(true)
.can_store(true),
);
{
let code = &Operand::new("code", &imm.trapcode);
ig.push(
Inst::new(
"trap",
r#"
Terminate execution unconditionally.
"#,
&formats.trap,
)
.operands_in(vec![code])
.can_trap(true)
.is_terminator(true),
);
let c = &Operand::new("c", Testable).with_doc("Controlling value to test");
ig.push(
Inst::new(
"trapz",
r#"
Trap when zero.
if ``c`` is non-zero, execution continues at the following instruction.
"#,
&formats.cond_trap,
)
.operands_in(vec![c, code])
.can_trap(true),
);
ig.push(
Inst::new(
"resumable_trap",
r#"
A resumable trap.
This instruction allows non-conditional traps to be used as non-terminal instructions.
"#,
&formats.trap,
)
.operands_in(vec![code])
.can_trap(true),
);
let c = &Operand::new("c", Testable).with_doc("Controlling value to test");
ig.push(
Inst::new(
"trapnz",
r#"
Trap when non-zero.
if ``c`` is zero, execution continues at the following instruction.
"#,
&formats.cond_trap,
)
.operands_in(vec![c, code])
.can_trap(true),
);
let Cond = &Operand::new("Cond", &imm.intcc);
let f = &Operand::new("f", iflags);
ig.push(
Inst::new(
"trapif",
r#"
Trap when condition is true in integer CPU flags.
"#,
&formats.int_cond_trap,
)
.operands_in(vec![Cond, f, code])
.can_trap(true),
);
let Cond = &Operand::new("Cond", &imm.floatcc);
let f = &Operand::new("f", fflags);
let code = &Operand::new("code", &imm.trapcode);
ig.push(
Inst::new(
"trapff",
r#"
Trap when condition is true in floating point CPU flags.
"#,
&formats.float_cond_trap,
)
.operands_in(vec![Cond, f, code])
.can_trap(true),
);
}
let rvals = &Operand::new("rvals", &entities.varargs).with_doc("return values");
ig.push(
Inst::new(
"return",
r#"
Return from the function.
Unconditionally transfer control to the calling function, passing the
provided return values. The list of return values must match the
function signature's return types.
"#,
&formats.multiary,
)
.operands_in(vec![rvals])
.is_return(true)
.is_terminator(true),
);
let rvals = &Operand::new("rvals", &entities.varargs).with_doc("return values");
ig.push(
Inst::new(
"fallthrough_return",
r#"
Return from the function by fallthrough.
This is a specialized instruction for use where one wants to append
a custom epilogue, which will then perform the real return. This
instruction has no encoding.
"#,
&formats.multiary,
)
.operands_in(vec![rvals])
.is_return(true)
.is_terminator(true),
);
let FN = &Operand::new("FN", &entities.func_ref)
.with_doc("function to call, declared by `function`");
let args = &Operand::new("args", &entities.varargs).with_doc("call arguments");
let rvals = &Operand::new("rvals", &entities.varargs).with_doc("return values");
ig.push(
Inst::new(
"call",
r#"
Direct function call.
Call a function which has been declared in the preamble. The argument
types must match the function's signature.
"#,
&formats.call,
)
.operands_in(vec![FN, args])
.operands_out(vec![rvals])
.is_call(true),
);
let SIG = &Operand::new("SIG", &entities.sig_ref).with_doc("function signature");
let callee = &Operand::new("callee", iAddr).with_doc("address of function to call");
let args = &Operand::new("args", &entities.varargs).with_doc("call arguments");
let rvals = &Operand::new("rvals", &entities.varargs).with_doc("return values");
ig.push(
Inst::new(
"call_indirect",
r#"
Indirect function call.
Call the function pointed to by `callee` with the given arguments. The
called function must match the specified signature.
Note that this is different from WebAssembly's ``call_indirect``; the
callee is a native address, rather than a table index. For WebAssembly,
`table_addr` and `load` are used to obtain a native address
from a table.
"#,
&formats.call_indirect,
)
.operands_in(vec![SIG, callee, args])
.operands_out(vec![rvals])
.is_call(true),
);
let FN = &Operand::new("FN", &entities.func_ref)
.with_doc("function to call, declared by `function`");
let addr = &Operand::new("addr", iAddr);
ig.push(
Inst::new(
"func_addr",
r#"
Get the address of a function.
Compute the absolute address of a function declared in the preamble.
The returned address can be used as a ``callee`` argument to
`call_indirect`. This is also a method for calling functions that
are too far away to be addressable by a direct `call`
instruction.
"#,
&formats.func_addr,
)
.operands_in(vec![FN])
.operands_out(vec![addr]),
);
}
#[allow(clippy::many_single_char_names)]
pub(crate) fn define(
all_instructions: &mut AllInstructions,
@ -20,6 +490,8 @@ pub(crate) fn define(
) -> InstructionGroup {
let mut ig = InstructionGroupBuilder::new(all_instructions);
define_control_flow(&mut ig, formats, imm, entities);
// Operand kind shorthands.
let iflags: &TypeVar = &ValueType::Special(types::Flag::IFlags.into()).into();
let fflags: &TypeVar = &ValueType::Special(types::Flag::FFlags.into()).into();
@ -114,426 +586,6 @@ pub(crate) fn define(
let MemTo = &TypeVar::copy_from(Mem, "MemTo".to_string());
let addr = &Operand::new("addr", iAddr);
let c = &Operand::new("c", Testable).with_doc("Controlling value to test");
let Cond = &Operand::new("Cond", &imm.intcc);
let x = &Operand::new("x", iB);
let y = &Operand::new("y", iB);
let EBB = &Operand::new("EBB", &entities.ebb).with_doc("Destination extended basic block");
let args = &Operand::new("args", &entities.varargs).with_doc("EBB arguments");
ig.push(
Inst::new(
"jump",
r#"
Jump.
Unconditionally jump to an extended basic block, passing the specified
EBB arguments. The number and types of arguments must match the
destination EBB.
"#,
&formats.jump,
)
.operands_in(vec![EBB, args])
.is_terminator(true)
.is_branch(true),
);
ig.push(
Inst::new(
"fallthrough",
r#"
Fall through to the next EBB.
This is the same as `jump`, except the destination EBB must be
the next one in the layout.
Jumps are turned into fall-through instructions by the branch
relaxation pass. There is no reason to use this instruction outside
that pass.
"#,
&formats.jump,
)
.operands_in(vec![EBB, args])
.is_terminator(true)
.is_branch(true),
);
ig.push(
Inst::new(
"brz",
r#"
Branch when zero.
If ``c`` is a `b1` value, take the branch when ``c`` is false. If
``c`` is an integer value, take the branch when ``c = 0``.
"#,
&formats.branch,
)
.operands_in(vec![c, EBB, args])
.is_branch(true),
);
ig.push(
Inst::new(
"brnz",
r#"
Branch when non-zero.
If ``c`` is a `b1` value, take the branch when ``c`` is true. If
``c`` is an integer value, take the branch when ``c != 0``.
"#,
&formats.branch,
)
.operands_in(vec![c, EBB, args])
.is_branch(true),
);
ig.push(
Inst::new(
"br_icmp",
r#"
Compare scalar integers and branch.
Compare ``x`` and ``y`` in the same way as the `icmp` instruction
and take the branch if the condition is true:
```text
br_icmp ugt v1, v2, ebb4(v5, v6)
```
is semantically equivalent to:
```text
v10 = icmp ugt, v1, v2
brnz v10, ebb4(v5, v6)
```
Some RISC architectures like MIPS and RISC-V provide instructions that
implement all or some of the condition codes. The instruction can also
be used to represent *macro-op fusion* on architectures like Intel's.
"#,
&formats.branch_icmp,
)
.operands_in(vec![Cond, x, y, EBB, args])
.is_branch(true),
);
let f = &Operand::new("f", iflags);
ig.push(
Inst::new(
"brif",
r#"
Branch when condition is true in integer CPU flags.
"#,
&formats.branch_int,
)
.operands_in(vec![Cond, f, EBB, args])
.is_branch(true),
);
let Cond = &Operand::new("Cond", &imm.floatcc);
let f = &Operand::new("f", fflags);
ig.push(
Inst::new(
"brff",
r#"
Branch when condition is true in floating point CPU flags.
"#,
&formats.branch_float,
)
.operands_in(vec![Cond, f, EBB, args])
.is_branch(true),
);
// The index into the br_table can be any type; legalizer will convert it to the right type.
let x = &Operand::new("x", iB).with_doc("index into jump table");
let entry = &Operand::new("entry", iAddr).with_doc("entry of jump table");
let JT = &Operand::new("JT", &entities.jump_table);
ig.push(
Inst::new(
"br_table",
r#"
Indirect branch via jump table.
Use ``x`` as an unsigned index into the jump table ``JT``. If a jump
table entry is found, branch to the corresponding EBB. If no entry was
found or the index is out-of-bounds, branch to the given default EBB.
Note that this branch instruction can't pass arguments to the targeted
blocks. Split critical edges as needed to work around this.
Do not confuse this with "tables" in WebAssembly. ``br_table`` is for
jump tables with destinations within the current function only -- think
of a ``match`` in Rust or a ``switch`` in C. If you want to call a
function in a dynamic library, that will typically use
``call_indirect``.
"#,
&formats.branch_table,
)
.operands_in(vec![x, EBB, JT])
.is_terminator(true)
.is_branch(true),
);
// These are the instructions which br_table legalizes to: they perform address computations,
// using pointer-sized integers, so their type variables are more constrained.
let x = &Operand::new("x", iAddr).with_doc("index into jump table");
let Size = &Operand::new("Size", &imm.uimm8).with_doc("Size in bytes");
ig.push(
Inst::new(
"jump_table_entry",
r#"
Get an entry from a jump table.
Load a serialized ``entry`` from a jump table ``JT`` at a given index
``addr`` with a specific ``Size``. The retrieved entry may need to be
decoded after loading, depending upon the jump table type used.
Currently, the only type supported is entries which are relative to the
base of the jump table.
"#,
&formats.branch_table_entry,
)
.operands_in(vec![x, addr, Size, JT])
.operands_out(vec![entry])
.can_load(true),
);
ig.push(
Inst::new(
"jump_table_base",
r#"
Get the absolute base address of a jump table.
This is used for jump tables wherein the entries are stored relative to
the base of jump table. In order to use these, generated code should first
load an entry using ``jump_table_entry``, then use this instruction to add
the relative base back to it.
"#,
&formats.branch_table_base,
)
.operands_in(vec![JT])
.operands_out(vec![addr]),
);
ig.push(
Inst::new(
"indirect_jump_table_br",
r#"
Branch indirectly via a jump table entry.
Unconditionally jump via a jump table entry that was previously loaded
with the ``jump_table_entry`` instruction.
"#,
&formats.indirect_jump,
)
.operands_in(vec![addr, JT])
.is_indirect_branch(true)
.is_terminator(true)
.is_branch(true),
);
ig.push(
Inst::new(
"debugtrap",
r#"
Encodes an assembly debug trap.
"#,
&formats.nullary,
)
.other_side_effects(true)
.can_load(true)
.can_store(true),
);
let code = &Operand::new("code", &imm.trapcode);
ig.push(
Inst::new(
"trap",
r#"
Terminate execution unconditionally.
"#,
&formats.trap,
)
.operands_in(vec![code])
.can_trap(true)
.is_terminator(true),
);
ig.push(
Inst::new(
"trapz",
r#"
Trap when zero.
if ``c`` is non-zero, execution continues at the following instruction.
"#,
&formats.cond_trap,
)
.operands_in(vec![c, code])
.can_trap(true),
);
ig.push(
Inst::new(
"resumable_trap",
r#"
A resumable trap.
This instruction allows non-conditional traps to be used as non-terminal instructions.
"#,
&formats.trap,
)
.operands_in(vec![code])
.can_trap(true),
);
ig.push(
Inst::new(
"trapnz",
r#"
Trap when non-zero.
if ``c`` is zero, execution continues at the following instruction.
"#,
&formats.cond_trap,
)
.operands_in(vec![c, code])
.can_trap(true),
);
let Cond = &Operand::new("Cond", &imm.intcc);
let f = &Operand::new("f", iflags);
ig.push(
Inst::new(
"trapif",
r#"
Trap when condition is true in integer CPU flags.
"#,
&formats.int_cond_trap,
)
.operands_in(vec![Cond, f, code])
.can_trap(true),
);
let Cond = &Operand::new("Cond", &imm.floatcc);
let f = &Operand::new("f", fflags);
ig.push(
Inst::new(
"trapff",
r#"
Trap when condition is true in floating point CPU flags.
"#,
&formats.float_cond_trap,
)
.operands_in(vec![Cond, f, code])
.can_trap(true),
);
let rvals = &Operand::new("rvals", &entities.varargs).with_doc("return values");
ig.push(
Inst::new(
"return",
r#"
Return from the function.
Unconditionally transfer control to the calling function, passing the
provided return values. The list of return values must match the
function signature's return types.
"#,
&formats.multiary,
)
.operands_in(vec![rvals])
.is_return(true)
.is_terminator(true),
);
ig.push(
Inst::new(
"fallthrough_return",
r#"
Return from the function by fallthrough.
This is a specialized instruction for use where one wants to append
a custom epilogue, which will then perform the real return. This
instruction has no encoding.
"#,
&formats.multiary,
)
.operands_in(vec![rvals])
.is_return(true)
.is_terminator(true),
);
let FN = &Operand::new("FN", &entities.func_ref)
.with_doc("function to call, declared by `function`");
let args = &Operand::new("args", &entities.varargs).with_doc("call arguments");
ig.push(
Inst::new(
"call",
r#"
Direct function call.
Call a function which has been declared in the preamble. The argument
types must match the function's signature.
"#,
&formats.call,
)
.operands_in(vec![FN, args])
.operands_out(vec![rvals])
.is_call(true),
);
let SIG = &Operand::new("SIG", &entities.sig_ref).with_doc("function signature");
let callee = &Operand::new("callee", iAddr).with_doc("address of function to call");
ig.push(
Inst::new(
"call_indirect",
r#"
Indirect function call.
Call the function pointed to by `callee` with the given arguments. The
called function must match the specified signature.
Note that this is different from WebAssembly's ``call_indirect``; the
callee is a native address, rather than a table index. For WebAssembly,
`table_addr` and `load` are used to obtain a native address
from a table.
"#,
&formats.call_indirect,
)
.operands_in(vec![SIG, callee, args])
.operands_out(vec![rvals])
.is_call(true),
);
ig.push(
Inst::new(
"func_addr",
r#"
Get the address of a function.
Compute the absolute address of a function declared in the preamble.
The returned address can be used as a ``callee`` argument to
`call_indirect`. This is also a method for calling functions that
are too far away to be addressable by a direct `call`
instruction.
"#,
&formats.func_addr,
)
.operands_in(vec![FN])
.operands_out(vec![addr]),
);
let SS = &Operand::new("SS", &entities.stack_slot);
let Offset = &Operand::new("Offset", &imm.offset32).with_doc("Byte offset from base address");

Просмотреть файл

@ -37,7 +37,7 @@ pub(crate) fn define() -> SettingGroup {
);
settings.add_bool(
"colocated_libcalls",
"use_colocated_libcalls",
r#"
Use colocated libcalls.
@ -177,7 +177,7 @@ pub(crate) fn define() -> SettingGroup {
// BaldrMonkey requires that not-yet-relocated function addresses be encoded
// as all-ones bitpatterns.
settings.add_bool(
"allones_funcaddrs",
"emit_all_ones_funcaddrs",
"Emit not-yet-relocated function addresses as all-ones bit patterns.",
false,
);
@ -185,7 +185,7 @@ pub(crate) fn define() -> SettingGroup {
// Stack probing options.
settings.add_bool(
"probestack_enabled",
"enable_probestack",
r#"
Enable the use of stack probes, for calling conventions which support this
functionality.
@ -218,7 +218,7 @@ pub(crate) fn define() -> SettingGroup {
// Jump table options.
settings.add_bool(
"jump_tables_enabled",
"enable_jump_tables",
"Enable the use of jump tables in generated machine code.",
true,
);

Просмотреть файл

@ -1 +1 @@
{"files":{"Cargo.toml":"3ccd54d6e48bdc6b58a65e52f139cf8edc2038b6c62aec12be6daab19d61d185","LICENSE":"268872b9816f90fd8e85db5a28d33f8150ebb8dd016653fb39ef1f94f2686bc5","README.md":"a410bc2f5dcbde499c0cd299c2620bc8111e3c5b3fccdd9e2d85caf3c24fdab3","src/condcodes.rs":"b8d433b2217b86e172d25b6c65a3ce0cc8ca221062cad1b28b0c78d2159fbda9","src/constant_hash.rs":"ffc619f45aad62c6fdcb83553a05879691a72e9a0103375b2d6cc12d52cf72d0","src/constants.rs":"fed03a10a6316e06aa174091db6e7d1fbb5f73c82c31193012ec5ab52f1c603a","src/isa/mod.rs":"428a950eca14acbe783899ccb1aecf15027f8cbe205578308ebde203d10535f3","src/isa/x86/encoding_bits.rs":"b180e4319e10f0e1c229cd9a63b5af8bb63be86f8f98cf1aef203355746f51cd","src/isa/x86/mod.rs":"01ef4e4d7437f938badbe2137892183c1ac684da0f68a5bec7e06aad34f43b9b","src/lib.rs":"91f26f998f11fb9cb74d2ec171424e29badd417beef023674850ace57149c656"},"package":null}
{"files":{"Cargo.toml":"4bd4ee47249d76fa655edfefd456fee8153b4f11f3fa10120540fefd1005d3f5","LICENSE":"268872b9816f90fd8e85db5a28d33f8150ebb8dd016653fb39ef1f94f2686bc5","README.md":"a410bc2f5dcbde499c0cd299c2620bc8111e3c5b3fccdd9e2d85caf3c24fdab3","src/condcodes.rs":"b8d433b2217b86e172d25b6c65a3ce0cc8ca221062cad1b28b0c78d2159fbda9","src/constant_hash.rs":"ffc619f45aad62c6fdcb83553a05879691a72e9a0103375b2d6cc12d52cf72d0","src/constants.rs":"fed03a10a6316e06aa174091db6e7d1fbb5f73c82c31193012ec5ab52f1c603a","src/isa/mod.rs":"428a950eca14acbe783899ccb1aecf15027f8cbe205578308ebde203d10535f3","src/isa/x86/encoding_bits.rs":"7e013fb804b13f9f83a0d517c6f5105856938d08ad378cc44a6fe6a59adef270","src/isa/x86/mod.rs":"01ef4e4d7437f938badbe2137892183c1ac684da0f68a5bec7e06aad34f43b9b","src/lib.rs":"91f26f998f11fb9cb74d2ec171424e29badd417beef023674850ace57149c656"},"package":null}

Просмотреть файл

@ -1,7 +1,7 @@
[package]
authors = ["The Cranelift Project Developers"]
name = "cranelift-codegen-shared"
version = "0.51.0"
version = "0.55.0"
description = "For code shared between cranelift-codegen-meta and cranelift-codegen"
license = "Apache-2.0 WITH LLVM-exception"
repository = "https://github.com/bytecodealliance/cranelift"

Просмотреть файл

@ -57,6 +57,22 @@ impl EncodingBits {
new
}
/// Returns a copy of the EncodingBits with the RRR bits set.
#[inline]
pub fn with_rrr(mut self, rrr: u8) -> Self {
debug_assert_eq!(self.rrr(), 0);
self.write(RRR, rrr.into());
self
}
/// Returns a copy of the EncodingBits with the REX.W bit set.
#[inline]
pub fn with_rex_w(mut self) -> Self {
debug_assert_eq!(self.rex_w(), 0);
self.write(REX_W, 1);
self
}
/// Returns the raw bits.
#[inline]
pub fn bits(self) -> u16 {

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

18
third_party/rust/cranelift-codegen/Cargo.toml поставляемый
Просмотреть файл

@ -1,7 +1,7 @@
[package]
authors = ["The Cranelift Project Developers"]
name = "cranelift-codegen"
version = "0.51.0"
version = "0.55.0"
description = "Low-level code generator library"
license = "Apache-2.0 WITH LLVM-exception"
documentation = "https://cranelift.readthedocs.io/"
@ -13,13 +13,14 @@ build = "build.rs"
edition = "2018"
[dependencies]
cranelift-codegen-shared = { path = "./shared", version = "0.51.0" }
cranelift-entity = { path = "../cranelift-entity", version = "0.51.0" }
cranelift-bforest = { path = "../cranelift-bforest", version = "0.51.0" }
cranelift-codegen-shared = { path = "./shared", version = "0.55.0" }
cranelift-entity = { path = "../cranelift-entity", version = "0.55.0" }
cranelift-bforest = { path = "../cranelift-bforest", version = "0.55.0" }
hashbrown = { version = "0.6", optional = true }
target-lexicon = "0.9"
target-lexicon = "0.10"
log = { version = "0.4.6", default-features = false }
serde = { version = "1.0.94", features = ["derive"], optional = true }
gimli = { version = "0.19.0", default-features = false, features = ["write"], optional = true }
smallvec = { version = "1.0.0" }
thiserror = "1.0.4"
byteorder = { version = "1.3.2", default-features = false }
@ -29,10 +30,10 @@ byteorder = { version = "1.3.2", default-features = false }
# accomodated in `tests`.
[build-dependencies]
cranelift-codegen-meta = { path = "meta", version = "0.51.0" }
cranelift-codegen-meta = { path = "meta", version = "0.55.0" }
[features]
default = ["std", "basic-blocks"]
default = ["std", "basic-blocks", "unwind"]
# The "std" feature enables use of libstd. The "core" feature enables use
# of some minimal std-like replacement libraries. At least one of these two
@ -47,6 +48,9 @@ core = ["hashbrown"]
# can significantly increase the size of the library.
testing_hooks = []
# This enables unwind info generation functionality.
unwind = ["gimli"]
# ISA targets for which we should build.
# If no ISA targets are explicitly enabled, the ISA target for the host machine is enabled.
x86 = []

Просмотреть файл

@ -155,6 +155,36 @@ pub trait CodeSink {
fn add_stackmap(&mut self, _: &[Value], _: &Function, _: &dyn TargetIsa);
}
/// Type of the frame unwind information.
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub enum FrameUnwindKind {
/// Windows fastcall unwinding (as in .pdata).
Fastcall,
/// FDE entry for libunwind (similar to .eh_frame format).
Libunwind,
}
/// Offset in frame unwind information buffer.
pub type FrameUnwindOffset = usize;
/// Sink for frame unwind information.
pub trait FrameUnwindSink {
/// Get the current position.
fn len(&self) -> FrameUnwindOffset;
/// Add bytes to the code section.
fn bytes(&mut self, _: &[u8]);
/// Reserves bytes in the buffer.
fn reserve(&mut self, _len: usize) {}
/// Add a relocation entry.
fn reloc(&mut self, _: Reloc, _: FrameUnwindOffset);
/// Specified offset to main structure.
fn set_entry_offset(&mut self, _: FrameUnwindOffset);
}
/// Report a bad encoding error.
#[cold]
pub fn bad_encoding(func: &Function, inst: Inst) -> ! {

Просмотреть файл

@ -10,8 +10,8 @@
//! single ISA instance.
use crate::binemit::{
relax_branches, shrink_instructions, CodeInfo, MemoryCodeSink, RelocSink, StackmapSink,
TrapSink,
relax_branches, shrink_instructions, CodeInfo, FrameUnwindKind, FrameUnwindSink,
MemoryCodeSink, RelocSink, StackmapSink, TrapSink,
};
use crate::dce::do_dce;
use crate::dominator_tree::DominatorTree;
@ -201,8 +201,13 @@ impl Context {
///
/// Only some calling conventions (e.g. Windows fastcall) will have unwind information.
/// This is a no-op if the function has no unwind information.
pub fn emit_unwind_info(&self, isa: &dyn TargetIsa, mem: &mut Vec<u8>) {
isa.emit_unwind_info(&self.func, mem);
pub fn emit_unwind_info(
&self,
isa: &dyn TargetIsa,
kind: FrameUnwindKind,
sink: &mut dyn FrameUnwindSink,
) {
isa.emit_unwind_info(&self.func, kind, sink);
}
/// Run the verifier on the function.

Просмотреть файл

@ -448,61 +448,6 @@ impl DominatorTree {
}
}
impl DominatorTree {
/// When splitting an `Ebb` using `Layout::split_ebb`, you can use this method to update
/// the dominator tree locally rather than recomputing it.
///
/// `old_ebb` is the `Ebb` before splitting, and `new_ebb` is the `Ebb` which now contains
/// the second half of `old_ebb`. `split_jump_inst` is the terminator jump instruction of
/// `old_ebb` that points to `new_ebb`.
pub fn recompute_split_ebb(&mut self, old_ebb: Ebb, new_ebb: Ebb, split_jump_inst: Inst) {
if !self.is_reachable(old_ebb) {
// old_ebb is unreachable, it stays so and new_ebb is unreachable too
self.nodes[new_ebb] = Default::default();
return;
}
// We use the RPO comparison on the postorder list so we invert the operands of the
// comparison
let old_ebb_postorder_index = self
.postorder
.as_slice()
.binary_search_by(|probe| self.rpo_cmp_ebb(old_ebb, *probe))
.expect("the old ebb is not declared to the dominator tree");
let new_ebb_rpo = self.insert_after_rpo(old_ebb, old_ebb_postorder_index, new_ebb);
self.nodes[new_ebb] = DomNode {
rpo_number: new_ebb_rpo,
idom: Some(split_jump_inst).into(),
};
}
// Insert new_ebb just after ebb in the RPO. This function checks
// if there is a gap in rpo numbers; if yes it returns the number in the gap and if
// not it renumbers.
fn insert_after_rpo(&mut self, ebb: Ebb, ebb_postorder_index: usize, new_ebb: Ebb) -> u32 {
let ebb_rpo_number = self.nodes[ebb].rpo_number;
let inserted_rpo_number = ebb_rpo_number + 1;
// If there is no gaps in RPo numbers to insert this new number, we iterate
// forward in RPO numbers and backwards in the postorder list of EBBs, renumbering the Ebbs
// until we find a gap
for (&current_ebb, current_rpo) in self.postorder[0..ebb_postorder_index]
.iter()
.rev()
.zip(inserted_rpo_number + 1..)
{
if self.nodes[current_ebb].rpo_number < current_rpo {
// There is no gap, we renumber
self.nodes[current_ebb].rpo_number = current_rpo;
} else {
// There is a gap, we stop the renumbering and exit
break;
}
}
// TODO: insert in constant time?
self.postorder.insert(ebb_postorder_index, new_ebb);
inserted_rpo_number
}
}
/// Optional pre-order information that can be computed for a dominator tree.
///
/// This data structure is computed from a `DominatorTree` and provides:
@ -681,8 +626,6 @@ mod tests {
use crate::flowgraph::ControlFlowGraph;
use crate::ir::types::*;
use crate::ir::{Function, InstBuilder, TrapCode};
use crate::settings;
use crate::verifier::{verify_context, VerifierErrors};
#[test]
fn empty() {
@ -886,64 +829,4 @@ mod tests {
assert!(!dt.dominates(jmp21, ebb2, &cur.func.layout));
assert!(dt.dominates(jmp21, jmp21, &cur.func.layout));
}
#[test]
fn renumbering() {
let mut func = Function::new();
let entry = func.dfg.make_ebb();
let ebb0 = func.dfg.make_ebb();
let ebb100 = func.dfg.make_ebb();
let mut cur = FuncCursor::new(&mut func);
cur.insert_ebb(entry);
cur.ins().jump(ebb0, &[]);
cur.insert_ebb(ebb0);
let cond = cur.ins().iconst(I32, 0);
let inst2 = cur.ins().brz(cond, ebb0, &[]);
let inst3 = cur.ins().brz(cond, ebb0, &[]);
let inst4 = cur.ins().brz(cond, ebb0, &[]);
let inst5 = cur.ins().brz(cond, ebb0, &[]);
cur.ins().jump(ebb100, &[]);
cur.insert_ebb(ebb100);
cur.ins().return_(&[]);
let mut cfg = ControlFlowGraph::with_function(cur.func);
let mut dt = DominatorTree::with_function(cur.func, &cfg);
let ebb1 = cur.func.dfg.make_ebb();
cur.func.layout.split_ebb(ebb1, inst2);
cur.goto_bottom(ebb0);
let middle_jump_inst = cur.ins().jump(ebb1, &[]);
dt.recompute_split_ebb(ebb0, ebb1, middle_jump_inst);
let ebb2 = cur.func.dfg.make_ebb();
cur.func.layout.split_ebb(ebb2, inst3);
cur.goto_bottom(ebb1);
let middle_jump_inst = cur.ins().jump(ebb2, &[]);
dt.recompute_split_ebb(ebb1, ebb2, middle_jump_inst);
let ebb3 = cur.func.dfg.make_ebb();
cur.func.layout.split_ebb(ebb3, inst4);
cur.goto_bottom(ebb2);
let middle_jump_inst = cur.ins().jump(ebb3, &[]);
dt.recompute_split_ebb(ebb2, ebb3, middle_jump_inst);
let ebb4 = cur.func.dfg.make_ebb();
cur.func.layout.split_ebb(ebb4, inst5);
cur.goto_bottom(ebb3);
let middle_jump_inst = cur.ins().jump(ebb4, &[]);
dt.recompute_split_ebb(ebb3, ebb4, middle_jump_inst);
cfg.compute(cur.func);
let flags = settings::Flags::new(settings::builder());
let mut errors = VerifierErrors::default();
verify_context(cur.func, &cfg, &dt, &flags, &mut errors).unwrap();
assert!(errors.0.is_empty());
}
}

Просмотреть файл

@ -14,6 +14,7 @@ use crate::isa::TargetIsa;
use crate::packed_option::ReservedValue;
use crate::write::write_operands;
use crate::HashMap;
use alloc::vec::Vec;
use core::fmt;
use core::iter;
use core::mem;
@ -776,6 +777,14 @@ impl DataFlowGraph {
self.ebbs[ebb].params.as_slice(&self.value_lists)
}
/// Get the types of the parameters on `ebb`.
pub fn ebb_param_types(&self, ebb: Ebb) -> Vec<Type> {
self.ebb_params(ebb)
.iter()
.map(|&v| self.value_type(v))
.collect()
}
/// Append a parameter with type `ty` to `ebb`.
pub fn append_ebb_param(&mut self, ebb: Ebb, ty: Type) -> Value {
let param = self.values.next_key();

Просмотреть файл

@ -102,6 +102,24 @@ impl Signature {
.count()
> 1
}
/// Collect the normal parameter types of the signature; see `[ArgumentPurpose::Normal]`.
pub fn param_types(&self) -> Vec<Type> {
self.params
.iter()
.filter(|ap| ap.purpose == ArgumentPurpose::Normal)
.map(|ap| ap.value_type)
.collect()
}
/// Collect the normal return types of the signature; see `[ArgumentPurpose::Normal]`.
pub fn return_types(&self) -> Vec<Type> {
self.returns
.iter()
.filter(|ap| ap.purpose == ArgumentPurpose::Normal)
.map(|ap| ap.value_type)
.collect()
}
}
/// Wrapper type capable of displaying a `Signature` with correct register names.

Просмотреть файл

@ -56,7 +56,7 @@ pub struct FrameLayout {
impl FrameLayout {
/// Create instance of FrameLayout.
pub fn new() -> Self {
FrameLayout {
Self {
initial: vec![].into_boxed_slice(),
instructions: HashMap::new(),
}

Просмотреть файл

@ -253,6 +253,11 @@ impl Function {
/// Starts collection of debug information.
pub fn collect_debug_info(&mut self) {
self.dfg.collect_debug_info();
self.collect_frame_layout_info();
}
/// Starts collection of frame layout information.
pub fn collect_frame_layout_info(&mut self) {
self.frame_layout = Some(FrameLayout::new());
}

Просмотреть файл

@ -22,7 +22,7 @@ use serde::{Deserialize, Serialize};
#[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))]
pub enum LibCall {
/// probe for stack overflow. These are emitted for functions which need
/// when the `probestack_enabled` setting is true.
/// when the `enable_probestack` setting is true.
Probestack,
/// ceil.f32
CeilF32,
@ -202,7 +202,7 @@ fn make_funcref(
func.import_function(ExtFuncData {
name: ExternalName::LibCall(libcall),
signature: sigref,
colocated: isa.flags().colocated_libcalls(),
colocated: isa.flags().use_colocated_libcalls(),
})
}

Просмотреть файл

@ -63,7 +63,6 @@ use crate::settings::SetResult;
use crate::timing;
use alloc::borrow::Cow;
use alloc::boxed::Box;
use alloc::vec::Vec;
use core::fmt;
use target_lexicon::{triple, Architecture, PointerWidth, Triple};
use thiserror::Error;
@ -198,7 +197,7 @@ impl TargetFrontendConfig {
/// Methods that are specialized to a target ISA. Implies a Display trait that shows the
/// shared flags, as well as any isa-specific flags.
pub trait TargetIsa: fmt::Display + Sync {
pub trait TargetIsa: fmt::Display + Send + Sync {
/// Get the name of this ISA.
fn name(&self) -> &'static str;
@ -382,7 +381,12 @@ pub trait TargetIsa: fmt::Display + Sync {
/// Emit unwind information for the given function.
///
/// Only some calling conventions (e.g. Windows fastcall) will have unwind information.
fn emit_unwind_info(&self, _func: &ir::Function, _mem: &mut Vec<u8>) {
fn emit_unwind_info(
&self,
_func: &ir::Function,
_kind: binemit::FrameUnwindKind,
_sink: &mut dyn binemit::FrameUnwindSink,
) {
// No-op by default
}
}

Просмотреть файл

@ -1,10 +1,15 @@
//! x86 ABI implementation.
use super::super::settings as shared_settings;
#[cfg(feature = "unwind")]
use super::fde::emit_fde;
use super::registers::{FPR, GPR, RU};
use super::settings as isa_settings;
#[cfg(feature = "unwind")]
use super::unwind::UnwindInfo;
use crate::abi::{legalize_args, ArgAction, ArgAssigner, ValueConversion};
#[cfg(feature = "unwind")]
use crate::binemit::{FrameUnwindKind, FrameUnwindSink};
use crate::cursor::{Cursor, CursorPosition, EncCursor};
use crate::ir;
use crate::ir::immediates::Imm64;
@ -18,7 +23,6 @@ use crate::regalloc::RegisterSet;
use crate::result::CodegenResult;
use crate::stack_layout::layout_stack;
use alloc::borrow::Cow;
use alloc::vec::Vec;
use core::i32;
use std::boxed::Box;
use target_lexicon::{PointerWidth, Triple};
@ -449,7 +453,7 @@ pub fn prologue_epilogue(func: &mut ir::Function, isa: &dyn TargetIsa) -> Codege
fn baldrdash_prologue_epilogue(func: &mut ir::Function, isa: &dyn TargetIsa) -> CodegenResult<()> {
debug_assert!(
!isa.flags().probestack_enabled(),
!isa.flags().enable_probestack(),
"baldrdash does not expect cranelift to emit stack probes"
);
@ -750,8 +754,7 @@ fn insert_common_prologue(
// Allocate stack frame storage.
if stack_size > 0 {
if isa.flags().probestack_enabled()
&& stack_size > (1 << isa.flags().probestack_size_log2())
if isa.flags().enable_probestack() && stack_size > (1 << isa.flags().probestack_size_log2())
{
// Emit a stack probe.
let rax = RU::rax as RegUnit;
@ -947,10 +950,25 @@ fn insert_common_epilogue(
}
}
pub fn emit_unwind_info(func: &ir::Function, isa: &dyn TargetIsa, mem: &mut Vec<u8>) {
// Assumption: RBP is being used as the frame pointer
// In the future, Windows fastcall codegen should usually omit the frame pointer
if let Some(info) = UnwindInfo::try_from_func(func, isa, Some(RU::rbp.into())) {
info.emit(mem);
#[cfg(feature = "unwind")]
pub fn emit_unwind_info(
func: &ir::Function,
isa: &dyn TargetIsa,
kind: FrameUnwindKind,
sink: &mut dyn FrameUnwindSink,
) {
match kind {
FrameUnwindKind::Fastcall => {
// Assumption: RBP is being used as the frame pointer
// In the future, Windows fastcall codegen should usually omit the frame pointer
if let Some(info) = UnwindInfo::try_from_func(func, isa, Some(RU::rbp.into())) {
info.emit(sink);
}
}
FrameUnwindKind::Libunwind => {
if func.frame_layout.is_some() {
emit_fde(func, isa, sink);
}
}
}
}

Просмотреть файл

@ -61,6 +61,12 @@ fn rex3(rm: RegUnit, reg: RegUnit, index: RegUnit) -> u8 {
BASE_REX | b | (x << 1) | (r << 2)
}
/// Determines whether a REX prefix should be emitted.
#[inline]
fn needs_rex(bits: u16, rex: u8) -> bool {
rex != BASE_REX || EncodingBits::from(bits).rex_w() == 1
}
// Emit a REX prefix.
//
// The R, X, and B bits are computed from registers using the functions above. The W bit is
@ -68,7 +74,7 @@ fn rex3(rm: RegUnit, reg: RegUnit, index: RegUnit) -> u8 {
fn rex_prefix<CS: CodeSink + ?Sized>(bits: u16, rex: u8, sink: &mut CS) {
debug_assert_eq!(rex & 0xf8, BASE_REX);
let w = EncodingBits::from(bits).rex_w();
sink.put1(rex | (u8::from(w) << 3));
sink.put1(rex | (w << 3));
}
// Emit a single-byte opcode with no REX prefix.
@ -80,11 +86,20 @@ fn put_op1<CS: CodeSink + ?Sized>(bits: u16, rex: u8, sink: &mut CS) {
// Emit a single-byte opcode with REX prefix.
fn put_rexop1<CS: CodeSink + ?Sized>(bits: u16, rex: u8, sink: &mut CS) {
debug_assert_eq!(bits & 0x0f00, 0, "Invalid encoding bits for Op1*");
debug_assert_eq!(bits & 0x0f00, 0, "Invalid encoding bits for RexOp1*");
rex_prefix(bits, rex, sink);
sink.put1(bits as u8);
}
/// Emit a single-byte opcode with inferred REX prefix.
fn put_dynrexop1<CS: CodeSink + ?Sized>(bits: u16, rex: u8, sink: &mut CS) {
debug_assert_eq!(bits & 0x0f00, 0, "Invalid encoding bits for DynRexOp1*");
if needs_rex(bits, rex) {
rex_prefix(bits, rex, sink);
}
sink.put1(bits as u8);
}
// Emit two-byte opcode: 0F XX
fn put_op2<CS: CodeSink + ?Sized>(bits: u16, rex: u8, sink: &mut CS) {
debug_assert_eq!(bits & 0x8f00, 0x0400, "Invalid encoding bits for Op2*");
@ -101,6 +116,20 @@ fn put_rexop2<CS: CodeSink + ?Sized>(bits: u16, rex: u8, sink: &mut CS) {
sink.put1(bits as u8);
}
/// Emit two-byte opcode: 0F XX with inferred REX prefix.
fn put_dynrexop2<CS: CodeSink + ?Sized>(bits: u16, rex: u8, sink: &mut CS) {
debug_assert_eq!(
bits & 0x0f00,
0x0400,
"Invalid encoding bits for DynRexOp2*"
);
if needs_rex(bits, rex) {
rex_prefix(bits, rex, sink);
}
sink.put1(0x0f);
sink.put1(bits as u8);
}
// Emit single-byte opcode with mandatory prefix.
fn put_mp1<CS: CodeSink + ?Sized>(bits: u16, rex: u8, sink: &mut CS) {
debug_assert_eq!(bits & 0x8c00, 0, "Invalid encoding bits for Mp1*");
@ -112,7 +141,7 @@ fn put_mp1<CS: CodeSink + ?Sized>(bits: u16, rex: u8, sink: &mut CS) {
// Emit single-byte opcode with mandatory prefix and REX.
fn put_rexmp1<CS: CodeSink + ?Sized>(bits: u16, rex: u8, sink: &mut CS) {
debug_assert_eq!(bits & 0x0c00, 0, "Invalid encoding bits for Mp1*");
debug_assert_eq!(bits & 0x0c00, 0, "Invalid encoding bits for RexMp1*");
let enc = EncodingBits::from(bits);
sink.put1(PREFIX[(enc.pp() - 1) as usize]);
rex_prefix(bits, rex, sink);
@ -131,7 +160,7 @@ fn put_mp2<CS: CodeSink + ?Sized>(bits: u16, rex: u8, sink: &mut CS) {
// Emit two-byte opcode (0F XX) with mandatory prefix and REX.
fn put_rexmp2<CS: CodeSink + ?Sized>(bits: u16, rex: u8, sink: &mut CS) {
debug_assert_eq!(bits & 0x0c00, 0x0400, "Invalid encoding bits for Mp2*");
debug_assert_eq!(bits & 0x0c00, 0x0400, "Invalid encoding bits for RexMp2*");
let enc = EncodingBits::from(bits);
sink.put1(PREFIX[(enc.pp() - 1) as usize]);
rex_prefix(bits, rex, sink);
@ -139,6 +168,22 @@ fn put_rexmp2<CS: CodeSink + ?Sized>(bits: u16, rex: u8, sink: &mut CS) {
sink.put1(bits as u8);
}
/// Emit two-byte opcode (0F XX) with mandatory prefix and inferred REX.
fn put_dynrexmp2<CS: CodeSink + ?Sized>(bits: u16, rex: u8, sink: &mut CS) {
debug_assert_eq!(
bits & 0x0c00,
0x0400,
"Invalid encoding bits for DynRexMp2*"
);
let enc = EncodingBits::from(bits);
sink.put1(PREFIX[(enc.pp() - 1) as usize]);
if needs_rex(bits, rex) {
rex_prefix(bits, rex, sink);
}
sink.put1(0x0f);
sink.put1(bits as u8);
}
// Emit three-byte opcode (0F 3[8A] XX) with mandatory prefix.
fn put_mp3<CS: CodeSink + ?Sized>(bits: u16, rex: u8, sink: &mut CS) {
debug_assert_eq!(bits & 0x8800, 0x0800, "Invalid encoding bits for Mp3*");
@ -152,7 +197,7 @@ fn put_mp3<CS: CodeSink + ?Sized>(bits: u16, rex: u8, sink: &mut CS) {
// Emit three-byte opcode (0F 3[8A] XX) with mandatory prefix and REX
fn put_rexmp3<CS: CodeSink + ?Sized>(bits: u16, rex: u8, sink: &mut CS) {
debug_assert_eq!(bits & 0x0800, 0x0800, "Invalid encoding bits for Mp3*");
debug_assert_eq!(bits & 0x0800, 0x0800, "Invalid encoding bits for RexMp3*");
let enc = EncodingBits::from(bits);
sink.put1(PREFIX[(enc.pp() - 1) as usize]);
rex_prefix(bits, rex, sink);

Просмотреть файл

@ -16,9 +16,20 @@ use crate::isa::{self, TargetIsa};
use crate::predicates;
use crate::regalloc::RegDiversions;
use cranelift_codegen_shared::isa::x86::EncodingBits;
include!(concat!(env!("OUT_DIR"), "/encoding-x86.rs"));
include!(concat!(env!("OUT_DIR"), "/legalize-x86.rs"));
/// Whether the REX prefix is needed for encoding extended registers (via REX.RXB).
///
/// Normal x86 instructions have only 3 bits for encoding a register.
/// The REX prefix adds REX.R, REX,X, and REX.B bits, interpreted as fourth bits.
pub fn is_extended_reg(reg: RegUnit) -> bool {
// Extended registers have the fourth bit set.
reg as u8 & 0b1000 != 0
}
pub fn needs_sib_byte(reg: RegUnit) -> bool {
reg == RU::r12 as RegUnit || reg == RU::rsp as RegUnit
}
@ -29,74 +40,179 @@ pub fn needs_sib_byte_or_offset(reg: RegUnit) -> bool {
needs_sib_byte(reg) || needs_offset(reg)
}
fn additional_size_if(
fn test_input(
op_index: usize,
inst: Inst,
divert: &RegDiversions,
func: &Function,
condition_func: fn(RegUnit) -> bool,
) -> u8 {
let addr_reg = divert.reg(func.dfg.inst_args(inst)[op_index], &func.locations);
if condition_func(addr_reg) {
1
} else {
0
}
) -> bool {
let in_reg = divert.reg(func.dfg.inst_args(inst)[op_index], &func.locations);
condition_func(in_reg)
}
fn size_plus_maybe_offset_for_in_reg_0(
sizing: &RecipeSizing,
_enc: Encoding,
fn test_result(
result_index: usize,
inst: Inst,
divert: &RegDiversions,
func: &Function,
) -> u8 {
sizing.base_size + additional_size_if(0, inst, divert, func, needs_offset)
condition_func: fn(RegUnit) -> bool,
) -> bool {
let out_reg = divert.reg(func.dfg.inst_results(inst)[result_index], &func.locations);
condition_func(out_reg)
}
fn size_plus_maybe_offset_for_in_reg_1(
fn size_plus_maybe_offset_for_inreg_0(
sizing: &RecipeSizing,
_enc: Encoding,
inst: Inst,
divert: &RegDiversions,
func: &Function,
) -> u8 {
sizing.base_size + additional_size_if(1, inst, divert, func, needs_offset)
let needs_offset = test_input(0, inst, divert, func, needs_offset);
sizing.base_size + if needs_offset { 1 } else { 0 }
}
fn size_plus_maybe_sib_for_in_reg_0(
fn size_plus_maybe_offset_for_inreg_1(
sizing: &RecipeSizing,
_enc: Encoding,
inst: Inst,
divert: &RegDiversions,
func: &Function,
) -> u8 {
sizing.base_size + additional_size_if(0, inst, divert, func, needs_sib_byte)
let needs_offset = test_input(1, inst, divert, func, needs_offset);
sizing.base_size + if needs_offset { 1 } else { 0 }
}
fn size_plus_maybe_sib_for_in_reg_1(
fn size_plus_maybe_sib_for_inreg_0(
sizing: &RecipeSizing,
_enc: Encoding,
inst: Inst,
divert: &RegDiversions,
func: &Function,
) -> u8 {
sizing.base_size + additional_size_if(1, inst, divert, func, needs_sib_byte)
let needs_sib = test_input(0, inst, divert, func, needs_sib_byte);
sizing.base_size + if needs_sib { 1 } else { 0 }
}
fn size_plus_maybe_sib_or_offset_for_in_reg_0(
fn size_plus_maybe_sib_for_inreg_1(
sizing: &RecipeSizing,
_enc: Encoding,
inst: Inst,
divert: &RegDiversions,
func: &Function,
) -> u8 {
sizing.base_size + additional_size_if(0, inst, divert, func, needs_sib_byte_or_offset)
let needs_sib = test_input(1, inst, divert, func, needs_sib_byte);
sizing.base_size + if needs_sib { 1 } else { 0 }
}
fn size_plus_maybe_sib_or_offset_for_in_reg_1(
fn size_plus_maybe_sib_or_offset_for_inreg_0(
sizing: &RecipeSizing,
_enc: Encoding,
inst: Inst,
divert: &RegDiversions,
func: &Function,
) -> u8 {
sizing.base_size + additional_size_if(1, inst, divert, func, needs_sib_byte_or_offset)
let needs_sib_or_offset = test_input(0, inst, divert, func, needs_sib_byte_or_offset);
sizing.base_size + if needs_sib_or_offset { 1 } else { 0 }
}
fn size_plus_maybe_sib_or_offset_for_inreg_1(
sizing: &RecipeSizing,
_enc: Encoding,
inst: Inst,
divert: &RegDiversions,
func: &Function,
) -> u8 {
let needs_sib_or_offset = test_input(1, inst, divert, func, needs_sib_byte_or_offset);
sizing.base_size + if needs_sib_or_offset { 1 } else { 0 }
}
/// Infers whether a dynamic REX prefix will be emitted, for use with one input reg.
///
/// A REX prefix is known to be emitted if either:
/// 1. The EncodingBits specify that REX.W is to be set.
/// 2. Registers are used that require REX.R or REX.B bits for encoding.
fn size_with_inferred_rex_for_inreg0(
sizing: &RecipeSizing,
enc: Encoding,
inst: Inst,
divert: &RegDiversions,
func: &Function,
) -> u8 {
let needs_rex = (EncodingBits::from(enc.bits()).rex_w() != 0)
|| test_input(0, inst, divert, func, is_extended_reg);
sizing.base_size + if needs_rex { 1 } else { 0 }
}
/// Infers whether a dynamic REX prefix will be emitted, based on the second operand.
fn size_with_inferred_rex_for_inreg1(
sizing: &RecipeSizing,
enc: Encoding,
inst: Inst,
divert: &RegDiversions,
func: &Function,
) -> u8 {
let needs_rex = (EncodingBits::from(enc.bits()).rex_w() != 0)
|| test_input(1, inst, divert, func, is_extended_reg);
sizing.base_size + if needs_rex { 1 } else { 0 }
}
/// Infers whether a dynamic REX prefix will be emitted, based on the third operand.
fn size_with_inferred_rex_for_inreg2(
sizing: &RecipeSizing,
enc: Encoding,
inst: Inst,
divert: &RegDiversions,
func: &Function,
) -> u8 {
let needs_rex = (EncodingBits::from(enc.bits()).rex_w() != 0)
|| test_input(2, inst, divert, func, is_extended_reg);
sizing.base_size + if needs_rex { 1 } else { 0 }
}
/// Infers whether a dynamic REX prefix will be emitted, for use with two input registers.
///
/// A REX prefix is known to be emitted if either:
/// 1. The EncodingBits specify that REX.W is to be set.
/// 2. Registers are used that require REX.R or REX.B bits for encoding.
fn size_with_inferred_rex_for_inreg0_inreg1(
sizing: &RecipeSizing,
enc: Encoding,
inst: Inst,
divert: &RegDiversions,
func: &Function,
) -> u8 {
let needs_rex = (EncodingBits::from(enc.bits()).rex_w() != 0)
|| test_input(0, inst, divert, func, is_extended_reg)
|| test_input(1, inst, divert, func, is_extended_reg);
sizing.base_size + if needs_rex { 1 } else { 0 }
}
/// Infers whether a dynamic REX prefix will be emitted, based on a single
/// input register and a single output register.
fn size_with_inferred_rex_for_inreg0_outreg0(
sizing: &RecipeSizing,
enc: Encoding,
inst: Inst,
divert: &RegDiversions,
func: &Function,
) -> u8 {
let needs_rex = (EncodingBits::from(enc.bits()).rex_w() != 0)
|| test_input(0, inst, divert, func, is_extended_reg)
|| test_result(0, inst, divert, func, is_extended_reg);
sizing.base_size + if needs_rex { 1 } else { 0 }
}
/// Infers whether a dynamic REX prefix will be emitted, for use with CMOV.
///
/// CMOV uses 3 inputs, with the REX is inferred from reg1 and reg2.
fn size_with_inferred_rex_for_cmov(
sizing: &RecipeSizing,
enc: Encoding,
inst: Inst,
divert: &RegDiversions,
func: &Function,
) -> u8 {
let needs_rex = (EncodingBits::from(enc.bits()).rex_w() != 0)
|| test_input(1, inst, divert, func, is_extended_reg)
|| test_input(2, inst, divert, func, is_extended_reg);
sizing.base_size + if needs_rex { 1 } else { 0 }
}
/// If the value's definition is a constant immediate, returns its unpacked value, or None

354
third_party/rust/cranelift-codegen/src/isa/x86/fde.rs поставляемый Normal file
Просмотреть файл

@ -0,0 +1,354 @@
//! Support for FDE data generation.
use crate::binemit::{FrameUnwindOffset, FrameUnwindSink, Reloc};
use crate::ir::{FrameLayoutChange, Function};
use crate::isa::{CallConv, RegUnit, TargetIsa};
use alloc::vec::Vec;
use core::convert::TryInto;
use gimli::write::{
Address, CallFrameInstruction, CommonInformationEntry, EhFrame, EndianVec,
FrameDescriptionEntry, FrameTable, Result, Writer,
};
use gimli::{Encoding, Format, LittleEndian, Register, X86_64};
use std::ptr;
pub type FDERelocEntry = (FrameUnwindOffset, Reloc);
const FUNCTION_ENTRY_ADDRESS: Address = Address::Symbol {
symbol: 0,
addend: 0,
};
#[derive(Clone)]
struct FDEWriter {
vec: EndianVec<LittleEndian>,
relocs: Vec<FDERelocEntry>,
}
impl FDEWriter {
fn new() -> Self {
Self {
vec: EndianVec::new(LittleEndian),
relocs: Vec::new(),
}
}
fn into_vec_and_relocs(self) -> (Vec<u8>, Vec<FDERelocEntry>) {
(self.vec.into_vec(), self.relocs)
}
}
impl Writer for FDEWriter {
type Endian = LittleEndian;
fn endian(&self) -> Self::Endian {
LittleEndian
}
fn len(&self) -> usize {
self.vec.len()
}
fn write(&mut self, bytes: &[u8]) -> Result<()> {
self.vec.write(bytes)
}
fn write_at(&mut self, offset: usize, bytes: &[u8]) -> Result<()> {
self.vec.write_at(offset, bytes)
}
fn write_address(&mut self, address: Address, size: u8) -> Result<()> {
match address {
Address::Constant(_) => self.vec.write_address(address, size),
Address::Symbol { .. } => {
assert_eq!(address, FUNCTION_ENTRY_ADDRESS);
let rt = match size {
4 => Reloc::Abs4,
8 => Reloc::Abs8,
_ => {
panic!("Unexpected address size at FDEWriter::write_address");
}
};
self.relocs.push((self.vec.len().try_into().unwrap(), rt));
self.vec.write_udata(0, size)
}
}
}
}
fn return_address_reg(isa: &dyn TargetIsa) -> Register {
assert!(isa.name() == "x86" && isa.pointer_bits() == 64);
X86_64::RA
}
fn map_reg(isa: &dyn TargetIsa, reg: RegUnit) -> Register {
assert!(isa.name() == "x86" && isa.pointer_bits() == 64);
// Mapping from https://github.com/bytecodealliance/cranelift/pull/902 by @iximeow
const X86_GP_REG_MAP: [gimli::Register; 16] = [
X86_64::RAX,
X86_64::RCX,
X86_64::RDX,
X86_64::RBX,
X86_64::RSP,
X86_64::RBP,
X86_64::RSI,
X86_64::RDI,
X86_64::R8,
X86_64::R9,
X86_64::R10,
X86_64::R11,
X86_64::R12,
X86_64::R13,
X86_64::R14,
X86_64::R15,
];
const X86_XMM_REG_MAP: [gimli::Register; 16] = [
X86_64::XMM0,
X86_64::XMM1,
X86_64::XMM2,
X86_64::XMM3,
X86_64::XMM4,
X86_64::XMM5,
X86_64::XMM6,
X86_64::XMM7,
X86_64::XMM8,
X86_64::XMM9,
X86_64::XMM10,
X86_64::XMM11,
X86_64::XMM12,
X86_64::XMM13,
X86_64::XMM14,
X86_64::XMM15,
];
let reg_info = isa.register_info();
let bank = reg_info.bank_containing_regunit(reg).unwrap();
match bank.name {
"IntRegs" => {
// x86 GP registers have a weird mapping to DWARF registers, so we use a
// lookup table.
X86_GP_REG_MAP[(reg - bank.first_unit) as usize]
}
"FloatRegs" => X86_XMM_REG_MAP[(reg - bank.first_unit) as usize],
_ => {
panic!("unsupported register bank: {}", bank.name);
}
}
}
fn to_cfi(
isa: &dyn TargetIsa,
change: &FrameLayoutChange,
cfa_def_reg: &mut Register,
cfa_def_offset: &mut i32,
) -> Option<CallFrameInstruction> {
Some(match change {
FrameLayoutChange::CallFrameAddressAt { reg, offset } => {
let mapped = map_reg(isa, *reg);
let offset = (*offset) as i32;
if mapped != *cfa_def_reg && offset != *cfa_def_offset {
*cfa_def_reg = mapped;
*cfa_def_offset = offset;
CallFrameInstruction::Cfa(mapped, offset)
} else if offset != *cfa_def_offset {
*cfa_def_offset = offset;
CallFrameInstruction::CfaOffset(offset)
} else if mapped != *cfa_def_reg {
*cfa_def_reg = mapped;
CallFrameInstruction::CfaRegister(mapped)
} else {
return None;
}
}
FrameLayoutChange::RegAt { reg, cfa_offset } => {
assert!(cfa_offset % -8 == 0);
let cfa_offset = *cfa_offset as i32;
let mapped = map_reg(isa, *reg);
CallFrameInstruction::Offset(mapped, cfa_offset)
}
FrameLayoutChange::ReturnAddressAt { cfa_offset } => {
assert!(cfa_offset % -8 == 0);
let cfa_offset = *cfa_offset as i32;
CallFrameInstruction::Offset(X86_64::RA, cfa_offset)
}
_ => {
return None;
}
})
}
/// Creates FDE structure from FrameLayout.
pub fn emit_fde(func: &Function, isa: &dyn TargetIsa, sink: &mut dyn FrameUnwindSink) {
assert!(isa.name() == "x86");
// Expecting function with System V prologue
assert!(
func.signature.call_conv == CallConv::Fast
|| func.signature.call_conv == CallConv::Cold
|| func.signature.call_conv == CallConv::SystemV
);
assert!(func.frame_layout.is_some(), "expected func.frame_layout");
let frame_layout = func.frame_layout.as_ref().unwrap();
let mut ebbs = func.layout.ebbs().collect::<Vec<_>>();
ebbs.sort_by_key(|ebb| func.offsets[*ebb]); // Ensure inst offsets always increase
let encinfo = isa.encoding_info();
let mut last_offset = 0;
let mut changes = Vec::new();
for ebb in ebbs {
for (offset, inst, size) in func.inst_offsets(ebb, &encinfo) {
let address_offset = (offset + size) as usize;
assert!(last_offset <= address_offset);
if let Some(cmds) = frame_layout.instructions.get(&inst) {
for cmd in cmds.iter() {
changes.push((address_offset, cmd.clone()));
}
}
last_offset = address_offset;
}
}
let len = last_offset as u32;
let word_size = isa.pointer_bytes() as i32;
let encoding = Encoding {
format: Format::Dwarf32,
version: 1,
address_size: word_size as u8,
};
let mut frames = FrameTable::default();
let mut cfa_def_reg = return_address_reg(isa);
let mut cfa_def_offset = 0i32;
let mut cie = CommonInformationEntry::new(
encoding,
/* code_alignment_factor = */ 1,
/* data_alignment_factor = */ -word_size as i8,
return_address_reg(isa),
);
for ch in frame_layout.initial.iter() {
if let Some(cfi) = to_cfi(isa, ch, &mut cfa_def_reg, &mut cfa_def_offset) {
cie.add_instruction(cfi);
}
}
let cie_id = frames.add_cie(cie);
let mut fde = FrameDescriptionEntry::new(FUNCTION_ENTRY_ADDRESS, len);
for (addr, ch) in changes.iter() {
if let Some(cfi) = to_cfi(isa, ch, &mut cfa_def_reg, &mut cfa_def_offset) {
fde.add_instruction((*addr) as u32, cfi);
}
}
frames.add_fde(cie_id, fde);
let mut eh_frame = EhFrame::from(FDEWriter::new());
frames.write_eh_frame(&mut eh_frame).unwrap();
let (bytes, relocs) = eh_frame.clone().into_vec_and_relocs();
let unwind_start = sink.len();
sink.bytes(&bytes);
for (off, r) in relocs {
sink.reloc(r, off + unwind_start);
}
let fde_offset = unsafe { ptr::read::<u32>(bytes.as_ptr() as *const u32) } as usize + 4;
sink.set_entry_offset(unwind_start + fde_offset);
// Need 0 marker for GCC unwind to end FDE "list".
sink.bytes(&[0, 0, 0, 0]);
}
#[cfg(test)]
mod tests {
use super::*;
use crate::binemit::{FrameUnwindOffset, Reloc};
use crate::cursor::{Cursor, FuncCursor};
use crate::ir::{ExternalName, InstBuilder, Signature, StackSlotData, StackSlotKind};
use crate::isa::{lookup, CallConv};
use crate::settings::{builder, Flags};
use crate::Context;
use std::str::FromStr;
use target_lexicon::triple;
struct SimpleUnwindSink(pub Vec<u8>, pub usize, pub Vec<(Reloc, usize)>);
impl FrameUnwindSink for SimpleUnwindSink {
fn len(&self) -> FrameUnwindOffset {
self.0.len()
}
fn bytes(&mut self, b: &[u8]) {
self.0.extend_from_slice(b);
}
fn reloc(&mut self, r: Reloc, off: FrameUnwindOffset) {
self.2.push((r, off));
}
fn set_entry_offset(&mut self, off: FrameUnwindOffset) {
self.1 = off;
}
}
#[test]
fn test_simple_func() {
let isa = lookup(triple!("x86_64"))
.expect("expect x86 ISA")
.finish(Flags::new(builder()));
let mut context = Context::for_function(create_function(
CallConv::SystemV,
Some(StackSlotData::new(StackSlotKind::ExplicitSlot, 64)),
));
context.func.collect_frame_layout_info();
context.compile(&*isa).expect("expected compilation");
let mut sink = SimpleUnwindSink(Vec::new(), 0, Vec::new());
emit_fde(&context.func, &*isa, &mut sink);
assert_eq!(
sink.0,
vec![
20, 0, 0, 0, // CIE len
0, 0, 0, 0, // CIE marker
1, // version
0, // augmentation string
1, // code aligment = 1
120, // data alignment = -8
16, // RA = r16
0x0c, 0x07, 0x08, // DW_CFA_def_cfa r7, 8
0x90, 0x01, // DW_CFA_offset r16, -8 * 1
0, 0, 0, 0, 0, 0, // padding
36, 0, 0, 0, // FDE len
28, 0, 0, 0, // CIE offset
0, 0, 0, 0, 0, 0, 0, 0, // addr reloc
16, 0, 0, 0, 0, 0, 0, 0, // function length
0x42, // DW_CFA_advance_loc 2
0x0e, 0x10, // DW_CFA_def_cfa_offset 16
0x86, 0x02, // DW_CFA_offset r6, -8 * 2
0x43, // DW_CFA_advance_loc 3
0x0d, 0x06, // DW_CFA_def_cfa_register
0x4a, // DW_CFA_advance_loc 10
0x0c, 0x07, 0x08, // DW_CFA_def_cfa r7, 8
0, 0, 0, 0, // padding
0, 0, 0, 0, // End of FDEs
]
);
assert_eq!(sink.1, 24);
assert_eq!(sink.2.len(), 1);
}
fn create_function(call_conv: CallConv, stack_slot: Option<StackSlotData>) -> Function {
let mut func =
Function::with_name_signature(ExternalName::user(0, 0), Signature::new(call_conv));
let ebb0 = func.dfg.make_ebb();
let mut pos = FuncCursor::new(&mut func);
pos.insert_ebb(ebb0);
pos.ins().return_(&[]);
if let Some(stack_slot) = stack_slot {
func.stack_slots.push(stack_slot);
}
func
}
}

Просмотреть файл

@ -3,14 +3,19 @@
mod abi;
mod binemit;
mod enc_tables;
#[cfg(feature = "unwind")]
mod fde;
mod registers;
pub mod settings;
#[cfg(feature = "unwind")]
mod unwind;
use super::super::settings as shared_settings;
#[cfg(feature = "testing_hooks")]
use crate::binemit::CodeSink;
use crate::binemit::{emit_function, MemoryCodeSink};
#[cfg(feature = "unwind")]
use crate::binemit::{FrameUnwindKind, FrameUnwindSink};
use crate::ir;
use crate::isa::enc_tables::{self as shared_enc_tables, lookup_enclist, Encodings};
use crate::isa::Builder as IsaBuilder;
@ -20,7 +25,6 @@ use crate::result::CodegenResult;
use crate::timing;
use alloc::borrow::Cow;
use alloc::boxed::Box;
use alloc::vec::Vec;
use core::fmt;
use target_lexicon::{PointerWidth, Triple};
@ -157,8 +161,14 @@ impl TargetIsa for Isa {
/// Emit unwind information for the given function.
///
/// Only some calling conventions (e.g. Windows fastcall) will have unwind information.
fn emit_unwind_info(&self, func: &ir::Function, mem: &mut Vec<u8>) {
abi::emit_unwind_info(func, self, mem);
#[cfg(feature = "unwind")]
fn emit_unwind_info(
&self,
func: &ir::Function,
kind: FrameUnwindKind,
sink: &mut dyn FrameUnwindSink,
) {
abi::emit_unwind_info(func, self, kind, sink);
}
}

Просмотреть файл

@ -1,6 +1,7 @@
//! Unwind information for x64 Windows.
use super::registers::RU;
use crate::binemit::FrameUnwindSink;
use crate::ir::{Function, InstructionData, Opcode};
use crate::isa::{CallConv, RegUnit, TargetIsa};
use alloc::vec::Vec;
@ -11,16 +12,20 @@ const SMALL_ALLOC_MAX_SIZE: u32 = 128;
/// Maximum (inclusive) size of a "large" stack allocation that can represented in 16-bits
const LARGE_ALLOC_16BIT_MAX_SIZE: u32 = 524280;
fn write_u16<T: ByteOrder>(mem: &mut Vec<u8>, v: u16) {
let mut buf = [0; 2];
T::write_u16(&mut buf, v);
mem.extend(buf.iter());
fn write_u8(sink: &mut dyn FrameUnwindSink, v: u8) {
sink.bytes(&[v]);
}
fn write_u32<T: ByteOrder>(mem: &mut Vec<u8>, v: u32) {
fn write_u16<T: ByteOrder>(sink: &mut dyn FrameUnwindSink, v: u16) {
let mut buf = [0; 2];
T::write_u16(&mut buf, v);
sink.bytes(&buf);
}
fn write_u32<T: ByteOrder>(sink: &mut dyn FrameUnwindSink, v: u32) {
let mut buf = [0; 4];
T::write_u32(&mut buf, v);
mem.extend(buf.iter());
sink.bytes(&buf);
}
/// The supported unwind codes for the x64 Windows ABI.
@ -36,7 +41,7 @@ enum UnwindCode {
}
impl UnwindCode {
fn emit(&self, mem: &mut Vec<u8>) {
fn emit(&self, sink: &mut dyn FrameUnwindSink) {
enum UnwindOperation {
PushNonvolatileRegister,
LargeStackAlloc,
@ -46,30 +51,37 @@ impl UnwindCode {
match self {
Self::PushRegister { offset, reg } => {
mem.push(*offset);
mem.push(((*reg as u8) << 4) | (UnwindOperation::PushNonvolatileRegister as u8));
write_u8(sink, *offset);
write_u8(
sink,
((*reg as u8) << 4) | (UnwindOperation::PushNonvolatileRegister as u8),
);
}
Self::StackAlloc { offset, size } => {
// Stack allocations on Windows must be a multiple of 8 and be at least 1 slot
assert!(*size >= 8);
assert!((*size % 8) == 0);
mem.push(*offset);
write_u8(sink, *offset);
if *size <= SMALL_ALLOC_MAX_SIZE {
mem.push(
write_u8(
sink,
((((*size - 8) / 8) as u8) << 4) | UnwindOperation::SmallStackAlloc as u8,
);
} else if *size <= LARGE_ALLOC_16BIT_MAX_SIZE {
mem.push(UnwindOperation::LargeStackAlloc as u8);
write_u16::<LittleEndian>(mem, (*size / 8) as u16);
write_u8(sink, UnwindOperation::LargeStackAlloc as u8);
write_u16::<LittleEndian>(sink, (*size / 8) as u16);
} else {
mem.push((1 << 4) | (UnwindOperation::LargeStackAlloc as u8));
write_u32::<LittleEndian>(mem, *size);
write_u8(sink, (1 << 4) | (UnwindOperation::LargeStackAlloc as u8));
write_u32::<LittleEndian>(sink, *size);
}
}
Self::SetFramePointer { offset, sp_offset } => {
mem.push(*offset);
mem.push((*sp_offset << 4) | (UnwindOperation::SetFramePointer as u8));
write_u8(sink, *offset);
write_u8(
sink,
(*sp_offset << 4) | (UnwindOperation::SetFramePointer as u8),
);
}
};
}
@ -231,48 +243,49 @@ impl UnwindInfo {
.fold(0, |nodes, c| nodes + c.node_count())
}
pub fn emit(&self, mem: &mut Vec<u8>) {
pub fn emit(&self, sink: &mut dyn FrameUnwindSink) {
const UNWIND_INFO_VERSION: u8 = 1;
let size = self.size();
let offset = mem.len();
let offset = sink.len();
// Ensure the memory is 32-bit aligned
assert_eq!(offset % 4, 0);
mem.reserve(offset + size);
sink.reserve(offset + size);
let node_count = self.node_count();
assert!(node_count <= 256);
mem.push((self.flags << 3) | UNWIND_INFO_VERSION);
mem.push(self.prologue_size);
mem.push(node_count as u8);
write_u8(sink, (self.flags << 3) | UNWIND_INFO_VERSION);
write_u8(sink, self.prologue_size);
write_u8(sink, node_count as u8);
if let Some(reg) = self.frame_register {
mem.push((self.frame_register_offset << 4) | reg as u8);
write_u8(sink, (self.frame_register_offset << 4) | reg as u8);
} else {
mem.push(0);
write_u8(sink, 0);
}
// Unwind codes are written in reverse order (prologue offset descending)
for code in self.unwind_codes.iter().rev() {
code.emit(mem);
code.emit(sink);
}
// To keep a 32-bit alignment, emit 2 bytes of padding if there's an odd number of 16-bit nodes
if (node_count & 1) == 1 {
write_u16::<LittleEndian>(mem, 0);
write_u16::<LittleEndian>(sink, 0);
}
// Ensure the correct number of bytes was emitted
assert_eq!(mem.len() - offset, size);
assert_eq!(sink.len() - offset, size);
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::binemit::{FrameUnwindOffset, Reloc};
use crate::cursor::{Cursor, FuncCursor};
use crate::ir::{ExternalName, InstBuilder, Signature, StackSlotData, StackSlotKind};
use crate::isa::{lookup, CallConv};
@ -281,6 +294,18 @@ mod tests {
use std::str::FromStr;
use target_lexicon::triple;
struct SimpleUnwindSink(pub Vec<u8>);
impl FrameUnwindSink for SimpleUnwindSink {
fn len(&self) -> FrameUnwindOffset {
self.0.len()
}
fn bytes(&mut self, b: &[u8]) {
self.0.extend_from_slice(b);
}
fn reloc(&mut self, _: Reloc, _: FrameUnwindOffset) {}
fn set_entry_offset(&mut self, _: FrameUnwindOffset) {}
}
#[test]
fn test_wrong_calling_convention() {
let isa = lookup(triple!("x86_64"))
@ -336,11 +361,11 @@ mod tests {
assert_eq!(unwind.size(), 12);
let mut mem = Vec::new();
unwind.emit(&mut mem);
let mut sink = SimpleUnwindSink(Vec::new());
unwind.emit(&mut sink);
assert_eq!(
mem,
sink.0,
[
0x01, // Version and flags (version 1, no flags)
0x09, // Prologue size
@ -400,11 +425,11 @@ mod tests {
assert_eq!(unwind.size(), 12);
let mut mem = Vec::new();
unwind.emit(&mut mem);
let mut sink = SimpleUnwindSink(Vec::new());
unwind.emit(&mut sink);
assert_eq!(
mem,
sink.0,
[
0x01, // Version and flags (version 1, no flags)
0x1B, // Prologue size
@ -464,11 +489,11 @@ mod tests {
assert_eq!(unwind.size(), 16);
let mut mem = Vec::new();
unwind.emit(&mut mem);
let mut sink = SimpleUnwindSink(Vec::new());
unwind.emit(&mut sink);
assert_eq!(
mem,
sink.0,
[
0x01, // Version and flags (version 1, no flags)
0x1B, // Prologue size

Просмотреть файл

@ -191,7 +191,7 @@ pub fn legalize_function(func: &mut ir::Function, cfg: &mut ControlFlowGraph, is
}
// Now that we've lowered all br_tables, we don't need the jump tables anymore.
if !isa.flags().jump_tables_enabled() {
if !isa.flags().enable_jump_tables() {
pos.func.jump_tables.clear();
}
}
@ -276,7 +276,7 @@ fn expand_br_table(
cfg: &mut ControlFlowGraph,
isa: &dyn TargetIsa,
) {
if isa.flags().jump_tables_enabled() {
if isa.flags().enable_jump_tables() {
expand_br_table_jt(inst, func, cfg, isa);
} else {
expand_br_table_conds(inst, func, cfg, isa);

Просмотреть файл

@ -384,7 +384,7 @@ mod tests {
probestack_size_log2 = 12\n\
enable_verifier = true\n\
is_pic = false\n\
colocated_libcalls = false\n\
use_colocated_libcalls = false\n\
avoid_div_traps = false\n\
enable_float = true\n\
enable_nan_canonicalization = false\n\
@ -393,10 +393,10 @@ mod tests {
enable_simd = false\n\
enable_atomics = true\n\
enable_safepoints = false\n\
allones_funcaddrs = false\n\
probestack_enabled = true\n\
emit_all_ones_funcaddrs = false\n\
enable_probestack = true\n\
probestack_func_adjusts_sp = false\n\
jump_tables_enabled = true\n"
enable_jump_tables = true\n"
);
assert_eq!(f.opt_level(), super::OptLevel::None);
assert_eq!(f.enable_simd(), false);

Просмотреть файл

@ -124,7 +124,8 @@ pub fn do_simple_gvn(func: &mut Function, domtree: &mut DominatorTree) {
use crate::scoped_hash_map::Entry::*;
match visible_values.entry(key) {
Occupied(entry) => {
debug_assert!(domtree.dominates(*entry.get(), inst, &func.layout));
let layout = &func.layout;
debug_assert!(domtree.dominates(*entry.get(), inst, layout));
// If the redundant instruction is representing the current
// scope, pick a new representative.
let old = scope_stack.last_mut().unwrap();

Просмотреть файл

@ -1971,6 +1971,9 @@ impl<'a> Verifier<'a> {
self.typecheck_function_signature(errors)?;
for ebb in self.func.layout.ebbs() {
if self.func.layout.first_inst(ebb).is_none() {
return errors.fatal((ebb, format!("{} cannot be empty", ebb)));
}
for inst in self.func.layout.ebb_insts(ebb) {
self.ebb_integrity(ebb, inst, errors)?;
self.instruction_integrity(inst, errors)?;
@ -2117,4 +2120,18 @@ mod tests {
"inst0 (v0, v1 = iconst.i32 42): has more result values than expected"
)
}
#[test]
fn test_empty_ebb() {
let mut func = Function::new();
let ebb0 = func.dfg.make_ebb();
func.layout.append_ebb(ebb0);
let flags = &settings::Flags::new(settings::builder());
let verifier = Verifier::new(&func, flags.into());
let mut errors = VerifierErrors::default();
let _ = verifier.run(&mut errors);
assert_err_with_msg!(errors, "ebb0 cannot be empty");
}
}

Просмотреть файл

@ -1 +1 @@
{"files":{"Cargo.toml":"6cf98e2d02e873cef38801f71a47ac39f7941bc702bd44cc54cc4a910d1bec54","LICENSE":"268872b9816f90fd8e85db5a28d33f8150ebb8dd016653fb39ef1f94f2686bc5","README.md":"96ceffbfd88fb06e3b41aa4d3087cffbbf8441d04eba7ab09662a72ab600a321","src/boxed_slice.rs":"69d539b72460c0aba1d30e0b72efb0c29d61558574d751c784794e14abf41352","src/iter.rs":"4a4d3309fe9aad14fd7702f02459f4277b4ddb50dba700e58dcc75665ffebfb3","src/keys.rs":"b8c2fba26dee15bf3d1880bb2b41e8d66fe1428d242ee6d9fd30ee94bbd0407d","src/lib.rs":"0cd9145c1528f95ee7770765faa2f9a1051791144e2936789248b25fdfe06fc1","src/list.rs":"4bf609eb7cc7c000c18da746596d5fcc67eece3f919ee2d76e19f6ac371640d1","src/map.rs":"546b36be4cbbd2423bacbed69cbe114c63538c3f635e15284ab8e4223e717705","src/packed_option.rs":"dccb3dd6fc87eba0101de56417f21cab67a4394831df9fa41e3bbddb70cdf694","src/primary.rs":"30d5e2ab8427fd2b2c29da395812766049e3c40845cc887af3ee233dba91a063","src/set.rs":"dd04a4954863cc106e168a7d9a89bcebd1c4e045e7ef9ec1f0dadc0a8eaf919d","src/sparse.rs":"536e31fdcf64450526f5e5b85e97406c26b998bc7e0d8161b6b449c24265449f"},"package":null}
{"files":{"Cargo.toml":"f996c9d9c38289ce69f727a9331594184be6b18b68f69343bf7ddf92a2241573","LICENSE":"268872b9816f90fd8e85db5a28d33f8150ebb8dd016653fb39ef1f94f2686bc5","README.md":"96ceffbfd88fb06e3b41aa4d3087cffbbf8441d04eba7ab09662a72ab600a321","src/boxed_slice.rs":"69d539b72460c0aba1d30e0b72efb0c29d61558574d751c784794e14abf41352","src/iter.rs":"4a4d3309fe9aad14fd7702f02459f4277b4ddb50dba700e58dcc75665ffebfb3","src/keys.rs":"b8c2fba26dee15bf3d1880bb2b41e8d66fe1428d242ee6d9fd30ee94bbd0407d","src/lib.rs":"0cd9145c1528f95ee7770765faa2f9a1051791144e2936789248b25fdfe06fc1","src/list.rs":"4bf609eb7cc7c000c18da746596d5fcc67eece3f919ee2d76e19f6ac371640d1","src/map.rs":"546b36be4cbbd2423bacbed69cbe114c63538c3f635e15284ab8e4223e717705","src/packed_option.rs":"dccb3dd6fc87eba0101de56417f21cab67a4394831df9fa41e3bbddb70cdf694","src/primary.rs":"30d5e2ab8427fd2b2c29da395812766049e3c40845cc887af3ee233dba91a063","src/set.rs":"dd04a4954863cc106e168a7d9a89bcebd1c4e045e7ef9ec1f0dadc0a8eaf919d","src/sparse.rs":"536e31fdcf64450526f5e5b85e97406c26b998bc7e0d8161b6b449c24265449f"},"package":null}

Просмотреть файл

@ -1,7 +1,7 @@
[package]
authors = ["The Cranelift Project Developers"]
name = "cranelift-entity"
version = "0.51.0"
version = "0.55.0"
description = "Data structures using entity references as mapping keys"
license = "Apache-2.0 WITH LLVM-exception"
documentation = "https://cranelift.readthedocs.io/"

Просмотреть файл

@ -1 +1 @@
{"files":{"Cargo.toml":"5564c8fe72dd80449647fcc8488f461f22b234929cfe534d13f600825d661d3f","LICENSE":"268872b9816f90fd8e85db5a28d33f8150ebb8dd016653fb39ef1f94f2686bc5","README.md":"dea43e8044284df50f8b8772e9b48ba8b109b45c74111ff73619775d57ad8d67","src/frontend.rs":"c8ba698562fe845282e3118cd2a66656161c2babe61096c62fbc373ec5380753","src/lib.rs":"2a8efc913364bdb700268fb66a6132d2d48f3fe10fe80443fcf17d9480a0f167","src/ssa.rs":"3e4dd91c59e3e5acde2ec758fc1bc4c5783940bce8637b7b67b180cfab0007c3","src/switch.rs":"6a31c37ed9e93ee943b7e98e28646804497d64a5a6a55aa1924c5feb27b52dfa","src/variable.rs":"399437bd7d2ac11a7a748bad7dd1f6dac58824d374ec318f36367a9d077cc225"},"package":null}
{"files":{"Cargo.toml":"fe6a59f44df0fa8aa9ad1de62e1c8559379b9e8ceb3545fb448fe48ff52360f5","LICENSE":"268872b9816f90fd8e85db5a28d33f8150ebb8dd016653fb39ef1f94f2686bc5","README.md":"dea43e8044284df50f8b8772e9b48ba8b109b45c74111ff73619775d57ad8d67","src/frontend.rs":"c8ba698562fe845282e3118cd2a66656161c2babe61096c62fbc373ec5380753","src/lib.rs":"2a8efc913364bdb700268fb66a6132d2d48f3fe10fe80443fcf17d9480a0f167","src/ssa.rs":"3e4dd91c59e3e5acde2ec758fc1bc4c5783940bce8637b7b67b180cfab0007c3","src/switch.rs":"6a31c37ed9e93ee943b7e98e28646804497d64a5a6a55aa1924c5feb27b52dfa","src/variable.rs":"399437bd7d2ac11a7a748bad7dd1f6dac58824d374ec318f36367a9d077cc225"},"package":null}

Просмотреть файл

@ -1,7 +1,7 @@
[package]
authors = ["The Cranelift Project Developers"]
name = "cranelift-frontend"
version = "0.51.0"
version = "0.55.0"
description = "Cranelift IR builder helper"
license = "Apache-2.0 WITH LLVM-exception"
documentation = "https://cranelift.readthedocs.io/"
@ -11,8 +11,8 @@ readme = "README.md"
edition = "2018"
[dependencies]
cranelift-codegen = { path = "../cranelift-codegen", version = "0.51.0", default-features = false }
target-lexicon = "0.9"
cranelift-codegen = { path = "../cranelift-codegen", version = "0.55.0", default-features = false }
target-lexicon = "0.10"
log = { version = "0.4.6", default-features = false }
hashbrown = { version = "0.6", optional = true }
smallvec = { version = "1.0.0" }

Просмотреть файл

@ -1 +1 @@
{"files":{"Cargo.toml":"09183eb6dfd8a6d33a033b46c32f8f2eca2f052af135a7b0599ecc8d9409f38c","LICENSE":"268872b9816f90fd8e85db5a28d33f8150ebb8dd016653fb39ef1f94f2686bc5","README.md":"f46f9c5df1b10bad0e87d9c2ad9f5e65bbb6749ac8843cd80ec357daa3b22c3e","src/code_translator.rs":"e60d0d35e54f2403101c4ed8af6202ae2d37cbaf63ebe21ccef6ef9ffa77ad72","src/environ/dummy.rs":"b918e7c7afd3be41d7b2b8587a1cb0119640508f475fc086f949a96d01b783d6","src/environ/mod.rs":"b6f33f619090ff497b4e22150d77a290f259716374ac2e377b73c47cd1dafe85","src/environ/spec.rs":"770b494bae5c50d6cc9e5e825e0455682f0d7e83373af0f231267ea394cc5aba","src/func_translator.rs":"0c18f09fa533b67f41ff1da9893eac8feabe9e7847620a5aa2c4ad0f2185afbb","src/lib.rs":"0dbbb3d5088799c3aaa94b083ca0c2f09906bd8fb36e9c0dd200b8122c50a8b6","src/module_translator.rs":"5e1bf9471d6f4f317bb2fb9b8697b5b08f7950520017c2869e69133e7f17a2b7","src/sections_translator.rs":"e9af588789b00c4e91e7a4bd87c7ea3c745dc1a5e00fc1f758ee8d9a46902a63","src/state/func_state.rs":"8394eb9b446fc286222b806c55689c19beb0a5b6c78c1d8dee7c19b0d5693661","src/state/mod.rs":"20014cb93615467b4d20321b52f67f66040417efcaa739a4804093bb559eed19","src/state/module_state.rs":"2f299b043deb806b48583fe54bbb46708f7d8a1454b7be0eb285568064e5a7f9","src/translation_utils.rs":"e3b56d34ab989e9e81a8b30b52fab11c886bfcb783b9c091d1a72ad35fdbe0d0","tests/wasm_testsuite.rs":"c1160bde8b0bd5d7d2eb5b6a066b60025dcebf758b1794fa32235c07e2fb2be2"},"package":null}
{"files":{"Cargo.toml":"758e4396c31b66d601fb6fb684da102e50d0dbaa4405086f6c0c86b0c27fe03d","LICENSE":"268872b9816f90fd8e85db5a28d33f8150ebb8dd016653fb39ef1f94f2686bc5","README.md":"f46f9c5df1b10bad0e87d9c2ad9f5e65bbb6749ac8843cd80ec357daa3b22c3e","src/code_translator.rs":"c6beac3cc13b5ed695d49a5a3dbd44569c2a4fd69e67abd613505d800fbbbfe5","src/environ/dummy.rs":"b918e7c7afd3be41d7b2b8587a1cb0119640508f475fc086f949a96d01b783d6","src/environ/mod.rs":"b6f33f619090ff497b4e22150d77a290f259716374ac2e377b73c47cd1dafe85","src/environ/spec.rs":"0c265a16f24c49c51cfd1d78754d90b7c7a5fa5512cfe555d5e10612ead6a9be","src/func_translator.rs":"cb5618e2ec62d28bdd7561cac0c58b591d904f7503f828c9a6887a70ab264e3d","src/lib.rs":"0dbbb3d5088799c3aaa94b083ca0c2f09906bd8fb36e9c0dd200b8122c50a8b6","src/module_translator.rs":"5e1bf9471d6f4f317bb2fb9b8697b5b08f7950520017c2869e69133e7f17a2b7","src/sections_translator.rs":"158631c43ee07a43790545201e2e597e4d71793e6f4a644851f9e5db4c0a2ef2","src/state/func_state.rs":"cc935f96a703769d075498ec2aa8fe191b8b9e3e5729e25eb409ffb82696d82e","src/state/mod.rs":"20014cb93615467b4d20321b52f67f66040417efcaa739a4804093bb559eed19","src/state/module_state.rs":"2f299b043deb806b48583fe54bbb46708f7d8a1454b7be0eb285568064e5a7f9","src/translation_utils.rs":"e3b56d34ab989e9e81a8b30b52fab11c886bfcb783b9c091d1a72ad35fdbe0d0","tests/wasm_testsuite.rs":"730304f139371e5ef3fd913ec271fc4db181869b447c6ed26c54313b5c31495c"},"package":null}

18
third_party/rust/cranelift-wasm/Cargo.toml поставляемый
Просмотреть файл

@ -1,6 +1,6 @@
[package]
name = "cranelift-wasm"
version = "0.51.0"
version = "0.55.0"
authors = ["The Cranelift Project Developers"]
description = "Translator from WebAssembly to Cranelift IR"
repository = "https://github.com/bytecodealliance/cranelift"
@ -11,23 +11,23 @@ keywords = ["webassembly", "wasm"]
edition = "2018"
[dependencies]
wasmparser = { version = "0.39.2", default-features = false }
cranelift-codegen = { path = "../cranelift-codegen", version = "0.51.0", default-features = false }
cranelift-entity = { path = "../cranelift-entity", version = "0.51.0" }
cranelift-frontend = { path = "../cranelift-frontend", version = "0.51.0", default-features = false }
wasmparser = { version = "0.47.0", default-features = false }
cranelift-codegen = { path = "../cranelift-codegen", version = "0.55.0", default-features = false }
cranelift-entity = { path = "../cranelift-entity", version = "0.55.0" }
cranelift-frontend = { path = "../cranelift-frontend", version = "0.55.0", default-features = false }
hashbrown = { version = "0.6", optional = true }
log = { version = "0.4.6", default-features = false }
serde = { version = "1.0.94", features = ["derive"], optional = true }
thiserror = "1.0.4"
[dev-dependencies]
wabt = "0.9.1"
target-lexicon = "0.9"
wat = "1.0.7"
target-lexicon = "0.10"
[features]
default = ["std", "basic-blocks"]
std = ["cranelift-codegen/std", "cranelift-frontend/std", "wasmparser/std"]
core = ["hashbrown", "cranelift-codegen/core", "cranelift-frontend/core", "wasmparser/core"]
std = ["cranelift-codegen/std", "cranelift-frontend/std"]
core = ["hashbrown", "cranelift-codegen/core", "cranelift-frontend/core"]
enable-serde = ["serde"]
# Temporary feature that enforces basic block semantics.

Просмотреть файл

@ -65,19 +65,19 @@ pub fn translate_operator<FE: FuncEnvironment + ?Sized>(
* `get_local` and `set_local` are treated as non-SSA variables and will completely
* disappear in the Cranelift Code
***********************************************************************************/
Operator::GetLocal { local_index } => {
Operator::LocalGet { local_index } => {
let val = builder.use_var(Variable::with_u32(*local_index));
state.push1(val);
let label = ValueLabel::from_u32(*local_index);
builder.set_val_label(val, label);
}
Operator::SetLocal { local_index } => {
Operator::LocalSet { local_index } => {
let val = state.pop1();
builder.def_var(Variable::with_u32(*local_index), val);
let label = ValueLabel::from_u32(*local_index);
builder.set_val_label(val, label);
}
Operator::TeeLocal { local_index } => {
Operator::LocalTee { local_index } => {
let val = state.peek1();
builder.def_var(Variable::with_u32(*local_index), val);
let label = ValueLabel::from_u32(*local_index);
@ -86,7 +86,7 @@ pub fn translate_operator<FE: FuncEnvironment + ?Sized>(
/********************************** Globals ****************************************
* `get_global` and `set_global` are handled by the environment.
***********************************************************************************/
Operator::GetGlobal { global_index } => {
Operator::GlobalGet { global_index } => {
let val = match state.get_global(builder.func, *global_index, environ)? {
GlobalVariable::Const(val) => val,
GlobalVariable::Memory { gv, offset, ty } => {
@ -97,7 +97,7 @@ pub fn translate_operator<FE: FuncEnvironment + ?Sized>(
};
state.push1(val);
}
Operator::SetGlobal { global_index } => {
Operator::GlobalSet { global_index } => {
match state.get_global(builder.func, *global_index, environ)? {
GlobalVariable::Const(_) => panic!("global #{} is a constant", *global_index),
GlobalVariable::Memory { gv, offset, ty } => {
@ -267,12 +267,14 @@ pub fn translate_operator<FE: FuncEnvironment + ?Sized>(
}
Operator::End => {
let frame = state.control_stack.pop().unwrap();
let next_ebb = frame.following_code();
if !builder.is_unreachable() || !builder.is_pristine() {
let return_count = frame.num_return_values();
builder
.ins()
.jump(frame.following_code(), state.peekn(return_count));
let return_args = state.peekn_mut(return_count);
let next_ebb_types = builder.func.dfg.ebb_param_types(next_ebb);
bitcast_arguments(return_args, &next_ebb_types, builder);
builder.ins().jump(frame.following_code(), return_args);
// You might expect that if we just finished an `if` block that
// didn't have a corresponding `else` block, then we would clean
// up our duplicate set of parameters that we pushed earlier
@ -280,16 +282,14 @@ pub fn translate_operator<FE: FuncEnvironment + ?Sized>(
// since we truncate the stack back to the original height
// below.
}
builder.switch_to_block(frame.following_code());
builder.seal_block(frame.following_code());
builder.switch_to_block(next_ebb);
builder.seal_block(next_ebb);
// If it is a loop we also have to seal the body loop block
if let ControlStackFrame::Loop { header, .. } = frame {
builder.seal_block(header)
}
state.stack.truncate(frame.original_stack_size());
state
.stack
.extend_from_slice(builder.ebb_params(frame.following_code()));
state.stack.extend_from_slice(builder.ebb_params(next_ebb));
}
/**************************** Branch instructions *********************************
* The branch instructions all have as arguments a target nesting level, which
@ -325,9 +325,17 @@ pub fn translate_operator<FE: FuncEnvironment + ?Sized>(
};
(return_count, frame.br_destination())
};
builder
.ins()
.jump(br_destination, state.peekn(return_count));
// Bitcast any vector arguments to their default type, I8X16, before jumping.
let destination_args = state.peekn_mut(return_count);
let destination_types = builder.func.dfg.ebb_param_types(br_destination);
bitcast_arguments(
destination_args,
&destination_types[..return_count],
builder,
);
builder.ins().jump(br_destination, destination_args);
state.popn(return_count);
state.reachable = false;
}
@ -406,7 +414,17 @@ pub fn translate_operator<FE: FuncEnvironment + ?Sized>(
frame.set_branched_to_exit();
frame.br_destination()
};
builder.ins().jump(real_dest_ebb, state.peekn(return_count));
// Bitcast any vector arguments to their default type, I8X16, before jumping.
let destination_args = state.peekn_mut(return_count);
let destination_types = builder.func.dfg.ebb_param_types(real_dest_ebb);
bitcast_arguments(
destination_args,
&destination_types[..return_count],
builder,
);
builder.ins().jump(real_dest_ebb, destination_args);
}
state.popn(return_count);
}
@ -420,10 +438,14 @@ pub fn translate_operator<FE: FuncEnvironment + ?Sized>(
(return_count, frame.br_destination())
};
{
let args = state.peekn(return_count);
let return_args = state.peekn_mut(return_count);
let return_types = &builder.func.signature.return_types();
bitcast_arguments(return_args, &return_types, builder);
match environ.return_mode() {
ReturnMode::NormalReturns => builder.ins().return_(args),
ReturnMode::FallthroughReturn => builder.ins().jump(br_destination, args),
ReturnMode::NormalReturns => builder.ins().return_(return_args),
ReturnMode::FallthroughReturn => {
builder.ins().jump(br_destination, return_args)
}
};
}
state.popn(return_count);
@ -436,11 +458,18 @@ pub fn translate_operator<FE: FuncEnvironment + ?Sized>(
************************************************************************************/
Operator::Call { function_index } => {
let (fref, num_args) = state.get_direct_func(builder.func, *function_index, environ)?;
// Bitcast any vector arguments to their default type, I8X16, before calling.
let callee_signature =
&builder.func.dfg.signatures[builder.func.dfg.ext_funcs[fref].signature];
let args = state.peekn_mut(num_args);
bitcast_arguments(args, &callee_signature.param_types(), builder);
let call = environ.translate_call(
builder.cursor(),
FuncIndex::from_u32(*function_index),
fref,
state.peekn(num_args),
args,
)?;
let inst_results = builder.inst_results(call);
debug_assert_eq!(
@ -459,6 +488,12 @@ pub fn translate_operator<FE: FuncEnvironment + ?Sized>(
let (sigref, num_args) = state.get_indirect_sig(builder.func, *index, environ)?;
let table = state.get_table(builder.func, *table_index, environ)?;
let callee = state.pop1();
// Bitcast any vector arguments to their default type, I8X16, before calling.
let callee_signature = &builder.func.dfg.signatures[sigref];
let args = state.peekn_mut(num_args);
bitcast_arguments(args, &callee_signature.param_types(), builder);
let call = environ.translate_call_indirect(
builder.cursor(),
TableIndex::from_u32(*table_index),
@ -639,11 +674,11 @@ pub fn translate_operator<FE: FuncEnvironment + ?Sized>(
let arg = state.pop1();
state.push1(builder.ins().popcnt(arg));
}
Operator::I64ExtendSI32 => {
Operator::I64ExtendI32S => {
let val = state.pop1();
state.push1(builder.ins().sextend(I64, val));
}
Operator::I64ExtendUI32 => {
Operator::I64ExtendI32U => {
let val = state.pop1();
state.push1(builder.ins().uextend(I64, val));
}
@ -679,19 +714,19 @@ pub fn translate_operator<FE: FuncEnvironment + ?Sized>(
let arg = state.pop1();
state.push1(builder.ins().fneg(arg));
}
Operator::F64ConvertUI64 | Operator::F64ConvertUI32 => {
Operator::F64ConvertI64U | Operator::F64ConvertI32U => {
let val = state.pop1();
state.push1(builder.ins().fcvt_from_uint(F64, val));
}
Operator::F64ConvertSI64 | Operator::F64ConvertSI32 => {
Operator::F64ConvertI64S | Operator::F64ConvertI32S => {
let val = state.pop1();
state.push1(builder.ins().fcvt_from_sint(F64, val));
}
Operator::F32ConvertSI64 | Operator::F32ConvertSI32 => {
Operator::F32ConvertI64S | Operator::F32ConvertI32S => {
let val = state.pop1();
state.push1(builder.ins().fcvt_from_sint(F32, val));
}
Operator::F32ConvertUI64 | Operator::F32ConvertUI32 => {
Operator::F32ConvertI64U | Operator::F32ConvertI32U => {
let val = state.pop1();
state.push1(builder.ins().fcvt_from_uint(F32, val));
}
@ -703,35 +738,35 @@ pub fn translate_operator<FE: FuncEnvironment + ?Sized>(
let val = state.pop1();
state.push1(builder.ins().fdemote(F32, val));
}
Operator::I64TruncSF64 | Operator::I64TruncSF32 => {
Operator::I64TruncF64S | Operator::I64TruncF32S => {
let val = state.pop1();
state.push1(builder.ins().fcvt_to_sint(I64, val));
}
Operator::I32TruncSF64 | Operator::I32TruncSF32 => {
Operator::I32TruncF64S | Operator::I32TruncF32S => {
let val = state.pop1();
state.push1(builder.ins().fcvt_to_sint(I32, val));
}
Operator::I64TruncUF64 | Operator::I64TruncUF32 => {
Operator::I64TruncF64U | Operator::I64TruncF32U => {
let val = state.pop1();
state.push1(builder.ins().fcvt_to_uint(I64, val));
}
Operator::I32TruncUF64 | Operator::I32TruncUF32 => {
Operator::I32TruncF64U | Operator::I32TruncF32U => {
let val = state.pop1();
state.push1(builder.ins().fcvt_to_uint(I32, val));
}
Operator::I64TruncSSatF64 | Operator::I64TruncSSatF32 => {
Operator::I64TruncSatF64S | Operator::I64TruncSatF32S => {
let val = state.pop1();
state.push1(builder.ins().fcvt_to_sint_sat(I64, val));
}
Operator::I32TruncSSatF64 | Operator::I32TruncSSatF32 => {
Operator::I32TruncSatF64S | Operator::I32TruncSatF32S => {
let val = state.pop1();
state.push1(builder.ins().fcvt_to_sint_sat(I32, val));
}
Operator::I64TruncUSatF64 | Operator::I64TruncUSatF32 => {
Operator::I64TruncSatF64U | Operator::I64TruncSatF32U => {
let val = state.pop1();
state.push1(builder.ins().fcvt_to_uint_sat(I64, val));
}
Operator::I32TruncUSatF64 | Operator::I32TruncUSatF32 => {
Operator::I32TruncSatF64U | Operator::I32TruncSatF32U => {
let val = state.pop1();
state.push1(builder.ins().fcvt_to_uint_sat(I32, val));
}
@ -912,15 +947,21 @@ pub fn translate_operator<FE: FuncEnvironment + ?Sized>(
Operator::F32Le | Operator::F64Le => {
translate_fcmp(FloatCC::LessThanOrEqual, builder, state)
}
Operator::TypedSelect { .. } => {
return Err(wasm_unsupported!("proposed typed select operator {:?}", op))
}
Operator::RefNull => state.push1(builder.ins().null(environ.reference_type())),
Operator::RefIsNull => {
let arg = state.pop1();
let val = builder.ins().is_null(arg);
state.push1(val);
}
Operator::Wake { .. }
| Operator::I32Wait { .. }
| Operator::I64Wait { .. }
Operator::RefFunc { .. } => {
return Err(wasm_unsupported!("proposed ref operator {:?}", op))
}
Operator::AtomicNotify { .. }
| Operator::I32AtomicWait { .. }
| Operator::I64AtomicWait { .. }
| Operator::I32AtomicLoad { .. }
| Operator::I64AtomicLoad { .. }
| Operator::I32AtomicLoad8U { .. }
@ -937,54 +978,54 @@ pub fn translate_operator<FE: FuncEnvironment + ?Sized>(
| Operator::I64AtomicStore32 { .. }
| Operator::I32AtomicRmwAdd { .. }
| Operator::I64AtomicRmwAdd { .. }
| Operator::I32AtomicRmw8UAdd { .. }
| Operator::I32AtomicRmw16UAdd { .. }
| Operator::I64AtomicRmw8UAdd { .. }
| Operator::I64AtomicRmw16UAdd { .. }
| Operator::I64AtomicRmw32UAdd { .. }
| Operator::I32AtomicRmw8AddU { .. }
| Operator::I32AtomicRmw16AddU { .. }
| Operator::I64AtomicRmw8AddU { .. }
| Operator::I64AtomicRmw16AddU { .. }
| Operator::I64AtomicRmw32AddU { .. }
| Operator::I32AtomicRmwSub { .. }
| Operator::I64AtomicRmwSub { .. }
| Operator::I32AtomicRmw8USub { .. }
| Operator::I32AtomicRmw16USub { .. }
| Operator::I64AtomicRmw8USub { .. }
| Operator::I64AtomicRmw16USub { .. }
| Operator::I64AtomicRmw32USub { .. }
| Operator::I32AtomicRmw8SubU { .. }
| Operator::I32AtomicRmw16SubU { .. }
| Operator::I64AtomicRmw8SubU { .. }
| Operator::I64AtomicRmw16SubU { .. }
| Operator::I64AtomicRmw32SubU { .. }
| Operator::I32AtomicRmwAnd { .. }
| Operator::I64AtomicRmwAnd { .. }
| Operator::I32AtomicRmw8UAnd { .. }
| Operator::I32AtomicRmw16UAnd { .. }
| Operator::I64AtomicRmw8UAnd { .. }
| Operator::I64AtomicRmw16UAnd { .. }
| Operator::I64AtomicRmw32UAnd { .. }
| Operator::I32AtomicRmw8AndU { .. }
| Operator::I32AtomicRmw16AndU { .. }
| Operator::I64AtomicRmw8AndU { .. }
| Operator::I64AtomicRmw16AndU { .. }
| Operator::I64AtomicRmw32AndU { .. }
| Operator::I32AtomicRmwOr { .. }
| Operator::I64AtomicRmwOr { .. }
| Operator::I32AtomicRmw8UOr { .. }
| Operator::I32AtomicRmw16UOr { .. }
| Operator::I64AtomicRmw8UOr { .. }
| Operator::I64AtomicRmw16UOr { .. }
| Operator::I64AtomicRmw32UOr { .. }
| Operator::I32AtomicRmw8OrU { .. }
| Operator::I32AtomicRmw16OrU { .. }
| Operator::I64AtomicRmw8OrU { .. }
| Operator::I64AtomicRmw16OrU { .. }
| Operator::I64AtomicRmw32OrU { .. }
| Operator::I32AtomicRmwXor { .. }
| Operator::I64AtomicRmwXor { .. }
| Operator::I32AtomicRmw8UXor { .. }
| Operator::I32AtomicRmw16UXor { .. }
| Operator::I64AtomicRmw8UXor { .. }
| Operator::I64AtomicRmw16UXor { .. }
| Operator::I64AtomicRmw32UXor { .. }
| Operator::I32AtomicRmw8XorU { .. }
| Operator::I32AtomicRmw16XorU { .. }
| Operator::I64AtomicRmw8XorU { .. }
| Operator::I64AtomicRmw16XorU { .. }
| Operator::I64AtomicRmw32XorU { .. }
| Operator::I32AtomicRmwXchg { .. }
| Operator::I64AtomicRmwXchg { .. }
| Operator::I32AtomicRmw8UXchg { .. }
| Operator::I32AtomicRmw16UXchg { .. }
| Operator::I64AtomicRmw8UXchg { .. }
| Operator::I64AtomicRmw16UXchg { .. }
| Operator::I64AtomicRmw32UXchg { .. }
| Operator::I32AtomicRmw8XchgU { .. }
| Operator::I32AtomicRmw16XchgU { .. }
| Operator::I64AtomicRmw8XchgU { .. }
| Operator::I64AtomicRmw16XchgU { .. }
| Operator::I64AtomicRmw32XchgU { .. }
| Operator::I32AtomicRmwCmpxchg { .. }
| Operator::I64AtomicRmwCmpxchg { .. }
| Operator::I32AtomicRmw8UCmpxchg { .. }
| Operator::I32AtomicRmw16UCmpxchg { .. }
| Operator::I64AtomicRmw8UCmpxchg { .. }
| Operator::I64AtomicRmw16UCmpxchg { .. }
| Operator::I64AtomicRmw32UCmpxchg { .. }
| Operator::Fence { .. } => {
| Operator::I32AtomicRmw8CmpxchgU { .. }
| Operator::I32AtomicRmw16CmpxchgU { .. }
| Operator::I64AtomicRmw8CmpxchgU { .. }
| Operator::I64AtomicRmw16CmpxchgU { .. }
| Operator::I64AtomicRmw32CmpxchgU { .. }
| Operator::AtomicFence { .. } => {
return Err(wasm_unsupported!("proposed thread operator {:?}", op));
}
Operator::MemoryCopy => {
@ -1039,7 +1080,7 @@ pub fn translate_operator<FE: FuncEnvironment + ?Sized>(
table,
)?);
}
Operator::TableCopy => {
Operator::TableCopy { .. } => {
// The WebAssembly MVP only supports one table and wasmparser will
// ensure that the table index specified is zero.
let dst_table_index = 0;
@ -1060,7 +1101,7 @@ pub fn translate_operator<FE: FuncEnvironment + ?Sized>(
len,
)?;
}
Operator::TableInit { segment } => {
Operator::TableInit { segment, table: _ } => {
// The WebAssembly MVP only supports one table and we assume it here.
let table_index = 0;
let table = state.get_table(builder.func, table_index, environ)?;
@ -1077,6 +1118,9 @@ pub fn translate_operator<FE: FuncEnvironment + ?Sized>(
len,
)?;
}
Operator::TableFill { .. } => {
return Err(wasm_unsupported!("proposed table operator {:?}", op));
}
Operator::ElemDrop { segment } => {
environ.translate_elem_drop(builder.cursor(), *segment)?;
}
@ -1183,6 +1227,10 @@ pub fn translate_operator<FE: FuncEnvironment + ?Sized>(
let (a, b) = pop2_with_bitcast(state, type_of(op), builder);
state.push1(builder.ins().imul(a, b))
}
Operator::V128AndNot => {
let (a, b) = pop2_with_bitcast(state, type_of(op), builder);
state.push1(builder.ins().band_not(a, b))
}
Operator::V128Not => {
let a = state.pop1();
state.push1(builder.ins().bnot(a));
@ -1330,20 +1378,41 @@ pub fn translate_operator<FE: FuncEnvironment + ?Sized>(
| Operator::I8x16ShrS
| Operator::I8x16ShrU
| Operator::I8x16Mul
| Operator::I64x2Mul
| Operator::I64x2ShrS
| Operator::I32x4TruncSF32x4Sat
| Operator::I32x4TruncUF32x4Sat
| Operator::I64x2TruncSF64x2Sat
| Operator::I64x2TruncUF64x2Sat
| Operator::F32x4ConvertSI32x4
| Operator::F32x4ConvertUI32x4
| Operator::F64x2ConvertSI64x2
| Operator::F64x2ConvertUI64x2 { .. }
| Operator::I32x4TruncSatF32x4S
| Operator::I32x4TruncSatF32x4U
| Operator::I64x2TruncSatF64x2S
| Operator::I64x2TruncSatF64x2U
| Operator::F32x4ConvertI32x4S
| Operator::F32x4ConvertI32x4U
| Operator::F64x2ConvertI64x2S
| Operator::F64x2ConvertI64x2U { .. }
| Operator::I8x16NarrowI16x8S { .. }
| Operator::I8x16NarrowI16x8U { .. }
| Operator::I16x8NarrowI32x4S { .. }
| Operator::I16x8NarrowI32x4U { .. }
| Operator::I16x8WidenLowI8x16S { .. }
| Operator::I16x8WidenHighI8x16S { .. }
| Operator::I16x8WidenLowI8x16U { .. }
| Operator::I16x8WidenHighI8x16U { .. }
| Operator::I32x4WidenLowI16x8S { .. }
| Operator::I32x4WidenHighI16x8S { .. }
| Operator::I32x4WidenLowI16x8U { .. }
| Operator::I32x4WidenHighI16x8U { .. }
| Operator::V8x16Swizzle
| Operator::I8x16LoadSplat { .. }
| Operator::I16x8LoadSplat { .. }
| Operator::I32x4LoadSplat { .. }
| Operator::I64x2LoadSplat { .. } => {
| Operator::V8x16LoadSplat { .. }
| Operator::V16x8LoadSplat { .. }
| Operator::V32x4LoadSplat { .. }
| Operator::V64x2LoadSplat { .. }
| Operator::I16x8Load8x8S { .. }
| Operator::I16x8Load8x8U { .. }
| Operator::I32x4Load16x4S { .. }
| Operator::I32x4Load16x4U { .. }
| Operator::I64x2Load32x2S { .. }
| Operator::I64x2Load32x2U { .. }
| Operator::I8x16RoundingAverageU { .. }
| Operator::I16x8RoundingAverageU { .. } => {
return Err(wasm_unsupported!("proposed SIMD operator {:?}", op));
}
};
@ -1604,6 +1673,11 @@ fn translate_br_if(
) {
let val = state.pop1();
let (br_destination, inputs) = translate_br_if_args(relative_depth, state);
// Bitcast any vector arguments to their default type, I8X16, before jumping.
let destination_types = builder.func.dfg.ebb_param_types(br_destination);
bitcast_arguments(inputs, &destination_types[..inputs.len()], builder);
builder.ins().brnz(val, br_destination, inputs);
#[cfg(feature = "basic-blocks")]
@ -1618,7 +1692,7 @@ fn translate_br_if(
fn translate_br_if_args(
relative_depth: u32,
state: &mut FuncTranslationState,
) -> (ir::Ebb, &[ir::Value]) {
) -> (ir::Ebb, &mut [ir::Value]) {
let i = state.control_stack.len() - 1 - (relative_depth as usize);
let (return_count, br_destination) = {
let frame = &mut state.control_stack[i];
@ -1632,7 +1706,7 @@ fn translate_br_if_args(
};
(return_count, frame.br_destination())
};
let inputs = state.peekn(return_count);
let inputs = state.peekn_mut(return_count);
(br_destination, inputs)
}
@ -1644,6 +1718,7 @@ fn type_of(operator: &Operator) -> Type {
| Operator::V128Const { .. }
| Operator::V128Not
| Operator::V128And
| Operator::V128AndNot
| Operator::V128Or
| Operator::V128Xor
| Operator::V128Bitselect => I8X16, // default type representing V128
@ -1727,8 +1802,8 @@ fn type_of(operator: &Operator) -> Type {
| Operator::I32x4Add
| Operator::I32x4Sub
| Operator::I32x4Mul
| Operator::F32x4ConvertSI32x4
| Operator::F32x4ConvertUI32x4 => I32X4,
| Operator::F32x4ConvertI32x4S
| Operator::F32x4ConvertI32x4U => I32X4,
Operator::I64x2Splat
| Operator::I64x2ExtractLane { .. }
@ -1741,8 +1816,8 @@ fn type_of(operator: &Operator) -> Type {
| Operator::I64x2ShrU
| Operator::I64x2Add
| Operator::I64x2Sub
| Operator::F64x2ConvertSI64x2
| Operator::F64x2ConvertUI64x2 => I64X2,
| Operator::F64x2ConvertI64x2S
| Operator::F64x2ConvertI64x2U => I64X2,
Operator::F32x4Splat
| Operator::F32x4ExtractLane { .. }
@ -1762,8 +1837,8 @@ fn type_of(operator: &Operator) -> Type {
| Operator::F32x4Div
| Operator::F32x4Min
| Operator::F32x4Max
| Operator::I32x4TruncSF32x4Sat
| Operator::I32x4TruncUF32x4Sat => F32X4,
| Operator::I32x4TruncSatF32x4S
| Operator::I32x4TruncSatF32x4U => F32X4,
Operator::F64x2Splat
| Operator::F64x2ExtractLane { .. }
@ -1783,11 +1858,12 @@ fn type_of(operator: &Operator) -> Type {
| Operator::F64x2Div
| Operator::F64x2Min
| Operator::F64x2Max
| Operator::I64x2TruncSF64x2Sat
| Operator::I64x2TruncUF64x2Sat => F64X2,
| Operator::I64x2TruncSatF64x2S
| Operator::I64x2TruncSatF64x2U => F64X2,
_ => unimplemented!(
"Currently only the SIMD instructions are translated to their return type: {:?}",
"Currently only SIMD instructions are mapped to their return type; the \
following instruction is not mapped: {:?}",
operator
),
}
@ -1795,7 +1871,7 @@ fn type_of(operator: &Operator) -> Type {
/// Some SIMD operations only operate on I8X16 in CLIF; this will convert them to that type by
/// adding a raw_bitcast if necessary.
fn optionally_bitcast_vector(
pub fn optionally_bitcast_vector(
value: Value,
needed_type: Type,
builder: &mut FunctionBuilder,
@ -1831,3 +1907,28 @@ fn pop2_with_bitcast(
let bitcast_b = optionally_bitcast_vector(b, needed_type, builder);
(bitcast_a, bitcast_b)
}
/// A helper for bitcasting a sequence of values (e.g. function arguments). If a value is a
/// vector type that does not match its expected type, this will modify the value in place to point
/// to the result of a `raw_bitcast`. This conversion is necessary to translate Wasm code that
/// uses `V128` as function parameters (or implicitly in EBB parameters) and still use specific
/// CLIF types (e.g. `I32X4`) in the function body.
pub fn bitcast_arguments(
arguments: &mut [Value],
expected_types: &[Type],
builder: &mut FunctionBuilder,
) {
assert_eq!(arguments.len(), expected_types.len());
for (i, t) in expected_types.iter().enumerate() {
if t.is_vector() {
assert!(
builder.func.dfg.value_type(arguments[i]).is_vector(),
"unexpected type mismatch: expected {}, argument {} was actually of type {}",
t,
arguments[i],
builder.func.dfg.value_type(arguments[i])
);
arguments[i] = optionally_bitcast_vector(arguments[i], *t, builder)
}
}
}

Просмотреть файл

@ -138,6 +138,12 @@ pub trait TargetEnvironment {
/// IR. The function environment provides information about the WebAssembly module as well as the
/// runtime environment.
pub trait FuncEnvironment: TargetEnvironment {
/// Is the given parameter of the given function a wasm-level parameter, as opposed to a hidden
/// parameter added for use by the implementation?
fn is_wasm_parameter(&self, signature: &ir::Signature, index: usize) -> bool {
signature.params[index].purpose == ir::ArgumentPurpose::Normal
}
/// Should the code be structured to use a single `fallthrough_return` instruction at the end
/// of the function body, rather than `return` instructions as needed? This is used by VMs
/// to append custom epilogues.
@ -302,6 +308,7 @@ pub trait FuncEnvironment: TargetEnvironment {
/// The `index` provided identifies the linear memory to query, and `heap` is the heap reference
/// returned by `make_heap` for the same index. `seg_index` is the index of the segment to copy
/// from.
#[allow(clippy::too_many_arguments)]
fn translate_memory_init(
&mut self,
pos: FuncCursor,
@ -325,6 +332,7 @@ pub trait FuncEnvironment: TargetEnvironment {
) -> WasmResult<ir::Value>;
/// Translate a `table.copy` WebAssembly instruction.
#[allow(clippy::too_many_arguments)]
fn translate_table_copy(
&mut self,
pos: FuncCursor,
@ -338,6 +346,7 @@ pub trait FuncEnvironment: TargetEnvironment {
) -> WasmResult<()>;
/// Translate a `table.init` WebAssembly instruction.
#[allow(clippy::too_many_arguments)]
fn translate_table_init(
&mut self,
pos: FuncCursor,

Просмотреть файл

@ -4,7 +4,7 @@
//! function to Cranelift IR guided by a `FuncEnvironment` which provides information about the
//! WebAssembly module and the runtime environment.
use crate::code_translator::translate_operator;
use crate::code_translator::{bitcast_arguments, translate_operator};
use crate::environ::{FuncEnvironment, ReturnMode, WasmResult};
use crate::state::{FuncTranslationState, ModuleTranslationState};
use crate::translation_utils::get_vmctx_value_label;
@ -99,7 +99,7 @@ impl FuncTranslator {
// `environ`. The callback functions may need to insert things in the entry block.
builder.ensure_inserted_ebb();
let num_params = declare_wasm_parameters(&mut builder, entry_block);
let num_params = declare_wasm_parameters(&mut builder, entry_block, environ);
// Set up the translation state with a single pushed control block representing the whole
// function and its return values.
@ -124,14 +124,18 @@ impl FuncTranslator {
/// Declare local variables for the signature parameters that correspond to WebAssembly locals.
///
/// Return the number of local variables declared.
fn declare_wasm_parameters(builder: &mut FunctionBuilder, entry_block: Ebb) -> usize {
fn declare_wasm_parameters<FE: FuncEnvironment + ?Sized>(
builder: &mut FunctionBuilder,
entry_block: Ebb,
environ: &FE,
) -> usize {
let sig_len = builder.func.signature.params.len();
let mut next_local = 0;
for i in 0..sig_len {
let param_type = builder.func.signature.params[i];
// There may be additional special-purpose parameters following the normal WebAssembly
// There may be additional special-purpose parameters in addition to the normal WebAssembly
// signature parameters. For example, a `vmctx` pointer.
if param_type.purpose == ir::ArgumentPurpose::Normal {
if environ.is_wasm_parameter(&builder.func.signature, i) {
// This is a normal WebAssembly signature parameter, so create a local for it.
let local = Variable::new(next_local);
builder.declare_var(local, param_type.value_type);
@ -240,7 +244,11 @@ fn parse_function_body<FE: FuncEnvironment + ?Sized>(
debug_assert!(builder.is_pristine());
if !builder.is_unreachable() {
match environ.return_mode() {
ReturnMode::NormalReturns => builder.ins().return_(&state.stack),
ReturnMode::NormalReturns => {
let return_types = &builder.func.signature.return_types();
bitcast_arguments(&mut state.stack, &return_types, builder);
builder.ins().return_(&state.stack)
}
ReturnMode::FallthroughReturn => builder.ins().fallthrough_return(&state.stack),
};
}

Просмотреть файл

@ -7,7 +7,7 @@
//! The special case of the initialize expressions for table elements offsets or global variables
//! is handled, according to the semantics of WebAssembly, to only specific expressions that are
//! interpreted on the fly.
use crate::environ::{ModuleEnvironment, WasmResult};
use crate::environ::{ModuleEnvironment, WasmError, WasmResult};
use crate::state::ModuleTranslationState;
use crate::translation_utils::{
tabletype_to_type, type_to_type, FuncIndex, Global, GlobalIndex, GlobalInit, Memory,
@ -17,14 +17,15 @@ use crate::{wasm_unsupported, HashMap};
use core::convert::TryFrom;
use cranelift_codegen::ir::immediates::V128Imm;
use cranelift_codegen::ir::{self, AbiParam, Signature};
use cranelift_entity::packed_option::ReservedValue;
use cranelift_entity::EntityRef;
use std::vec::Vec;
use wasmparser::{
self, CodeSectionReader, Data, DataKind, DataSectionReader, Element, ElementKind,
self, CodeSectionReader, Data, DataKind, DataSectionReader, Element, ElementItem, ElementKind,
ElementSectionReader, Export, ExportSectionReader, ExternalKind, FuncType,
FunctionSectionReader, GlobalSectionReader, GlobalType, ImportSectionEntryType,
ImportSectionReader, MemorySectionReader, MemoryType, NameSectionReader, Naming, NamingReader,
Operator, TableSectionReader, TypeSectionReader,
Operator, TableSectionReader, Type, TypeSectionReader,
};
/// Parses the Type section of the wasm module.
@ -141,7 +142,13 @@ pub fn parse_function_section(
functions: FunctionSectionReader,
environ: &mut dyn ModuleEnvironment,
) -> WasmResult<()> {
environ.reserve_func_types(functions.get_count())?;
let num_functions = functions.get_count();
if num_functions == std::u32::MAX {
// We reserve `u32::MAX` for our own use in cranelift-entity.
return Err(WasmError::ImplLimitExceeded);
}
environ.reserve_func_types(num_functions)?;
for entry in functions {
let sigindex = entry?;
@ -217,7 +224,7 @@ pub fn parse_global_section(
GlobalInit::V128Const(V128Imm::from(value.bytes().to_vec().as_slice()))
}
Operator::RefNull => GlobalInit::RefNullConst,
Operator::GetGlobal { global_index } => {
Operator::GlobalGet { global_index } => {
GlobalInit::GetGlobal(GlobalIndex::from_u32(global_index))
}
ref s => {
@ -286,7 +293,13 @@ pub fn parse_element_section<'data>(
environ.reserve_table_elements(elements.get_count())?;
for entry in elements {
let Element { kind, items } = entry?;
let Element { kind, items, ty } = entry?;
if ty != Type::AnyFunc {
return Err(wasm_unsupported!(
"unsupported table element type: {:?}",
ty
));
}
if let ElementKind::Active {
table_index,
init_expr,
@ -295,7 +308,7 @@ pub fn parse_element_section<'data>(
let mut init_expr_reader = init_expr.get_binary_reader();
let (base, offset) = match init_expr_reader.read_operator()? {
Operator::I32Const { value } => (None, value as u32 as usize),
Operator::GetGlobal { global_index } => {
Operator::GlobalGet { global_index } => {
(Some(GlobalIndex::from_u32(global_index)), 0)
}
ref s => {
@ -308,8 +321,11 @@ pub fn parse_element_section<'data>(
let items_reader = items.get_items_reader()?;
let mut elems = Vec::with_capacity(usize::try_from(items_reader.get_count()).unwrap());
for item in items_reader {
let x = item?;
elems.push(FuncIndex::from_u32(x));
let elem = match item? {
ElementItem::Null => FuncIndex::reserved_value(),
ElementItem::Func(index) => FuncIndex::from_u32(index),
};
elems.push(elem);
}
environ.declare_table_elements(
TableIndex::from_u32(table_index),
@ -318,10 +334,7 @@ pub fn parse_element_section<'data>(
elems.into_boxed_slice(),
)?
} else {
return Err(wasm_unsupported!(
"unsupported passive elements section: {:?}",
kind
));
return Err(wasm_unsupported!("unsupported passive elements section",));
}
}
Ok(())
@ -359,7 +372,7 @@ pub fn parse_data_section<'data>(
let mut init_expr_reader = init_expr.get_binary_reader();
let (base, offset) = match init_expr_reader.read_operator()? {
Operator::I32Const { value } => (None, value as u32 as usize),
Operator::GetGlobal { global_index } => {
Operator::GlobalGet { global_index } => {
(Some(GlobalIndex::from_u32(global_index)), 0)
}
ref s => {
@ -417,6 +430,11 @@ fn parse_function_name_subsection(
let mut function_names = HashMap::new();
for _ in 0..naming_reader.get_count() {
let Naming { index, name } = naming_reader.read().ok()?;
if index == std::u32::MAX {
// We reserve `u32::MAX` for our own use in cranelift-entity.
return None;
}
if function_names
.insert(FuncIndex::from_u32(index), name)
.is_some()

Просмотреть файл

@ -306,31 +306,40 @@ impl FuncTranslationState {
(v1, v2, v3)
}
/// Helper to ensure the the stack size is at least as big as `n`; note that due to
/// `debug_assert` this will not execute in non-optimized builds.
#[inline]
fn ensure_length_is_at_least(&self, n: usize) {
debug_assert!(
n <= self.stack.len(),
"attempted to access {} values but stack only has {} values",
n,
self.stack.len()
)
}
/// Pop the top `n` values on the stack.
///
/// The popped values are not returned. Use `peekn` to look at them before popping.
pub(crate) fn popn(&mut self, n: usize) {
debug_assert!(
n <= self.stack.len(),
"popn({}) but stack only has {} values",
n,
self.stack.len()
);
self.ensure_length_is_at_least(n);
let new_len = self.stack.len() - n;
self.stack.truncate(new_len);
}
/// Peek at the top `n` values on the stack in the order they were pushed.
pub(crate) fn peekn(&self, n: usize) -> &[Value] {
debug_assert!(
n <= self.stack.len(),
"peekn({}) but stack only has {} values",
n,
self.stack.len()
);
self.ensure_length_is_at_least(n);
&self.stack[self.stack.len() - n..]
}
/// Peek at the top `n` values on the stack in the order they were pushed.
pub(crate) fn peekn_mut(&mut self, n: usize) -> &mut [Value] {
self.ensure_length_is_at_least(n);
let len = self.stack.len();
&mut self.stack[len - n..]
}
/// Push a block on the control stack.
pub(crate) fn push_block(
&mut self,
@ -465,7 +474,7 @@ impl FuncTranslationState {
Occupied(entry) => Ok(*entry.get()),
Vacant(entry) => {
let sig = environ.make_indirect_sig(func, index)?;
Ok(*entry.insert((sig, normal_args(&func.dfg.signatures[sig]))))
Ok(*entry.insert((sig, num_wasm_parameters(environ, &func.dfg.signatures[sig]))))
}
}
}
@ -486,17 +495,20 @@ impl FuncTranslationState {
Vacant(entry) => {
let fref = environ.make_direct_func(func, index)?;
let sig = func.dfg.ext_funcs[fref].signature;
Ok(*entry.insert((fref, normal_args(&func.dfg.signatures[sig]))))
Ok(*entry.insert((
fref,
num_wasm_parameters(environ, &func.dfg.signatures[sig]),
)))
}
}
}
}
/// Count the number of normal parameters in a signature.
/// Exclude special-purpose parameters that represent runtime stuff and not WebAssembly arguments.
fn normal_args(sig: &ir::Signature) -> usize {
sig.params
.iter()
.filter(|arg| arg.purpose == ir::ArgumentPurpose::Normal)
fn num_wasm_parameters<FE: FuncEnvironment + ?Sized>(
environ: &FE,
signature: &ir::Signature,
) -> usize {
(0..signature.params.len())
.filter(|index| environ.is_wasm_parameter(signature, *index))
.count()
}

Просмотреть файл

@ -10,7 +10,6 @@ use std::io::prelude::*;
use std::path::Path;
use std::str::FromStr;
use target_lexicon::triple;
use wabt::{wat2wasm_with_features, Features, Wat2Wasm};
#[test]
fn testsuite() {
@ -47,15 +46,14 @@ fn use_fallthrough_return() {
#[test]
fn use_name_section() {
let wat = r#"
let data = wat::parse_str(
r#"
(module $module_name
(func $func_name (local $loc_name i32)
)
)"#;
let data = Wat2Wasm::new()
.write_debug_names(true)
.convert(wat)
.unwrap_or_else(|e| panic!("error converting wat to wasm: {:?}", e));
)"#,
)
.unwrap();
let flags = Flags::new(settings::builder());
let triple = triple!("riscv64");
@ -79,23 +77,13 @@ fn read_file(path: &Path) -> io::Result<Vec<u8>> {
}
fn read_module(path: &Path) -> Vec<u8> {
let mut features = Features::new();
features.enable_all();
match path.extension() {
None => {
panic!("the file extension is not wasm or wat");
}
Some(ext) => match ext.to_str() {
Some("wasm") => read_file(path).expect("error reading wasm file"),
Some("wat") => {
let wat = read_file(path).expect("error reading wat file");
match wat2wasm_with_features(&wat, features) {
Ok(wasm) => wasm,
Err(e) => {
panic!("error converting wat to wasm: {:?}", e);
}
}
}
Some("wat") => wat::parse_file(path).expect("failed to parse wat"),
None | Some(&_) => panic!("the file extension for {:?} is not wasm or wat", path),
},
}

1
third_party/rust/target-lexicon-0.9.0/.cargo-checksum.json поставляемый Normal file
Просмотреть файл

@ -0,0 +1 @@
{"files":{"Cargo.lock":"a1a162e6ce8fc2234a6ddf7090410006a1920ace8738772e32a5b50e4780c19d","Cargo.toml":"f3b545fa0f184fd0d3624e6e5c205fcbdf1ad0934a2e08406549ad53c2a62ac3","LICENSE":"268872b9816f90fd8e85db5a28d33f8150ebb8dd016653fb39ef1f94f2686bc5","README.md":"c3467056d91be3f59562158ee9604c729b5b5f473efbefb036032803eb76809e","build.rs":"723100e9cdc30cd8c48407233c2cffa10f5b10703a0a11bac1230d8b86e49ccf","examples/host.rs":"503bafddfb372123fe4dc0e7b8037808beb5bfe6df60c00d3315922bd3792c6c","examples/misc.rs":"49a579845450b7b020ed5c97dca142fc548725893cbc82f6f750ee0caab2beca","newlist":"89564342916321c5bc35e772d374a7f0af22cc9ae6dcc0027eca48d2269f18cb","src/host.rs":"fb543df4f362e9119a58523563e453110f4e3a426f0995911d0ca386657cf1d9","src/lib.rs":"4414353c30f25d44df6cc14f7f9eea9991222289c6aa662b74406f6923235970","src/parse_error.rs":"b3735eabc0fd0a9dfdd6375662f20ec96a79852a00a05a98fb2e421545285e53","src/targets.rs":"9ccc0849cff06d8906dacbdc15136cc47fab85ccd795033ddfdde1397dfcfe32","src/triple.rs":"949bd83b043b53b18f643ebc3fbebbfe02a13998b787fda432a5d36aa27d20bd","test.sh":"22e3c630a6c84e90d5c70c367a6712be8eeca1e7682c00d1f65bf53e330e9191"},"package":"6f4c118a7a38378f305a9e111fcb2f7f838c0be324bfb31a77ea04f7f6e684b4"}

6
third_party/rust/target-lexicon-0.9.0/Cargo.lock сгенерированный поставляемый Normal file
Просмотреть файл

@ -0,0 +1,6 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
[[package]]
name = "target-lexicon"
version = "0.9.0"

33
third_party/rust/target-lexicon-0.9.0/Cargo.toml поставляемый Normal file
Просмотреть файл

@ -0,0 +1,33 @@
# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO
#
# When uploading crates to the registry Cargo will automatically
# "normalize" Cargo.toml files for maximal compatibility
# with all versions of Cargo and also rewrite `path` dependencies
# to registry (e.g., crates.io) dependencies
#
# If you believe there's an error in this file please file an
# issue against the rust-lang/cargo repository. If you're
# editing this file be aware that the upstream Cargo.toml
# will likely look very different (and much more reasonable)
[package]
edition = "2018"
name = "target-lexicon"
version = "0.9.0"
authors = ["Dan Gohman <sunfish@mozilla.com>"]
description = "Targeting utilities for compilers and related tools"
documentation = "https://docs.rs/target-lexicon/"
readme = "README.md"
keywords = ["target", "host", "triple", "compiler", "jit"]
categories = ["no-std"]
license = "Apache-2.0 WITH LLVM-exception"
repository = "https://github.com/CraneStation/target-lexicon"
[features]
default = []
std = []
[badges.maintenance]
status = "passively-maintained"
[badges.travis-ci]
repository = "CraneStation/target-lexicon"

220
third_party/rust/target-lexicon-0.9.0/LICENSE поставляемый Normal file
Просмотреть файл

@ -0,0 +1,220 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
--- LLVM Exceptions to the Apache 2.0 License ----
As an exception, if, as a result of your compiling your source code, portions
of this Software are embedded into an Object form of such source code, you
may redistribute such embedded portions in such Object form without complying
with the conditions of Sections 4(a), 4(b) and 4(d) of the License.
In addition, if you combine or link compiled forms of this Software with
software that is licensed under the GPLv2 ("Combined Software") and if a
court of competent jurisdiction determines that the patent provision (Section
3), the indemnity provision (Section 9) or other Section of the License
conflicts with the conditions of the GPLv2, you may retroactively and
prospectively choose to deem waived or otherwise exclude such Section(s) of
the License, but only in their entirety and only with respect to the Combined
Software.

20
third_party/rust/target-lexicon-0.9.0/README.md поставляемый Normal file
Просмотреть файл

@ -0,0 +1,20 @@
This is a library for managing targets for compilers and related tools.
Currently, the main feature is support for decoding "triples", which
are strings that identify a particular target configuration. They're named
"triples" because historically they contained three fields, though over time
they've added additional fields. This library provides a `Triple` struct
containing enums for each of fields of a triple. `Triple` implements
`FromStr` and `fmt::Display` so it can be converted to and from the
conventional string representation of a triple.
`Triple` also has functions for querying a triple's endianness,
pointer bit width, and binary format.
And, `Triple` and the enum types have `host()` constructors, for targeting
the host.
It supports all triples currently used by rustc and rustup.
It does not support reading JSON target files itself. To use it with a JSON
target file, construct a `Triple` using the value of the "llvm-target" field.

162
third_party/rust/target-lexicon-0.9.0/build.rs поставляемый Normal file
Просмотреть файл

@ -0,0 +1,162 @@
//! build.rs file to obtain the host information.
// Allow dead code in triple.rs and targets.rs for our purposes here.
#![allow(dead_code)]
use std::env;
use std::fs::File;
use std::io::{self, Write};
use std::path::PathBuf;
use std::str::FromStr;
extern crate alloc;
// Include triple.rs and targets.rs so we can parse the TARGET environment variable.
mod triple {
include!("src/triple.rs");
}
mod targets {
include!("src/targets.rs");
}
// Stub out `ParseError` to minimally support triple.rs and targets.rs.
mod parse_error {
#[derive(Debug)]
pub enum ParseError {
UnrecognizedArchitecture(String),
UnrecognizedVendor(String),
UnrecognizedOperatingSystem(String),
UnrecognizedEnvironment(String),
UnrecognizedBinaryFormat(String),
UnrecognizedField(String),
}
}
use self::triple::Triple;
fn main() {
let out_dir =
PathBuf::from(env::var("OUT_DIR").expect("The OUT_DIR environment variable must be set"));
let target = env::var("TARGET").expect("The TARGET environment variable must be set");
let triple = Triple::from_str(&target).expect(&format!("Invalid target name: '{}'", target));
let out = File::create(out_dir.join("host.rs")).expect("error creating host.rs");
write_host_rs(out, triple).expect("error writing host.rs");
}
fn write_host_rs(mut out: File, triple: Triple) -> io::Result<()> {
// The generated Debug implementation for the inner architecture variants
// doesn't print the enum name qualifier, so import them here. There
// shouldn't be any conflicts because these enums all share a namespace
// in the triple string format.
writeln!(out, "#[allow(unused_imports)]")?;
writeln!(out, "use crate::Aarch64Architecture::*;")?;
writeln!(out, "#[allow(unused_imports)]")?;
writeln!(out, "use crate::ArmArchitecture::*;")?;
writeln!(out)?;
writeln!(out, "/// The `Triple` of the current host.")?;
writeln!(out, "pub const HOST: Triple = Triple {{")?;
writeln!(
out,
" architecture: Architecture::{:?},",
triple.architecture
)?;
writeln!(out, " vendor: Vendor::{:?},", triple.vendor)?;
writeln!(
out,
" operating_system: OperatingSystem::{:?},",
triple.operating_system
)?;
writeln!(
out,
" environment: Environment::{:?},",
triple.environment
)?;
writeln!(
out,
" binary_format: BinaryFormat::{:?},",
triple.binary_format
)?;
writeln!(out, "}};")?;
writeln!(out)?;
writeln!(out, "impl Architecture {{")?;
writeln!(out, " /// Return the architecture for the current host.")?;
writeln!(out, " pub const fn host() -> Self {{")?;
writeln!(out, " Architecture::{:?}", triple.architecture)?;
writeln!(out, " }}")?;
writeln!(out, "}}")?;
writeln!(out)?;
writeln!(out, "impl Vendor {{")?;
writeln!(out, " /// Return the vendor for the current host.")?;
writeln!(out, " pub const fn host() -> Self {{")?;
writeln!(out, " Vendor::{:?}", triple.vendor)?;
writeln!(out, " }}")?;
writeln!(out, "}}")?;
writeln!(out)?;
writeln!(out, "impl OperatingSystem {{")?;
writeln!(
out,
" /// Return the operating system for the current host."
)?;
writeln!(out, " pub const fn host() -> Self {{")?;
writeln!(
out,
" OperatingSystem::{:?}",
triple.operating_system
)?;
writeln!(out, " }}")?;
writeln!(out, "}}")?;
writeln!(out)?;
writeln!(out, "impl Environment {{")?;
writeln!(out, " /// Return the environment for the current host.")?;
writeln!(out, " pub const fn host() -> Self {{")?;
writeln!(out, " Environment::{:?}", triple.environment)?;
writeln!(out, " }}")?;
writeln!(out, "}}")?;
writeln!(out)?;
writeln!(out, "impl BinaryFormat {{")?;
writeln!(
out,
" /// Return the binary format for the current host."
)?;
writeln!(out, " pub const fn host() -> Self {{")?;
writeln!(out, " BinaryFormat::{:?}", triple.binary_format)?;
writeln!(out, " }}")?;
writeln!(out, "}}")?;
writeln!(out)?;
writeln!(out, "impl Triple {{")?;
writeln!(out, " /// Return the triple for the current host.")?;
writeln!(out, " pub const fn host() -> Self {{")?;
writeln!(out, " Self {{")?;
writeln!(
out,
" architecture: Architecture::{:?},",
triple.architecture
)?;
writeln!(out, " vendor: Vendor::{:?},", triple.vendor)?;
writeln!(
out,
" operating_system: OperatingSystem::{:?},",
triple.operating_system
)?;
writeln!(
out,
" environment: Environment::{:?},",
triple.environment
)?;
writeln!(
out,
" binary_format: BinaryFormat::{:?},",
triple.binary_format
)?;
writeln!(out, " }}")?;
writeln!(out, " }}")?;
writeln!(out, "}}")?;
Ok(())
}

12
third_party/rust/target-lexicon-0.9.0/examples/host.rs поставляемый Normal file
Просмотреть файл

@ -0,0 +1,12 @@
extern crate target_lexicon;
use target_lexicon::HOST;
fn main() {
println!(
"{}",
HOST.pointer_width()
.expect("architecture should be known")
.bytes()
);
}

14
third_party/rust/target-lexicon-0.9.0/examples/misc.rs поставляемый Normal file
Просмотреть файл

@ -0,0 +1,14 @@
extern crate target_lexicon;
use core::str::FromStr;
use target_lexicon::{Triple, HOST};
fn main() {
println!("The host triple is {}.", HOST);
let e = Triple::from_str("riscv32-unknown-unknown")
.expect("expected to recognize the RISC-V target")
.endianness()
.expect("expected to know the endianness of RISC-V");
println!("The endianness of RISC-V is {:?}.", e);
}

7
third_party/rust/target-lexicon-0.9.0/newlist поставляемый Executable file
Просмотреть файл

@ -0,0 +1,7 @@
#!/bin/bash
set -euo pipefail
rustup target list | sed 's/ (.*//' > list.txt
rustc +nightly --print target-list >> list.txt
cat list.txt | sort | uniq |sed 's/\(.*\)/ "\1",/' > sorted.txt
rm list.txt

56
third_party/rust/target-lexicon-0.9.0/src/host.rs поставляемый Normal file
Просмотреть файл

@ -0,0 +1,56 @@
use crate::{Architecture, BinaryFormat, Environment, OperatingSystem, Triple, Vendor};
// Include the implementations of the `HOST` object containing information
// about the current host.
include!(concat!(env!("OUT_DIR"), "/host.rs"));
#[cfg(test)]
mod tests {
#[cfg(target_os = "linux")]
#[test]
fn test_linux() {
use super::*;
assert_eq!(OperatingSystem::host(), OperatingSystem::Linux);
}
#[cfg(target_os = "macos")]
#[test]
fn test_macos() {
use super::*;
assert_eq!(OperatingSystem::host(), OperatingSystem::Darwin);
}
#[cfg(windows)]
#[test]
fn test_windows() {
use super::*;
assert_eq!(OperatingSystem::host(), OperatingSystem::Windows);
}
#[cfg(target_pointer_width = "16")]
#[test]
fn test_ptr16() {
use super::*;
assert_eq!(Architecture::host().pointer_width().unwrap().bits(), 16);
}
#[cfg(target_pointer_width = "32")]
#[test]
fn test_ptr32() {
use super::*;
assert_eq!(Architecture::host().pointer_width().unwrap().bits(), 32);
}
#[cfg(target_pointer_width = "64")]
#[test]
fn test_ptr64() {
use super::*;
assert_eq!(Architecture::host().pointer_width().unwrap().bits(), 64);
}
#[test]
fn host_object() {
use super::*;
assert_eq!(HOST, Triple::host());
}
}

34
third_party/rust/target-lexicon-0.9.0/src/lib.rs поставляемый Normal file
Просмотреть файл

@ -0,0 +1,34 @@
//! Target triple support.
#![deny(missing_docs, trivial_numeric_casts, unused_extern_crates)]
#![warn(unused_import_braces)]
#![cfg_attr(
feature = "cargo-clippy",
warn(
clippy::float_arithmetic,
clippy::mut_mut,
clippy::nonminimal_bool,
clippy::option_map_unwrap_or,
clippy::option_map_unwrap_or_else,
clippy::print_stdout,
clippy::unicode_not_nfc,
clippy::use_self
)
)]
#![cfg_attr(not(feature = "std"), no_std)]
extern crate alloc;
mod host;
mod parse_error;
mod targets;
#[macro_use]
mod triple;
pub use self::host::HOST;
pub use self::parse_error::ParseError;
pub use self::targets::{
Aarch64Architecture, Architecture, ArmArchitecture, BinaryFormat, Environment, OperatingSystem,
Vendor,
};
pub use self::triple::{CallingConvention, Endianness, PointerWidth, Triple};

34
third_party/rust/target-lexicon-0.9.0/src/parse_error.rs поставляемый Normal file
Просмотреть файл

@ -0,0 +1,34 @@
use alloc::string::String;
use core::fmt;
/// An error returned from parsing a triple.
#[derive(Clone, Debug, PartialEq, Eq)]
#[allow(missing_docs)]
pub enum ParseError {
UnrecognizedArchitecture(String),
UnrecognizedVendor(String),
UnrecognizedOperatingSystem(String),
UnrecognizedEnvironment(String),
UnrecognizedBinaryFormat(String),
UnrecognizedField(String),
}
impl fmt::Display for ParseError {
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
use ParseError::*;
match self {
UnrecognizedArchitecture(msg) => write!(fmt, "Unrecognized architecture: {}", msg),
UnrecognizedVendor(msg) => write!(fmt, "Unrecognized vendor: {}", msg),
UnrecognizedOperatingSystem(msg) => {
write!(fmt, "Unrecognized operating system: {}", msg)
}
UnrecognizedEnvironment(msg) => write!(fmt, "Unrecognized environment: {}", msg),
UnrecognizedBinaryFormat(msg) => write!(fmt, "Unrecognized binary format: {}", msg),
UnrecognizedField(msg) => write!(fmt, "Unrecognized field: {}", msg),
}
}
}
#[cfg(feature = "std")]
impl std::error::Error for ParseError {}

1123
third_party/rust/target-lexicon-0.9.0/src/targets.rs поставляемый Normal file

Разница между файлами не показана из-за своего большого размера Загрузить разницу

369
third_party/rust/target-lexicon-0.9.0/src/triple.rs поставляемый Normal file
Просмотреть файл

@ -0,0 +1,369 @@
// This file defines the `Triple` type and support code shared by all targets.
use crate::parse_error::ParseError;
use crate::targets::{
default_binary_format, Architecture, ArmArchitecture, BinaryFormat, Environment,
OperatingSystem, Vendor,
};
use alloc::borrow::ToOwned;
use core::fmt;
use core::str::FromStr;
/// The target memory endianness.
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
#[allow(missing_docs)]
pub enum Endianness {
Little,
Big,
}
/// The width of a pointer (in the default address space).
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
#[allow(missing_docs)]
pub enum PointerWidth {
U16,
U32,
U64,
}
impl PointerWidth {
/// Return the number of bits in a pointer.
pub fn bits(self) -> u8 {
match self {
PointerWidth::U16 => 16,
PointerWidth::U32 => 32,
PointerWidth::U64 => 64,
}
}
/// Return the number of bytes in a pointer.
///
/// For these purposes, there are 8 bits in a byte.
pub fn bytes(self) -> u8 {
match self {
PointerWidth::U16 => 2,
PointerWidth::U32 => 4,
PointerWidth::U64 => 8,
}
}
}
/// The calling convention, which specifies things like which registers are
/// used for passing arguments, which registers are callee-saved, and so on.
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
#[allow(missing_docs)]
pub enum CallingConvention {
/// "System V", which is used on most Unix-like platfoms. Note that the
/// specific conventions vary between hardware architectures; for example,
/// x86-32's "System V" is entirely different from x86-64's "System V".
SystemV,
/// The WebAssembly C ABI.
/// https://github.com/WebAssembly/tool-conventions/blob/master/BasicCABI.md
WasmBasicCAbi,
/// "Windows Fastcall", which is used on Windows. Note that like "System V",
/// this varies between hardware architectures. On x86-32 it describes what
/// Windows documentation calls "fastcall", and on x86-64 it describes what
/// Windows documentation often just calls the Windows x64 calling convention
/// (though the compiler still recognizes "fastcall" as an alias for it).
WindowsFastcall,
}
/// A target "triple". Historically such things had three fields, though they've
/// added additional fields over time.
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub struct Triple {
/// The "architecture" (and sometimes the subarchitecture).
pub architecture: Architecture,
/// The "vendor" (whatever that means).
pub vendor: Vendor,
/// The "operating system" (sometimes also the environment).
pub operating_system: OperatingSystem,
/// The "environment" on top of the operating system (often omitted for
/// operating systems with a single predominant environment).
pub environment: Environment,
/// The "binary format" (rarely used).
pub binary_format: BinaryFormat,
}
impl Triple {
/// Return the endianness of this target's architecture.
pub fn endianness(&self) -> Result<Endianness, ()> {
self.architecture.endianness()
}
/// Return the pointer width of this target's architecture.
pub fn pointer_width(&self) -> Result<PointerWidth, ()> {
self.architecture.pointer_width()
}
/// Return the default calling convention for the given target triple.
pub fn default_calling_convention(&self) -> Result<CallingConvention, ()> {
Ok(match self.operating_system {
OperatingSystem::Bitrig
| OperatingSystem::Cloudabi
| OperatingSystem::Darwin
| OperatingSystem::Dragonfly
| OperatingSystem::Freebsd
| OperatingSystem::Fuchsia
| OperatingSystem::Haiku
| OperatingSystem::Ios
| OperatingSystem::L4re
| OperatingSystem::Linux
| OperatingSystem::MacOSX { .. }
| OperatingSystem::Netbsd
| OperatingSystem::Openbsd
| OperatingSystem::Redox
| OperatingSystem::Solaris => CallingConvention::SystemV,
OperatingSystem::Windows => CallingConvention::WindowsFastcall,
OperatingSystem::Nebulet
| OperatingSystem::Emscripten
| OperatingSystem::Wasi
| OperatingSystem::Unknown => match self.architecture {
Architecture::Wasm32 => CallingConvention::WasmBasicCAbi,
_ => return Err(()),
},
_ => return Err(()),
})
}
}
impl Default for Triple {
fn default() -> Self {
Self {
architecture: Architecture::Unknown,
vendor: Vendor::Unknown,
operating_system: OperatingSystem::Unknown,
environment: Environment::Unknown,
binary_format: BinaryFormat::Unknown,
}
}
}
impl Default for Architecture {
fn default() -> Self {
Architecture::Unknown
}
}
impl Default for Vendor {
fn default() -> Self {
Vendor::Unknown
}
}
impl Default for OperatingSystem {
fn default() -> Self {
OperatingSystem::Unknown
}
}
impl Default for Environment {
fn default() -> Self {
Environment::Unknown
}
}
impl Default for BinaryFormat {
fn default() -> Self {
BinaryFormat::Unknown
}
}
impl fmt::Display for Triple {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let implied_binary_format = default_binary_format(&self);
write!(f, "{}", self.architecture)?;
if self.vendor == Vendor::Unknown
&& ((self.operating_system == OperatingSystem::Linux
&& (self.environment == Environment::Android
|| self.environment == Environment::Androideabi
|| self.environment == Environment::Kernel))
|| self.operating_system == OperatingSystem::Fuchsia
|| self.operating_system == OperatingSystem::Wasi
|| (self.operating_system == OperatingSystem::None_
&& (self.architecture == Architecture::Arm(ArmArchitecture::Armebv7r)
|| self.architecture == Architecture::Arm(ArmArchitecture::Armv7r)
|| self.architecture == Architecture::Arm(ArmArchitecture::Thumbv6m)
|| self.architecture == Architecture::Arm(ArmArchitecture::Thumbv7em)
|| self.architecture == Architecture::Arm(ArmArchitecture::Thumbv7m)
|| self.architecture == Architecture::Arm(ArmArchitecture::Thumbv8mBase)
|| self.architecture == Architecture::Arm(ArmArchitecture::Thumbv8mMain)
|| self.architecture == Architecture::Msp430
|| self.architecture == Architecture::X86_64)))
{
// As a special case, omit the vendor for Android, Fuchsia, Wasi, and sometimes
// None_, depending on the hardware architecture. This logic is entirely
// ad-hoc, and is just sufficient to handle the current set of recognized
// triples.
write!(f, "-{}", self.operating_system)?;
} else {
write!(f, "-{}-{}", self.vendor, self.operating_system)?;
}
if self.environment != Environment::Unknown {
write!(f, "-{}", self.environment)?;
}
if self.binary_format != implied_binary_format {
write!(f, "-{}", self.binary_format)?;
}
Ok(())
}
}
impl FromStr for Triple {
type Err = ParseError;
fn from_str(s: &str) -> Result<Self, Self::Err> {
let mut parts = s.split('-');
let mut result = Self::default();
let mut current_part;
current_part = parts.next();
if let Some(s) = current_part {
if let Ok(architecture) = Architecture::from_str(s) {
result.architecture = architecture;
current_part = parts.next();
} else {
// Insist that the triple start with a valid architecture.
return Err(ParseError::UnrecognizedArchitecture(s.to_owned()));
}
}
let mut has_vendor = false;
let mut has_operating_system = false;
if let Some(s) = current_part {
if let Ok(vendor) = Vendor::from_str(s) {
has_vendor = true;
result.vendor = vendor;
current_part = parts.next();
}
}
if !has_operating_system {
if let Some(s) = current_part {
if let Ok(operating_system) = OperatingSystem::from_str(s) {
has_operating_system = true;
result.operating_system = operating_system;
current_part = parts.next();
}
}
}
let mut has_environment = false;
if let Some(s) = current_part {
if let Ok(environment) = Environment::from_str(s) {
has_environment = true;
result.environment = environment;
current_part = parts.next();
}
}
let mut has_binary_format = false;
if let Some(s) = current_part {
if let Ok(binary_format) = BinaryFormat::from_str(s) {
has_binary_format = true;
result.binary_format = binary_format;
current_part = parts.next();
}
}
// The binary format is frequently omitted; if that's the case here,
// infer it from the other fields.
if !has_binary_format {
result.binary_format = default_binary_format(&result);
}
if let Some(s) = current_part {
Err(
if !has_vendor && !has_operating_system && !has_environment && !has_binary_format {
ParseError::UnrecognizedVendor(s.to_owned())
} else if !has_operating_system && !has_environment && !has_binary_format {
ParseError::UnrecognizedOperatingSystem(s.to_owned())
} else if !has_environment && !has_binary_format {
ParseError::UnrecognizedEnvironment(s.to_owned())
} else if !has_binary_format {
ParseError::UnrecognizedBinaryFormat(s.to_owned())
} else {
ParseError::UnrecognizedField(s.to_owned())
},
)
} else {
Ok(result)
}
}
}
/// A convenient syntax for triple literals.
///
/// This currently expands to code that just calls `Triple::from_str` and does
/// an `expect`, though in the future it would be cool to use procedural macros
/// or so to report errors at compile time instead.
#[macro_export]
macro_rules! triple {
($str:tt) => {
target_lexicon::Triple::from_str($str).expect("invalid triple literal")
};
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn parse_errors() {
assert_eq!(
Triple::from_str(""),
Err(ParseError::UnrecognizedArchitecture("".to_owned()))
);
assert_eq!(
Triple::from_str("foo"),
Err(ParseError::UnrecognizedArchitecture("foo".to_owned()))
);
assert_eq!(
Triple::from_str("unknown-foo"),
Err(ParseError::UnrecognizedVendor("foo".to_owned()))
);
assert_eq!(
Triple::from_str("unknown-unknown-foo"),
Err(ParseError::UnrecognizedOperatingSystem("foo".to_owned()))
);
assert_eq!(
Triple::from_str("unknown-unknown-unknown-foo"),
Err(ParseError::UnrecognizedEnvironment("foo".to_owned()))
);
assert_eq!(
Triple::from_str("unknown-unknown-unknown-unknown-foo"),
Err(ParseError::UnrecognizedBinaryFormat("foo".to_owned()))
);
assert_eq!(
Triple::from_str("unknown-unknown-unknown-unknown-unknown-foo"),
Err(ParseError::UnrecognizedField("foo".to_owned()))
);
}
#[test]
fn defaults() {
assert_eq!(
Triple::from_str("unknown-unknown-unknown"),
Ok(Triple::default())
);
assert_eq!(
Triple::from_str("unknown-unknown-unknown-unknown"),
Ok(Triple::default())
);
assert_eq!(
Triple::from_str("unknown-unknown-unknown-unknown-unknown"),
Ok(Triple::default())
);
}
#[test]
fn unknown_properties() {
assert_eq!(Triple::default().endianness(), Err(()));
assert_eq!(Triple::default().pointer_width(), Err(()));
assert_eq!(Triple::default().default_calling_convention(), Err(()));
}
}

11
third_party/rust/target-lexicon-0.9.0/test.sh поставляемый Executable file
Просмотреть файл

@ -0,0 +1,11 @@
#!/bin/bash
set -oeu pipefail
for trip in wasm32-unknown-unknown wasm32-wasi arm-unknown-linux-gnueabi aarch64-unknown-linux-gnu; do
echo TARGET $trip
cargo build --target $trip --all
cp target/$trip/debug/build/target-lexicon-*/out/host.rs host.rs
rustfmt host.rs
diff -u target/$trip/debug/build/target-lexicon-*/out/host.rs host.rs
done

Просмотреть файл

@ -1 +1 @@
{"files":{"Cargo.lock":"a1a162e6ce8fc2234a6ddf7090410006a1920ace8738772e32a5b50e4780c19d","Cargo.toml":"f3b545fa0f184fd0d3624e6e5c205fcbdf1ad0934a2e08406549ad53c2a62ac3","LICENSE":"268872b9816f90fd8e85db5a28d33f8150ebb8dd016653fb39ef1f94f2686bc5","README.md":"c3467056d91be3f59562158ee9604c729b5b5f473efbefb036032803eb76809e","build.rs":"723100e9cdc30cd8c48407233c2cffa10f5b10703a0a11bac1230d8b86e49ccf","examples/host.rs":"503bafddfb372123fe4dc0e7b8037808beb5bfe6df60c00d3315922bd3792c6c","examples/misc.rs":"49a579845450b7b020ed5c97dca142fc548725893cbc82f6f750ee0caab2beca","newlist":"89564342916321c5bc35e772d374a7f0af22cc9ae6dcc0027eca48d2269f18cb","src/host.rs":"fb543df4f362e9119a58523563e453110f4e3a426f0995911d0ca386657cf1d9","src/lib.rs":"4414353c30f25d44df6cc14f7f9eea9991222289c6aa662b74406f6923235970","src/parse_error.rs":"b3735eabc0fd0a9dfdd6375662f20ec96a79852a00a05a98fb2e421545285e53","src/targets.rs":"9ccc0849cff06d8906dacbdc15136cc47fab85ccd795033ddfdde1397dfcfe32","src/triple.rs":"949bd83b043b53b18f643ebc3fbebbfe02a13998b787fda432a5d36aa27d20bd","test.sh":"22e3c630a6c84e90d5c70c367a6712be8eeca1e7682c00d1f65bf53e330e9191"},"package":"6f4c118a7a38378f305a9e111fcb2f7f838c0be324bfb31a77ea04f7f6e684b4"}
{"files":{"Cargo.lock":"8e4587915716186b38c3e202791d595629d132256f27ad6869069bcac7e85253","Cargo.toml":"e3f845dc9dbe5f658993b69b09cd6ee8c4e00ef4dcc9fb083be2346f51effd04","LICENSE":"268872b9816f90fd8e85db5a28d33f8150ebb8dd016653fb39ef1f94f2686bc5","README.md":"c3467056d91be3f59562158ee9604c729b5b5f473efbefb036032803eb76809e","a":"0063b040e749e5cc9c82e682c67c53ae1830500f0c4aa85507b1ca4ed8454886","build.rs":"85d6a1b6392b56946f48c0ff1526736a37fe012951bf3855709da1d6cfb4baa0","examples/host.rs":"503bafddfb372123fe4dc0e7b8037808beb5bfe6df60c00d3315922bd3792c6c","examples/misc.rs":"49a579845450b7b020ed5c97dca142fc548725893cbc82f6f750ee0caab2beca","host.rs":"331a7217b0b5fae0d7c37bd6f5e8caa2762a220c51fb23f5cf354fa76d91974a","newlist":"89564342916321c5bc35e772d374a7f0af22cc9ae6dcc0027eca48d2269f18cb","sorted.txt":"ea6d3912b5d1eba7be33e99f1dd45953d80863dad75c5fc0ed1cd8020373b974","src/host.rs":"fb543df4f362e9119a58523563e453110f4e3a426f0995911d0ca386657cf1d9","src/lib.rs":"89986c98b9a04e0f1e957e0127e23a53048a1f0d597493723c4bba031c2ca32d","src/parse_error.rs":"b3735eabc0fd0a9dfdd6375662f20ec96a79852a00a05a98fb2e421545285e53","src/targets.rs":"f2048f06e3e2151a8181d8c92651fa45e64b8bfdfd18ead4b6c18ee7c9fb9003","src/triple.rs":"4704266fec8763bc70d230aad3608bdb790b51e41149056daa2ce0d5fdaef5a3","test.sh":"4458bbd0ece260fe335054b53caeb57d9022258d9a07b6b44b994f6ce2ca82c6"},"package":"ab0e7238dcc7b40a7be719a25365910f6807bd864f4cce6b2e6b873658e2b19d"}

2
third_party/rust/target-lexicon/Cargo.lock сгенерированный поставляемый
Просмотреть файл

@ -2,5 +2,5 @@
# It is not intended for manual editing.
[[package]]
name = "target-lexicon"
version = "0.9.0"
version = "0.10.0"

2
third_party/rust/target-lexicon/Cargo.toml поставляемый
Просмотреть файл

@ -13,7 +13,7 @@
[package]
edition = "2018"
name = "target-lexicon"
version = "0.9.0"
version = "0.10.0"
authors = ["Dan Gohman <sunfish@mozilla.com>"]
description = "Targeting utilities for compilers and related tools"
documentation = "https://docs.rs/target-lexicon/"

59
third_party/rust/target-lexicon/a поставляемый Normal file
Просмотреть файл

@ -0,0 +1,59 @@
diff --git a/src/targets.rs b/src/targets.rs
index 6ae570e..3aa1044 100644
--- a/src/targets.rs
+++ b/src/targets.rs
@@ -1,6 +1,7 @@
// This file defines all the identifier enums and target-aware logic.
use crate::triple::{Endianness, PointerWidth, Triple};
+use alloc::string::String;
use core::fmt;
use core::str::FromStr;
@@ -292,7 +293,7 @@ impl Aarch64Architecture {
/// The "vendor" field, which in practice is little more than an arbitrary
/// modifier.
-#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
+#[derive(Clone, Debug, PartialEq, Eq, Hash)]
#[allow(missing_docs)]
pub enum Vendor {
Unknown,
@@ -306,6 +307,7 @@ pub enum Vendor {
Sun,
Uwp,
Wrs,
+ Custom(String),
}
/// The "operating system" field, which sometimes implies an environment, and
@@ -717,6 +719,7 @@ impl fmt::Display for Vendor {
Vendor::Sun => "sun",
Vendor::Uwp => "uwp",
Vendor::Wrs => "wrs",
+ Vendor::Custom(ref name) => name,
};
f.write_str(s)
}
@@ -738,7 +741,20 @@ impl FromStr for Vendor {
"sun" => Vendor::Sun,
"uwp" => Vendor::Uwp,
"wrs" => Vendor::Wrs,
- _ => return Err(()),
+ custom => {
+ use alloc::borrow::ToOwned;
+ if Architecture::from_str(custom).is_ok()
+ || OperatingSystem::from_str(custom).is_ok()
+ || Environment::from_str(custom).is_ok()
+ || BinaryFormat::from_str(custom).is_ok()
+ {
+ return Err(());
+ }
+ if custom.find(|c: char| !c.is_ascii_alphanumeric() && c != '_' && c != '.').is_some() {
+ return Err(());
+ }
+ Vendor::Custom(custom.to_owned())
+ }
})
}
}

23
third_party/rust/target-lexicon/build.rs поставляемый
Просмотреть файл

@ -32,6 +32,7 @@ mod parse_error {
}
}
use self::targets::Vendor;
use self::triple::Triple;
fn main() {
@ -52,6 +53,8 @@ fn write_host_rs(mut out: File, triple: Triple) -> io::Result<()> {
writeln!(out, "use crate::Aarch64Architecture::*;")?;
writeln!(out, "#[allow(unused_imports)]")?;
writeln!(out, "use crate::ArmArchitecture::*;")?;
writeln!(out, "#[allow(unused_imports)]")?;
writeln!(out, "use crate::CustomVendor;")?;
writeln!(out)?;
writeln!(out, "/// The `Triple` of the current host.")?;
writeln!(out, "pub const HOST: Triple = Triple {{")?;
@ -60,7 +63,7 @@ fn write_host_rs(mut out: File, triple: Triple) -> io::Result<()> {
" architecture: Architecture::{:?},",
triple.architecture
)?;
writeln!(out, " vendor: Vendor::{:?},", triple.vendor)?;
writeln!(out, " vendor: {},", vendor_display(&triple.vendor))?;
writeln!(
out,
" operating_system: OperatingSystem::{:?},",
@ -90,7 +93,7 @@ fn write_host_rs(mut out: File, triple: Triple) -> io::Result<()> {
writeln!(out, "impl Vendor {{")?;
writeln!(out, " /// Return the vendor for the current host.")?;
writeln!(out, " pub const fn host() -> Self {{")?;
writeln!(out, " Vendor::{:?}", triple.vendor)?;
writeln!(out, " {}", vendor_display(&triple.vendor))?;
writeln!(out, " }}")?;
writeln!(out, "}}")?;
writeln!(out)?;
@ -138,7 +141,11 @@ fn write_host_rs(mut out: File, triple: Triple) -> io::Result<()> {
" architecture: Architecture::{:?},",
triple.architecture
)?;
writeln!(out, " vendor: Vendor::{:?},", triple.vendor)?;
writeln!(
out,
" vendor: {},",
vendor_display(&triple.vendor)
)?;
writeln!(
out,
" operating_system: OperatingSystem::{:?},",
@ -160,3 +167,13 @@ fn write_host_rs(mut out: File, triple: Triple) -> io::Result<()> {
Ok(())
}
fn vendor_display(vendor: &Vendor) -> String {
match vendor {
Vendor::Custom(custom) => format!(
"Vendor::Custom(CustomVendor::Static({:?}))",
custom.as_str()
),
known => format!("Vendor::{:?}", known),
}
}

63
third_party/rust/target-lexicon/host.rs поставляемый Normal file
Просмотреть файл

@ -0,0 +1,63 @@
#[allow(unused_imports)]
use crate::Aarch64Architecture::*;
#[allow(unused_imports)]
use crate::ArmArchitecture::*;
#[allow(unused_imports)]
use crate::CustomVendor;
/// The `Triple` of the current host.
pub const HOST: Triple = Triple {
architecture: Architecture::Aarch64(Aarch64),
vendor: Vendor::Unknown,
operating_system: OperatingSystem::Linux,
environment: Environment::Gnu,
binary_format: BinaryFormat::Elf,
};
impl Architecture {
/// Return the architecture for the current host.
pub const fn host() -> Self {
Architecture::Aarch64(Aarch64)
}
}
impl Vendor {
/// Return the vendor for the current host.
pub const fn host() -> Self {
Vendor::Unknown
}
}
impl OperatingSystem {
/// Return the operating system for the current host.
pub const fn host() -> Self {
OperatingSystem::Linux
}
}
impl Environment {
/// Return the environment for the current host.
pub const fn host() -> Self {
Environment::Gnu
}
}
impl BinaryFormat {
/// Return the binary format for the current host.
pub const fn host() -> Self {
BinaryFormat::Elf
}
}
impl Triple {
/// Return the triple for the current host.
pub const fn host() -> Self {
Self {
architecture: Architecture::Aarch64(Aarch64),
vendor: Vendor::Unknown,
operating_system: OperatingSystem::Linux,
environment: Environment::Gnu,
binary_format: BinaryFormat::Elf,
}
}
}

143
third_party/rust/target-lexicon/sorted.txt поставляемый Normal file
Просмотреть файл

@ -0,0 +1,143 @@
"aarch64-apple-ios",
"aarch64-fuchsia",
"aarch64-linux-android",
"aarch64-pc-windows-msvc",
"aarch64-unknown-cloudabi",
"aarch64-unknown-freebsd",
"aarch64-unknown-hermit",
"aarch64-unknown-linux-gnu",
"aarch64-unknown-linux-musl",
"aarch64-unknown-netbsd",
"aarch64-unknown-none",
"aarch64-unknown-none-softfloat",
"aarch64-unknown-openbsd",
"aarch64-unknown-redox",
"aarch64-uwp-windows-msvc",
"aarch64-wrs-vxworks",
"armebv7r-none-eabi",
"armebv7r-none-eabihf",
"arm-linux-androideabi",
"arm-unknown-linux-gnueabi",
"arm-unknown-linux-gnueabihf",
"arm-unknown-linux-musleabi",
"arm-unknown-linux-musleabihf",
"armv4t-unknown-linux-gnueabi",
"armv5te-unknown-linux-gnueabi",
"armv5te-unknown-linux-musleabi",
"armv6-unknown-freebsd",
"armv6-unknown-netbsd-eabihf",
"armv7-apple-ios",
"armv7-linux-androideabi",
"armv7r-none-eabi",
"armv7r-none-eabihf",
"armv7s-apple-ios",
"armv7-unknown-cloudabi-eabihf",
"armv7-unknown-freebsd",
"armv7-unknown-linux-gnueabi",
"armv7-unknown-linux-gnueabihf",
"armv7-unknown-linux-musleabi",
"armv7-unknown-linux-musleabihf",
"armv7-unknown-netbsd-eabihf",
"armv7-wrs-vxworks-eabihf",
"asmjs-unknown-emscripten",
"hexagon-unknown-linux-musl",
"i386-apple-ios",
"i586-pc-windows-msvc",
"i586-unknown-linux-gnu",
"i586-unknown-linux-musl",
"i686-apple-darwin",
"i686-linux-android",
"i686-pc-windows-gnu",
"i686-pc-windows-msvc",
"i686-unknown-cloudabi",
"i686-unknown-dragonfly",
"i686-unknown-freebsd",
"i686-unknown-haiku",
"i686-unknown-linux-gnu",
"i686-unknown-linux-musl",
"i686-unknown-netbsd",
"i686-unknown-openbsd",
"i686-unknown-uefi",
"i686-uwp-windows-gnu",
"i686-uwp-windows-msvc",
"i686-wrs-vxworks",
"mips64el-unknown-linux-gnuabi64",
"mips64el-unknown-linux-muslabi64",
"mips64-unknown-linux-gnuabi64",
"mips64-unknown-linux-muslabi64",
"mipsel-unknown-linux-gnu",
"mipsel-unknown-linux-musl",
"mipsel-unknown-linux-uclibc",
"mipsisa32r6el-unknown-linux-gnu",
"mipsisa32r6-unknown-linux-gnu",
"mipsisa64r6el-unknown-linux-gnuabi64",
"mipsisa64r6-unknown-linux-gnuabi64",
"mips-unknown-linux-gnu",
"mips-unknown-linux-musl",
"mips-unknown-linux-uclibc",
"msp430-none-elf",
"nvptx64-nvidia-cuda",
"powerpc64le-unknown-linux-gnu",
"powerpc64le-unknown-linux-musl",
"powerpc64-unknown-freebsd",
"powerpc64-unknown-linux-gnu",
"powerpc64-unknown-linux-musl",
"powerpc64-wrs-vxworks",
"powerpc-unknown-linux-gnu",
"powerpc-unknown-linux-gnuspe",
"powerpc-unknown-linux-musl",
"powerpc-unknown-netbsd",
"powerpc-wrs-vxworks",
"powerpc-wrs-vxworks-spe",
"riscv32imac-unknown-none-elf",
"riscv32imc-unknown-none-elf",
"riscv32i-unknown-none-elf",
"riscv64gc-unknown-none-elf",
"riscv64imac-unknown-none-elf",
"s390x-unknown-linux-gnu",
"sparc64-unknown-linux-gnu",
"sparc64-unknown-netbsd",
"sparc64-unknown-openbsd",
"sparc-unknown-linux-gnu",
"sparcv9-sun-solaris",
"thumbv6m-none-eabi",
"thumbv7a-pc-windows-msvc",
"thumbv7em-none-eabi",
"thumbv7em-none-eabihf",
"thumbv7m-none-eabi",
"thumbv7neon-linux-androideabi",
"thumbv7neon-unknown-linux-gnueabihf",
"thumbv7neon-unknown-linux-musleabihf",
"thumbv8m.base-none-eabi",
"thumbv8m.main-none-eabi",
"thumbv8m.main-none-eabihf",
"wasm32-unknown-emscripten",
"wasm32-unknown-unknown",
"wasm32-wasi",
"x86_64-apple-darwin",
"x86_64-apple-ios",
"x86_64-fortanix-unknown-sgx",
"x86_64-fuchsia",
"x86_64-linux-android",
"x86_64-linux-kernel",
"x86_64-pc-solaris",
"x86_64-pc-windows-gnu",
"x86_64-pc-windows-msvc",
"x86_64-rumprun-netbsd",
"x86_64-sun-solaris",
"x86_64-unknown-cloudabi",
"x86_64-unknown-dragonfly",
"x86_64-unknown-freebsd",
"x86_64-unknown-haiku",
"x86_64-unknown-hermit",
"x86_64-unknown-l4re-uclibc",
"x86_64-unknown-linux-gnu",
"x86_64-unknown-linux-gnux32",
"x86_64-unknown-linux-musl",
"x86_64-unknown-netbsd",
"x86_64-unknown-openbsd",
"x86_64-unknown-redox",
"x86_64-unknown-uefi",
"x86_64-uwp-windows-gnu",
"x86_64-uwp-windows-msvc",
"x86_64-wrs-vxworks",

4
third_party/rust/target-lexicon/src/lib.rs поставляемый
Просмотреть файл

@ -28,7 +28,7 @@ mod triple;
pub use self::host::HOST;
pub use self::parse_error::ParseError;
pub use self::targets::{
Aarch64Architecture, Architecture, ArmArchitecture, BinaryFormat, Environment, OperatingSystem,
Vendor,
Aarch64Architecture, Architecture, ArmArchitecture, BinaryFormat, CustomVendor, Environment,
OperatingSystem, Vendor,
};
pub use self::triple::{CallingConvention, Endianness, PointerWidth, Triple};

169
third_party/rust/target-lexicon/src/targets.rs поставляемый
Просмотреть файл

@ -1,7 +1,10 @@
// This file defines all the identifier enums and target-aware logic.
use crate::triple::{Endianness, PointerWidth, Triple};
use alloc::boxed::Box;
use alloc::string::String;
use core::fmt;
use core::hash::{Hash, Hasher};
use core::str::FromStr;
/// The "architecture" field, which in some cases also specifies a specific
@ -290,9 +293,42 @@ impl Aarch64Architecture {
}
}
/// A string for a `Vendor::Custom` that can either be used in `const`
/// contexts or hold dynamic strings.
#[derive(Clone, Debug, Eq)]
pub enum CustomVendor {
/// An owned `String`. This supports the general case.
Owned(Box<String>),
/// A static `str`, so that `CustomVendor` can be constructed in `const`
/// contexts.
Static(&'static str),
}
impl CustomVendor {
/// Extracts a string slice.
pub fn as_str(&self) -> &str {
match self {
CustomVendor::Owned(s) => s,
CustomVendor::Static(s) => s,
}
}
}
impl PartialEq for CustomVendor {
fn eq(&self, other: &Self) -> bool {
self.as_str() == other.as_str()
}
}
impl Hash for CustomVendor {
fn hash<H: Hasher>(&self, state: &mut H) {
self.as_str().hash(state)
}
}
/// The "vendor" field, which in practice is little more than an arbitrary
/// modifier.
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
#[allow(missing_docs)]
pub enum Vendor {
Unknown,
@ -306,6 +342,15 @@ pub enum Vendor {
Sun,
Uwp,
Wrs,
/// A custom vendor. "Custom" in this context means that the vendor is
/// not specifically recognized by upstream Autotools, LLVM, Rust, or other
/// relevant authorities on triple naming. It's useful for people building
/// and using locally patched toolchains.
///
/// Outside of such patched environments, users of `target-lexicon` should
/// treat `Custom` the same as `Unknown` and ignore the string.
Custom(CustomVendor),
}
/// The "operating system" field, which sometimes implies an environment, and
@ -717,6 +762,7 @@ impl fmt::Display for Vendor {
Vendor::Sun => "sun",
Vendor::Uwp => "uwp",
Vendor::Wrs => "wrs",
Vendor::Custom(ref name) => name.as_str(),
};
f.write_str(s)
}
@ -738,7 +784,43 @@ impl FromStr for Vendor {
"sun" => Vendor::Sun,
"uwp" => Vendor::Uwp,
"wrs" => Vendor::Wrs,
_ => return Err(()),
custom => {
use alloc::borrow::ToOwned;
// A custom vendor. Since triple syntax is so loosely defined,
// be as conservative as we can to avoid potential ambiguities.
// We err on the side of being too strict here, as we can
// always relax it if needed.
// Don't allow empty string names.
if custom.is_empty() {
return Err(());
}
// Don't allow any other recognized name as a custom vendor,
// since vendors can be omitted in some contexts.
if Architecture::from_str(custom).is_ok()
|| OperatingSystem::from_str(custom).is_ok()
|| Environment::from_str(custom).is_ok()
|| BinaryFormat::from_str(custom).is_ok()
{
return Err(());
}
// Require the first character to be an ascii lowercase.
if !custom.chars().nth(0).unwrap().is_ascii_lowercase() {
return Err(());
}
// Restrict the set of characters permitted in a custom vendor.
if custom.chars().any(|c: char| {
!(c.is_ascii_lowercase() || c.is_ascii_digit() || c == '_' || c == '.')
}) {
return Err(());
}
Vendor::Custom(CustomVendor::Owned(Box::new(custom.to_owned())))
}
})
}
}
@ -1120,4 +1202,87 @@ mod tests {
assert_eq!(t.environment, Environment::Eabihf);
assert_eq!(t.binary_format, BinaryFormat::Elf);
}
#[test]
fn custom_vendors() {
// Test various invalid cases.
assert!(Triple::from_str("x86_64--linux").is_err());
assert!(Triple::from_str("x86_64-42-linux").is_err());
assert!(Triple::from_str("x86_64-__customvendor__-linux").is_err());
assert!(Triple::from_str("x86_64-^-linux").is_err());
assert!(Triple::from_str("x86_64- -linux").is_err());
assert!(Triple::from_str("x86_64-CustomVendor-linux").is_err());
assert!(Triple::from_str("x86_64-linux-linux").is_err());
assert!(Triple::from_str("x86_64-x86_64-linux").is_err());
assert!(Triple::from_str("x86_64-elf-linux").is_err());
assert!(Triple::from_str("x86_64-gnu-linux").is_err());
assert!(Triple::from_str("x86_64-linux-customvendor").is_err());
assert!(Triple::from_str("customvendor").is_err());
assert!(Triple::from_str("customvendor-x86_64").is_err());
assert!(Triple::from_str("x86_64-").is_err());
assert!(Triple::from_str("x86_64--").is_err());
// Test various Unicode things.
assert!(
Triple::from_str("x86_64-𝓬𝓾𝓼𝓽𝓸𝓶𝓿𝓮𝓷𝓭𝓸𝓻-linux").is_err(),
"unicode font hazard"
);
assert!(
Triple::from_str("x86_64-ćúśtőḿvéńdőŕ-linux").is_err(),
"diacritical mark stripping hazard"
);
assert!(
Triple::from_str("x86_64-customvendοr-linux").is_err(),
"homoglyph hazard"
);
assert!(Triple::from_str("x86_64-customvendor-linux").is_ok());
assert!(
Triple::from_str("x86_64-ffi-linux").is_err(),
"normalization hazard"
);
assert!(Triple::from_str("x86_64-ffi-linux").is_ok());
assert!(
Triple::from_str("x86_64-customvendor-linux").is_err(),
"zero-width character hazard"
);
assert!(
Triple::from_str("x86_64-customvendor-linux").is_err(),
"BOM hazard"
);
// Test some valid cases.
let t = Triple::from_str("x86_64-customvendor-linux")
.expect("can't parse target with custom vendor");
assert_eq!(t.architecture, Architecture::X86_64);
assert_eq!(
t.vendor,
Vendor::Custom(CustomVendor::Static("customvendor"))
);
assert_eq!(t.operating_system, OperatingSystem::Linux);
assert_eq!(t.environment, Environment::Unknown);
assert_eq!(t.binary_format, BinaryFormat::Elf);
assert_eq!(t.to_string(), "x86_64-customvendor-linux");
let t =
Triple::from_str("x86_64-customvendor").expect("can't parse target with custom vendor");
assert_eq!(t.architecture, Architecture::X86_64);
assert_eq!(
t.vendor,
Vendor::Custom(CustomVendor::Static("customvendor"))
);
assert_eq!(t.operating_system, OperatingSystem::Unknown);
assert_eq!(t.environment, Environment::Unknown);
assert_eq!(t.binary_format, BinaryFormat::Unknown);
assert_eq!(
Triple::from_str("unknown-foo"),
Ok(Triple {
architecture: Architecture::Unknown,
vendor: Vendor::Custom(CustomVendor::Static("foo")),
operating_system: OperatingSystem::Unknown,
environment: Environment::Unknown,
binary_format: BinaryFormat::Unknown,
})
);
}
}

Просмотреть файл

@ -322,10 +322,6 @@ mod tests {
Triple::from_str("foo"),
Err(ParseError::UnrecognizedArchitecture("foo".to_owned()))
);
assert_eq!(
Triple::from_str("unknown-foo"),
Err(ParseError::UnrecognizedVendor("foo".to_owned()))
);
assert_eq!(
Triple::from_str("unknown-unknown-foo"),
Err(ParseError::UnrecognizedOperatingSystem("foo".to_owned()))

1
third_party/rust/target-lexicon/test.sh поставляемый
Просмотреть файл

@ -2,6 +2,7 @@
set -oeu pipefail
cargo clean
for trip in wasm32-unknown-unknown wasm32-wasi arm-unknown-linux-gnueabi aarch64-unknown-linux-gnu; do
echo TARGET $trip
cargo build --target $trip --all

Просмотреть файл

@ -1 +1 @@
{"files":{"Cargo.lock":"c6fca2a5cc9f95e23b077b723dca051c28808b0bb99a2221104002026fcccae9","Cargo.toml":"bab0e452ba9beb0f5efd7f46a6e6d16e5e6b18751a014157a152b1aae37ed517","LICENSE":"a6c48161a09acc75a0e25503bab66a731eb5fba5392ed4bb4743e4ba5085327a","README.md":"df9c5aa22ca3bcf6221c7e4297cd741cbbdfb39294b4ef28c4d382688395611a","benches/benchmark.rs":"951abd671bd1a5a33d09379b023de000e89fc5f99a5950f0b3b2f571021aa402","compare-master.sh":"165490eab36ef4eceb2913a6c5cdeff479a05e1e0119a7f4551b03dbcda51ad4","examples/dump.rs":"de2bbdba75e21b9ff92b32697b3d9941f8695b8f7e3a8dee8fc5d7f4c3a0649c","examples/simple.rs":"c79ae542913e72cfcd03711543d173b2e8f62783e6c206459953bdb94dbb8c0c","format-all.sh":"6b02a40629ef3d2c0b9671222582a6217d526317a41262ae06c7a95de53bcbeb","src/binary_reader.rs":"39e0a785a41e2513926ab140a1e07f38a6e898737d098d1d038ba5229e7c24b3","src/lib.rs":"a17f353162053e0e915a0e0d1f4d4ba86a7a8e4ff949c83faad004b707ac003f","src/limits.rs":"4e4f9b7ed1d26e7a6727e36b136015cd9f4e38f596b3c8f82236789f45905cae","src/operators_validator.rs":"12bb14c9e9fb7b20af8039aff0a6aaaa4a8af0c55ad3366fb6844758fda1f5a3","src/parser.rs":"c5afcf039a62952f4e674773416d4c4507711d10b4248ed3bce5e1223cc97034","src/primitives.rs":"65b7ddf0fb0bde4df0823a23ced952720e7dd8c4b630fdcd988096ccb8ea1379","src/readers/code_section.rs":"2034c399b76428ac993c22f551f3c541b132d8b4ccc74e34f0043e25534d107b","src/readers/data_count_section.rs":"27ef37517b6beac21245008b14b5416b851c52d0af8e2ae85c1456674e1c9a9e","src/readers/data_section.rs":"e7e2a539d2d3049d4a8f68df9ea2f21d97e7061657bbd91845e1df3e9c1f2ebc","src/readers/element_section.rs":"e31e1d819c0b10acf58b8975238554245defe36db1c3206683b056c52978fb21","src/readers/export_section.rs":"7c74f7a11406a95c162f6ad4f77aafd0b1eee309f33b69f06bea12b23925e143","src/readers/function_section.rs":"57c0479ba8d7f61908ed74e86cbc26553fdd6d2d952f032ce29385a39f82efd3","src/readers/global_section.rs":"5fa18bed0fffadcc2dbdcbaedbe4e4398992fd1ce9e611b0319333a7681082ac","src/readers/import_section.rs":"1db4bf7290d04783d5cf526050d025b15a1daaf2bd97fca1a92ecb873d48f641","src/readers/init_expr.rs":"7020c80013dad4518a5f969c3ab4d624b46d778f03e632871cf343964f63441c","src/readers/linking_section.rs":"9df71f3ee5356f0d273c099212213353080001e261ca697caddf6b847fb5af09","src/readers/memory_section.rs":"83212f86cfc40d18fb392e9234c880afdf443f4af38a727ba346f9c740ef8718","src/readers/mod.rs":"188aa45a893f4d17df7633a3df6a32438b64e192e001ddcc50543e007b4f7db4","src/readers/module.rs":"311b877264bf9d035280cad0c61eb3640c15505c4da5e8ba45c7bf9e067abbd4","src/readers/name_section.rs":"297f57393d5fef745ec265438108aa6eb7ed2762c03c3beb539493612442f3da","src/readers/operators.rs":"da43ee8afcb0c1d6e7f1e19e8a10143101f0c598b1e533a394c7397f43881a82","src/readers/producers_section.rs":"674f402fc4545c94487f827153871b37adab44ed5eff4070a436eb18e514023a","src/readers/reloc_section.rs":"0ef818a8b83a4542c4c29c23642436a92d3e7c37bc0248e817ed5a9d65ec38ce","src/readers/section_reader.rs":"3d2260449fa0455d710ba6d97810372ec36cba70722c10dd236c3a18ca0eb56f","src/readers/sourcemappingurl_section.rs":"ababe84d51e4817ad19f827aa2b5239578e7f202e5ec06dd688b618885138434","src/readers/start_section.rs":"3eeae00e1aa0fcb2e0d93b7b0eaac30a60d3f1431c71c589cd3f73adb363d532","src/readers/table_section.rs":"e564876825a7b31df2b5dc850279b523e26dc50a08da935cc8d635a49e809951","src/readers/type_section.rs":"2fa33a7b793f3bfa01c259b5dbc38633b7343931886ab41f0cb96dd78db3bf6e","src/tests.rs":"661dcb6ea83e0e066d14efc22f3939b1a935bc9681cc6d971bf0398038a0cf40","src/validator.rs":"4dfd7176fc1fced1730ecf6ee8c9225751a6ba3047862b9cfc8b151d9526a378","test-all.sh":"f36e3e9bf9c39456bab3ac170d3a09911becf2b7e0d0e2a58854ce1750da0d1f","test-no_std.sh":"f8bc939b378fe618b7ec6297152708e7c8740858eb94e5756464934a38796b8c"},"package":"e5083b449454f7de0b15f131eee17de54b5a71dcb9adcf11df2b2f78fad0cd82"}
{"files":{"CODE_OF_CONDUCT.md":"a13aaaf393818bd91207c618724d3fb74944ca5161201822a84af951bcf655ef","Cargo.lock":"75d9e05f0cb74776829fd6880c7ef89f3018ffce6ebd49590cac9f0c37b1b8ea","Cargo.toml":"448969b263b876a461f5bfbe1609ab85d5f2e82b62659f17675e4d7446c77db4","LICENSE":"a6c48161a09acc75a0e25503bab66a731eb5fba5392ed4bb4743e4ba5085327a","ORG_CODE_OF_CONDUCT.md":"59c4c4435538496193cd73e89b2cd971d1011dba573158cf108abe6af6603e6b","README.md":"90c9b0e3dd91a63b6a8088b72200b3118fa0bbdf3320cd98609bd4cc4ef09902","SECURITY.md":"4d75afb09dd28eb5982e3a1f768ee398d90204669ceef3240a16b31dcf04148a","benches/benchmark.rs":"951abd671bd1a5a33d09379b023de000e89fc5f99a5950f0b3b2f571021aa402","compare-master.sh":"165490eab36ef4eceb2913a6c5cdeff479a05e1e0119a7f4551b03dbcda51ad4","examples/dump.rs":"de2bbdba75e21b9ff92b32697b3d9941f8695b8f7e3a8dee8fc5d7f4c3a0649c","examples/simple.rs":"c79ae542913e72cfcd03711543d173b2e8f62783e6c206459953bdb94dbb8c0c","format-all.sh":"6b02a40629ef3d2c0b9671222582a6217d526317a41262ae06c7a95de53bcbeb","src/binary_reader.rs":"982458f41f2e58dec1b5b02f2eb9ea61d7d9e8da4168cafc600b689a36ca734a","src/lib.rs":"cdf3b945d35d451eaea690292d43b7705f61670b82bf251b463ff86c3640b6cc","src/limits.rs":"34e5cda95fb67669011ba95ca60f48fc777f3e3fa279ff68a1f2a072032a4abd","src/operators_validator.rs":"8f27e83b81d1445b3cfb4eef91ca2e5de3a5d295325339ac4ba0909fb8096876","src/parser.rs":"24018005521106118bc16a2234da3fb70d3d9f413801eb9c8ef8c61e374e06cf","src/primitives.rs":"f5b25a13a4e32fb48e927bb950360dd6af0d87200c17ebd2073811cae9552ce3","src/readers/code_section.rs":"2034c399b76428ac993c22f551f3c541b132d8b4ccc74e34f0043e25534d107b","src/readers/data_count_section.rs":"27ef37517b6beac21245008b14b5416b851c52d0af8e2ae85c1456674e1c9a9e","src/readers/data_section.rs":"e7e2a539d2d3049d4a8f68df9ea2f21d97e7061657bbd91845e1df3e9c1f2ebc","src/readers/element_section.rs":"e685af8a189f0cfa9f250c3fd221f9f14d20886f609c4c86a75c7408a106b8e0","src/readers/export_section.rs":"7c74f7a11406a95c162f6ad4f77aafd0b1eee309f33b69f06bea12b23925e143","src/readers/function_section.rs":"57c0479ba8d7f61908ed74e86cbc26553fdd6d2d952f032ce29385a39f82efd3","src/readers/global_section.rs":"5fa18bed0fffadcc2dbdcbaedbe4e4398992fd1ce9e611b0319333a7681082ac","src/readers/import_section.rs":"1db4bf7290d04783d5cf526050d025b15a1daaf2bd97fca1a92ecb873d48f641","src/readers/init_expr.rs":"7020c80013dad4518a5f969c3ab4d624b46d778f03e632871cf343964f63441c","src/readers/linking_section.rs":"9df71f3ee5356f0d273c099212213353080001e261ca697caddf6b847fb5af09","src/readers/memory_section.rs":"83212f86cfc40d18fb392e9234c880afdf443f4af38a727ba346f9c740ef8718","src/readers/mod.rs":"ad0f49a8d2a6469d4a8a5695e60eb6f47be9c6e5994937b9ec9396f8c529fed6","src/readers/module.rs":"c2c4a0e22f7ae2102f1a96094c66faeefdbd87d42736a436f9b9f6387a525c75","src/readers/name_section.rs":"297f57393d5fef745ec265438108aa6eb7ed2762c03c3beb539493612442f3da","src/readers/operators.rs":"53bf7ea87529980a3a3e1afd92ddf488ae4dc04a40cda39dbf548e4d20c8a55c","src/readers/producers_section.rs":"674f402fc4545c94487f827153871b37adab44ed5eff4070a436eb18e514023a","src/readers/reloc_section.rs":"0ef818a8b83a4542c4c29c23642436a92d3e7c37bc0248e817ed5a9d65ec38ce","src/readers/section_reader.rs":"3d2260449fa0455d710ba6d97810372ec36cba70722c10dd236c3a18ca0eb56f","src/readers/sourcemappingurl_section.rs":"ababe84d51e4817ad19f827aa2b5239578e7f202e5ec06dd688b618885138434","src/readers/start_section.rs":"3eeae00e1aa0fcb2e0d93b7b0eaac30a60d3f1431c71c589cd3f73adb363d532","src/readers/table_section.rs":"e564876825a7b31df2b5dc850279b523e26dc50a08da935cc8d635a49e809951","src/readers/type_section.rs":"2fa33a7b793f3bfa01c259b5dbc38633b7343931886ab41f0cb96dd78db3bf6e","src/tests.rs":"ff77788d9630c8d0218b9aa52bde8f3e738d130a22f192ac7257b71b8300bda9","src/validator.rs":"cf9c1a9cbb4b4544579789c1b524a2c9845619120c8141c0d360db1ffa58e2f9","test-all.sh":"f36e3e9bf9c39456bab3ac170d3a09911becf2b7e0d0e2a58854ce1750da0d1f"},"package":"1add8db5a53a2f64f13418b241982c4ab533d7a9e1e8a5dcadccce633d8d393b"}

49
third_party/rust/wasmparser/CODE_OF_CONDUCT.md поставляемый Normal file
Просмотреть файл

@ -0,0 +1,49 @@
# Contributor Covenant Code of Conduct
*Note*: this Code of Conduct pertains to individuals' behavior. Please also see the [Organizational Code of Conduct][OCoC].
## Our Pledge
In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation.
## Our Standards
Examples of behavior that contributes to creating a positive environment include:
* Using welcoming and inclusive language
* Being respectful of differing viewpoints and experiences
* Gracefully accepting constructive criticism
* Focusing on what is best for the community
* Showing empathy towards other community members
Examples of unacceptable behavior by participants include:
* The use of sexualized language or imagery and unwelcome sexual attention or advances
* Trolling, insulting/derogatory comments, and personal or political attacks
* Public or private harassment
* Publishing others' private information, such as a physical or electronic address, without explicit permission
* Other conduct which could reasonably be considered inappropriate in a professional setting
## Our Responsibilities
Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior.
Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful.
## Scope
This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers.
## Enforcement
Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the Bytecode Alliance CoC team at [report@bytecodealliance.org](mailto:report@bytecodealliance.org). The CoC team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The CoC team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately.
Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the Bytecode Alliance's leadership.
## Attribution
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version]
[OCoC]: ORG_CODE_OF_CONDUCT.md
[homepage]: https://www.contributor-covenant.org
[version]: https://www.contributor-covenant.org/version/1/4/

242
third_party/rust/wasmparser/Cargo.lock сгенерированный поставляемый
Просмотреть файл

@ -1,30 +1,22 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
[[package]]
name = "arrayvec"
version = "0.4.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"nodrop 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "atty"
version = "0.2.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "autocfg"
version = "0.1.6"
version = "0.1.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "bitflags"
version = "1.1.0"
version = "1.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
@ -35,7 +27,7 @@ dependencies = [
"lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"regex-automata 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.100 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@ -48,14 +40,9 @@ name = "cast"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "cc"
version = "1.0.45"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "cfg-if"
version = "0.1.9"
version = "0.1.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
@ -63,7 +50,7 @@ name = "clap"
version = "2.33.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"bitflags 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"textwrap 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
"unicode-width 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
]
@ -73,15 +60,7 @@ name = "cloudabi"
version = "0.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"bitflags 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "cmake"
version = "0.1.42"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cc 1.0.45 (registry+https://github.com/rust-lang/crates.io-index)",
"bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@ -94,18 +73,18 @@ dependencies = [
"clap 2.33.0 (registry+https://github.com/rust-lang/crates.io-index)",
"criterion-plot 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
"csv 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"itertools 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
"itertools 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)",
"num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)",
"num-traits 0.2.9 (registry+https://github.com/rust-lang/crates.io-index)",
"rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
"rand_os 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
"rand_xoshiro 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"rayon 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"rayon-core 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.100 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_derive 1.0.100 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_derive 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 1.0.41 (registry+https://github.com/rust-lang/crates.io-index)",
"tinytemplate 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
"walkdir 2.2.9 (registry+https://github.com/rust-lang/crates.io-index)",
]
@ -117,28 +96,28 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
"cast 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"itertools 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
"itertools 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "crossbeam-deque"
version = "0.7.1"
version = "0.7.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"crossbeam-epoch 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
"crossbeam-utils 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)",
"crossbeam-epoch 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
"crossbeam-utils 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "crossbeam-epoch"
version = "0.7.2"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"arrayvec 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)",
"cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
"crossbeam-utils 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)",
"autocfg 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
"cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
"crossbeam-utils 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"memoffset 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
"memoffset 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)",
"scopeguard 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
@ -155,7 +134,17 @@ name = "crossbeam-utils"
version = "0.6.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
"cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "crossbeam-utils"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"autocfg 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
"cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
@ -167,8 +156,8 @@ dependencies = [
"bstr 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
"csv-core 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
"itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)",
"ryu 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.100 (registry+https://github.com/rust-lang/crates.io-index)",
"ryu 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@ -181,7 +170,7 @@ dependencies = [
[[package]]
name = "either"
version = "1.5.2"
version = "1.5.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
@ -190,21 +179,19 @@ version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "glob"
version = "0.2.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "hashbrown"
version = "0.5.0"
name = "hermit-abi"
version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "itertools"
version = "0.8.0"
version = "0.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"either 1.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
"either 1.5.3 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@ -217,9 +204,14 @@ name = "lazy_static"
version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "leb128"
version = "0.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "libc"
version = "0.2.62"
version = "0.2.65"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
@ -227,41 +219,37 @@ name = "memchr"
version = "2.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "memoffset"
version = "0.5.1"
version = "0.5.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "nodrop"
version = "0.1.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "num-traits"
version = "0.2.8"
version = "0.2.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"autocfg 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
"autocfg 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "num_cpus"
version = "1.10.1"
version = "1.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)",
"hermit-abi 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "proc-macro2"
version = "1.0.3"
version = "1.0.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
@ -272,7 +260,7 @@ name = "quote"
version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"proc-macro2 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
"proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@ -295,7 +283,7 @@ 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-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)",
"rand_core 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
"rdrand 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
@ -315,8 +303,8 @@ name = "rayon"
version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"crossbeam-deque 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
"either 1.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
"crossbeam-deque 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
"either 1.5.3 (registry+https://github.com/rust-lang/crates.io-index)",
"rayon-core 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
@ -325,11 +313,11 @@ name = "rayon-core"
version = "1.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"crossbeam-deque 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
"crossbeam-deque 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
"crossbeam-queue 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"crossbeam-utils 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"num_cpus 1.10.1 (registry+https://github.com/rust-lang/crates.io-index)",
"num_cpus 1.11.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@ -358,7 +346,7 @@ dependencies = [
[[package]]
name = "ryu"
version = "1.0.0"
version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
@ -389,35 +377,35 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "serde"
version = "1.0.100"
version = "1.0.102"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "serde_derive"
version = "1.0.100"
version = "1.0.102"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"proc-macro2 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
"proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
"quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
"syn 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
"syn 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "serde_json"
version = "1.0.40"
version = "1.0.41"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)",
"ryu 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.100 (registry+https://github.com/rust-lang/crates.io-index)",
"ryu 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "syn"
version = "1.0.5"
version = "1.0.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"proc-macro2 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
"proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
"quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
"unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
@ -435,8 +423,8 @@ name = "tinytemplate"
version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"serde 1.0.100 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 1.0.41 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@ -449,27 +437,6 @@ name = "unicode-xid"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "wabt"
version = "0.9.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"serde 1.0.100 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_derive 1.0.100 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)",
"wabt-sys 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "wabt-sys"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cc 1.0.45 (registry+https://github.com/rust-lang/crates.io-index)",
"cmake 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)",
"glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "walkdir"
version = "2.2.9"
@ -482,11 +449,18 @@ dependencies = [
[[package]]
name = "wasmparser"
version = "0.39.2"
version = "0.47.0"
dependencies = [
"criterion 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
"hashbrown 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
"wabt 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)",
"wast 5.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "wast"
version = "5.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"leb128 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@ -517,40 +491,37 @@ version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[metadata]
"checksum arrayvec 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)" = "b8d73f9beda665eaa98ab9e4f7442bd4e7de6652587de55b2525e52e29c1b0ba"
"checksum atty 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)" = "1803c647a3ec87095e7ae7acfca019e98de5ec9a7d01343f611cf3152ed71a90"
"checksum autocfg 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "b671c8fb71b457dd4ae18c4ba1e59aa81793daacc361d82fcd410cef0d491875"
"checksum bitflags 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3d155346769a6855b86399e9bc3814ab343cd3d62c7e985113d46a0ec3c281fd"
"checksum autocfg 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "1d49d90015b3c36167a20fe2810c5cd875ad504b39cff3d4eae7977e6b7c1cb2"
"checksum bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693"
"checksum bstr 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "8d6c2c5b58ab920a4f5aeaaca34b4488074e8cc7596af94e6f8c6ff247c60245"
"checksum byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a7c3dd8985a7111efc5c80b44e23ecdd8c007de8ade3b96595387e812b957cf5"
"checksum cast 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "926013f2860c46252efceabb19f4a6b308197505082c609025aa6706c011d427"
"checksum cc 1.0.45 (registry+https://github.com/rust-lang/crates.io-index)" = "4fc9a35e1f4290eb9e5fc54ba6cf40671ed2a2514c3eeb2b2a908dda2ea5a1be"
"checksum cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "b486ce3ccf7ffd79fdeb678eac06a9e6c09fc88d33836340becb8fffe87c5e33"
"checksum cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822"
"checksum clap 2.33.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5067f5bb2d80ef5d68b4c87db81601f0b75bca627bc2ef76b141d7b846a3c6d9"
"checksum cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f"
"checksum cmake 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)" = "81fb25b677f8bf1eb325017cb6bb8452f87969db0fedb4f757b297bee78a7c62"
"checksum criterion 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "0363053954f3e679645fc443321ca128b7b950a6fe288cf5f9335cc22ee58394"
"checksum criterion-plot 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "76f9212ddf2f4a9eb2d401635190600656a1f88a932ef53d06e7fa4c7e02fb8e"
"checksum crossbeam-deque 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b18cd2e169ad86297e6bc0ad9aa679aee9daa4f19e8163860faf7c164e4f5a71"
"checksum crossbeam-epoch 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "fedcd6772e37f3da2a9af9bf12ebe046c0dfe657992377b4df982a2b54cd37a9"
"checksum crossbeam-deque 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c3aa945d63861bfe624b55d153a39684da1e8c0bc8fba932f7ee3a3c16cea3ca"
"checksum crossbeam-epoch 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5064ebdbf05ce3cb95e45c8b086f72263f4166b29b97f6baff7ef7fe047b55ac"
"checksum crossbeam-queue 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7c979cd6cfe72335896575c6b5688da489e420d36a27a0b9eb0c73db574b4a4b"
"checksum crossbeam-utils 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)" = "04973fa96e96579258a5091af6003abde64af786b860f18622b82e026cca60e6"
"checksum crossbeam-utils 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ce446db02cdc3165b94ae73111e570793400d0794e46125cc4056c81cbb039f4"
"checksum csv 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "37519ccdfd73a75821cac9319d4fce15a81b9fcf75f951df5b9988aa3a0af87d"
"checksum csv-core 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "9b5cadb6b25c77aeff80ba701712494213f4a8418fcda2ee11b6560c3ad0bf4c"
"checksum either 1.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "5527cfe0d098f36e3f8839852688e63c8fff1c90b2b405aef730615f9a7bcf7b"
"checksum either 1.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "bb1f6b1ce1c140482ea30ddd3335fc0024ac7ee112895426e0a629a6c20adfe3"
"checksum fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba"
"checksum glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "8be18de09a56b60ed0edf84bc9df007e30040691af7acd1c41874faac5895bfb"
"checksum hashbrown 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e1de41fb8dba9714efd92241565cdff73f78508c95697dd56787d3cba27e2353"
"checksum itertools 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5b8467d9c1cebe26feb08c640139247fac215782d35371ade9a2136ed6085358"
"checksum hermit-abi 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "307c3c9f937f38e3534b1d6447ecf090cafcc9744e4a6360e8b037b2cf5af120"
"checksum itertools 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "87fa75c9dea7b07be3138c49abbb83fd4bea199b5cdc76f9804458edc5da0d6e"
"checksum itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "501266b7edd0174f8530248f87f99c88fbe60ca4ef3dd486835b8d8d53136f7f"
"checksum lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
"checksum libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)" = "34fcd2c08d2f832f376f4173a231990fa5aef4e99fb569867318a227ef4c06ba"
"checksum leb128 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "3576a87f2ba00f6f106fdfcd16db1d698d648a26ad8e0573cad8537c3c362d2a"
"checksum libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)" = "1a31a0627fdf1f6a39ec0dd577e101440b7db22672c0901fe00a9a6fbb5c24e8"
"checksum memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "88579771288728879b57485cc7d6b07d648c9f0141eb955f8ab7f9d45394468e"
"checksum memoffset 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ce6075db033bbbb7ee5a0bbd3a3186bbae616f57fb001c485c7ff77955f8177f"
"checksum nodrop 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)" = "2f9667ddcc6cc8a43afc9b7917599d7216aa09c463919ea32c59ed6cac8bc945"
"checksum num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "6ba9a427cfca2be13aa6f6403b0b7e7368fe982bfa16fccc450ce74c46cd9b32"
"checksum num_cpus 1.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "bcef43580c035376c0705c42792c294b66974abbfd2789b511784023f71f3273"
"checksum proc-macro2 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "e98a83a9f9b331f54b924e68a66acb1bb35cb01fb0a23645139967abefb697e8"
"checksum memoffset 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "75189eb85871ea5c2e2c15abbdd541185f63b408415e5051f5cac122d8c774b9"
"checksum num-traits 0.2.9 (registry+https://github.com/rust-lang/crates.io-index)" = "443c53b3c3531dfcbfa499d8893944db78474ad7a1d87fa2d94d1a2231693ac6"
"checksum num_cpus 1.11.1 (registry+https://github.com/rust-lang/crates.io-index)" = "76dac5ed2a876980778b8b85f75a71b6cbf0db0b1232ee12f826bccb00d09d72"
"checksum proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "9c9e470a8dc4aeae2dee2f335e8f533e2d4b347e1434e5671afc49b054592f27"
"checksum quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "053a8c8bcc71fcce321828dc897a98ab9760bef03a4fc36693c231e5b3216cfe"
"checksum rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b"
"checksum rand_core 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9c33a3c44ca05fa6f1807d8e6743f3824e8509beca625669633be0acbdf509dc"
@ -561,22 +532,21 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
"checksum rdrand 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2"
"checksum regex-automata 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "92b73c2a1770c255c240eaa4ee600df1704a38dc3feaa6e949e7fcd4f8dc09f9"
"checksum rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a"
"checksum ryu 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c92464b447c0ee8c4fb3824ecc8383b81717b9f1e74ba2e72540aef7b9f82997"
"checksum ryu 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "bfa8506c1de11c9c4e4c38863ccbe02a305c8188e85a05a784c9e11e1c3910c8"
"checksum same-file 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "585e8ddcedc187886a30fa705c47985c3fa88d06624095856b36ca0b82ff4421"
"checksum scopeguard 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b42e15e59b18a828bbf5c58ea01debb36b9b096346de35d941dcb89009f24a0d"
"checksum semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403"
"checksum semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3"
"checksum serde 1.0.100 (registry+https://github.com/rust-lang/crates.io-index)" = "f4473e8506b213730ff2061073b48fa51dcc66349219e2e7c5608f0296a1d95a"
"checksum serde_derive 1.0.100 (registry+https://github.com/rust-lang/crates.io-index)" = "11e410fde43e157d789fc290d26bc940778ad0fdd47836426fbac36573710dbb"
"checksum serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)" = "051c49229f282f7c6f3813f8286cc1e3323e8051823fce42c7ea80fe13521704"
"checksum syn 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "66850e97125af79138385e9b88339cbcd037e3f28ceab8c5ad98e64f0f1f80bf"
"checksum serde 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)" = "0c4b39bd9b0b087684013a792c59e3e07a46a01d2322518d8a1104641a0b1be0"
"checksum serde_derive 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)" = "ca13fc1a832f793322228923fbb3aba9f3f44444898f835d31ad1b74fa0a2bf8"
"checksum serde_json 1.0.41 (registry+https://github.com/rust-lang/crates.io-index)" = "2f72eb2a68a7dc3f9a691bfda9305a1c017a6215e5a4545c258500d2099a37c2"
"checksum syn 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)" = "661641ea2aa15845cddeb97dad000d22070bb5c1fb456b96c1cba883ec691e92"
"checksum textwrap 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060"
"checksum tinytemplate 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "4574b75faccaacddb9b284faecdf0b544b80b6b294f3d062d325c5726a209c20"
"checksum unicode-width 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "7007dbd421b92cc6e28410fe7362e2e0a2503394908f417b68ec8d1c364c4e20"
"checksum unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "826e7639553986605ec5979c7dd957c7895e93eabed50ab2ffa7f6128a75097c"
"checksum wabt 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)" = "3c5c5c1286c6e578416982609f47594265f9d489f9b836157d403ad605a46693"
"checksum wabt-sys 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "af5d153dc96aad7dc13ab90835b892c69867948112d95299e522d370c4e13a08"
"checksum walkdir 2.2.9 (registry+https://github.com/rust-lang/crates.io-index)" = "9658c94fa8b940eab2250bd5a457f9c48b748420d71293b165c8cdbe2f55f71e"
"checksum wast 5.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8d1de68310854a9840d39487701a8c1acccb5c9f9f2650d5fce3cdfe6650c372"
"checksum winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "8093091eeb260906a183e6ae1abdba2ef5ef2257a21801128899c3fc699229c6"
"checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
"checksum winapi-util 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7168bab6e1daee33b4557efd0e95d5ca70a03706d39fa5f3fe7a236f584b03c9"

12
third_party/rust/wasmparser/Cargo.toml поставляемый
Просмотреть файл

@ -13,7 +13,7 @@
[package]
edition = "2018"
name = "wasmparser"
version = "0.39.2"
version = "0.47.0"
authors = ["Yury Delendik <ydelendik@mozilla.com>"]
exclude = ["fuzz/**/*", "tests/**/*", "testsuite/**/*"]
description = "A simple event-driven library for parsing WebAssembly binary files.\n"
@ -24,19 +24,13 @@ repository = "https://github.com/yurydelendik/wasmparser.rs"
[[bench]]
name = "benchmark"
harness = false
[dependencies.hashbrown]
version = "0.5.0"
optional = true
[dev-dependencies.criterion]
version = "0.2"
[dev-dependencies.wabt]
version = "0.9.2"
[dev-dependencies.wast]
version = "5.0.0"
[features]
core = ["hashbrown"]
default = ["std"]
deterministic = []
std = []
[badges.travis-ci]
repository = "yurydelendik/wasmparser.rs"

139
third_party/rust/wasmparser/ORG_CODE_OF_CONDUCT.md поставляемый Normal file
Просмотреть файл

@ -0,0 +1,139 @@
# Bytecode Alliance Organizational Code of Conduct (OCoC)
*Note*: this Code of Conduct pertains to organizations' behavior. Please also see the [Individual Code of Conduct](CODE_OF_CONDUCT.md).
## Preamble
The Bytecode Alliance (BA) welcomes involvement from organizations,
including commercial organizations. This document is an
*organizational* code of conduct, intended particularly to provide
guidance to commercial organizations. It is distinct from the
[Individual Code of Conduct (ICoC)](CODE_OF_CONDUCT.md), and does not
replace the ICoC. This OCoC applies to any group of people acting in
concert as a BA member or as a participant in BA activities, whether
or not that group is formally incorporated in some jurisdiction.
The code of conduct described below is not a set of rigid rules, and
we did not write it to encompass every conceivable scenario that might
arise. For example, it is theoretically possible there would be times
when asserting patents is in the best interest of the BA community as
a whole. In such instances, consult with the BA, strive for
consensus, and interpret these rules with an intent that is generous
to the community the BA serves.
While we may revise these guidelines from time to time based on
real-world experience, overall they are based on a simple principle:
*Bytecode Alliance members should observe the distinction between
public community functions and private functions — especially
commercial ones — and should ensure that the latter support, or at
least do not harm, the former.*
## Guidelines
* **Do not cause confusion about Wasm standards or interoperability.**
Having an interoperable WebAssembly core is a high priority for
the BA, and members should strive to preserve that core. It is fine
to develop additional non-standard features or APIs, but they
should always be clearly distinguished from the core interoperable
Wasm.
Treat the WebAssembly name and any BA-associated names with
respect, and follow BA trademark and branding guidelines. If you
distribute a customized version of software originally produced by
the BA, or if you build a product or service using BA-derived
software, use names that clearly distinguish your work from the
original. (You should still provide proper attribution to the
original, of course, wherever such attribution would normally be
given.)
Further, do not use the WebAssembly name or BA-associated names in
other public namespaces in ways that could cause confusion, e.g.,
in company names, names of commercial service offerings, domain
names, publicly-visible social media accounts or online service
accounts, etc. It may sometimes be reasonable, however, to
register such a name in a new namespace and then immediately donate
control of that account to the BA, because that would help the project
maintain its identity.
* **Do not restrict contributors.** If your company requires
employees or contractors to sign non-compete agreements, those
agreements must not prevent people from participating in the BA or
contributing to related projects.
This does not mean that all non-compete agreements are incompatible
with this code of conduct. For example, a company may restrict an
employee's ability to solicit the company's customers. However, an
agreement must not block any form of technical or social
participation in BA activities, including but not limited to the
implementation of particular features.
The accumulation of experience and expertise in individual persons,
who are ultimately free to direct their energy and attention as
they decide, is one of the most important drivers of progress in
open source projects. A company that limits this freedom may hinder
the success of the BA's efforts.
* **Do not use patents as offensive weapons.** If any BA participant
prevents the adoption or development of BA technologies by
asserting its patents, that undermines the purpose of the
coalition. The collaboration fostered by the BA cannot include
members who act to undermine its work.
* **Practice responsible disclosure** for security vulnerabilities.
Use designated, non-public reporting channels to disclose technical
vulnerabilities, and give the project a reasonable period to
respond, remediate, and patch.
Vulnerability reporters may patch their company's own offerings, as
long as that patching does not significantly delay the reporting of
the vulnerability. Vulnerability information should never be used
for unilateral commercial advantage. Vendors may legitimately
compete on the speed and reliability with which they deploy
security fixes, but withholding vulnerability information damages
everyone in the long run by risking harm to the BA project's
reputation and to the security of all users.
* **Respect the letter and spirit of open source practice.** While
there is not space to list here all possible aspects of standard
open source practice, some examples will help show what we mean:
* Abide by all applicable open source license terms. Do not engage
in copyright violation or misattribution of any kind.
* Do not claim others' ideas or designs as your own.
* When others engage in publicly visible work (e.g., an upcoming
demo that is coordinated in a public issue tracker), do not
unilaterally announce early releases or early demonstrations of
that work ahead of their schedule in order to secure private
advantage (such as marketplace advantage) for yourself.
The BA reserves the right to determine what constitutes good open
source practices and to take action as it deems appropriate to
encourage, and if necessary enforce, such practices.
## Enforcement
Instances of organizational behavior in violation of the OCoC may
be reported by contacting the Bytecode Alliance CoC team at
[report@bytecodealliance.org](mailto:report@bytecodealliance.org). The
CoC team will review and investigate all complaints, and will respond
in a way that it deems appropriate to the circumstances. The CoC team
is obligated to maintain confidentiality with regard to the reporter of
an incident. Further details of specific enforcement policies may be
posted separately.
When the BA deems an organization in violation of this OCoC, the BA
will, at its sole discretion, determine what action to take. The BA
will decide what type, degree, and duration of corrective action is
needed, if any, before a violating organization can be considered for
membership (if it was not already a member) or can have its membership
reinstated (if it was a member and the BA canceled its membership due
to the violation).
In practice, the BA's first approach will be to start a conversation,
with punitive enforcement used only as a last resort. Violations
often turn out to be unintentional and swiftly correctable with all
parties acting in good faith.

2
third_party/rust/wasmparser/README.md поставляемый
Просмотреть файл

@ -1,5 +1,7 @@
# The WebAssembly binary file decoder in Rust
**A [Bytecode Alliance](https://bytecodealliance.org/) project**
[![Build Status](https://travis-ci.org/yurydelendik/wasmparser.rs.svg?branch=master)](https://travis-ci.org/yurydelendik/wasmparser.rs)
[![crates.io link](https://img.shields.io/crates/v/wasmparser.svg)](https://crates.io/crates/wasmparser)

29
third_party/rust/wasmparser/SECURITY.md поставляемый Normal file
Просмотреть файл

@ -0,0 +1,29 @@
# Security Policy
Building secure foundations for software development is at the core of what we do in the Bytecode Alliance. Contributions of external security researchers are a vital part of that.
## Scope
If you believe you've found a security issue in any website, service, or software owned or operated by the Bytecode Alliance, we encourage you to notify us.
## How to Submit a Report
To submit a vulnerability report to the Bytecode Alliance, please contact us at [security@bytecodealliance.org](mailto:security@bytecodealliance.org). Your submission will be reviewed and validated by a member of our security team.
## Safe Harbor
The Bytecode Alliance supports safe harbor for security researchers who:
* Make a good faith effort to avoid privacy violations, destruction of data, and interruption or degradation of our services.
* Only interact with accounts you own or with explicit permission of the account holder. If you do encounter Personally Identifiable Information (PII) contact us immediately, do not proceed with access, and immediately purge any local information.
* Provide us with a reasonable amount of time to resolve vulnerabilities prior to any disclosure to the public or a third-party.
We will consider activities conducted consistent with this policy to constitute "authorized" conduct and will not pursue civil action or initiate a complaint to law enforcement. We will help to the extent we can if legal action is initiated by a third party against you.
Please submit a report to us before engaging in conduct that may be inconsistent with or unaddressed by this policy.
## Preferences
* Please provide detailed reports with reproducible steps and a clearly defined impact.
* Submit one vulnerability per report.
* Social engineering (e.g. phishing, vishing, smishing) is prohibited.

Просмотреть файл

@ -14,6 +14,7 @@
*/
use std::boxed::Box;
use std::convert::TryInto;
use std::str;
use std::vec::Vec;
@ -38,36 +39,43 @@ fn is_name_prefix(name: &str, prefix: &'static str) -> bool {
name.starts_with(prefix)
}
const WASM_MAGIC_NUMBER: u32 = 0x6d736100;
const WASM_MAGIC_NUMBER: &'static [u8; 4] = b"\0asm";
const WASM_EXPERIMENTAL_VERSION: u32 = 0xd;
const WASM_SUPPORTED_VERSION: u32 = 0x1;
pub struct SectionHeader<'a> {
pub(crate) struct SectionHeader<'a> {
pub code: SectionCode<'a>,
pub payload_start: usize,
pub payload_len: usize,
}
/// Bytecode range in the WebAssembly module.
#[derive(Debug, Copy, Clone)]
#[derive(Copy, Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
pub struct Range {
/// The start bound of the range.
pub start: usize,
/// The end bound of the range.
pub end: usize,
}
impl Range {
/// Constructs a new instance of `Range`.
///
/// # Panics
/// If `start` is greater than `end`.
pub fn new(start: usize, end: usize) -> Range {
assert!(start <= end);
Range { start, end }
}
/// Returns a new slice between `start` and `end - 1` from `data`.
pub fn slice<'a>(&self, data: &'a [u8]) -> &'a [u8] {
&data[self.start..self.end]
}
}
/// A binary reader of the WebAssembly structures and types.
#[derive(Clone)]
#[derive(Clone, Debug)]
pub struct BinaryReader<'a> {
pub(crate) buffer: &'a [u8],
pub(crate) position: usize,
@ -94,6 +102,7 @@ impl<'a> BinaryReader<'a> {
}
}
/// Constructs a `BinaryReader` with an explicit starting offset.
pub fn new_with_offset(data: &[u8], original_offset: usize) -> BinaryReader {
BinaryReader {
buffer: data,
@ -106,6 +115,7 @@ impl<'a> BinaryReader<'a> {
self.original_offset + self.position
}
/// Returns a range from the starting offset to the end of the buffer.
pub fn range(&self) -> Range {
Range {
start: self.original_offset,
@ -178,6 +188,7 @@ impl<'a> BinaryReader<'a> {
-0x05 => Ok(Type::V128),
-0x10 => Ok(Type::AnyFunc),
-0x11 => Ok(Type::AnyRef),
-0x12 => Ok(Type::NullRef),
-0x20 => Ok(Type::Func),
-0x40 => Ok(Type::EmptyBlockType),
_ => Err(BinaryReaderError {
@ -374,18 +385,26 @@ impl<'a> BinaryReader<'a> {
})
}
/// Returns whether the `BinaryReader` has reached the end of the file.
pub fn eof(&self) -> bool {
self.position >= self.buffer.len()
}
/// Returns the `BinaryReader`'s current position.
pub fn current_position(&self) -> usize {
self.position
}
/// Returns the number of bytes remaining in the `BinaryReader`.
pub fn bytes_remaining(&self) -> usize {
self.buffer.len() - self.position
}
/// Advances the `BinaryReader` `size` bytes, and returns a slice from the
/// current position of `size` length.
///
/// # Errors
/// If `size` exceeds the remaining length in `BinaryReader`.
pub fn read_bytes(&mut self, size: usize) -> Result<&'a [u8]> {
self.ensure_has_bytes(size)?;
let start = self.position;
@ -393,22 +412,38 @@ impl<'a> BinaryReader<'a> {
Ok(&self.buffer[start..self.position])
}
/// Advances the `BinaryReader` four bytes and returns a `u32`.
/// # Errors
/// If `BinaryReader` has less than four bytes remaining.
pub fn read_u32(&mut self) -> Result<u32> {
self.ensure_has_bytes(4)?;
let b1 = u32::from(self.buffer[self.position]);
let b2 = u32::from(self.buffer[self.position + 1]);
let b3 = u32::from(self.buffer[self.position + 2]);
let b4 = u32::from(self.buffer[self.position + 3]);
let word = u32::from_le_bytes(
self.buffer[self.position..self.position + 4]
.try_into()
.unwrap(),
);
self.position += 4;
Ok(b1 | (b2 << 8) | (b3 << 16) | (b4 << 24))
Ok(word)
}
/// Advances the `BinaryReader` eight bytes and returns a `u64`.
/// # Errors
/// If `BinaryReader` has less than eight bytes remaining.
pub fn read_u64(&mut self) -> Result<u64> {
let w1 = u64::from(self.read_u32()?);
let w2 = u64::from(self.read_u32()?);
Ok(w1 | (w2 << 32))
self.ensure_has_bytes(8)?;
let word = u64::from_le_bytes(
self.buffer[self.position..self.position + 8]
.try_into()
.unwrap(),
);
self.position += 8;
Ok(word)
}
/// Advances the `BinaryReader` a single byte, and returns the data as
/// a `u32`.
/// # Errors
/// If `BinaryReader` has no bytes remaining.
pub fn read_u8(&mut self) -> Result<u32> {
self.ensure_has_byte()?;
let b = u32::from(self.buffer[self.position]);
@ -416,6 +451,11 @@ impl<'a> BinaryReader<'a> {
Ok(b)
}
/// Advances the `BinaryReader` up to two bytes to parse a variable
/// length integer as a `u8`.
/// # Errors
/// If `BinaryReader` has less than one or two bytes remaining, or the
/// integer is larger than eight bits.
pub fn read_var_u8(&mut self) -> Result<u32> {
// Optimization for single byte i32.
let byte = self.read_u8()?;
@ -433,6 +473,11 @@ impl<'a> BinaryReader<'a> {
Ok(result)
}
/// Advances the `BinaryReader` up to four bytes to parse a variable
/// length integer as a `u32`.
/// # Errors
/// If `BinaryReader` has less than one or up to four bytes remaining, or
/// the integer is larger than 32 bits.
pub fn read_var_u32(&mut self) -> Result<u32> {
// Optimization for single byte i32.
let byte = self.read_u8()?;
@ -460,6 +505,11 @@ impl<'a> BinaryReader<'a> {
Ok(result)
}
/// Advances the `BinaryReader` up to four bytes over a variable length 32
/// bit integer, discarding the result.
/// # Errors
/// If `BinaryReader` has less than one or up to four bytes remaining, or
/// the integer is larger than 32 bits.
pub fn skip_var_32(&mut self) -> Result<()> {
for _ in 0..5 {
let byte = self.read_u8()?;
@ -473,16 +523,26 @@ impl<'a> BinaryReader<'a> {
})
}
/// Alias method for `BinaryReader::skip_var_u32`.
pub fn skip_type(&mut self) -> Result<()> {
self.skip_var_32()
}
/// Advances the `BinaryReader` `len` bytes, skipping the result.
/// # Errors
/// If `BinaryReader` has less than `len` bytes remaining.
pub fn skip_bytes(&mut self, len: usize) -> Result<()> {
self.ensure_has_bytes(len)?;
self.position += len;
Ok(())
}
/// Advances the `BinaryReader` past a WebAssembly string. This method does
/// not perform any utf-8 validation.
/// # Errors
/// If `BinaryReader` has less than four bytes, the string's length exceeds
/// the remaining bytes, or the string length
/// exceeds `limits::MAX_WASM_STRING_SIZE`.
pub fn skip_string(&mut self) -> Result<()> {
let len = self.read_var_u32()? as usize;
if len > MAX_WASM_STRING_SIZE {
@ -502,6 +562,11 @@ impl<'a> BinaryReader<'a> {
self.position = position;
}
/// Advances the `BinaryReader` up to four bytes to parse a variable
/// length integer as a `i32`.
/// # Errors
/// If `BinaryReader` has less than one or up to four bytes remaining, or
/// the integer is larger than 32 bits.
pub fn read_var_i32(&mut self) -> Result<i32> {
// Optimization for single byte i32.
let byte = self.read_u8()?;
@ -534,6 +599,11 @@ impl<'a> BinaryReader<'a> {
Ok((result << ashift) >> ashift)
}
/// Advances the `BinaryReader` up to four bytes to parse a variable
/// length integer as a signed 33 bit integer, returned as a `i64`.
/// # Errors
/// If `BinaryReader` has less than one or up to five bytes remaining, or
/// the integer is larger than 33 bits.
pub fn read_var_s33(&mut self) -> Result<i64> {
// Optimization for single byte.
let byte = self.read_u8()?;
@ -551,7 +621,7 @@ impl<'a> BinaryReader<'a> {
let sign_and_unused_bit = (byte << 1) as i8 >> (33 - shift);
if continuation_bit || (sign_and_unused_bit != 0 && sign_and_unused_bit != -1) {
return Err(BinaryReaderError {
message: "Invalid var_i33",
message: "Invalid var_s33",
offset: self.original_position() - 1,
});
}
@ -566,6 +636,11 @@ impl<'a> BinaryReader<'a> {
Ok((result << ashift) >> ashift)
}
/// Advances the `BinaryReader` up to eight bytes to parse a variable
/// length integer as a 64 bit integer, returned as a `i64`.
/// # Errors
/// If `BinaryReader` has less than one or up to eight bytes remaining, or
/// the integer is larger than 64 bits.
pub fn read_var_i64(&mut self) -> Result<i64> {
let mut result: i64 = 0;
let mut shift = 0;
@ -592,16 +667,31 @@ impl<'a> BinaryReader<'a> {
Ok((result << ashift) >> ashift)
}
/// Advances the `BinaryReader` up to four bytes to parse a variable
/// length integer as a 32 bit floating point integer, returned as `Ieee32`.
/// # Errors
/// If `BinaryReader` has less than one or up to four bytes remaining, or
/// the integer is larger than 32 bits.
pub fn read_f32(&mut self) -> Result<Ieee32> {
let value = self.read_u32()?;
Ok(Ieee32(value))
}
/// Advances the `BinaryReader` up to four bytes to parse a variable
/// length integer as a 32 bit floating point integer, returned as `Ieee32`.
/// # Errors
/// If `BinaryReader` has less than one or up to four bytes remaining, or
/// the integer is larger than 32 bits.
pub fn read_f64(&mut self) -> Result<Ieee64> {
let value = self.read_u64()?;
Ok(Ieee64(value))
}
/// Reads a WebAssembly string from the module.
/// # Errors
/// If `BinaryReader` has less than up to four bytes remaining, the string's
/// length exceeds the remaining bytes, the string's length exceeds
/// `limits::MAX_WASM_STRING_SIZE`, or the string contains invalid utf-8.
pub fn read_string(&mut self) -> Result<&'a str> {
let len = self.read_var_u32()? as usize;
if len > MAX_WASM_STRING_SIZE {
@ -617,9 +707,9 @@ impl<'a> BinaryReader<'a> {
})
}
fn read_memarg_of_align(&mut self, align: u32) -> Result<MemoryImmediate> {
fn read_memarg_of_align(&mut self, max_align: u32) -> Result<MemoryImmediate> {
let imm = self.read_memarg()?;
if align != imm.flags {
if imm.flags > max_align {
return Err(BinaryReaderError {
message: "Unexpected memarg alignment",
offset: self.original_position() - 1,
@ -631,16 +721,16 @@ impl<'a> BinaryReader<'a> {
fn read_0xfe_operator(&mut self) -> Result<Operator<'a>> {
let code = self.read_u8()? as u8;
Ok(match code {
0x00 => Operator::Wake {
0x00 => Operator::AtomicNotify {
memarg: self.read_memarg_of_align(2)?,
},
0x01 => Operator::I32Wait {
0x01 => Operator::I32AtomicWait {
memarg: self.read_memarg_of_align(2)?,
},
0x02 => Operator::I64Wait {
0x02 => Operator::I64AtomicWait {
memarg: self.read_memarg_of_align(3)?,
},
0x03 => Operator::Fence {
0x03 => Operator::AtomicFence {
flags: self.read_u8()? as u8,
},
0x10 => Operator::I32AtomicLoad {
@ -691,19 +781,19 @@ impl<'a> BinaryReader<'a> {
0x1f => Operator::I64AtomicRmwAdd {
memarg: self.read_memarg_of_align(3)?,
},
0x20 => Operator::I32AtomicRmw8UAdd {
0x20 => Operator::I32AtomicRmw8AddU {
memarg: self.read_memarg_of_align(0)?,
},
0x21 => Operator::I32AtomicRmw16UAdd {
0x21 => Operator::I32AtomicRmw16AddU {
memarg: self.read_memarg_of_align(1)?,
},
0x22 => Operator::I64AtomicRmw8UAdd {
0x22 => Operator::I64AtomicRmw8AddU {
memarg: self.read_memarg_of_align(0)?,
},
0x23 => Operator::I64AtomicRmw16UAdd {
0x23 => Operator::I64AtomicRmw16AddU {
memarg: self.read_memarg_of_align(1)?,
},
0x24 => Operator::I64AtomicRmw32UAdd {
0x24 => Operator::I64AtomicRmw32AddU {
memarg: self.read_memarg_of_align(2)?,
},
0x25 => Operator::I32AtomicRmwSub {
@ -712,19 +802,19 @@ impl<'a> BinaryReader<'a> {
0x26 => Operator::I64AtomicRmwSub {
memarg: self.read_memarg_of_align(3)?,
},
0x27 => Operator::I32AtomicRmw8USub {
0x27 => Operator::I32AtomicRmw8SubU {
memarg: self.read_memarg_of_align(0)?,
},
0x28 => Operator::I32AtomicRmw16USub {
0x28 => Operator::I32AtomicRmw16SubU {
memarg: self.read_memarg_of_align(1)?,
},
0x29 => Operator::I64AtomicRmw8USub {
0x29 => Operator::I64AtomicRmw8SubU {
memarg: self.read_memarg_of_align(0)?,
},
0x2a => Operator::I64AtomicRmw16USub {
0x2a => Operator::I64AtomicRmw16SubU {
memarg: self.read_memarg_of_align(1)?,
},
0x2b => Operator::I64AtomicRmw32USub {
0x2b => Operator::I64AtomicRmw32SubU {
memarg: self.read_memarg_of_align(2)?,
},
0x2c => Operator::I32AtomicRmwAnd {
@ -733,19 +823,19 @@ impl<'a> BinaryReader<'a> {
0x2d => Operator::I64AtomicRmwAnd {
memarg: self.read_memarg_of_align(3)?,
},
0x2e => Operator::I32AtomicRmw8UAnd {
0x2e => Operator::I32AtomicRmw8AndU {
memarg: self.read_memarg_of_align(0)?,
},
0x2f => Operator::I32AtomicRmw16UAnd {
0x2f => Operator::I32AtomicRmw16AndU {
memarg: self.read_memarg_of_align(1)?,
},
0x30 => Operator::I64AtomicRmw8UAnd {
0x30 => Operator::I64AtomicRmw8AndU {
memarg: self.read_memarg_of_align(0)?,
},
0x31 => Operator::I64AtomicRmw16UAnd {
0x31 => Operator::I64AtomicRmw16AndU {
memarg: self.read_memarg_of_align(1)?,
},
0x32 => Operator::I64AtomicRmw32UAnd {
0x32 => Operator::I64AtomicRmw32AndU {
memarg: self.read_memarg_of_align(2)?,
},
0x33 => Operator::I32AtomicRmwOr {
@ -754,19 +844,19 @@ impl<'a> BinaryReader<'a> {
0x34 => Operator::I64AtomicRmwOr {
memarg: self.read_memarg_of_align(3)?,
},
0x35 => Operator::I32AtomicRmw8UOr {
0x35 => Operator::I32AtomicRmw8OrU {
memarg: self.read_memarg_of_align(0)?,
},
0x36 => Operator::I32AtomicRmw16UOr {
0x36 => Operator::I32AtomicRmw16OrU {
memarg: self.read_memarg_of_align(1)?,
},
0x37 => Operator::I64AtomicRmw8UOr {
0x37 => Operator::I64AtomicRmw8OrU {
memarg: self.read_memarg_of_align(0)?,
},
0x38 => Operator::I64AtomicRmw16UOr {
0x38 => Operator::I64AtomicRmw16OrU {
memarg: self.read_memarg_of_align(1)?,
},
0x39 => Operator::I64AtomicRmw32UOr {
0x39 => Operator::I64AtomicRmw32OrU {
memarg: self.read_memarg_of_align(2)?,
},
0x3a => Operator::I32AtomicRmwXor {
@ -775,19 +865,19 @@ impl<'a> BinaryReader<'a> {
0x3b => Operator::I64AtomicRmwXor {
memarg: self.read_memarg_of_align(3)?,
},
0x3c => Operator::I32AtomicRmw8UXor {
0x3c => Operator::I32AtomicRmw8XorU {
memarg: self.read_memarg_of_align(0)?,
},
0x3d => Operator::I32AtomicRmw16UXor {
0x3d => Operator::I32AtomicRmw16XorU {
memarg: self.read_memarg_of_align(1)?,
},
0x3e => Operator::I64AtomicRmw8UXor {
0x3e => Operator::I64AtomicRmw8XorU {
memarg: self.read_memarg_of_align(0)?,
},
0x3f => Operator::I64AtomicRmw16UXor {
0x3f => Operator::I64AtomicRmw16XorU {
memarg: self.read_memarg_of_align(1)?,
},
0x40 => Operator::I64AtomicRmw32UXor {
0x40 => Operator::I64AtomicRmw32XorU {
memarg: self.read_memarg_of_align(2)?,
},
0x41 => Operator::I32AtomicRmwXchg {
@ -796,19 +886,19 @@ impl<'a> BinaryReader<'a> {
0x42 => Operator::I64AtomicRmwXchg {
memarg: self.read_memarg_of_align(3)?,
},
0x43 => Operator::I32AtomicRmw8UXchg {
0x43 => Operator::I32AtomicRmw8XchgU {
memarg: self.read_memarg_of_align(0)?,
},
0x44 => Operator::I32AtomicRmw16UXchg {
0x44 => Operator::I32AtomicRmw16XchgU {
memarg: self.read_memarg_of_align(1)?,
},
0x45 => Operator::I64AtomicRmw8UXchg {
0x45 => Operator::I64AtomicRmw8XchgU {
memarg: self.read_memarg_of_align(0)?,
},
0x46 => Operator::I64AtomicRmw16UXchg {
0x46 => Operator::I64AtomicRmw16XchgU {
memarg: self.read_memarg_of_align(1)?,
},
0x47 => Operator::I64AtomicRmw32UXchg {
0x47 => Operator::I64AtomicRmw32XchgU {
memarg: self.read_memarg_of_align(2)?,
},
0x48 => Operator::I32AtomicRmwCmpxchg {
@ -817,19 +907,19 @@ impl<'a> BinaryReader<'a> {
0x49 => Operator::I64AtomicRmwCmpxchg {
memarg: self.read_memarg_of_align(3)?,
},
0x4a => Operator::I32AtomicRmw8UCmpxchg {
0x4a => Operator::I32AtomicRmw8CmpxchgU {
memarg: self.read_memarg_of_align(0)?,
},
0x4b => Operator::I32AtomicRmw16UCmpxchg {
0x4b => Operator::I32AtomicRmw16CmpxchgU {
memarg: self.read_memarg_of_align(1)?,
},
0x4c => Operator::I64AtomicRmw8UCmpxchg {
0x4c => Operator::I64AtomicRmw8CmpxchgU {
memarg: self.read_memarg_of_align(0)?,
},
0x4d => Operator::I64AtomicRmw16UCmpxchg {
0x4d => Operator::I64AtomicRmw16CmpxchgU {
memarg: self.read_memarg_of_align(1)?,
},
0x4e => Operator::I64AtomicRmw32UCmpxchg {
0x4e => Operator::I64AtomicRmw32CmpxchgU {
memarg: self.read_memarg_of_align(2)?,
},
@ -849,7 +939,7 @@ impl<'a> BinaryReader<'a> {
} else {
self.position = position;
let idx = self.read_var_s33()?;
if idx < 0 || idx > (core::u32::MAX as i64) {
if idx < 0 || idx > (std::u32::MAX as i64) {
return Err(BinaryReaderError {
message: "invalid function type",
offset: position,
@ -859,6 +949,10 @@ impl<'a> BinaryReader<'a> {
}
}
/// Reads the next available `Operator`.
/// # Errors
/// If `BinaryReader` has less bytes remaining than required to parse
/// the `Operator`.
pub fn read_operator(&mut self) -> Result<Operator<'a>> {
let code = self.read_u8()? as u8;
Ok(match code {
@ -894,19 +988,31 @@ impl<'a> BinaryReader<'a> {
},
0x1a => Operator::Drop,
0x1b => Operator::Select,
0x20 => Operator::GetLocal {
0x1c => {
let results = self.read_var_u32()?;
if results != 1 {
return Err(BinaryReaderError {
message: "bad number of results",
offset: self.position,
});
}
Operator::TypedSelect {
ty: self.read_type()?,
}
}
0x20 => Operator::LocalGet {
local_index: self.read_var_u32()?,
},
0x21 => Operator::SetLocal {
0x21 => Operator::LocalSet {
local_index: self.read_var_u32()?,
},
0x22 => Operator::TeeLocal {
0x22 => Operator::LocalTee {
local_index: self.read_var_u32()?,
},
0x23 => Operator::GetGlobal {
0x23 => Operator::GlobalGet {
global_index: self.read_var_u32()?,
},
0x24 => Operator::SetGlobal {
0x24 => Operator::GlobalSet {
global_index: self.read_var_u32()?,
},
0x25 => Operator::TableGet {
@ -1101,25 +1207,25 @@ impl<'a> BinaryReader<'a> {
0xa5 => Operator::F64Max,
0xa6 => Operator::F64Copysign,
0xa7 => Operator::I32WrapI64,
0xa8 => Operator::I32TruncSF32,
0xa9 => Operator::I32TruncUF32,
0xaa => Operator::I32TruncSF64,
0xab => Operator::I32TruncUF64,
0xac => Operator::I64ExtendSI32,
0xad => Operator::I64ExtendUI32,
0xae => Operator::I64TruncSF32,
0xaf => Operator::I64TruncUF32,
0xb0 => Operator::I64TruncSF64,
0xb1 => Operator::I64TruncUF64,
0xb2 => Operator::F32ConvertSI32,
0xb3 => Operator::F32ConvertUI32,
0xb4 => Operator::F32ConvertSI64,
0xb5 => Operator::F32ConvertUI64,
0xa8 => Operator::I32TruncF32S,
0xa9 => Operator::I32TruncF32U,
0xaa => Operator::I32TruncF64S,
0xab => Operator::I32TruncF64U,
0xac => Operator::I64ExtendI32S,
0xad => Operator::I64ExtendI32U,
0xae => Operator::I64TruncF32S,
0xaf => Operator::I64TruncF32U,
0xb0 => Operator::I64TruncF64S,
0xb1 => Operator::I64TruncF64U,
0xb2 => Operator::F32ConvertI32S,
0xb3 => Operator::F32ConvertI32U,
0xb4 => Operator::F32ConvertI64S,
0xb5 => Operator::F32ConvertI64U,
0xb6 => Operator::F32DemoteF64,
0xb7 => Operator::F64ConvertSI32,
0xb8 => Operator::F64ConvertUI32,
0xb9 => Operator::F64ConvertSI64,
0xba => Operator::F64ConvertUI64,
0xb7 => Operator::F64ConvertI32S,
0xb8 => Operator::F64ConvertI32U,
0xb9 => Operator::F64ConvertI64S,
0xba => Operator::F64ConvertI64U,
0xbb => Operator::F64PromoteF32,
0xbc => Operator::I32ReinterpretF32,
0xbd => Operator::I64ReinterpretF64,
@ -1134,6 +1240,9 @@ impl<'a> BinaryReader<'a> {
0xd0 => Operator::RefNull,
0xd1 => Operator::RefIsNull,
0xd2 => Operator::RefFunc {
function_index: self.read_var_u32()?,
},
0xfc => self.read_0xfc_operator()?,
0xfd => self.read_0xfd_operator()?,
@ -1151,14 +1260,14 @@ impl<'a> BinaryReader<'a> {
fn read_0xfc_operator(&mut self) -> Result<Operator<'a>> {
let code = self.read_u8()? as u8;
Ok(match code {
0x00 => Operator::I32TruncSSatF32,
0x01 => Operator::I32TruncUSatF32,
0x02 => Operator::I32TruncSSatF64,
0x03 => Operator::I32TruncUSatF64,
0x04 => Operator::I64TruncSSatF32,
0x05 => Operator::I64TruncUSatF32,
0x06 => Operator::I64TruncSSatF64,
0x07 => Operator::I64TruncUSatF64,
0x00 => Operator::I32TruncSatF32S,
0x01 => Operator::I32TruncSatF32U,
0x02 => Operator::I32TruncSatF64S,
0x03 => Operator::I32TruncSatF64U,
0x04 => Operator::I64TruncSatF32S,
0x05 => Operator::I64TruncSatF32U,
0x06 => Operator::I64TruncSatF64S,
0x07 => Operator::I64TruncSatF64U,
0x08 => {
let segment = self.read_var_u32()?;
@ -1176,15 +1285,15 @@ impl<'a> BinaryReader<'a> {
Operator::DataDrop { segment }
}
0x0a => {
let src = self.read_u8()?;
if src != 0 {
let dst = self.read_u8()?;
if dst != 0 {
return Err(BinaryReaderError {
message: "reserved byte must be zero",
offset: self.original_position() - 1,
});
}
let dst = self.read_u8()?;
if dst != 0 {
let src = self.read_u8()?;
if src != 0 {
return Err(BinaryReaderError {
message: "reserved byte must be zero",
offset: self.original_position() - 1,
@ -1204,35 +1313,20 @@ impl<'a> BinaryReader<'a> {
}
0x0c => {
let segment = self.read_var_u32()?;
let table = self.read_u8()?;
if table != 0 {
return Err(BinaryReaderError {
message: "reserved byte must be zero",
offset: self.original_position() - 1,
});
}
Operator::TableInit { segment }
let table = self.read_var_u32()?;
Operator::TableInit { segment, table }
}
0x0d => {
let segment = self.read_var_u32()?;
Operator::ElemDrop { segment }
}
0x0e => {
let src = self.read_u8()?;
if src != 0 {
return Err(BinaryReaderError {
message: "reserved byte must be zero",
offset: self.original_position() - 1,
});
let dst_table = self.read_var_u32()?;
let src_table = self.read_var_u32()?;
Operator::TableCopy {
src_table,
dst_table,
}
let dst = self.read_u8()?;
if dst != 0 {
return Err(BinaryReaderError {
message: "reserved byte must be zero",
offset: self.original_position() - 1,
});
}
Operator::TableCopy
}
0x0f => {
@ -1244,6 +1338,11 @@ impl<'a> BinaryReader<'a> {
Operator::TableSize { table }
}
0x11 => {
let table = self.read_var_u32()?;
Operator::TableFill { table }
}
_ => {
return Err(BinaryReaderError {
message: "Unknown 0xfc opcode",
@ -1420,6 +1519,7 @@ impl<'a> BinaryReader<'a> {
0x89 => Operator::I64x2ShrU,
0x8a => Operator::I64x2Add,
0x8d => Operator::I64x2Sub,
0x90 => Operator::I64x2Mul,
0x95 => Operator::F32x4Abs,
0x96 => Operator::F32x4Neg,
0x97 => Operator::F32x4Sqrt,
@ -1438,34 +1538,67 @@ impl<'a> BinaryReader<'a> {
0xa8 => Operator::F64x2Div,
0xa9 => Operator::F64x2Min,
0xaa => Operator::F64x2Max,
0xab => Operator::I32x4TruncSF32x4Sat,
0xac => Operator::I32x4TruncUF32x4Sat,
0xad => Operator::I64x2TruncSF64x2Sat,
0xae => Operator::I64x2TruncUF64x2Sat,
0xaf => Operator::F32x4ConvertSI32x4,
0xb0 => Operator::F32x4ConvertUI32x4,
0xb1 => Operator::F64x2ConvertSI64x2,
0xb2 => Operator::F64x2ConvertUI64x2,
0xab => Operator::I32x4TruncSatF32x4S,
0xac => Operator::I32x4TruncSatF32x4U,
0xad => Operator::I64x2TruncSatF64x2S,
0xae => Operator::I64x2TruncSatF64x2U,
0xaf => Operator::F32x4ConvertI32x4S,
0xb0 => Operator::F32x4ConvertI32x4U,
0xb1 => Operator::F64x2ConvertI64x2S,
0xb2 => Operator::F64x2ConvertI64x2U,
0xc0 => Operator::V8x16Swizzle,
0x03 | 0xc1 => {
let mut lanes = [0 as SIMDLaneIndex; 16];
for i in 0..16 {
lanes[i] = self.read_lane_index(32)?
for lane in &mut lanes {
*lane = self.read_lane_index(32)?
}
Operator::V8x16Shuffle { lanes }
}
0xc2 => Operator::I8x16LoadSplat {
0xc2 => Operator::V8x16LoadSplat {
memarg: self.read_memarg_of_align(0)?,
},
0xc3 => Operator::I16x8LoadSplat {
0xc3 => Operator::V16x8LoadSplat {
memarg: self.read_memarg_of_align(1)?,
},
0xc4 => Operator::I32x4LoadSplat {
0xc4 => Operator::V32x4LoadSplat {
memarg: self.read_memarg_of_align(2)?,
},
0xc5 => Operator::I64x2LoadSplat {
0xc5 => Operator::V64x2LoadSplat {
memarg: self.read_memarg_of_align(3)?,
},
0xc6 => Operator::I8x16NarrowI16x8S,
0xc7 => Operator::I8x16NarrowI16x8U,
0xc8 => Operator::I16x8NarrowI32x4S,
0xc9 => Operator::I16x8NarrowI32x4U,
0xca => Operator::I16x8WidenLowI8x16S,
0xcb => Operator::I16x8WidenHighI8x16S,
0xcc => Operator::I16x8WidenLowI8x16U,
0xcd => Operator::I16x8WidenHighI8x16U,
0xce => Operator::I32x4WidenLowI16x8S,
0xcf => Operator::I32x4WidenHighI16x8S,
0xd0 => Operator::I32x4WidenLowI16x8U,
0xd1 => Operator::I32x4WidenHighI16x8U,
0xd2 => Operator::I16x8Load8x8S {
memarg: self.read_memarg_of_align(3)?,
},
0xd3 => Operator::I16x8Load8x8U {
memarg: self.read_memarg_of_align(3)?,
},
0xd4 => Operator::I32x4Load16x4S {
memarg: self.read_memarg_of_align(3)?,
},
0xd5 => Operator::I32x4Load16x4U {
memarg: self.read_memarg_of_align(3)?,
},
0xd6 => Operator::I64x2Load32x2S {
memarg: self.read_memarg_of_align(3)?,
},
0xd7 => Operator::I64x2Load32x2U {
memarg: self.read_memarg_of_align(3)?,
},
0xd8 => Operator::V128AndNot,
0xd9 => Operator::I8x16RoundingAverageU,
0xda => Operator::I16x8RoundingAverageU,
_ => {
return Err(BinaryReaderError {
message: "Unknown 0xfd opcode",
@ -1476,7 +1609,7 @@ impl<'a> BinaryReader<'a> {
}
pub(crate) fn read_file_header(&mut self) -> Result<u32> {
let magic_number = self.read_u32()?;
let magic_number = self.read_bytes(4)?;
if magic_number != WASM_MAGIC_NUMBER {
return Err(BinaryReaderError {
message: "Bad magic number",
@ -1567,6 +1700,11 @@ impl<'a> BrTable<'a> {
self.cnt
}
/// Returns whether `BrTable` doesn't have any labels apart from the default one.
pub fn is_empty(&self) -> bool {
self.len() == 0
}
/// Reads br_table entries.
///
/// # Examples
@ -1609,6 +1747,7 @@ impl<'a> BrTable<'a> {
/// }
/// }
/// ```
#[derive(Clone, Debug)]
pub struct BrTableIterator<'a> {
reader: BinaryReader<'a>,
}

16
third_party/rust/wasmparser/src/lib.rs поставляемый
Просмотреть файл

@ -23,24 +23,11 @@
//! this is not the right library for you. You could however, build such
//! a data-structure using this library.
#![cfg_attr(not(feature = "std"), no_std)]
#[cfg(not(feature = "std"))]
#[macro_use]
extern crate alloc as std;
#[cfg(feature = "std")]
#[macro_use]
extern crate std;
#[cfg(not(feature = "std"))]
use hashbrown::HashSet;
#[cfg(feature = "std")]
use std::collections::HashSet;
pub use crate::binary_reader::BinaryReader;
pub use crate::binary_reader::Range;
use crate::binary_reader::SectionHeader;
pub use crate::parser::ElemSectionEntryTable;
pub use crate::parser::LocalName;
pub use crate::parser::NameEntry;
pub use crate::parser::Parser;
@ -88,6 +75,7 @@ pub use crate::readers::Data;
pub use crate::readers::DataKind;
pub use crate::readers::DataSectionReader;
pub use crate::readers::Element;
pub use crate::readers::ElementItem;
pub use crate::readers::ElementItems;
pub use crate::readers::ElementItemsReader;
pub use crate::readers::ElementKind;

18
third_party/rust/wasmparser/src/limits.rs поставляемый
Просмотреть файл

@ -15,20 +15,20 @@
// The following limits are imposed by wasmparser on WebAssembly modules.
// The limits are agreed upon with other engines for consistency.
pub const MAX_WASM_TYPES: usize = 1000000;
pub const MAX_WASM_FUNCTIONS: usize = 1000000;
pub const _MAX_WASM_IMPORTS: usize = 100000;
pub const _MAX_WASM_EXPORTS: usize = 100000;
pub const MAX_WASM_GLOBALS: usize = 1000000;
pub const _MAX_WASM_DATA_SEGMENTS: usize = 100000;
pub const MAX_WASM_TYPES: usize = 1_000_000;
pub const MAX_WASM_FUNCTIONS: usize = 1_000_000;
pub const _MAX_WASM_IMPORTS: usize = 100_000;
pub const _MAX_WASM_EXPORTS: usize = 100_000;
pub const MAX_WASM_GLOBALS: usize = 1_000_000;
pub const _MAX_WASM_DATA_SEGMENTS: usize = 100_000;
pub const MAX_WASM_MEMORY_PAGES: usize = 65536;
pub const MAX_WASM_STRING_SIZE: usize = 100000;
pub const MAX_WASM_STRING_SIZE: usize = 100_000;
pub const _MAX_WASM_MODULE_SIZE: usize = 1024 * 1024 * 1024; //= 1 GiB
pub const MAX_WASM_FUNCTION_SIZE: usize = 128 * 1024;
pub const MAX_WASM_FUNCTION_LOCALS: usize = 50000;
pub const MAX_WASM_FUNCTION_PARAMS: usize = 1000;
pub const MAX_WASM_FUNCTION_RETURNS: usize = 1000;
pub const _MAX_WASM_TABLE_SIZE: usize = 10000000;
pub const MAX_WASM_TABLE_ENTRIES: usize = 10000000;
pub const _MAX_WASM_TABLE_SIZE: usize = 10_000_000;
pub const MAX_WASM_TABLE_ENTRIES: usize = 10_000_000;
pub const MAX_WASM_TABLES: usize = 1;
pub const MAX_WASM_MEMORIES: usize = 1;

Просмотреть файл

@ -13,10 +13,9 @@
* limitations under the License.
*/
use core::cmp::min;
use core::result;
use std::cmp::min;
use std::result;
use std::str;
use std::vec::Vec;
use crate::primitives::{
FuncType, GlobalType, MemoryImmediate, MemoryType, Operator, SIMDLaneIndex, TableType, Type,
@ -27,9 +26,9 @@ use crate::primitives::{
pub(crate) fn is_subtype_supertype(subtype: Type, supertype: Type) -> bool {
match supertype {
Type::AnyRef => {
subtype == Type::AnyRef || subtype == Type::AnyFunc || subtype == Type::Null
subtype == Type::AnyRef || subtype == Type::AnyFunc || subtype == Type::NullRef
}
Type::AnyFunc => subtype == Type::AnyFunc || subtype == Type::Null,
Type::AnyFunc => subtype == Type::AnyFunc || subtype == Type::NullRef,
_ => subtype == supertype,
}
}
@ -373,10 +372,10 @@ impl OperatorValidator {
fn check_operands(&self, expected_types: &[Type]) -> OperatorValidatorResult<()> {
let len = expected_types.len();
self.check_frame_size(len)?;
for i in 0..len {
for (i, expected_type) in expected_types.iter().enumerate() {
if !self
.func_state
.assert_stack_type_at(len - 1 - i, expected_types[i])
.assert_stack_type_at(len - 1 - i, *expected_type)
{
return Err("stack operand type mismatch");
}
@ -498,7 +497,7 @@ impl OperatorValidator {
self.check_memory_index(0, resources)?;
let align = memarg.flags;
if align > max_align {
return Err("align is required to be at most the number of accessed bytes");
return Err("alignment must not be larger than natural");
}
Ok(())
}
@ -572,6 +571,9 @@ impl OperatorValidator {
| TypeOrFuncType::Type(Type::I64)
| TypeOrFuncType::Type(Type::F32)
| TypeOrFuncType::Type(Type::F64) => Ok(()),
TypeOrFuncType::Type(Type::AnyRef) | TypeOrFuncType::Type(Type::AnyFunc) => {
self.check_reference_types_enabled()
}
TypeOrFuncType::Type(Type::V128) => self.check_simd_enabled(),
TypeOrFuncType::FuncType(idx) => {
let idx = idx as usize;
@ -622,28 +624,35 @@ impl OperatorValidator {
self.check_frame_size(3)?;
let func_state = &self.func_state;
let last_block = func_state.last_block();
Ok(if last_block.is_stack_polymorphic() {
let ty = if last_block.is_stack_polymorphic() {
match func_state.stack_types.len() - last_block.stack_starts_at {
0 => None,
0 => return Ok(None),
1 => {
self.check_operands_1(Type::I32)?;
None
return Ok(None);
}
2 => {
self.check_operands_1(Type::I32)?;
Some(func_state.stack_types[func_state.stack_types.len() - 2])
func_state.stack_types[func_state.stack_types.len() - 2]
}
_ => {
let ty = func_state.stack_types[func_state.stack_types.len() - 3];
self.check_operands_2(ty, Type::I32)?;
Some(ty)
ty
}
}
} else {
let ty = func_state.stack_types[func_state.stack_types.len() - 3];
self.check_operands_2(ty, Type::I32)?;
Some(ty)
})
ty
};
if !ty.is_valid_for_old_select() {
return Err("invalid type for select");
}
Ok(Some(ty))
}
pub(crate) fn process_operator(
@ -687,10 +696,9 @@ impl OperatorValidator {
self.func_state.end_function();
return Ok(FunctionEnd::Yes);
}
if {
let last_block = &self.func_state.last_block();
last_block.is_else_allowed && last_block.start_types != last_block.return_types
} {
let last_block = &self.func_state.last_block();
if last_block.is_else_allowed && last_block.start_types != last_block.return_types {
return Err("else is expected: if block has a type that can't be implemented with a no-op");
}
self.func_state.pop_block()
@ -760,14 +768,18 @@ impl OperatorValidator {
let ty = self.check_select()?;
self.func_state.change_frame_after_select(ty)?;
}
Operator::GetLocal { local_index } => {
Operator::TypedSelect { ty } => {
self.check_operands(&[Type::I32, ty, ty])?;
self.func_state.change_frame_after_select(Some(ty))?;
}
Operator::LocalGet { local_index } => {
if local_index as usize >= self.func_state.local_types.len() {
return Err("local index out of bounds");
}
let local_type = self.func_state.local_types[local_index as usize];
self.func_state.change_frame_with_type(0, local_type)?;
}
Operator::SetLocal { local_index } => {
Operator::LocalSet { local_index } => {
if local_index as usize >= self.func_state.local_types.len() {
return Err("local index out of bounds");
}
@ -775,7 +787,7 @@ impl OperatorValidator {
self.check_operands_1(local_type)?;
self.func_state.change_frame(1)?;
}
Operator::TeeLocal { local_index } => {
Operator::LocalTee { local_index } => {
if local_index as usize >= self.func_state.local_types.len() {
return Err("local index out of bounds");
}
@ -783,14 +795,14 @@ impl OperatorValidator {
self.check_operands_1(local_type)?;
self.func_state.change_frame_with_type(1, local_type)?;
}
Operator::GetGlobal { global_index } => {
Operator::GlobalGet { global_index } => {
if global_index as usize >= resources.globals().len() {
return Err("global index out of bounds");
}
let ty = &resources.globals()[global_index as usize];
self.func_state.change_frame_with_type(0, ty.content_type)?;
}
Operator::SetGlobal { global_index } => {
Operator::GlobalSet { global_index } => {
if global_index as usize >= resources.globals().len() {
return Err("global index out of bounds");
}
@ -1089,32 +1101,32 @@ impl OperatorValidator {
self.check_operands_1(Type::I64)?;
self.func_state.change_frame_with_type(1, Type::I32)?;
}
Operator::I32TruncSF32 | Operator::I32TruncUF32 => {
Operator::I32TruncF32S | Operator::I32TruncF32U => {
self.check_operands_1(Type::F32)?;
self.func_state.change_frame_with_type(1, Type::I32)?;
}
Operator::I32TruncSF64 | Operator::I32TruncUF64 => {
Operator::I32TruncF64S | Operator::I32TruncF64U => {
self.check_operands_1(Type::F64)?;
self.func_state.change_frame_with_type(1, Type::I32)?;
}
Operator::I64ExtendSI32 | Operator::I64ExtendUI32 => {
Operator::I64ExtendI32S | Operator::I64ExtendI32U => {
self.check_operands_1(Type::I32)?;
self.func_state.change_frame_with_type(1, Type::I64)?;
}
Operator::I64TruncSF32 | Operator::I64TruncUF32 => {
Operator::I64TruncF32S | Operator::I64TruncF32U => {
self.check_operands_1(Type::F32)?;
self.func_state.change_frame_with_type(1, Type::I64)?;
}
Operator::I64TruncSF64 | Operator::I64TruncUF64 => {
Operator::I64TruncF64S | Operator::I64TruncF64U => {
self.check_operands_1(Type::F64)?;
self.func_state.change_frame_with_type(1, Type::I64)?;
}
Operator::F32ConvertSI32 | Operator::F32ConvertUI32 => {
Operator::F32ConvertI32S | Operator::F32ConvertI32U => {
self.check_non_deterministic_enabled()?;
self.check_operands_1(Type::I32)?;
self.func_state.change_frame_with_type(1, Type::F32)?;
}
Operator::F32ConvertSI64 | Operator::F32ConvertUI64 => {
Operator::F32ConvertI64S | Operator::F32ConvertI64U => {
self.check_non_deterministic_enabled()?;
self.check_operands_1(Type::I64)?;
self.func_state.change_frame_with_type(1, Type::F32)?;
@ -1124,12 +1136,12 @@ impl OperatorValidator {
self.check_operands_1(Type::F64)?;
self.func_state.change_frame_with_type(1, Type::F32)?;
}
Operator::F64ConvertSI32 | Operator::F64ConvertUI32 => {
Operator::F64ConvertI32S | Operator::F64ConvertI32U => {
self.check_non_deterministic_enabled()?;
self.check_operands_1(Type::I32)?;
self.func_state.change_frame_with_type(1, Type::F64)?;
}
Operator::F64ConvertSI64 | Operator::F64ConvertUI64 => {
Operator::F64ConvertI64S | Operator::F64ConvertI64U => {
self.check_non_deterministic_enabled()?;
self.check_operands_1(Type::I64)?;
self.func_state.change_frame_with_type(1, Type::F64)?;
@ -1157,19 +1169,19 @@ impl OperatorValidator {
self.check_operands_1(Type::I64)?;
self.func_state.change_frame_with_type(1, Type::F64)?;
}
Operator::I32TruncSSatF32 | Operator::I32TruncUSatF32 => {
Operator::I32TruncSatF32S | Operator::I32TruncSatF32U => {
self.check_operands_1(Type::F32)?;
self.func_state.change_frame_with_type(1, Type::I32)?;
}
Operator::I32TruncSSatF64 | Operator::I32TruncUSatF64 => {
Operator::I32TruncSatF64S | Operator::I32TruncSatF64U => {
self.check_operands_1(Type::F64)?;
self.func_state.change_frame_with_type(1, Type::I32)?;
}
Operator::I64TruncSSatF32 | Operator::I64TruncUSatF32 => {
Operator::I64TruncSatF32S | Operator::I64TruncSatF32U => {
self.check_operands_1(Type::F32)?;
self.func_state.change_frame_with_type(1, Type::I64)?;
}
Operator::I64TruncSSatF64 | Operator::I64TruncUSatF64 => {
Operator::I64TruncSatF64S | Operator::I64TruncSatF64U => {
self.check_operands_1(Type::F64)?;
self.func_state.change_frame_with_type(1, Type::I64)?;
}
@ -1222,16 +1234,16 @@ impl OperatorValidator {
| Operator::I32AtomicRmwAnd { ref memarg }
| Operator::I32AtomicRmwOr { ref memarg }
| Operator::I32AtomicRmwXor { ref memarg }
| Operator::I32AtomicRmw16UAdd { ref memarg }
| Operator::I32AtomicRmw16USub { ref memarg }
| Operator::I32AtomicRmw16UAnd { ref memarg }
| Operator::I32AtomicRmw16UOr { ref memarg }
| Operator::I32AtomicRmw16UXor { ref memarg }
| Operator::I32AtomicRmw8UAdd { ref memarg }
| Operator::I32AtomicRmw8USub { ref memarg }
| Operator::I32AtomicRmw8UAnd { ref memarg }
| Operator::I32AtomicRmw8UOr { ref memarg }
| Operator::I32AtomicRmw8UXor { ref memarg } => {
| Operator::I32AtomicRmw16AddU { ref memarg }
| Operator::I32AtomicRmw16SubU { ref memarg }
| Operator::I32AtomicRmw16AndU { ref memarg }
| Operator::I32AtomicRmw16OrU { ref memarg }
| Operator::I32AtomicRmw16XorU { ref memarg }
| Operator::I32AtomicRmw8AddU { ref memarg }
| Operator::I32AtomicRmw8SubU { ref memarg }
| Operator::I32AtomicRmw8AndU { ref memarg }
| Operator::I32AtomicRmw8OrU { ref memarg }
| Operator::I32AtomicRmw8XorU { ref memarg } => {
self.check_threads_enabled()?;
self.check_shared_memarg_wo_align(memarg, resources)?;
self.check_operands_2(Type::I32, Type::I32)?;
@ -1242,79 +1254,79 @@ impl OperatorValidator {
| Operator::I64AtomicRmwAnd { ref memarg }
| Operator::I64AtomicRmwOr { ref memarg }
| Operator::I64AtomicRmwXor { ref memarg }
| Operator::I64AtomicRmw32UAdd { ref memarg }
| Operator::I64AtomicRmw32USub { ref memarg }
| Operator::I64AtomicRmw32UAnd { ref memarg }
| Operator::I64AtomicRmw32UOr { ref memarg }
| Operator::I64AtomicRmw32UXor { ref memarg }
| Operator::I64AtomicRmw16UAdd { ref memarg }
| Operator::I64AtomicRmw16USub { ref memarg }
| Operator::I64AtomicRmw16UAnd { ref memarg }
| Operator::I64AtomicRmw16UOr { ref memarg }
| Operator::I64AtomicRmw16UXor { ref memarg }
| Operator::I64AtomicRmw8UAdd { ref memarg }
| Operator::I64AtomicRmw8USub { ref memarg }
| Operator::I64AtomicRmw8UAnd { ref memarg }
| Operator::I64AtomicRmw8UOr { ref memarg }
| Operator::I64AtomicRmw8UXor { ref memarg } => {
| Operator::I64AtomicRmw32AddU { ref memarg }
| Operator::I64AtomicRmw32SubU { ref memarg }
| Operator::I64AtomicRmw32AndU { ref memarg }
| Operator::I64AtomicRmw32OrU { ref memarg }
| Operator::I64AtomicRmw32XorU { ref memarg }
| Operator::I64AtomicRmw16AddU { ref memarg }
| Operator::I64AtomicRmw16SubU { ref memarg }
| Operator::I64AtomicRmw16AndU { ref memarg }
| Operator::I64AtomicRmw16OrU { ref memarg }
| Operator::I64AtomicRmw16XorU { ref memarg }
| Operator::I64AtomicRmw8AddU { ref memarg }
| Operator::I64AtomicRmw8SubU { ref memarg }
| Operator::I64AtomicRmw8AndU { ref memarg }
| Operator::I64AtomicRmw8OrU { ref memarg }
| Operator::I64AtomicRmw8XorU { ref memarg } => {
self.check_threads_enabled()?;
self.check_shared_memarg_wo_align(memarg, resources)?;
self.check_operands_2(Type::I32, Type::I64)?;
self.func_state.change_frame_with_type(2, Type::I64)?;
}
Operator::I32AtomicRmwXchg { ref memarg }
| Operator::I32AtomicRmw16UXchg { ref memarg }
| Operator::I32AtomicRmw8UXchg { ref memarg } => {
| Operator::I32AtomicRmw16XchgU { ref memarg }
| Operator::I32AtomicRmw8XchgU { ref memarg } => {
self.check_threads_enabled()?;
self.check_shared_memarg_wo_align(memarg, resources)?;
self.check_operands_2(Type::I32, Type::I32)?;
self.func_state.change_frame_with_type(2, Type::I32)?;
}
Operator::I32AtomicRmwCmpxchg { ref memarg }
| Operator::I32AtomicRmw16UCmpxchg { ref memarg }
| Operator::I32AtomicRmw8UCmpxchg { ref memarg } => {
| Operator::I32AtomicRmw16CmpxchgU { ref memarg }
| Operator::I32AtomicRmw8CmpxchgU { ref memarg } => {
self.check_threads_enabled()?;
self.check_shared_memarg_wo_align(memarg, resources)?;
self.check_operands(&[Type::I32, Type::I32, Type::I32])?;
self.func_state.change_frame_with_type(3, Type::I32)?;
}
Operator::I64AtomicRmwXchg { ref memarg }
| Operator::I64AtomicRmw32UXchg { ref memarg }
| Operator::I64AtomicRmw16UXchg { ref memarg }
| Operator::I64AtomicRmw8UXchg { ref memarg } => {
| Operator::I64AtomicRmw32XchgU { ref memarg }
| Operator::I64AtomicRmw16XchgU { ref memarg }
| Operator::I64AtomicRmw8XchgU { ref memarg } => {
self.check_threads_enabled()?;
self.check_shared_memarg_wo_align(memarg, resources)?;
self.check_operands_2(Type::I32, Type::I64)?;
self.func_state.change_frame_with_type(2, Type::I64)?;
}
Operator::I64AtomicRmwCmpxchg { ref memarg }
| Operator::I64AtomicRmw32UCmpxchg { ref memarg }
| Operator::I64AtomicRmw16UCmpxchg { ref memarg }
| Operator::I64AtomicRmw8UCmpxchg { ref memarg } => {
| Operator::I64AtomicRmw32CmpxchgU { ref memarg }
| Operator::I64AtomicRmw16CmpxchgU { ref memarg }
| Operator::I64AtomicRmw8CmpxchgU { ref memarg } => {
self.check_threads_enabled()?;
self.check_shared_memarg_wo_align(memarg, resources)?;
self.check_operands(&[Type::I32, Type::I64, Type::I64])?;
self.func_state.change_frame_with_type(3, Type::I64)?;
}
Operator::Wake { ref memarg } => {
Operator::AtomicNotify { ref memarg } => {
self.check_threads_enabled()?;
self.check_shared_memarg_wo_align(memarg, resources)?;
self.check_operands_2(Type::I32, Type::I32)?;
self.func_state.change_frame_with_type(2, Type::I32)?;
}
Operator::I32Wait { ref memarg } => {
Operator::I32AtomicWait { ref memarg } => {
self.check_threads_enabled()?;
self.check_shared_memarg_wo_align(memarg, resources)?;
self.check_operands(&[Type::I32, Type::I32, Type::I64])?;
self.func_state.change_frame_with_type(3, Type::I32)?;
}
Operator::I64Wait { ref memarg } => {
Operator::I64AtomicWait { ref memarg } => {
self.check_threads_enabled()?;
self.check_shared_memarg_wo_align(memarg, resources)?;
self.check_operands(&[Type::I32, Type::I64, Type::I64])?;
self.func_state.change_frame_with_type(3, Type::I32)?;
}
Operator::Fence { ref flags } => {
Operator::AtomicFence { ref flags } => {
self.check_threads_enabled()?;
if *flags != 0 {
return Err("non-zero flags for fence not supported yet");
@ -1322,13 +1334,20 @@ impl OperatorValidator {
}
Operator::RefNull => {
self.check_reference_types_enabled()?;
self.func_state.change_frame_with_type(0, Type::Null)?;
self.func_state.change_frame_with_type(0, Type::NullRef)?;
}
Operator::RefIsNull => {
self.check_reference_types_enabled()?;
self.check_operands(&[Type::AnyRef])?;
self.func_state.change_frame_with_type(1, Type::I32)?;
}
Operator::RefFunc { function_index } => {
self.check_reference_types_enabled()?;
if function_index as usize >= resources.func_type_indices().len() {
return Err("function index out of bounds");
}
self.func_state.change_frame_with_type(0, Type::AnyFunc)?;
}
Operator::V128Load { ref memarg } => {
self.check_simd_enabled()?;
self.check_memarg(memarg, 4, resources)?;
@ -1503,6 +1522,7 @@ impl OperatorValidator {
| Operator::I32x4GeS
| Operator::I32x4GeU
| Operator::V128And
| Operator::V128AndNot
| Operator::V128Or
| Operator::V128Xor
| Operator::I8x16Add
@ -1523,7 +1543,14 @@ impl OperatorValidator {
| Operator::I32x4Sub
| Operator::I32x4Mul
| Operator::I64x2Add
| Operator::I64x2Sub => {
| Operator::I64x2Sub
| Operator::I64x2Mul
| Operator::I8x16RoundingAverageU
| Operator::I16x8RoundingAverageU
| Operator::I8x16NarrowI16x8S
| Operator::I8x16NarrowI16x8U
| Operator::I16x8NarrowI32x4S
| Operator::I16x8NarrowI32x4U => {
self.check_simd_enabled()?;
self.check_operands_2(Type::V128, Type::V128)?;
self.func_state.change_frame_with_type(2, Type::V128)?;
@ -1534,10 +1561,10 @@ impl OperatorValidator {
| Operator::F64x2Abs
| Operator::F64x2Neg
| Operator::F64x2Sqrt
| Operator::F32x4ConvertSI32x4
| Operator::F32x4ConvertUI32x4
| Operator::F64x2ConvertSI64x2
| Operator::F64x2ConvertUI64x2 => {
| Operator::F32x4ConvertI32x4S
| Operator::F32x4ConvertI32x4U
| Operator::F64x2ConvertI64x2S
| Operator::F64x2ConvertI64x2U => {
self.check_non_deterministic_enabled()?;
self.check_simd_enabled()?;
self.check_operands_1(Type::V128)?;
@ -1548,10 +1575,18 @@ impl OperatorValidator {
| Operator::I16x8Neg
| Operator::I32x4Neg
| Operator::I64x2Neg
| Operator::I32x4TruncSF32x4Sat
| Operator::I32x4TruncUF32x4Sat
| Operator::I64x2TruncSF64x2Sat
| Operator::I64x2TruncUF64x2Sat => {
| Operator::I32x4TruncSatF32x4S
| Operator::I32x4TruncSatF32x4U
| Operator::I64x2TruncSatF64x2S
| Operator::I64x2TruncSatF64x2U
| Operator::I16x8WidenLowI8x16S
| Operator::I16x8WidenHighI8x16S
| Operator::I16x8WidenLowI8x16U
| Operator::I16x8WidenHighI8x16U
| Operator::I32x4WidenLowI16x8S
| Operator::I32x4WidenHighI16x8S
| Operator::I32x4WidenLowI16x8U
| Operator::I32x4WidenHighI16x8U => {
self.check_simd_enabled()?;
self.check_operands_1(Type::V128)?;
self.func_state.change_frame_with_type(1, Type::V128)?;
@ -1602,12 +1637,34 @@ impl OperatorValidator {
}
self.func_state.change_frame_with_type(2, Type::V128)?;
}
Operator::I8x16LoadSplat { ref memarg }
| Operator::I16x8LoadSplat { ref memarg }
| Operator::I32x4LoadSplat { ref memarg }
| Operator::I64x2LoadSplat { ref memarg } => {
Operator::V8x16LoadSplat { ref memarg } => {
self.check_simd_enabled()?;
self.check_memarg(memarg, 4, resources)?;
self.check_memarg(memarg, 0, resources)?;
self.check_operands_1(Type::I32)?;
self.func_state.change_frame_with_type(1, Type::V128)?;
}
Operator::V16x8LoadSplat { ref memarg } => {
self.check_simd_enabled()?;
self.check_memarg(memarg, 1, resources)?;
self.check_operands_1(Type::I32)?;
self.func_state.change_frame_with_type(1, Type::V128)?;
}
Operator::V32x4LoadSplat { ref memarg } => {
self.check_simd_enabled()?;
self.check_memarg(memarg, 2, resources)?;
self.check_operands_1(Type::I32)?;
self.func_state.change_frame_with_type(1, Type::V128)?;
}
Operator::V64x2LoadSplat { ref memarg }
| Operator::I16x8Load8x8S { ref memarg }
| Operator::I16x8Load8x8U { ref memarg }
| Operator::I32x4Load16x4S { ref memarg }
| Operator::I32x4Load16x4U { ref memarg }
| Operator::I64x2Load32x2S { ref memarg }
| Operator::I64x2Load32x2U { ref memarg } => {
self.check_simd_enabled()?;
self.check_memarg(memarg, 3, resources)?;
self.check_operands_1(Type::I32)?;
self.func_state.change_frame_with_type(1, Type::V128)?;
}
@ -1632,12 +1689,15 @@ impl OperatorValidator {
self.check_operands(&[Type::I32, Type::I32, Type::I32])?;
self.func_state.change_frame(3)?;
}
Operator::TableInit { segment } => {
Operator::TableInit { segment, table } => {
self.check_bulk_memory_enabled()?;
if segment >= resources.element_count() {
return Err("segment index out of bounds");
}
if 0 >= resources.tables().len() {
if table > 0 {
self.check_reference_types_enabled()?;
}
if table as usize >= resources.tables().len() {
return Err("table index out of bounds");
}
self.check_operands(&[Type::I32, Type::I32, Type::I32])?;
@ -1649,9 +1709,17 @@ impl OperatorValidator {
return Err("segment index out of bounds");
}
}
Operator::TableCopy => {
Operator::TableCopy {
src_table,
dst_table,
} => {
self.check_bulk_memory_enabled()?;
if 0 >= resources.tables().len() {
if src_table > 0 || dst_table > 0 {
self.check_reference_types_enabled()?;
}
if src_table as usize >= resources.tables().len()
|| dst_table as usize >= resources.tables().len()
{
return Err("table index out of bounds");
}
self.check_operands(&[Type::I32, Type::I32, Type::I32])?;
@ -1659,34 +1727,46 @@ impl OperatorValidator {
}
Operator::TableGet { table } => {
self.check_reference_types_enabled()?;
if table as usize >= resources.tables().len() {
return Err("table index out of bounds");
}
let ty = match resources.tables().get(table as usize) {
Some(ty) => ty.element_type,
None => return Err("table index out of bounds"),
};
self.check_operands(&[Type::I32])?;
self.func_state.change_frame_with_type(1, Type::AnyRef)?;
self.func_state.change_frame_with_type(1, ty)?;
}
Operator::TableSet { table } => {
self.check_reference_types_enabled()?;
if table as usize >= resources.tables().len() {
return Err("table index out of bounds");
}
self.check_operands(&[Type::I32, Type::AnyRef])?;
let ty = match resources.tables().get(table as usize) {
Some(ty) => ty.element_type,
None => return Err("table index out of bounds"),
};
self.check_operands(&[Type::I32, ty])?;
self.func_state.change_frame(2)?;
}
Operator::TableGrow { table } => {
self.check_reference_types_enabled()?;
if table as usize >= resources.tables().len() {
return Err("table index out of bounds");
}
self.check_operands(&[Type::I32])?;
self.func_state.change_frame_with_type(1, Type::I32)?;
let ty = match resources.tables().get(table as usize) {
Some(ty) => ty.element_type,
None => return Err("table index out of bounds"),
};
self.check_operands(&[ty, Type::I32])?;
self.func_state.change_frame_with_type(2, Type::I32)?;
}
Operator::TableSize { table } => {
self.check_reference_types_enabled()?;
if table as usize >= resources.tables().len() {
return Err("table index out of bounds");
}
self.func_state.change_frame_with_type(1, Type::I32)?;
self.func_state.change_frame_with_type(0, Type::I32)?;
}
Operator::TableFill { table } => {
self.check_bulk_memory_enabled()?;
let ty = match resources.tables().get(table as usize) {
Some(ty) => ty.element_type,
None => return Err("table index out of bounds"),
};
self.check_operands(&[Type::I32, ty, Type::I32])?;
self.func_state.change_frame(3)?;
}
}
Ok(FunctionEnd::No)

106
third_party/rust/wasmparser/src/parser.rs поставляемый
Просмотреть файл

@ -28,11 +28,12 @@ use crate::primitives::{
};
use crate::readers::{
CodeSectionReader, Data, DataKind, DataSectionReader, Element, ElementItems, ElementKind,
ElementSectionReader, Export, ExportSectionReader, FunctionBody, FunctionSectionReader, Global,
GlobalSectionReader, Import, ImportSectionReader, LinkingSectionReader, MemorySectionReader,
ModuleReader, Name, NameSectionReader, NamingReader, OperatorsReader, Reloc,
RelocSectionReader, Section, SectionReader, TableSectionReader, TypeSectionReader,
CodeSectionReader, Data, DataKind, DataSectionReader, Element, ElementItem, ElementItems,
ElementKind, ElementSectionReader, Export, ExportSectionReader, FunctionBody,
FunctionSectionReader, Global, GlobalSectionReader, Import, ImportSectionReader,
LinkingSectionReader, MemorySectionReader, ModuleReader, Name, NameSectionReader, NamingReader,
OperatorsReader, Reloc, RelocSectionReader, Section, SectionReader, TableSectionReader,
TypeSectionReader,
};
use crate::binary_reader::{BinaryReader, Range};
@ -60,10 +61,10 @@ pub struct RelocEntry {
pub addend: Option<u32>,
}
enum InitExpressionContinuation {
GlobalSection,
ElementSection,
DataSection,
enum InitExpressionContinuationSection {
Global,
Element,
Data,
}
#[derive(Debug)]
@ -116,9 +117,12 @@ pub enum ParserState<'a> {
EndFunctionBody,
SkippingFunctionBody,
BeginPassiveElementSectionEntry(Type),
BeginActiveElementSectionEntry(u32),
ElementSectionEntryBody(Box<[u32]>),
BeginElementSectionEntry {
/// `None` means this is a passive or defined entry
table: ElemSectionEntryTable,
ty: Type,
},
ElementSectionEntryBody(Box<[ElementItem]>),
EndElementSectionEntry,
BeginPassiveDataSectionEntry,
@ -138,6 +142,13 @@ pub enum ParserState<'a> {
SourceMappingURL(&'a str),
}
#[derive(Debug, Copy, Clone)]
pub enum ElemSectionEntryTable {
Passive,
Declared,
Active(u32),
}
#[derive(Debug, Copy, Clone)]
pub enum ParserInput {
Default,
@ -206,7 +217,7 @@ pub struct Parser<'a> {
section_reader: ParserSectionReader<'a>,
element_items: Option<ElementItems<'a>>,
current_function_body: Option<FunctionBody<'a>>,
init_expr_continuation: Option<InitExpressionContinuation>,
init_expr_continuation: Option<InitExpressionContinuationSection>,
current_data_segment: Option<&'a [u8]>,
binary_reader: Option<BinaryReader<'a>>,
operators_reader: Option<OperatorsReader<'a>>,
@ -385,7 +396,7 @@ impl<'a> Parser<'a> {
Ok(())
}
fn read_init_expression_body(&mut self, cont: InitExpressionContinuation) {
fn read_init_expression_body(&mut self, cont: InitExpressionContinuationSection) {
self.state = ParserState::BeginInitExpressionBody;
self.init_expr_continuation = Some(cont);
}
@ -419,19 +430,19 @@ impl<'a> Parser<'a> {
if self.section_entries_left == 0 {
return self.check_section_end();
}
let Element { kind, items } = section_reader!(self, ElementSectionReader).read()?;
match kind {
ElementKind::Passive(ty) => {
self.state = ParserState::BeginPassiveElementSectionEntry(ty);
}
let Element { kind, items, ty } = section_reader!(self, ElementSectionReader).read()?;
let table = match kind {
ElementKind::Passive => ElemSectionEntryTable::Passive,
ElementKind::Declared => ElemSectionEntryTable::Declared,
ElementKind::Active {
table_index,
init_expr,
} => {
self.state = ParserState::BeginActiveElementSectionEntry(table_index);
self.operators_reader = Some(init_expr.get_operators_reader());
ElemSectionEntryTable::Active(table_index)
}
}
};
self.state = ParserState::BeginElementSectionEntry { table, ty };
self.element_items = Some(items);
self.section_entries_left -= 1;
Ok(())
@ -450,7 +461,7 @@ impl<'a> Parser<'a> {
offset: 0, // reader.position - 1, // TODO offset
});
}
let mut elements: Vec<u32> = Vec::with_capacity(num_elements);
let mut elements = Vec::with_capacity(num_elements);
for _ in 0..num_elements {
elements.push(reader.read()?);
}
@ -863,7 +874,7 @@ impl<'a> Parser<'a> {
fn read_data_chunk(&mut self) -> Result<()> {
let data = self.current_data_segment.expect("data");
if data.len() == 0 {
if data.is_empty() {
self.state = ParserState::EndDataSectionEntryBody;
self.current_data_segment = None;
return Ok(());
@ -907,31 +918,32 @@ impl<'a> Parser<'a> {
ParserState::TableSectionEntry(_) => self.read_table_entry()?,
ParserState::ExportSectionEntry { .. } => self.read_export_entry()?,
ParserState::BeginGlobalSectionEntry(_) => {
self.read_init_expression_body(InitExpressionContinuation::GlobalSection)
self.read_init_expression_body(InitExpressionContinuationSection::Global)
}
ParserState::EndGlobalSectionEntry => self.read_global_entry()?,
ParserState::BeginPassiveElementSectionEntry(_) => self.read_element_entry_body()?,
ParserState::BeginActiveElementSectionEntry(_) => {
self.read_init_expression_body(InitExpressionContinuation::ElementSection)
ParserState::BeginElementSectionEntry {
table: ElemSectionEntryTable::Active(_),
..
} => self.read_init_expression_body(InitExpressionContinuationSection::Element),
ParserState::BeginElementSectionEntry { table: _, .. } => {
self.read_element_entry_body()?
}
ParserState::BeginInitExpressionBody | ParserState::InitExpressionOperator(_) => {
self.read_init_expression_operator()?
}
ParserState::BeginPassiveDataSectionEntry => {
self.read_data_entry_body()?;
}
ParserState::BeginPassiveDataSectionEntry => self.read_data_entry_body()?,
ParserState::BeginActiveDataSectionEntry(_) => {
self.read_init_expression_body(InitExpressionContinuation::DataSection)
self.read_init_expression_body(InitExpressionContinuationSection::Data)
}
ParserState::EndInitExpressionBody => {
match self.init_expr_continuation {
Some(InitExpressionContinuation::GlobalSection) => {
Some(InitExpressionContinuationSection::Global) => {
self.state = ParserState::EndGlobalSectionEntry
}
Some(InitExpressionContinuation::ElementSection) => {
Some(InitExpressionContinuationSection::Element) => {
self.read_element_entry_body()?
}
Some(InitExpressionContinuation::DataSection) => self.read_data_entry_body()?,
Some(InitExpressionContinuationSection::Data) => self.read_data_entry_body()?,
None => unreachable!(),
}
self.init_expr_continuation = None;
@ -1078,11 +1090,19 @@ impl<'a> WasmDecoder<'a> for Parser<'a> {
/// # 0x80, 0x80, 0x80, 0x0, 0x0, 0x0, 0xb];
/// use wasmparser::{WasmDecoder, Parser, ParserState};
/// let mut parser = Parser::new(data);
/// let mut types = Vec::new();
/// let mut function_types = Vec::new();
/// let mut function_readers = Vec::new();
/// loop {
/// match *parser.read() {
/// match parser.read() {
/// ParserState::Error(_) |
/// ParserState::EndWasm => break,
/// ParserState::TypeSectionEntry(ty) => {
/// types.push(ty.clone());
/// }
/// ParserState::FunctionSectionEntry(id) => {
/// function_types.push(id.clone());
/// }
/// ParserState::BeginFunctionBody {..} => {
/// let reader = parser.create_binary_reader();
/// function_readers.push(reader);
@ -1091,9 +1111,21 @@ impl<'a> WasmDecoder<'a> for Parser<'a> {
/// }
/// }
/// for (i, reader) in function_readers.iter_mut().enumerate() {
/// println!("Function {}", i);
/// // Access the function type through the types table.
/// let ty = &types[function_types[i] as usize];
/// println!("\nFunction {} of type {:?}", i, ty);
/// // Read the local declarations required by the function body.
/// let local_decls_len = reader.read_local_count().unwrap();
/// let mut local_decls = Vec::with_capacity(local_decls_len);
/// let mut local_count = ty.params.len();
/// for _ in 0..local_decls_len {
/// let local_decl = reader.read_local_decl(&mut local_count).unwrap();
/// local_decls.push(local_decl);
/// }
/// println!("Function locals: vars {:?}; total {} ", local_decls, local_count);
/// // Read the operations of the function body.
/// while let Ok(ref op) = reader.read_operator() {
/// println!(" {:?}", op);
/// println!(" {:?}", op);
/// }
/// }
/// ```

218
third_party/rust/wasmparser/src/primitives.rs поставляемый
Просмотреть файл

@ -13,12 +13,9 @@
* limitations under the License.
*/
use core::result;
use std::boxed::Box;
use std::fmt;
#[cfg(feature = "std")]
use std::error::Error;
use std::fmt;
use std::result;
#[derive(Debug, Copy, Clone)]
pub struct BinaryReaderError {
@ -28,7 +25,6 @@ pub struct BinaryReaderError {
pub type Result<T> = result::Result<T, BinaryReaderError>;
#[cfg(feature = "std")]
impl Error for BinaryReaderError {}
impl fmt::Display for BinaryReaderError {
@ -82,9 +78,18 @@ pub enum Type {
V128,
AnyFunc,
AnyRef,
NullRef,
Func,
EmptyBlockType,
Null,
}
impl Type {
pub(crate) fn is_valid_for_old_select(&self) -> bool {
match self {
Type::I32 | Type::I64 | Type::F32 | Type::F64 => true,
_ => false,
}
}
}
/// Either a value type or a function type.
@ -150,7 +155,7 @@ pub enum ImportSectionEntryType {
Global(GlobalType),
}
#[derive(Debug)]
#[derive(Debug, Copy, Clone)]
pub struct MemoryImmediate {
pub flags: u32,
pub offset: u32,
@ -187,7 +192,7 @@ pub enum RelocType {
}
/// A br_table entries representation.
#[derive(Debug)]
#[derive(Debug, Clone)]
pub struct BrTable<'a> {
pub(crate) buffer: &'a [u8],
pub(crate) cnt: usize,
@ -233,7 +238,7 @@ pub type SIMDLaneIndex = u8;
/// Instructions as defined [here].
///
/// [here]: https://webassembly.github.io/spec/core/binary/instructions.html
#[derive(Debug)]
#[derive(Debug, Clone)]
pub enum Operator<'a> {
Unreachable,
Nop,
@ -250,11 +255,12 @@ pub enum Operator<'a> {
CallIndirect { index: u32, table_index: u32 },
Drop,
Select,
GetLocal { local_index: u32 },
SetLocal { local_index: u32 },
TeeLocal { local_index: u32 },
GetGlobal { global_index: u32 },
SetGlobal { global_index: u32 },
TypedSelect { ty: Type },
LocalGet { local_index: u32 },
LocalSet { local_index: u32 },
LocalTee { local_index: u32 },
GlobalGet { global_index: u32 },
GlobalSet { global_index: u32 },
I32Load { memarg: MemoryImmediate },
I64Load { memarg: MemoryImmediate },
F32Load { memarg: MemoryImmediate },
@ -286,6 +292,7 @@ pub enum Operator<'a> {
F64Const { value: Ieee64 },
RefNull,
RefIsNull,
RefFunc { function_index: u32 },
I32Eqz,
I32Eq,
I32Ne,
@ -385,25 +392,25 @@ pub enum Operator<'a> {
F64Max,
F64Copysign,
I32WrapI64,
I32TruncSF32,
I32TruncUF32,
I32TruncSF64,
I32TruncUF64,
I64ExtendSI32,
I64ExtendUI32,
I64TruncSF32,
I64TruncUF32,
I64TruncSF64,
I64TruncUF64,
F32ConvertSI32,
F32ConvertUI32,
F32ConvertSI64,
F32ConvertUI64,
I32TruncF32S,
I32TruncF32U,
I32TruncF64S,
I32TruncF64U,
I64ExtendI32S,
I64ExtendI32U,
I64TruncF32S,
I64TruncF32U,
I64TruncF64S,
I64TruncF64U,
F32ConvertI32S,
F32ConvertI32U,
F32ConvertI64S,
F32ConvertI64U,
F32DemoteF64,
F64ConvertSI32,
F64ConvertUI32,
F64ConvertSI64,
F64ConvertUI64,
F64ConvertI32S,
F64ConvertI32U,
F64ConvertI64S,
F64ConvertI64U,
F64PromoteF32,
I32ReinterpretF32,
I64ReinterpretF64,
@ -417,14 +424,14 @@ pub enum Operator<'a> {
// 0xFC operators
// Non-trapping Float-to-int Conversions
I32TruncSSatF32,
I32TruncUSatF32,
I32TruncSSatF64,
I32TruncUSatF64,
I64TruncSSatF32,
I64TruncUSatF32,
I64TruncSSatF64,
I64TruncUSatF64,
I32TruncSatF32S,
I32TruncSatF32U,
I32TruncSatF64S,
I32TruncSatF64U,
I64TruncSatF32S,
I64TruncSatF32U,
I64TruncSatF64S,
I64TruncSatF64U,
// 0xFC operators
// bulk memory https://github.com/WebAssembly/bulk-memory-operations/blob/master/proposals/bulk-memory-operations/Overview.md
@ -432,9 +439,10 @@ pub enum Operator<'a> {
DataDrop { segment: u32 },
MemoryCopy,
MemoryFill,
TableInit { segment: u32 },
TableInit { segment: u32, table: u32 },
ElemDrop { segment: u32 },
TableCopy,
TableCopy { dst_table: u32, src_table: u32 },
TableFill { table: u32 },
TableGet { table: u32 },
TableSet { table: u32 },
TableGrow { table: u32 },
@ -442,10 +450,10 @@ pub enum Operator<'a> {
// 0xFE operators
// https://github.com/WebAssembly/threads/blob/master/proposals/threads/Overview.md
Wake { memarg: MemoryImmediate },
I32Wait { memarg: MemoryImmediate },
I64Wait { memarg: MemoryImmediate },
Fence { flags: u8 },
AtomicNotify { memarg: MemoryImmediate },
I32AtomicWait { memarg: MemoryImmediate },
I64AtomicWait { memarg: MemoryImmediate },
AtomicFence { flags: u8 },
I32AtomicLoad { memarg: MemoryImmediate },
I64AtomicLoad { memarg: MemoryImmediate },
I32AtomicLoad8U { memarg: MemoryImmediate },
@ -462,53 +470,53 @@ pub enum Operator<'a> {
I64AtomicStore32 { memarg: MemoryImmediate },
I32AtomicRmwAdd { memarg: MemoryImmediate },
I64AtomicRmwAdd { memarg: MemoryImmediate },
I32AtomicRmw8UAdd { memarg: MemoryImmediate },
I32AtomicRmw16UAdd { memarg: MemoryImmediate },
I64AtomicRmw8UAdd { memarg: MemoryImmediate },
I64AtomicRmw16UAdd { memarg: MemoryImmediate },
I64AtomicRmw32UAdd { memarg: MemoryImmediate },
I32AtomicRmw8AddU { memarg: MemoryImmediate },
I32AtomicRmw16AddU { memarg: MemoryImmediate },
I64AtomicRmw8AddU { memarg: MemoryImmediate },
I64AtomicRmw16AddU { memarg: MemoryImmediate },
I64AtomicRmw32AddU { memarg: MemoryImmediate },
I32AtomicRmwSub { memarg: MemoryImmediate },
I64AtomicRmwSub { memarg: MemoryImmediate },
I32AtomicRmw8USub { memarg: MemoryImmediate },
I32AtomicRmw16USub { memarg: MemoryImmediate },
I64AtomicRmw8USub { memarg: MemoryImmediate },
I64AtomicRmw16USub { memarg: MemoryImmediate },
I64AtomicRmw32USub { memarg: MemoryImmediate },
I32AtomicRmw8SubU { memarg: MemoryImmediate },
I32AtomicRmw16SubU { memarg: MemoryImmediate },
I64AtomicRmw8SubU { memarg: MemoryImmediate },
I64AtomicRmw16SubU { memarg: MemoryImmediate },
I64AtomicRmw32SubU { memarg: MemoryImmediate },
I32AtomicRmwAnd { memarg: MemoryImmediate },
I64AtomicRmwAnd { memarg: MemoryImmediate },
I32AtomicRmw8UAnd { memarg: MemoryImmediate },
I32AtomicRmw16UAnd { memarg: MemoryImmediate },
I64AtomicRmw8UAnd { memarg: MemoryImmediate },
I64AtomicRmw16UAnd { memarg: MemoryImmediate },
I64AtomicRmw32UAnd { memarg: MemoryImmediate },
I32AtomicRmw8AndU { memarg: MemoryImmediate },
I32AtomicRmw16AndU { memarg: MemoryImmediate },
I64AtomicRmw8AndU { memarg: MemoryImmediate },
I64AtomicRmw16AndU { memarg: MemoryImmediate },
I64AtomicRmw32AndU { memarg: MemoryImmediate },
I32AtomicRmwOr { memarg: MemoryImmediate },
I64AtomicRmwOr { memarg: MemoryImmediate },
I32AtomicRmw8UOr { memarg: MemoryImmediate },
I32AtomicRmw16UOr { memarg: MemoryImmediate },
I64AtomicRmw8UOr { memarg: MemoryImmediate },
I64AtomicRmw16UOr { memarg: MemoryImmediate },
I64AtomicRmw32UOr { memarg: MemoryImmediate },
I32AtomicRmw8OrU { memarg: MemoryImmediate },
I32AtomicRmw16OrU { memarg: MemoryImmediate },
I64AtomicRmw8OrU { memarg: MemoryImmediate },
I64AtomicRmw16OrU { memarg: MemoryImmediate },
I64AtomicRmw32OrU { memarg: MemoryImmediate },
I32AtomicRmwXor { memarg: MemoryImmediate },
I64AtomicRmwXor { memarg: MemoryImmediate },
I32AtomicRmw8UXor { memarg: MemoryImmediate },
I32AtomicRmw16UXor { memarg: MemoryImmediate },
I64AtomicRmw8UXor { memarg: MemoryImmediate },
I64AtomicRmw16UXor { memarg: MemoryImmediate },
I64AtomicRmw32UXor { memarg: MemoryImmediate },
I32AtomicRmw8XorU { memarg: MemoryImmediate },
I32AtomicRmw16XorU { memarg: MemoryImmediate },
I64AtomicRmw8XorU { memarg: MemoryImmediate },
I64AtomicRmw16XorU { memarg: MemoryImmediate },
I64AtomicRmw32XorU { memarg: MemoryImmediate },
I32AtomicRmwXchg { memarg: MemoryImmediate },
I64AtomicRmwXchg { memarg: MemoryImmediate },
I32AtomicRmw8UXchg { memarg: MemoryImmediate },
I32AtomicRmw16UXchg { memarg: MemoryImmediate },
I64AtomicRmw8UXchg { memarg: MemoryImmediate },
I64AtomicRmw16UXchg { memarg: MemoryImmediate },
I64AtomicRmw32UXchg { memarg: MemoryImmediate },
I32AtomicRmw8XchgU { memarg: MemoryImmediate },
I32AtomicRmw16XchgU { memarg: MemoryImmediate },
I64AtomicRmw8XchgU { memarg: MemoryImmediate },
I64AtomicRmw16XchgU { memarg: MemoryImmediate },
I64AtomicRmw32XchgU { memarg: MemoryImmediate },
I32AtomicRmwCmpxchg { memarg: MemoryImmediate },
I64AtomicRmwCmpxchg { memarg: MemoryImmediate },
I32AtomicRmw8UCmpxchg { memarg: MemoryImmediate },
I32AtomicRmw16UCmpxchg { memarg: MemoryImmediate },
I64AtomicRmw8UCmpxchg { memarg: MemoryImmediate },
I64AtomicRmw16UCmpxchg { memarg: MemoryImmediate },
I64AtomicRmw32UCmpxchg { memarg: MemoryImmediate },
I32AtomicRmw8CmpxchgU { memarg: MemoryImmediate },
I32AtomicRmw16CmpxchgU { memarg: MemoryImmediate },
I64AtomicRmw8CmpxchgU { memarg: MemoryImmediate },
I64AtomicRmw16CmpxchgU { memarg: MemoryImmediate },
I64AtomicRmw32CmpxchgU { memarg: MemoryImmediate },
// 0xFD operators
// SIMD https://github.com/WebAssembly/simd/blob/master/proposals/simd/BinarySIMD.md
@ -579,6 +587,7 @@ pub enum Operator<'a> {
F64x2Ge,
V128Not,
V128And,
V128AndNot,
V128Or,
V128Xor,
V128Bitselect,
@ -625,6 +634,7 @@ pub enum Operator<'a> {
I64x2ShrU,
I64x2Add,
I64x2Sub,
I64x2Mul,
F32x4Abs,
F32x4Neg,
F32x4Sqrt,
@ -643,18 +653,38 @@ pub enum Operator<'a> {
F64x2Div,
F64x2Min,
F64x2Max,
I32x4TruncSF32x4Sat,
I32x4TruncUF32x4Sat,
I64x2TruncSF64x2Sat,
I64x2TruncUF64x2Sat,
F32x4ConvertSI32x4,
F32x4ConvertUI32x4,
F64x2ConvertSI64x2,
F64x2ConvertUI64x2,
I32x4TruncSatF32x4S,
I32x4TruncSatF32x4U,
I64x2TruncSatF64x2S,
I64x2TruncSatF64x2U,
F32x4ConvertI32x4S,
F32x4ConvertI32x4U,
F64x2ConvertI64x2S,
F64x2ConvertI64x2U,
V8x16Swizzle,
V8x16Shuffle { lanes: [SIMDLaneIndex; 16] },
I8x16LoadSplat { memarg: MemoryImmediate },
I16x8LoadSplat { memarg: MemoryImmediate },
I32x4LoadSplat { memarg: MemoryImmediate },
I64x2LoadSplat { memarg: MemoryImmediate },
V8x16LoadSplat { memarg: MemoryImmediate },
V16x8LoadSplat { memarg: MemoryImmediate },
V32x4LoadSplat { memarg: MemoryImmediate },
V64x2LoadSplat { memarg: MemoryImmediate },
I8x16NarrowI16x8S,
I8x16NarrowI16x8U,
I16x8NarrowI32x4S,
I16x8NarrowI32x4U,
I16x8WidenLowI8x16S,
I16x8WidenHighI8x16S,
I16x8WidenLowI8x16U,
I16x8WidenHighI8x16U,
I32x4WidenLowI16x8S,
I32x4WidenHighI16x8S,
I32x4WidenLowI16x8U,
I32x4WidenHighI16x8U,
I16x8Load8x8S { memarg: MemoryImmediate },
I16x8Load8x8U { memarg: MemoryImmediate },
I32x4Load16x4S { memarg: MemoryImmediate },
I32x4Load16x4U { memarg: MemoryImmediate },
I64x2Load32x2S { memarg: MemoryImmediate },
I64x2Load32x2U { memarg: MemoryImmediate },
I8x16RoundingAverageU,
I16x8RoundingAverageU,
}

Просмотреть файл

@ -17,47 +17,62 @@ use super::{
BinaryReader, BinaryReaderError, InitExpr, Result, SectionIteratorLimited, SectionReader,
SectionWithLimitedItems, Type,
};
use crate::{ExternalKind, Operator};
#[derive(Debug, Copy, Clone)]
#[derive(Clone)]
pub struct Element<'a> {
pub kind: ElementKind<'a>,
pub items: ElementItems<'a>,
pub ty: Type,
}
#[derive(Debug, Copy, Clone)]
#[derive(Clone)]
pub enum ElementKind<'a> {
Passive(Type),
Passive,
Active {
table_index: u32,
init_expr: InitExpr<'a>,
},
Declared,
}
#[derive(Debug, Copy, Clone)]
pub struct ElementItems<'a> {
exprs: bool,
offset: usize,
data: &'a [u8],
}
#[derive(Debug)]
pub enum ElementItem {
Null,
Func(u32),
}
impl<'a> ElementItems<'a> {
pub fn get_items_reader<'b>(&self) -> Result<ElementItemsReader<'b>>
where
'a: 'b,
{
ElementItemsReader::new(self.data, self.offset)
ElementItemsReader::new(self.data, self.offset, self.exprs)
}
}
pub struct ElementItemsReader<'a> {
reader: BinaryReader<'a>,
count: u32,
exprs: bool,
}
impl<'a> ElementItemsReader<'a> {
pub fn new(data: &[u8], offset: usize) -> Result<ElementItemsReader> {
pub fn new(data: &[u8], offset: usize, exprs: bool) -> Result<ElementItemsReader> {
let mut reader = BinaryReader::new_with_offset(data, offset);
let count = reader.read_var_u32()?;
Ok(ElementItemsReader { reader, count })
Ok(ElementItemsReader {
reader,
count,
exprs,
})
}
pub fn original_position(&self) -> usize {
@ -68,13 +83,41 @@ impl<'a> ElementItemsReader<'a> {
self.count
}
pub fn read(&mut self) -> Result<u32> {
self.reader.read_var_u32()
pub fn uses_exprs(&self) -> bool {
self.exprs
}
pub fn read(&mut self) -> Result<ElementItem> {
if self.exprs {
let offset = self.reader.original_position();
let ret = match self.reader.read_operator()? {
Operator::RefNull => ElementItem::Null,
Operator::RefFunc { function_index } => ElementItem::Func(function_index),
_ => {
return Err(BinaryReaderError {
message: "invalid passive segment",
offset,
})
}
};
match self.reader.read_operator()? {
Operator::End => {}
_ => {
return Err(BinaryReaderError {
message: "invalid passive segment",
offset,
})
}
}
Ok(ret)
} else {
self.reader.read_var_u32().map(ElementItem::Func)
}
}
}
impl<'a> IntoIterator for ElementItemsReader<'a> {
type Item = Result<u32>;
type Item = Result<ElementItem>;
type IntoIter = ElementItemsIterator<'a>;
fn into_iter(self) -> Self::IntoIter {
let count = self.count;
@ -93,7 +136,7 @@ pub struct ElementItemsIterator<'a> {
}
impl<'a> Iterator for ElementItemsIterator<'a> {
type Item = Result<u32>;
type Item = Result<ElementItem>;
fn next(&mut self) -> Option<Self::Item> {
if self.err || self.left == 0 {
return None;
@ -132,12 +175,8 @@ impl<'a> ElementSectionReader<'a> {
/// Reads content of the element section.
///
/// # Examples
/// ```
/// # let data: &[u8] = &[0x00, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00,
/// # 0x01, 0x4, 0x01, 0x60, 0x00, 0x00, 0x03, 0x02, 0x01, 0x00,
/// # 0x05, 0x03, 0x01, 0x00, 0x02,
/// # 0x09, 0x07, 0x01, 0x00, 0x41, 0x00, 0x0B, 0x01, 0x00,
/// # 0x0a, 0x05, 0x01, 0x03, 0x00, 0x01, 0x0b];
/// ```no-run
/// # let data: &[u8] = &[];
/// use wasmparser::{ModuleReader, ElementKind};
///use wasmparser::Result;
/// let mut reader = ModuleReader::new(data).expect("module reader");
@ -148,7 +187,6 @@ impl<'a> ElementSectionReader<'a> {
/// let mut element_reader = section.get_element_section_reader().expect("element section reader");
/// for _ in 0..element_reader.get_count() {
/// let element = element_reader.read().expect("element");
/// println!("Element: {:?}", element);
/// if let ElementKind::Active { init_expr, .. } = element.kind {
/// let mut init_expr_reader = init_expr.get_binary_reader();
/// let op = init_expr_reader.read_operator().expect("op");
@ -157,7 +195,7 @@ impl<'a> ElementSectionReader<'a> {
/// let mut items_reader = element.items.get_items_reader().expect("items reader");
/// for _ in 0..items_reader.get_count() {
/// let item = items_reader.read().expect("item");
/// println!(" Item: {}", item);
/// println!(" Item: {:?}", item);
/// }
/// }
/// ```
@ -166,19 +204,23 @@ impl<'a> ElementSectionReader<'a> {
'a: 'b,
{
let flags = self.reader.read_var_u32()?;
let kind = if flags == 1 {
let ty = self.reader.read_type()?;
ElementKind::Passive(ty)
if (flags & !0b111) != 0 {
return Err(BinaryReaderError {
message: "invalid flags byte in element segment",
offset: self.reader.original_position() - 1,
});
}
let kind = if flags & 0b001 != 0 {
if flags & 0b010 != 0 {
ElementKind::Declared
} else {
ElementKind::Passive
}
} else {
let table_index = match flags {
0 => 0,
2 => self.reader.read_var_u32()?,
_ => {
return Err(BinaryReaderError {
message: "invalid flags byte in element segment",
offset: self.reader.original_position() - 1,
});
}
let table_index = if flags & 0b010 == 0 {
0
} else {
self.reader.read_var_u32()?
};
let init_expr = {
let expr_offset = self.reader.position;
@ -191,17 +233,42 @@ impl<'a> ElementSectionReader<'a> {
init_expr,
}
};
let exprs = flags & 0b100 != 0;
let ty = if flags & 0b011 != 0 {
if exprs {
self.reader.read_type()?
} else {
match self.reader.read_external_kind()? {
ExternalKind::Function => Type::AnyFunc,
_ => {
return Err(BinaryReaderError {
message: "only the function external type is supported in elem segment",
offset: self.reader.original_position() - 1,
});
}
}
}
} else {
Type::AnyFunc
};
let data_start = self.reader.position;
let items_count = self.reader.read_var_u32()?;
for _ in 0..items_count {
self.reader.skip_var_32()?;
if exprs {
for _ in 0..items_count {
self.reader.skip_init_expr()?;
}
} else {
for _ in 0..items_count {
self.reader.skip_var_32()?;
}
}
let data_end = self.reader.position;
let items = ElementItems {
offset: self.reader.original_offset + data_start,
data: &self.reader.buffer[data_start..data_end],
exprs,
};
Ok(Element { kind, items })
Ok(Element { kind, items, ty })
}
}

Просмотреть файл

@ -29,6 +29,7 @@ pub use self::data_section::Data;
pub use self::data_section::DataKind;
pub use self::data_section::DataSectionReader;
pub use self::element_section::Element;
pub use self::element_section::ElementItem;
pub use self::element_section::ElementItems;
pub use self::element_section::ElementItemsReader;
pub use self::element_section::ElementKind;

Просмотреть файл

@ -13,8 +13,6 @@
* limitations under the License.
*/
use core::iter::{IntoIterator, Iterator};
use super::{
BinaryReader, BinaryReaderError, CustomSectionKind, Range, Result, SectionCode, SectionHeader,
};

Просмотреть файл

@ -15,8 +15,9 @@
use super::{BinaryReader, BinaryReaderError, Operator, Result};
#[derive(Clone)]
pub struct OperatorsReader<'a> {
reader: BinaryReader<'a>,
pub(crate) reader: BinaryReader<'a>,
}
impl<'a> OperatorsReader<'a> {

118
third_party/rust/wasmparser/src/tests.rs поставляемый
Просмотреть файл

@ -13,7 +13,6 @@
* limitations under the License.
*/
#[cfg(feature = "std")]
#[cfg(test)]
mod simple_tests {
use crate::operators_validator::OperatorValidatorConfig;
@ -316,7 +315,6 @@ mod simple_tests {
}
}
#[cfg(feature = "std")]
#[cfg(test)]
mod wast_tests {
use crate::operators_validator::OperatorValidatorConfig;
@ -324,8 +322,7 @@ mod wast_tests {
use crate::validator::{ValidatingParser, ValidatingParserConfig};
use crate::BinaryReaderError;
use std::fs::{read, read_dir};
use wabt::script::{Command, CommandKind, ModuleBinary, ScriptParser};
use wabt::Features;
use std::str;
const SPEC_TESTS_PATH: &str = "testsuite";
@ -345,10 +342,10 @@ mod wast_tests {
}
fn validate_module(
module: ModuleBinary,
mut module: wast::Module,
config: ValidatingParserConfig,
) -> Result<(), BinaryReaderError> {
let data = &module.into_vec();
let data = module.encode().unwrap();
let mut parser = ValidatingParser::new(data.as_slice(), Some(config));
let mut max_iteration = 100000000;
loop {
@ -366,20 +363,6 @@ mod wast_tests {
Ok(())
}
fn to_features(config: &ValidatingParserConfig) -> Features {
let mut features = Features::new();
if config.operator_config.enable_simd {
features.enable_simd();
}
if config.operator_config.enable_multi_value {
features.enable_multi_value();
}
if config.operator_config.enable_reference_types {
features.enable_reference_types();
}
features
}
fn run_wabt_scripts<F>(
filename: &str,
wast: &[u8],
@ -395,27 +378,39 @@ mod wast_tests {
return;
}
let features = to_features(&config);
let mut parser: ScriptParser<f32, f64> =
ScriptParser::from_source_and_name_with_features(wast, filename, features)
.expect("script parser");
let contents = str::from_utf8(wast).unwrap();
let buf = wast::parser::ParseBuffer::new(&contents)
.map_err(|mut e| {
e.set_path(filename.as_ref());
e
})
.unwrap();
let wast = wast::parser::parse::<wast::Wast>(&buf)
.map_err(|mut e| {
e.set_path(filename.as_ref());
e
})
.unwrap();
while let Some(Command { kind, line }) = parser.next().expect("parser") {
if skip_test(filename, line) {
for directive in wast.directives {
use wast::WastDirective::*;
let (line, _col) = directive.span().linecol_in(&contents);
let line = line + 1;
if skip_test(filename, line as u64) {
println!("{}:{}: skipping", filename, line);
continue;
}
match kind {
CommandKind::Module { module, .. }
| CommandKind::AssertUninstantiable { module, .. }
| CommandKind::AssertUnlinkable { module, .. } => {
match directive {
Module(module) | AssertUnlinkable { module, .. } => {
if let Err(err) = validate_module(module, config.clone()) {
panic!("{}:{}: invalid module: {}", filename, line, err.message);
}
}
CommandKind::AssertInvalid { module, .. }
| CommandKind::AssertMalformed { module, .. } => {
AssertInvalid { module, .. }
| AssertMalformed {
module: wast::QuoteModule::Module(module),
..
} => {
// TODO diffentiate between assert_invalid and assert_malformed
if let Ok(_) = validate_module(module, config.clone()) {
panic!(
@ -425,13 +420,23 @@ mod wast_tests {
}
// TODO: Check the assert_invalid or assert_malformed message
}
CommandKind::Register { .. }
| CommandKind::PerformAction(_)
| CommandKind::AssertReturn { .. }
| CommandKind::AssertTrap { .. }
| CommandKind::AssertExhaustion { .. }
| CommandKind::AssertReturnCanonicalNan { .. }
| CommandKind::AssertReturnArithmeticNan { .. } => (),
AssertMalformed {
module: wast::QuoteModule::Quote(_),
..
}
| Register { .. }
| Invoke { .. }
| AssertTrap { .. }
| AssertReturn { .. }
| AssertReturnCanonicalNan { .. }
| AssertReturnArithmeticNan { .. }
| AssertReturnCanonicalNanF32x4 { .. }
| AssertReturnCanonicalNanF64x2 { .. }
| AssertReturnArithmeticNanF32x4 { .. }
| AssertReturnArithmeticNanF64x2 { .. }
| AssertReturnFunc { .. }
| AssertExhaustion { .. } => {}
}
}
}
@ -469,12 +474,16 @@ mod wast_tests {
config
},
|name, line| match (name, line) {
("simd_address.wast", _)
| ("simd_const.wast", _)
| ("simd_f32x4_cmp.wast", _)
| ("simd_store.wast", _)
| ("simd_lane.wast", _)
| ("simd_load.wast", _) => true,
// FIXME(WebAssembly/simd#140) needs a few updates to the
// `*.wast` file to successfully parse it (or so I think)
("simd_lane.wast", _) => true,
("simd_load_extend.wast", _) => true,
("simd_f32x4_arith.wast", _) => true,
("simd_f64x2_arith.wast", _) => true,
("simd_f32x4.wast", _) => true,
("simd_f64x2.wast", _) => true,
("simd_const.wast", _) => true,
("simd_load_splat.wast", _) => true,
_ => false,
},
);
@ -494,23 +503,14 @@ mod wast_tests {
{
let mut config: ValidatingParserConfig = default_config();
config.operator_config.enable_reference_types = true;
config.operator_config.enable_bulk_memory = true;
config
},
|name, line| match (name, line) {
("ref_null.wast", _)
| ("ref_is_null.wast", _)
| ("ref_func.wast", _)
| ("linking.wast", _)
| ("globals.wast", _)
| ("imports.wast", _)
| ("br_table.wast", _)
("br_table.wast", _)
| ("select.wast", _)
| ("table_get.wast", _)
| ("table_set.wast", _)
| ("table_size.wast", _)
| ("table_fill.wast", _)
| ("table_grow.wast", _)
| ("exports.wast", _) => true,
| ("binary.wast", _)
| ("linking.wast", 280) => true,
_ => false,
},
);

161
third_party/rust/wasmparser/src/validator.rs поставляемый
Просмотреть файл

@ -13,11 +13,9 @@
* limitations under the License.
*/
use super::HashSet;
use core::result;
use std::collections::HashSet;
use std::result;
use std::str;
use std::string::String;
use std::vec::Vec;
use crate::limits::{
MAX_WASM_FUNCTIONS, MAX_WASM_FUNCTION_LOCALS, MAX_WASM_GLOBALS, MAX_WASM_MEMORIES,
@ -37,6 +35,7 @@ use crate::operators_validator::{
is_subtype_supertype, FunctionEnd, OperatorValidator, OperatorValidatorConfig,
WasmModuleResources, DEFAULT_OPERATOR_VALIDATOR_CONFIG,
};
use crate::{ElemSectionEntryTable, ElementItem};
use crate::readers::FunctionBody;
@ -45,6 +44,7 @@ type ValidatorResult<'a, T> = result::Result<T, ParserState<'a>>;
struct InitExpressionState {
ty: Type,
global_count: usize,
function_count: usize,
validated: bool,
}
@ -179,8 +179,8 @@ impl<'a> ValidatingParser<'a> {
&self.resources
}
fn create_validation_error(&self, message: &'static str) -> Option<ParserState<'a>> {
Some(ParserState::Error(BinaryReaderError {
fn set_validation_error(&mut self, message: &'static str) {
self.validation_error = Some(ParserState::Error(BinaryReaderError {
message,
offset: self.read_position.unwrap(),
}))
@ -196,7 +196,7 @@ impl<'a> ValidatingParser<'a> {
fn check_value_type(&self, ty: Type) -> ValidatorResult<'a, ()> {
match ty {
Type::I32 | Type::I64 | Type::F32 | Type::F64 => Ok(()),
Type::Null | Type::AnyFunc | Type::AnyRef => {
Type::NullRef | Type::AnyFunc | Type::AnyRef => {
if !self.config.operator_config.enable_reference_types {
return self.create_error("reference types support is not enabled");
}
@ -241,11 +241,15 @@ impl<'a> ValidatingParser<'a> {
}
fn check_table_type(&self, table_type: &TableType) -> ValidatorResult<'a, ()> {
if let Type::AnyFunc = table_type.element_type {
self.check_limits(&table_type.limits)
} else {
self.create_error("element is not anyfunc")
match table_type.element_type {
Type::AnyFunc => {}
_ => {
if !self.config.operator_config.enable_reference_types {
return self.create_error("element is not anyfunc");
}
}
}
self.check_limits(&table_type.limits)
}
fn check_memory_type(&self, memory_type: &MemoryType) -> ValidatorResult<'a, ()> {
@ -277,7 +281,9 @@ impl<'a> ValidatingParser<'a> {
Ok(())
}
ImportSectionEntryType::Table(ref table_type) => {
if self.resources.tables.len() >= MAX_WASM_TABLES {
if !self.config.operator_config.enable_reference_types
&& self.resources.tables.len() >= MAX_WASM_TABLES
{
return self.create_error("tables count must be at most 1");
}
self.check_table_type(table_type)
@ -311,7 +317,7 @@ impl<'a> ValidatingParser<'a> {
if !self.config.operator_config.enable_reference_types {
return self.create_error("reference types support is not enabled");
}
Type::Null
Type::NullRef
}
Operator::V128Const { .. } => {
if !self.config.operator_config.enable_simd {
@ -319,12 +325,18 @@ impl<'a> ValidatingParser<'a> {
}
Type::V128
}
Operator::GetGlobal { global_index } => {
Operator::GlobalGet { global_index } => {
if global_index as usize >= state.global_count {
return self.create_error("init_expr global index out of bounds");
}
self.resources.globals[global_index as usize].content_type
}
Operator::RefFunc { function_index } => {
if function_index as usize >= state.function_count {
return self.create_error("init_expr function index out of bounds");
}
Type::AnyFunc
}
_ => return self.create_error("invalid init_expr operator"),
};
if !is_subtype_supertype(ty, state.ty) {
@ -382,13 +394,10 @@ impl<'a> ValidatingParser<'a> {
fn process_begin_section(&self, code: &SectionCode) -> ValidatorResult<'a, SectionOrderState> {
let order_state = SectionOrderState::from_section_code(code);
Ok(match self.section_order_state {
SectionOrderState::Initial => {
if order_state.is_none() {
SectionOrderState::Initial
} else {
order_state.unwrap()
}
}
SectionOrderState::Initial => match order_state {
Some(section) => section,
_ => SectionOrderState::Initial,
},
previous => {
if let Some(order_state_unwraped) = order_state {
if previous >= order_state_unwraped {
@ -406,7 +415,7 @@ impl<'a> ValidatingParser<'a> {
match *self.parser.last_state() {
ParserState::BeginWasm { version } => {
if version != 1 {
self.validation_error = self.create_validation_error("bad wasm file version");
self.set_validation_error("bad wasm file version");
}
}
ParserState::BeginSection { ref code, .. } => {
@ -422,8 +431,7 @@ impl<'a> ValidatingParser<'a> {
if check.is_err() {
self.validation_error = check.err();
} else if self.resources.types.len() > MAX_WASM_TYPES {
self.validation_error =
self.create_validation_error("types count is out of bounds");
self.set_validation_error("types count is out of bounds");
} else {
self.resources.types.push(func_type.clone());
}
@ -452,19 +460,18 @@ impl<'a> ValidatingParser<'a> {
}
ParserState::FunctionSectionEntry(type_index) => {
if type_index as usize >= self.resources.types.len() {
self.validation_error =
self.create_validation_error("func type index out of bounds");
self.set_validation_error("func type index out of bounds");
} else if self.resources.func_type_indices.len() >= MAX_WASM_FUNCTIONS {
self.validation_error =
self.create_validation_error("functions count out of bounds");
self.set_validation_error("functions count out of bounds");
} else {
self.resources.func_type_indices.push(type_index);
}
}
ParserState::TableSectionEntry(ref table_type) => {
if self.resources.tables.len() >= MAX_WASM_TABLES {
self.validation_error =
self.create_validation_error("tables count must be at most 1");
if !self.config.operator_config.enable_reference_types
&& self.resources.tables.len() >= MAX_WASM_TABLES
{
self.set_validation_error("tables count must be at most 1");
} else {
self.validation_error = self.check_table_type(table_type).err();
self.resources.tables.push(table_type.clone());
@ -472,8 +479,7 @@ impl<'a> ValidatingParser<'a> {
}
ParserState::MemorySectionEntry(ref memory_type) => {
if self.resources.memories.len() >= MAX_WASM_MEMORIES {
self.validation_error =
self.create_validation_error("memories count must be at most 1");
self.set_validation_error("memories count must be at most 1");
} else {
self.validation_error = self.check_memory_type(memory_type).err();
self.resources.memories.push(memory_type.clone());
@ -481,13 +487,13 @@ impl<'a> ValidatingParser<'a> {
}
ParserState::BeginGlobalSectionEntry(global_type) => {
if self.resources.globals.len() >= MAX_WASM_GLOBALS {
self.validation_error =
self.create_validation_error("globals count out of bounds");
self.set_validation_error("globals count out of bounds");
} else {
self.validation_error = self.check_global_type(global_type).err();
self.init_expression_state = Some(InitExpressionState {
ty: global_type.content_type,
global_count: self.resources.globals.len(),
function_count: self.resources.func_type_indices.len(),
validated: false,
});
self.resources.globals.push(global_type);
@ -502,7 +508,7 @@ impl<'a> ValidatingParser<'a> {
}
ParserState::EndInitExpressionBody => {
if !self.init_expression_state.as_ref().unwrap().validated {
self.validation_error = self.create_validation_error("init_expr is empty");
self.set_validation_error("init_expr is empty");
}
self.init_expression_state = None;
}
@ -516,39 +522,50 @@ impl<'a> ValidatingParser<'a> {
ParserState::DataCountSectionEntry(count) => {
self.resources.data_count = Some(count);
}
ParserState::BeginPassiveElementSectionEntry(_ty) => {
ParserState::BeginElementSectionEntry { table, ty } => {
self.resources.element_count += 1;
}
ParserState::BeginActiveElementSectionEntry(table_index) => {
self.resources.element_count += 1;
if table_index as usize >= self.resources.tables.len() {
self.validation_error =
self.create_validation_error("element section table index out of bounds");
} else {
assert!(
self.resources.tables[table_index as usize].element_type == Type::AnyFunc
);
if let ElemSectionEntryTable::Active(table_index) = table {
let table = match self.resources.tables.get(table_index as usize) {
Some(t) => t,
None => {
self.set_validation_error("element section table index out of bounds");
return;
}
};
if !is_subtype_supertype(ty, table.element_type) {
self.set_validation_error("element_type != table type");
return;
}
if !self.config.operator_config.enable_reference_types {
if ty != Type::AnyFunc {
self.set_validation_error(
"element_type != anyfunc is not supported yet",
);
return;
}
}
self.init_expression_state = Some(InitExpressionState {
ty: Type::I32,
global_count: self.resources.globals.len(),
function_count: self.resources.func_type_indices.len(),
validated: false,
});
}
}
ParserState::ElementSectionEntryBody(ref indices) => {
for func_index in &**indices {
if *func_index as usize >= self.resources.func_type_indices.len() {
self.validation_error =
self.create_validation_error("element func index out of bounds");
break;
for item in &**indices {
if let ElementItem::Func(func_index) = item {
if *func_index as usize >= self.resources.func_type_indices.len() {
self.set_validation_error("element func index out of bounds");
break;
}
}
}
}
ParserState::BeginFunctionBody { .. } => {
let index = (self.current_func_index + self.func_imports_count) as usize;
if index as usize >= self.resources.func_type_indices.len() {
self.validation_error =
self.create_validation_error("func type is not defined");
self.set_validation_error("func type is not defined");
}
}
ParserState::FunctionBodyLocals { ref locals } => {
@ -565,11 +582,9 @@ impl<'a> ValidatingParser<'a> {
.as_mut()
.unwrap()
.process_operator(operator, &self.resources);
match check {
Ok(_) => (),
Err(err) => {
self.validation_error = self.create_validation_error(err);
}
if let Err(err) = check {
self.set_validation_error(err);
}
}
ParserState::EndFunctionBody => {
@ -578,8 +593,8 @@ impl<'a> ValidatingParser<'a> {
.as_ref()
.unwrap()
.process_end_function();
if check.is_err() {
self.validation_error = self.create_validation_error(check.err().unwrap());
if let Err(err) = check {
self.set_validation_error(err);
}
self.current_func_index += 1;
self.current_operator_validator = None;
@ -589,12 +604,12 @@ impl<'a> ValidatingParser<'a> {
}
ParserState::BeginActiveDataSectionEntry(memory_index) => {
if memory_index as usize >= self.resources.memories.len() {
self.validation_error =
self.create_validation_error("data section memory index out of bounds");
self.set_validation_error("data section memory index out of bounds");
} else {
self.init_expression_state = Some(InitExpressionState {
ty: Type::I32,
global_count: self.resources.globals.len(),
function_count: self.resources.func_type_indices.len(),
validated: false,
});
}
@ -603,15 +618,13 @@ impl<'a> ValidatingParser<'a> {
if self.resources.func_type_indices.len()
!= self.current_func_index as usize + self.func_imports_count as usize
{
self.validation_error = self.create_validation_error(
self.set_validation_error(
"function and code section have inconsistent lengths",
);
}
if let Some(data_count) = self.resources.data_count {
if data_count != self.data_found {
self.validation_error = self.create_validation_error(
"data count section and passive data mismatch",
);
self.set_validation_error("data count section and passive data mismatch");
}
}
}
@ -803,10 +816,10 @@ pub fn validate_function_body(
let mut locals_reader = function_body.get_locals_reader()?;
let local_count = locals_reader.get_count() as usize;
if local_count > MAX_WASM_FUNCTION_LOCALS {
Err(BinaryReaderError {
return Err(BinaryReaderError {
message: "locals exceed maximum",
offset: locals_reader.original_position(),
})?;
});
}
let mut locals: Vec<(u32, Type)> = Vec::with_capacity(local_count);
let mut locals_total: usize = 0;
@ -820,10 +833,10 @@ pub fn validate_function_body(
offset: locals_reader.original_position(),
})?;
if locals_total > MAX_WASM_FUNCTION_LOCALS {
Err(BinaryReaderError {
return Err(BinaryReaderError {
message: "locals exceed maximum",
offset: locals_reader.original_position(),
})?;
});
}
locals.push((count, ty));
}
@ -848,10 +861,10 @@ pub fn validate_function_body(
}
}
if !eof_found {
Err(BinaryReaderError {
return Err(BinaryReaderError {
message: "end of function not found",
offset: last_op,
})?;
});
}
Ok(())
}
@ -867,7 +880,7 @@ pub fn validate(bytes: &[u8], config: Option<ValidatingParserConfig>) -> Result<
let state = parser.read_with_input(next_input);
match *state {
ParserState::EndWasm => break,
ParserState::Error(e) => Err(e)?,
ParserState::Error(e) => return Err(e),
ParserState::BeginFunctionBody { range } => {
parser_input = Some(ParserInput::SkipFunctionBody);
func_ranges.push(range);

23
third_party/rust/wasmparser/test-no_std.sh поставляемый
Просмотреть файл

@ -1,23 +0,0 @@
#!/bin/bash
set -euo pipefail
# This is the test script for testing the no_std configuration of
# packages which support it.
# Repository top-level directory.
topdir=$(dirname "$0")
cd "$topdir"
function banner {
echo "====== $* ======"
}
banner "Rust unit tests"
# Test with just "core" enabled.
cargo +nightly test --no-default-features --features core
# Test with "core" and "std" enabled at the same time.
cargo +nightly test --features core
banner "OK"