mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-23 12:51:06 +00:00
Bug 1831176: Update wast crate. r=yury,glandium,supply-chain-reviewers
Updating wast to the latest version in order to get the new binary encoding for cast instructions. Differential Revision: https://phabricator.services.mozilla.com/D184022
This commit is contained in:
parent
b648995bf4
commit
67731fc42a
55
Cargo.lock
generated
55
Cargo.lock
generated
@ -2390,7 +2390,7 @@ dependencies = [
|
||||
"futures-sink",
|
||||
"futures-util",
|
||||
"http",
|
||||
"indexmap",
|
||||
"indexmap 1.9.3",
|
||||
"slab",
|
||||
"tokio",
|
||||
"tokio-util",
|
||||
@ -2591,15 +2591,22 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "indexmap"
|
||||
version = "1.9.2"
|
||||
version = "1.9.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1885e79c1fc4b10f0e172c475f458b7f7b93061064d98c3293e98c5ba0c8b399"
|
||||
checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"hashbrown",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "indexmap"
|
||||
version = "2.999.999"
|
||||
dependencies = [
|
||||
"indexmap 1.9.3",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "inherent"
|
||||
version = "1.0.7"
|
||||
@ -2737,7 +2744,7 @@ version = "0.1.0"
|
||||
source = "git+https://github.com/mozilla-spidermonkey/jsparagus?rev=64ba08e24749616de2344112f226d1ef4ba893ae#64ba08e24749616de2344112f226d1ef4ba893ae"
|
||||
dependencies = [
|
||||
"bumpalo",
|
||||
"indexmap",
|
||||
"indexmap 1.9.3",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -2747,7 +2754,7 @@ source = "git+https://github.com/mozilla-spidermonkey/jsparagus?rev=64ba08e24749
|
||||
dependencies = [
|
||||
"bumpalo",
|
||||
"byteorder",
|
||||
"indexmap",
|
||||
"indexmap 1.9.3",
|
||||
"jsparagus-ast",
|
||||
"jsparagus-scope",
|
||||
"jsparagus-stencil",
|
||||
@ -2785,7 +2792,7 @@ name = "jsparagus-scope"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/mozilla-spidermonkey/jsparagus?rev=64ba08e24749616de2344112f226d1ef4ba893ae#64ba08e24749616de2344112f226d1ef4ba893ae"
|
||||
dependencies = [
|
||||
"indexmap",
|
||||
"indexmap 1.9.3",
|
||||
"jsparagus-ast",
|
||||
"jsparagus-stencil",
|
||||
]
|
||||
@ -3460,7 +3467,7 @@ dependencies = [
|
||||
"getrandom",
|
||||
"hashbrown",
|
||||
"hyper",
|
||||
"indexmap",
|
||||
"indexmap 1.9.3",
|
||||
"libc",
|
||||
"log",
|
||||
"memchr",
|
||||
@ -3581,7 +3588,7 @@ dependencies = [
|
||||
"bitflags 2.999.999",
|
||||
"codespan-reporting",
|
||||
"hexf-parse",
|
||||
"indexmap",
|
||||
"indexmap 1.9.3",
|
||||
"log",
|
||||
"num-traits",
|
||||
"rustc-hash",
|
||||
@ -3656,7 +3663,7 @@ name = "neqo-transport"
|
||||
version = "0.6.4"
|
||||
source = "git+https://github.com/mozilla/neqo?tag=v0.6.4#80db3a01f3273c7e742ba560fa99246fc8b30c4f"
|
||||
dependencies = [
|
||||
"indexmap",
|
||||
"indexmap 1.9.3",
|
||||
"lazy_static",
|
||||
"log",
|
||||
"neqo-common",
|
||||
@ -4152,7 +4159,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bd39bc6cdc9355ad1dc5eeedefee696bb35c34caf21768741e81826c0bbd7225"
|
||||
dependencies = [
|
||||
"base64 0.13.999",
|
||||
"indexmap",
|
||||
"indexmap 1.9.3",
|
||||
"line-wrap",
|
||||
"serde",
|
||||
"time 0.3.17",
|
||||
@ -4724,7 +4731,7 @@ version = "1.0.93"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cad406b69c91885b5107daf2c29572f6c8cdb3c66826821e286c533490c0bc76"
|
||||
dependencies = [
|
||||
"indexmap",
|
||||
"indexmap 1.9.3",
|
||||
"itoa",
|
||||
"ryu",
|
||||
"serde",
|
||||
@ -4788,7 +4795,7 @@ version = "0.8.26"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "578a7433b776b56a35785ed5ce9a7e777ac0598aac5a6dd1b4b18a307c7fc71b"
|
||||
dependencies = [
|
||||
"indexmap",
|
||||
"indexmap 1.9.3",
|
||||
"ryu",
|
||||
"serde",
|
||||
"yaml-rust",
|
||||
@ -4808,7 +4815,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b4f1641177943b4e6faf7622463ae6dfe0f143eb88799e91e2e2e68ede568af5"
|
||||
dependencies = [
|
||||
"data-encoding",
|
||||
"indexmap",
|
||||
"indexmap 1.9.3",
|
||||
"rust_decimal",
|
||||
]
|
||||
|
||||
@ -4999,7 +5006,7 @@ dependencies = [
|
||||
"euclid",
|
||||
"fxhash",
|
||||
"gecko-profiler",
|
||||
"indexmap",
|
||||
"indexmap 1.9.3",
|
||||
"itertools",
|
||||
"itoa",
|
||||
"lazy_static",
|
||||
@ -5884,22 +5891,22 @@ version = "0.2.100"
|
||||
|
||||
[[package]]
|
||||
name = "wasm-encoder"
|
||||
version = "0.29.0"
|
||||
version = "0.31.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "18c41dbd92eaebf3612a39be316540b8377c871cb9bde6b064af962984912881"
|
||||
checksum = "06a3d1b4a575ffb873679402b2aedb3117555eb65c27b1b86c8a91e574bc2a2a"
|
||||
dependencies = [
|
||||
"leb128",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-smith"
|
||||
version = "0.12.10"
|
||||
version = "0.12.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "027ec1c470cd5d56c43b8e02040250b136ddb5975dd76a1c16915137f5f17e76"
|
||||
checksum = "706fc2c6fb0af287ea9147d343485536b5857b72cd32b1d4091619583b334103"
|
||||
dependencies = [
|
||||
"arbitrary",
|
||||
"flagset",
|
||||
"indexmap",
|
||||
"indexmap 2.999.999",
|
||||
"leb128",
|
||||
"wasm-encoder",
|
||||
"wasmparser",
|
||||
@ -5907,19 +5914,19 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "wasmparser"
|
||||
version = "0.107.0"
|
||||
version = "0.109.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "29e3ac9b780c7dda0cac7a52a5d6d2d6707cc6e3451c9db209b6c758f40d7acb"
|
||||
checksum = "8bf9564f29de2890ee34406af52d2a92dec6ef044c8ddfc5add5db8dcfd36e6c"
|
||||
dependencies = [
|
||||
"indexmap",
|
||||
"indexmap 2.999.999",
|
||||
"semver",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wast"
|
||||
version = "60.0.0"
|
||||
version = "62.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bd06cc744b536e30387e72a48fdd492105b9c938bb4f415c39c616a7a0a697ad"
|
||||
checksum = "c7f7ee878019d69436895f019b65f62c33da63595d8e857cbdc87c13ecb29a32"
|
||||
dependencies = [
|
||||
"leb128",
|
||||
"memchr",
|
||||
|
@ -147,6 +147,9 @@ ntapi = { path = "build/rust/ntapi" }
|
||||
# Patch nix 0.24 to 0.26
|
||||
nix = { path = "build/rust/nix" }
|
||||
|
||||
# Patch indexmap 2.0 to 1.0
|
||||
indexmap = { path = "build/rust/indexmap" }
|
||||
|
||||
# Patch autocfg to hide rustc output. Workaround for https://github.com/cuviper/autocfg/issues/30
|
||||
autocfg = { path = "third_party/rust/autocfg" }
|
||||
|
||||
|
11
build/rust/indexmap/Cargo.toml
Normal file
11
build/rust/indexmap/Cargo.toml
Normal file
@ -0,0 +1,11 @@
|
||||
[package]
|
||||
name = "indexmap"
|
||||
version = "2.999.999"
|
||||
edition = "2021"
|
||||
license = "MPL-2.0"
|
||||
|
||||
[lib]
|
||||
path = "lib.rs"
|
||||
|
||||
[dependencies.indexmap]
|
||||
version = "1.9.3"
|
5
build/rust/indexmap/lib.rs
Normal file
5
build/rust/indexmap/lib.rs
Normal file
@ -0,0 +1,5 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
pub use indexmap::*;
|
@ -5,6 +5,6 @@ authors = ["Christian Holler"]
|
||||
license = "MPL-2.0"
|
||||
|
||||
[dependencies]
|
||||
wasm-smith = "0.12.10"
|
||||
wasm-smith = "0.12.12"
|
||||
arbitrary = { version = "1.0.0", features = ["derive"] }
|
||||
libc = "0.2"
|
||||
|
@ -2,7 +2,7 @@
|
||||
wasmFullPass(`
|
||||
(module
|
||||
(func $f1)
|
||||
(elem declare $f1)
|
||||
(elem declare func $f1)
|
||||
(elem declare funcref (ref.null func))
|
||||
(func $run)
|
||||
(export "run" (func $run))
|
||||
@ -24,7 +24,7 @@ wasmFullPass(`
|
||||
(module
|
||||
(func $f1)
|
||||
(table 1 1 funcref)
|
||||
(elem $e1 declare $f1)
|
||||
(elem $e1 declare func $f1)
|
||||
(func (export "testfn") (table.init $e1 (i32.const 0) (i32.const 0) (i32.const 1)))
|
||||
)
|
||||
`);
|
||||
@ -36,7 +36,7 @@ wasmEvalText(`
|
||||
(module
|
||||
(func $f1)
|
||||
(table 1 1 funcref)
|
||||
(elem $e1 declare $f1)
|
||||
(elem $e1 declare func $f1)
|
||||
(func $start (elem.drop $e1) (elem.drop $e1))
|
||||
(start $start)
|
||||
)
|
||||
@ -47,7 +47,7 @@ wasmAssert(`
|
||||
(module
|
||||
(func $f1)
|
||||
(table 1 1 funcref)
|
||||
(elem declare $f1)
|
||||
(elem declare func $f1)
|
||||
(func $at (param i32) (result i32)
|
||||
local.get 0
|
||||
table.get 0
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
let { plusOne } = wasmEvalText(`(module
|
||||
(; forward declaration so that ref.func works ;)
|
||||
(elem declare $plusOneRef)
|
||||
(elem declare func $plusOneRef)
|
||||
(type $t (func (param i32) (result i32)))
|
||||
|
||||
(func $plusOneRef (param i32) (result i32)
|
||||
@ -49,7 +49,7 @@ wasmFailValidateText(`(module
|
||||
// signature mismatch
|
||||
wasmFailValidateText(`(module
|
||||
(type $t (func (param i32) (result i32)))
|
||||
(elem declare $plusOneRef)
|
||||
(elem declare func $plusOneRef)
|
||||
(func $plusOneRef (param f32) (result f32)
|
||||
(f32.add
|
||||
local.get 0
|
||||
@ -75,7 +75,7 @@ let { loadInt } = wasmEvalText(`(module
|
||||
|
||||
let { callLoadInt } = wasmEvalText(`(module
|
||||
(type $t (func (result i32)))
|
||||
(elem declare 0)
|
||||
(elem declare func 0)
|
||||
(import "" "loadInt" (func (result i32)))
|
||||
(func (export "callLoadInt") (result i32)
|
||||
ref.func 0
|
||||
|
@ -79,7 +79,7 @@ wasmValidateText(`(module
|
||||
)
|
||||
)`);
|
||||
wasmFailValidateText(`(module
|
||||
(elem declare 0)
|
||||
(elem declare func 0)
|
||||
(func
|
||||
(local (ref func))
|
||||
i32.const 0
|
||||
@ -93,7 +93,7 @@ wasmFailValidateText(`(module
|
||||
)
|
||||
)`, /local\.get read from unset local/);
|
||||
wasmValidateText(`(module
|
||||
(elem declare 0)
|
||||
(elem declare func 0)
|
||||
(func (result funcref)
|
||||
(local (ref func) (ref func))
|
||||
i32.const 0
|
||||
@ -154,7 +154,7 @@ assertErrorMessage(() => runMultiNullStack(), TypeError, /cannot pass null to no
|
||||
// can have non-nullable globals
|
||||
wasmEvalText(`(module
|
||||
(func $f)
|
||||
(elem declare $f)
|
||||
(elem declare func $f)
|
||||
(global (ref func) ref.func $f)
|
||||
)`);
|
||||
}
|
||||
|
@ -635,7 +635,7 @@ assertErrorMessage(() => wasmEvalText(`(module
|
||||
// validation: array-type imm-operand needs to be "in range"
|
||||
assertErrorMessage(() => wasmEvalText(`(module
|
||||
(type $a (array funcref))
|
||||
(elem $e funcref $f1 $f2 $f3 $f4)
|
||||
(elem $e func $f1 $f2 $f3 $f4)
|
||||
(func $f1 (export "f1"))
|
||||
(func $f2 (export "f2"))
|
||||
(func $f3 (export "f3"))
|
||||
@ -650,7 +650,7 @@ assertErrorMessage(() => wasmEvalText(`(module
|
||||
// validation: array-type imm-operand must refer to an array type
|
||||
assertErrorMessage(() => wasmEvalText(`(module
|
||||
(type $a (func (param i64) (result f64)))
|
||||
(elem $e funcref $f1 $f2 $f3 $f4)
|
||||
(elem $e func $f1 $f2 $f3 $f4)
|
||||
(func $f1 (export "f1"))
|
||||
(func $f2 (export "f2"))
|
||||
(func $f3 (export "f3"))
|
||||
@ -666,7 +666,7 @@ assertErrorMessage(() => wasmEvalText(`(module
|
||||
// elements
|
||||
assertErrorMessage(() => wasmEvalText(`(module
|
||||
(type $a (array f32))
|
||||
(elem $e funcref $f1 $f2 $f3 $f4)
|
||||
(elem $e func $f1 $f2 $f3 $f4)
|
||||
(func $f1 (export "f1"))
|
||||
(func $f2 (export "f2"))
|
||||
(func $f3 (export "f3"))
|
||||
@ -681,7 +681,7 @@ assertErrorMessage(() => wasmEvalText(`(module
|
||||
// validation: destination elem type must be a supertype of src elem type
|
||||
assertErrorMessage(() => wasmEvalText(`(module
|
||||
(type $a (array eqref))
|
||||
(elem $e funcref $f1)
|
||||
(elem $e func $f1)
|
||||
(func $f1 (export "f1"))
|
||||
;; The implied copy here is from elem-seg-of-funcrefs to
|
||||
;; array-of-eqrefs, which must fail, because funcref isn't
|
||||
@ -696,7 +696,7 @@ assertErrorMessage(() => wasmEvalText(`(module
|
||||
// validation: segment index must be "in range"
|
||||
assertErrorMessage(() => wasmEvalText(`(module
|
||||
(type $a (array funcref))
|
||||
(elem $e funcref $f1 $f2 $f3 $f4)
|
||||
(elem $e func $f1 $f2 $f3 $f4)
|
||||
(func $f1 (export "f1"))
|
||||
(func $f2 (export "f2"))
|
||||
(func $f3 (export "f3"))
|
||||
@ -714,7 +714,7 @@ assertErrorMessage(() => wasmEvalText(`(module
|
||||
let { newElem } = wasmEvalText(`(module
|
||||
(table 4 funcref)
|
||||
(type $a (array funcref))
|
||||
(elem $e (offset (i32.const 0)) funcref $f1 $f2 $f3 $f4)
|
||||
(elem $e (offset (i32.const 0)) func $f1 $f2 $f3 $f4)
|
||||
(func $f1 (export "f1"))
|
||||
(func $f2 (export "f2"))
|
||||
(func $f3 (export "f3"))
|
||||
@ -736,7 +736,7 @@ assertErrorMessage(() => wasmEvalText(`(module
|
||||
let { newElem } = wasmEvalText(`(module
|
||||
(table 4 funcref)
|
||||
(type $a (array funcref))
|
||||
(elem $e (offset (i32.const 0)) funcref $f1 $f2 $f3 $f4)
|
||||
(elem $e (offset (i32.const 0)) func $f1 $f2 $f3 $f4)
|
||||
(func $f1 (export "f1"))
|
||||
(func $f2 (export "f2"))
|
||||
(func $f3 (export "f3"))
|
||||
@ -758,7 +758,7 @@ assertErrorMessage(() => wasmEvalText(`(module
|
||||
let { newElem } = wasmEvalText(`(module
|
||||
(table 4 funcref)
|
||||
(type $a (array funcref))
|
||||
(elem $e (offset (i32.const 0)) funcref $f1 $f2 $f3 $f4)
|
||||
(elem $e (offset (i32.const 0)) func $f1 $f2 $f3 $f4)
|
||||
(func $f1 (export "f1"))
|
||||
(func $f2 (export "f2"))
|
||||
(func $f3 (export "f3"))
|
||||
@ -777,7 +777,7 @@ assertErrorMessage(() => wasmEvalText(`(module
|
||||
{
|
||||
let { newElem } = wasmEvalText(`(module
|
||||
(type $a (array funcref))
|
||||
(elem $e funcref $f1 $f2 $f3 $f4)
|
||||
(elem $e func $f1 $f2 $f3 $f4)
|
||||
(func $f1 (export "f1"))
|
||||
(func $f2 (export "f2"))
|
||||
(func $f3 (export "f3"))
|
||||
@ -797,7 +797,7 @@ assertErrorMessage(() => wasmEvalText(`(module
|
||||
{
|
||||
let { newElem, f1, f2, f3, f4 } = wasmEvalText(`(module
|
||||
(type $a (array funcref))
|
||||
(elem $e funcref $f1 $f2 $f3 $f4)
|
||||
(elem $e func $f1 $f2 $f3 $f4)
|
||||
(func $f1 (export "f1"))
|
||||
(func $f2 (export "f2"))
|
||||
(func $f3 (export "f3"))
|
||||
|
@ -452,16 +452,6 @@ assertErrorMessage(() => ins.pop(),
|
||||
assertEq(ins.testg(10), 20);
|
||||
}
|
||||
|
||||
// Test that field names must be unique in the module.
|
||||
|
||||
assertErrorMessage(() => wasmTextToBinary(
|
||||
`(module
|
||||
(type $s (struct (field $x i32)))
|
||||
(type $t (struct (field $x i32)))
|
||||
)`),
|
||||
SyntaxError,
|
||||
/duplicate identifier for field/);
|
||||
|
||||
// negative tests
|
||||
|
||||
// Wrong type passed as initializer
|
||||
|
@ -6,7 +6,7 @@ const v2vSigSection = sigSection([v2vSig]);
|
||||
// 'ref.func' parses, validates and returns a non-null value
|
||||
wasmFullPass(`
|
||||
(module
|
||||
(elem declare $run)
|
||||
(elem declare func $run)
|
||||
(func $run (result i32)
|
||||
ref.func $run
|
||||
ref.is_null
|
||||
@ -19,7 +19,7 @@ wasmFullPass(`
|
||||
{
|
||||
let {f1} = wasmEvalText(`
|
||||
(module
|
||||
(elem declare $f1)
|
||||
(elem declare func $f1)
|
||||
(func $f1 (result funcref) ref.func $f1)
|
||||
(export "f1" (func $f1))
|
||||
)
|
||||
@ -31,7 +31,7 @@ wasmFullPass(`
|
||||
{
|
||||
let {f1, f2} = wasmEvalText(`
|
||||
(module
|
||||
(elem declare $f1)
|
||||
(elem declare func $f1)
|
||||
(func $f1)
|
||||
(func $f2 (result funcref) ref.func $f1)
|
||||
(export "f1" (func $f1))
|
||||
@ -45,7 +45,7 @@ wasmFullPass(`
|
||||
{
|
||||
let i1 = wasmEvalText(`
|
||||
(module
|
||||
(elem declare $f1)
|
||||
(elem declare func $f1)
|
||||
(func $f1)
|
||||
(export "f1" (func $f1))
|
||||
)
|
||||
@ -53,7 +53,7 @@ wasmFullPass(`
|
||||
let i2 = wasmEvalText(`
|
||||
(module
|
||||
(import "" "f1" (func $f1))
|
||||
(elem declare $f1)
|
||||
(elem declare func $f1)
|
||||
(func $f2 (result funcref) ref.func $f1)
|
||||
(export "f1" (func $f1))
|
||||
(export "f2" (func $f2))
|
||||
@ -91,7 +91,7 @@ assertErrorMessage(() => validFuncRefText('', 'funcref'), WebAssembly.CompileErr
|
||||
// referenced function can be forward declared via segments
|
||||
assertEq(validFuncRefText('(elem 0 (i32.const 0) func $referenced)', 'funcref') instanceof WebAssembly.Instance, true);
|
||||
assertEq(validFuncRefText('(elem func $referenced)', 'funcref') instanceof WebAssembly.Instance, true);
|
||||
assertEq(validFuncRefText('(elem declare $referenced)', 'funcref') instanceof WebAssembly.Instance, true);
|
||||
assertEq(validFuncRefText('(elem declare func $referenced)', 'funcref') instanceof WebAssembly.Instance, true);
|
||||
|
||||
// also when the segment is passive or active 'funcref'
|
||||
assertEq(validFuncRefText('(elem 0 (i32.const 0) funcref (ref.func $referenced))', 'funcref') instanceof WebAssembly.Instance, true);
|
||||
@ -125,7 +125,7 @@ assertErrorMessage(() => new WebAssembly.Module(
|
||||
var ins = new WebAssembly.Instance(new WebAssembly.Module(wasmTextToBinary(`
|
||||
(module
|
||||
(import "m" "f" (func $f (param i32) (result i32)))
|
||||
(elem declare $f)
|
||||
(elem declare func $f)
|
||||
(table 1 funcref)
|
||||
(func (export "f")
|
||||
(table.set 0 (i32.const 0) (ref.func $f))))`)),
|
||||
|
@ -413,7 +413,7 @@ assertErrorMessage(() => wasmEvalText(
|
||||
(func $f
|
||||
(table.copy 0 (i32.const 0) (i32.const 0) (i32.const 2))))`), // target without source
|
||||
SyntaxError,
|
||||
/unexpected token, expected an identifier or u32/);
|
||||
/unexpected token, expected an index or an identifier/);
|
||||
|
||||
// Make sure that dead code doesn't prevent compilation.
|
||||
wasmEvalText(
|
||||
|
@ -6,7 +6,7 @@ function wasmEvalText(str, imports) {
|
||||
}
|
||||
let { newElem, f1, f2, f3, f4 } = wasmEvalText(`
|
||||
(type $a (array funcref))
|
||||
(elem $e funcref $f1 $f2 $f3 $f4)
|
||||
(elem $e func $f1 $f2 $f3 $f4)
|
||||
(func $f1 )
|
||||
(func $f2 )
|
||||
(func $f3 )
|
||||
|
@ -20,4 +20,4 @@ mozilla-central-workspace-hack = { version = "0.1", features = ["jsrust"], optio
|
||||
jsrust_shared = { path = "./shared" }
|
||||
# Workaround for https://github.com/rust-lang/rust/issues/58393
|
||||
mozglue-static = { path = "../../../mozglue/static/rust" }
|
||||
wast = "60.0.0"
|
||||
wast = "62.0.0"
|
||||
|
@ -3950,12 +3950,24 @@ user-id = 3618 # David Tolnay (dtolnay)
|
||||
start = "2019-05-02"
|
||||
end = "2024-04-25"
|
||||
|
||||
[[trusted.equivalent]]
|
||||
criteria = "safe-to-deploy"
|
||||
user-id = 539 # Josh Stone (cuviper)
|
||||
start = "2023-02-05"
|
||||
end = "2024-07-17"
|
||||
|
||||
[[trusted.flate2]]
|
||||
criteria = "safe-to-deploy"
|
||||
user-id = 4333 # Josh Triplett (joshtriplett)
|
||||
start = "2020-09-30"
|
||||
end = "2024-05-05"
|
||||
|
||||
[[trusted.hashbrown]]
|
||||
criteria = "safe-to-deploy"
|
||||
user-id = 2915 # Amanieu d'Antras (Amanieu)
|
||||
start = "2019-04-02"
|
||||
end = "2024-07-17"
|
||||
|
||||
[[trusted.headers]]
|
||||
criteria = "safe-to-deploy"
|
||||
user-id = 359 # Sean McArthur (seanmonstar)
|
||||
|
@ -213,10 +213,6 @@ notes = "Upstream project which we pin."
|
||||
[policy.wr_malloc_size_of]
|
||||
audit-as-crates-io = false
|
||||
|
||||
[[exemptions.adler]]
|
||||
version = "1.0.2"
|
||||
criteria = "safe-to-deploy"
|
||||
|
||||
[[exemptions.ahash]]
|
||||
version = "0.7.6"
|
||||
criteria = "safe-to-deploy"
|
||||
@ -645,10 +641,6 @@ criteria = "safe-to-deploy"
|
||||
version = "0.10.0"
|
||||
criteria = "safe-to-deploy"
|
||||
|
||||
[[exemptions.pin-project-lite]]
|
||||
version = "0.2.9"
|
||||
criteria = "safe-to-deploy"
|
||||
|
||||
[[exemptions.plain]]
|
||||
version = "0.2.3"
|
||||
criteria = "safe-to-deploy"
|
||||
|
@ -226,8 +226,8 @@ user-login = "seanmonstar"
|
||||
user-name = "Sean McArthur"
|
||||
|
||||
[[publisher.indexmap]]
|
||||
version = "1.9.2"
|
||||
when = "2022-11-17"
|
||||
version = "1.9.3"
|
||||
when = "2023-03-24"
|
||||
user-id = 539
|
||||
user-login = "cuviper"
|
||||
user-name = "Josh Stone"
|
||||
@ -540,29 +540,29 @@ user-login = "alexcrichton"
|
||||
user-name = "Alex Crichton"
|
||||
|
||||
[[publisher.wasm-encoder]]
|
||||
version = "0.29.0"
|
||||
when = "2023-05-26"
|
||||
version = "0.31.0"
|
||||
when = "2023-07-17"
|
||||
user-id = 1
|
||||
user-login = "alexcrichton"
|
||||
user-name = "Alex Crichton"
|
||||
|
||||
[[publisher.wasm-smith]]
|
||||
version = "0.12.10"
|
||||
when = "2023-05-26"
|
||||
version = "0.12.12"
|
||||
when = "2023-07-17"
|
||||
user-id = 1
|
||||
user-login = "alexcrichton"
|
||||
user-name = "Alex Crichton"
|
||||
|
||||
[[publisher.wasmparser]]
|
||||
version = "0.107.0"
|
||||
when = "2023-05-26"
|
||||
version = "0.109.0"
|
||||
when = "2023-07-17"
|
||||
user-id = 1
|
||||
user-login = "alexcrichton"
|
||||
user-name = "Alex Crichton"
|
||||
|
||||
[[publisher.wast]]
|
||||
version = "60.0.0"
|
||||
when = "2023-05-26"
|
||||
version = "62.0.0"
|
||||
when = "2023-07-17"
|
||||
user-id = 1
|
||||
user-login = "alexcrichton"
|
||||
user-name = "Alex Crichton"
|
||||
@ -649,6 +649,12 @@ I am employed by a member of the Bytecode Alliance and plan to continue doing
|
||||
so and will actively maintain this crate over time.
|
||||
"""
|
||||
|
||||
[[audits.bytecode-alliance.audits.adler]]
|
||||
who = "Alex Crichton <alex@alexcrichton.com>"
|
||||
criteria = "safe-to-deploy"
|
||||
version = "1.0.2"
|
||||
notes = "This is a small crate which forbids unsafe code and is a straightforward implementation of the adler hashing algorithm."
|
||||
|
||||
[[audits.bytecode-alliance.audits.arrayref]]
|
||||
who = "Nick Fitzgerald <fitzgen@gmail.com>"
|
||||
criteria = "safe-to-deploy"
|
||||
@ -881,30 +887,6 @@ throughout the ecosystem and skimming the crate shows no usage of `std::*` APIs
|
||||
and nothing suspicious.
|
||||
"""
|
||||
|
||||
[[audits.bytecode-alliance.audits.wasm-encoder]]
|
||||
who = "Alex Crichton <alex@alexcrichton.com>"
|
||||
criteria = "safe-to-deploy"
|
||||
version = "0.25.0"
|
||||
notes = "The Bytecode Alliance is the author of this crate."
|
||||
|
||||
[[audits.bytecode-alliance.audits.wasm-smith]]
|
||||
who = "Alex Crichton <alex@alexcrichton.com>"
|
||||
criteria = "safe-to-run"
|
||||
version = "0.12.5"
|
||||
notes = "The Bytecode Alliance is the author of this crate."
|
||||
|
||||
[[audits.bytecode-alliance.audits.wasmparser]]
|
||||
who = "Alex Crichton <alex@alexcrichton.com>"
|
||||
criteria = "safe-to-deploy"
|
||||
version = "0.102.0"
|
||||
notes = "The Bytecode Alliance is the author of this crate."
|
||||
|
||||
[[audits.bytecode-alliance.audits.wast]]
|
||||
who = "Alex Crichton <alex@alexcrichton.com>"
|
||||
criteria = "safe-to-deploy"
|
||||
version = "55.0.0"
|
||||
notes = "The Bytecode Alliance is the author of this crate."
|
||||
|
||||
[[audits.embark-studios.audits.anyhow]]
|
||||
who = "Johan Andersson <opensource@embark-studios.com>"
|
||||
criteria = "safe-to-deploy"
|
||||
@ -1027,6 +1009,13 @@ criteria = "safe-to-run"
|
||||
version = "1.0.12"
|
||||
aggregated-from = "https://chromium.googlesource.com/chromiumos/third_party/rust_crates/+/refs/heads/main/cargo-vet/audits.toml?format=TEXT"
|
||||
|
||||
[[audits.google.audits.pin-project-lite]]
|
||||
who = "David Koloski <dkoloski@google.com>"
|
||||
criteria = "safe-to-deploy"
|
||||
version = "0.2.9"
|
||||
notes = "Reviewed on https://fxrev.dev/824504"
|
||||
aggregated-from = "https://fuchsia.googlesource.com/fuchsia/+/refs/heads/main/third_party/rust_crates/supply-chain/audits.toml?format=TEXT"
|
||||
|
||||
[[audits.google.audits.scoped-tls]]
|
||||
who = "George Burgess IV <gbiv@google.com>"
|
||||
criteria = "safe-to-run"
|
||||
|
@ -1 +1 @@
|
||||
{"files":{"Cargo.toml":"c77d3a8863367bbd5e9a6da5d8f100515da5e5a1441c293cbc09ffd947b7302b","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"ecc269ef87fd38a1d98e30bfac9ba964a9dbd9315c3770fed98d4d7cb5882055","README.md":"f8b02aa7c20fc0f5bc13de9e9e78899ec8cdbc16c2db880a1d0bc14c25b07542","RELEASES.md":"38d29c78198505ec88702c1ba723d087a775fcda6559da1842b6f17a9cdf6a71","benches/bench.rs":"3b2900abbc9e8a60af78b0395222ee75e86bc68519a0f38477387d1572eed397","benches/faststring.rs":"5fdd6cdb19d0557ed58f241e809a240cf8939d9e5b87a72d5f127f81ab98380b","build.rs":"558b4d0b9e9b3a44f7e1a2b69f7a7567ea721cd45cb54f4e458e850bf702f35c","src/arbitrary.rs":"bb8bda10f686abe57eef1446d3fc3fc6fb251f95629b28c20e620a4838c43db8","src/equivalent.rs":"2e6ae24ef09a09b917f4e2b0f6288f901878e42f5080f61b1bd1afdcc90aba87","src/lib.rs":"ea2cbe4f6cc2c4a75f42c9fc936503e6bee0f136c60f6811a2a9907ed8886443","src/macros.rs":"80c22f630e7f81e6fa663ca4c9e50cf5f332c8905d72d1338bd16f24eb353c2a","src/map.rs":"2e9cbfa240865cfd6b6b972bdbdb39283e6302dd2d0d72b3c2bfce4414bf5729","src/map/core.rs":"8422cd774c5db7d83cdeb0c5836c10f29caa1bee8d95b0d674b01b32e7ce80d8","src/map/core/raw.rs":"4e5fac4fecccc352268351d8b1f82b345067b5c029bba7e6ab88e8f8bc799c6a","src/mutable_keys.rs":"a919065b59000286eb11c7d46f6896bf0a1d484c9dac5e61d80bb8990c9fbedb","src/rayon/map.rs":"1a508c7c95c5d56113b851f7ce140d62ad541f1c6129352a7ec62d5bea7af4a1","src/rayon/mod.rs":"019e9379ccab57a299ab5b5a2c0efc7561b77a715a5afe8f797c7e8330c6206c","src/rayon/set.rs":"ba00e88e90fb7ab803589f99f24b595d60309e541aae3d01fdde21bff3840194","src/rustc.rs":"fe7a348c5a10a66880cb6c737593fe79d3b6de40f44ba0d7b89204aa95e14a3a","src/serde.rs":"d45ec8fb9c02594ca6f2e9b20764778b2b4193a24a52f1e233160a33efc6e683","src/serde_seq.rs":"c54a52fa607b6ccddda1e76e829778ca304c49b5f434edc5e582a5386c35d662","src/set.rs":"0a57affb623fa6b28df18cc14841e4f076cbd1da5c809635d202f865640af1ee","src/util.rs":"ab712bce71b54cf2763e6010e64bb5944d1d59ce15e2f2beffa7ceed204d6a68","tests/equivalent_trait.rs":"efe9393069e3cfc893d2c9c0343679979578e437fdb98a10baefeced027ba310","tests/macros_full_path.rs":"c33c86d7341581fdd08e2e6375a4afca507fa603540c54a3b9e51c4cd011cd71","tests/quick.rs":"1addbc6cbcb1aae5b8bde0fb0e18197d947e8f13244e4ae7ebf97bdda00eafea","tests/tests.rs":"f6dbeeb0e2950402b0e66ac52bf74c9e4197d3c5d9c0dde64a7998a2ef74d327"},"package":"1885e79c1fc4b10f0e172c475f458b7f7b93061064d98c3293e98c5ba0c8b399"}
|
||||
{"files":{"Cargo.toml":"1290d383adfdcd24f158a4619afb5547d633c83c0a1ab3b5c1ee0dabe4fb1f36","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"ecc269ef87fd38a1d98e30bfac9ba964a9dbd9315c3770fed98d4d7cb5882055","README.md":"f8b02aa7c20fc0f5bc13de9e9e78899ec8cdbc16c2db880a1d0bc14c25b07542","RELEASES.md":"85d9d9bc78e94df7ce90300bb94099b9ab2696d1b3f6b815c22761522878e679","benches/bench.rs":"3b2900abbc9e8a60af78b0395222ee75e86bc68519a0f38477387d1572eed397","benches/faststring.rs":"5fdd6cdb19d0557ed58f241e809a240cf8939d9e5b87a72d5f127f81ab98380b","build.rs":"558b4d0b9e9b3a44f7e1a2b69f7a7567ea721cd45cb54f4e458e850bf702f35c","src/arbitrary.rs":"bb8bda10f686abe57eef1446d3fc3fc6fb251f95629b28c20e620a4838c43db8","src/equivalent.rs":"2e6ae24ef09a09b917f4e2b0f6288f901878e42f5080f61b1bd1afdcc90aba87","src/lib.rs":"ea2cbe4f6cc2c4a75f42c9fc936503e6bee0f136c60f6811a2a9907ed8886443","src/macros.rs":"80c22f630e7f81e6fa663ca4c9e50cf5f332c8905d72d1338bd16f24eb353c2a","src/map.rs":"2e9cbfa240865cfd6b6b972bdbdb39283e6302dd2d0d72b3c2bfce4414bf5729","src/map/core.rs":"8422cd774c5db7d83cdeb0c5836c10f29caa1bee8d95b0d674b01b32e7ce80d8","src/map/core/raw.rs":"4e5fac4fecccc352268351d8b1f82b345067b5c029bba7e6ab88e8f8bc799c6a","src/mutable_keys.rs":"a919065b59000286eb11c7d46f6896bf0a1d484c9dac5e61d80bb8990c9fbedb","src/rayon/map.rs":"1a508c7c95c5d56113b851f7ce140d62ad541f1c6129352a7ec62d5bea7af4a1","src/rayon/mod.rs":"019e9379ccab57a299ab5b5a2c0efc7561b77a715a5afe8f797c7e8330c6206c","src/rayon/set.rs":"ba00e88e90fb7ab803589f99f24b595d60309e541aae3d01fdde21bff3840194","src/rustc.rs":"fe7a348c5a10a66880cb6c737593fe79d3b6de40f44ba0d7b89204aa95e14a3a","src/serde.rs":"d45ec8fb9c02594ca6f2e9b20764778b2b4193a24a52f1e233160a33efc6e683","src/serde_seq.rs":"c54a52fa607b6ccddda1e76e829778ca304c49b5f434edc5e582a5386c35d662","src/set.rs":"0a57affb623fa6b28df18cc14841e4f076cbd1da5c809635d202f865640af1ee","src/util.rs":"ab712bce71b54cf2763e6010e64bb5944d1d59ce15e2f2beffa7ceed204d6a68","tests/equivalent_trait.rs":"efe9393069e3cfc893d2c9c0343679979578e437fdb98a10baefeced027ba310","tests/macros_full_path.rs":"c33c86d7341581fdd08e2e6375a4afca507fa603540c54a3b9e51c4cd011cd71","tests/quick.rs":"1addbc6cbcb1aae5b8bde0fb0e18197d947e8f13244e4ae7ebf97bdda00eafea","tests/tests.rs":"f6dbeeb0e2950402b0e66ac52bf74c9e4197d3c5d9c0dde64a7998a2ef74d327"},"package":"bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99"}
|
5
third_party/rust/indexmap/Cargo.toml
vendored
5
third_party/rust/indexmap/Cargo.toml
vendored
@ -13,7 +13,7 @@
|
||||
edition = "2021"
|
||||
rust-version = "1.56"
|
||||
name = "indexmap"
|
||||
version = "1.9.2"
|
||||
version = "1.9.3"
|
||||
description = "A hash table with consistent order and fast iteration."
|
||||
documentation = "https://docs.rs/indexmap/"
|
||||
readme = "README.md"
|
||||
@ -66,8 +66,9 @@ version = "1.4.1"
|
||||
optional = true
|
||||
|
||||
[dependencies.rustc-rayon]
|
||||
version = "0.4"
|
||||
version = "0.5"
|
||||
optional = true
|
||||
package = "rustc-rayon"
|
||||
|
||||
[dependencies.serde]
|
||||
version = "1.0"
|
||||
|
4
third_party/rust/indexmap/RELEASES.md
vendored
4
third_party/rust/indexmap/RELEASES.md
vendored
@ -1,3 +1,7 @@
|
||||
- 1.9.3
|
||||
|
||||
- Bump the `rustc-rayon` dependency, for compiler use only.
|
||||
|
||||
- 1.9.2
|
||||
|
||||
- `IndexMap` and `IndexSet` both implement `arbitrary::Arbitrary<'_>` and
|
||||
|
@ -1 +1 @@
|
||||
{"files":{"Cargo.toml":"017a8c6533b5524a7cc9c9c4f67c64fac705139e6690f792db35aa53a4060b3e","LICENSE":"268872b9816f90fd8e85db5a28d33f8150ebb8dd016653fb39ef1f94f2686bc5","README.md":"ac016c4843a7e1a5737255b39418732783592222dc518020730edf9dd46a1c13","src/component.rs":"469b853ac8bd9b034bc701f9fdf3da9c4c944b8a08438de1608d5d5d63e4765b","src/component/aliases.rs":"be5215154b872ed5664f3bfe2aa1391f36a2575aa9d53971ab61868a1c446e9d","src/component/canonicals.rs":"9ab83dc38f01be083e4f4b391214232d5527eb81f6adb459c0719da9c8c7e168","src/component/components.rs":"07b8cae3a400e1955cc39d142569910b4fef2136021053d0ddbd6404d810aa52","src/component/exports.rs":"25582534c0dec431c767c0e7f6cfb389cb597c24c8a80b72e81f08e25f13dadb","src/component/imports.rs":"c824ffeba530fe142655d3143b1c86e172485d46f05ea1c45fdb9f31ad22f00e","src/component/instances.rs":"4238b7cd93e987cbc3a7b57a397f82faea4cbc4b884cabb915f8f16ec9b02e20","src/component/modules.rs":"9e80907e72360fae4d8057b6b0e7a6b58edd7ba6aba6e63ba17346518e169617","src/component/names.rs":"f3b6691f822d53eb743b397a4e735786501cf000451753ae9a65031ae3249835","src/component/start.rs":"4055553d5c99c99abbc01bb8abb928ecb8b909d148b647a9977fbd444bb464a3","src/component/types.rs":"3d714f89e94293d285ad9347cc649788cdf45e4816f9ea9b91c5fb87084dbf44","src/core.rs":"a00656f82a623656c59a2d7230b40a5849a5083e117bc57061746f6e3022c7bb","src/core/code.rs":"ee841eab282781257f6d22f70d2061ffc106b93a0615aedd00f2b8d8feea0b50","src/core/custom.rs":"6883b79152f38ab902fa52a647098bcc64821ef3bc7b0f1cc9911e702b4f2856","src/core/data.rs":"c9d59eab2ab811bd950da52e6766c7df2367986c7a3a0d94d7aeb47d86f203ac","src/core/dump.rs":"8feaa532e3851186277ec1f4906e7fdc82c6399b211b8c928b16e293db1205b0","src/core/elements.rs":"35e64746d1924f37a101969e289fe0049d967c9b5452516d78ced4e1a7858b4d","src/core/exports.rs":"f37351587cd0cfa7608f94e0fcbfa09d41c7df1d123c47825992c364d5d9ff11","src/core/functions.rs":"c18b9872ac0c21048a3ce32e5e44e8e702f97a57fa1b3a07bdd98c7f6c820f09","src/core/globals.rs":"560d8e8c818d968cd8a101ab3c639f723b1c754716aa1178d1c4570efd84d010","src/core/imports.rs":"782bbc2e70b379831f85716c0f50c0221d1487c8cba26e8845028b2ae1962c0c","src/core/linking.rs":"2f1053d9c2671e91a2b6e253dd38921bfc5f1b8a1a047b10c843033fe0f492de","src/core/memories.rs":"840d15fcd9bd4a668298491c6a91455b145c5c7ff1adf8c769aaf49d6c664d3a","src/core/names.rs":"80e93b756cdd1234cd088f98be8dd720fadede755ed5b884e6adacd7ef050072","src/core/producers.rs":"f4916c1cf61e26170cd10fe350de7dad18005461c362909b9557c16c507517bc","src/core/start.rs":"a01d4a91bcd93048977ccafc6af160357297450395bf598351f5a3e6d322e0de","src/core/tables.rs":"d5ae8c92c8707332eda6be6e5649f2f8042a1c6242494b0174cbee5e1971cace","src/core/tags.rs":"26d58904871d92f395eed67d4c25f0914b337d213bab2288011abe3ad31fa12b","src/core/types.rs":"3d7cbd703608aa8a49116685ab41d4f505507bb53dfaadaf41620be12dea582b","src/lib.rs":"e61325ab8de1b4c404f4ee7665eef404fca2d23322a9c8f94efec8426edc166b","src/raw.rs":"a6a72cfe8f88ea6476eccee4acf362030ba2d2e5710215bc4f13cde7de6d71ae"},"package":"18c41dbd92eaebf3612a39be316540b8377c871cb9bde6b064af962984912881"}
|
||||
{"files":{"Cargo.toml":"e50a4bb80d433cfa63a3e78b342afe04640eb400c686b2f48bfacc680f76ba71","LICENSE":"268872b9816f90fd8e85db5a28d33f8150ebb8dd016653fb39ef1f94f2686bc5","README.md":"ac016c4843a7e1a5737255b39418732783592222dc518020730edf9dd46a1c13","src/component.rs":"222dd5da8d78696ebde282dacbf08a12a439f5f376d09870a2d4c1390ee99bf3","src/component/aliases.rs":"be5215154b872ed5664f3bfe2aa1391f36a2575aa9d53971ab61868a1c446e9d","src/component/canonicals.rs":"a4f9c7a2b8ac3783d7337a5579cf71df2f33b315b354965980bd2c483d3aa141","src/component/components.rs":"07b8cae3a400e1955cc39d142569910b4fef2136021053d0ddbd6404d810aa52","src/component/exports.rs":"25582534c0dec431c767c0e7f6cfb389cb597c24c8a80b72e81f08e25f13dadb","src/component/imports.rs":"c824ffeba530fe142655d3143b1c86e172485d46f05ea1c45fdb9f31ad22f00e","src/component/instances.rs":"4238b7cd93e987cbc3a7b57a397f82faea4cbc4b884cabb915f8f16ec9b02e20","src/component/modules.rs":"9e80907e72360fae4d8057b6b0e7a6b58edd7ba6aba6e63ba17346518e169617","src/component/names.rs":"f3b6691f822d53eb743b397a4e735786501cf000451753ae9a65031ae3249835","src/component/start.rs":"4055553d5c99c99abbc01bb8abb928ecb8b909d148b647a9977fbd444bb464a3","src/component/types.rs":"cbc7a3dc0f3e23024cc82edfc9b8a3f49111faa44ef89fb06ca08c10794211e3","src/core.rs":"a00656f82a623656c59a2d7230b40a5849a5083e117bc57061746f6e3022c7bb","src/core/code.rs":"ee841eab282781257f6d22f70d2061ffc106b93a0615aedd00f2b8d8feea0b50","src/core/custom.rs":"4b9f07b701dc7b6990d92fb43016c28fb971411670bb6a48553b92b1c35eb9a3","src/core/data.rs":"c9d59eab2ab811bd950da52e6766c7df2367986c7a3a0d94d7aeb47d86f203ac","src/core/dump.rs":"8feaa532e3851186277ec1f4906e7fdc82c6399b211b8c928b16e293db1205b0","src/core/elements.rs":"2df1ad85f683b5cf3ce43c8cfef3f08f74a17cec9171537e3f24205dc067b4f7","src/core/exports.rs":"f37351587cd0cfa7608f94e0fcbfa09d41c7df1d123c47825992c364d5d9ff11","src/core/functions.rs":"c18b9872ac0c21048a3ce32e5e44e8e702f97a57fa1b3a07bdd98c7f6c820f09","src/core/globals.rs":"560d8e8c818d968cd8a101ab3c639f723b1c754716aa1178d1c4570efd84d010","src/core/imports.rs":"782bbc2e70b379831f85716c0f50c0221d1487c8cba26e8845028b2ae1962c0c","src/core/linking.rs":"2f1053d9c2671e91a2b6e253dd38921bfc5f1b8a1a047b10c843033fe0f492de","src/core/memories.rs":"840d15fcd9bd4a668298491c6a91455b145c5c7ff1adf8c769aaf49d6c664d3a","src/core/names.rs":"80e93b756cdd1234cd088f98be8dd720fadede755ed5b884e6adacd7ef050072","src/core/producers.rs":"f4916c1cf61e26170cd10fe350de7dad18005461c362909b9557c16c507517bc","src/core/start.rs":"a01d4a91bcd93048977ccafc6af160357297450395bf598351f5a3e6d322e0de","src/core/tables.rs":"d5ae8c92c8707332eda6be6e5649f2f8042a1c6242494b0174cbee5e1971cace","src/core/tags.rs":"26d58904871d92f395eed67d4c25f0914b337d213bab2288011abe3ad31fa12b","src/core/types.rs":"507a100b4d30016aa7f718fd9bd1011e13a836f2d27974f66d50e9a9cbc41515","src/lib.rs":"e61325ab8de1b4c404f4ee7665eef404fca2d23322a9c8f94efec8426edc166b","src/raw.rs":"a6a72cfe8f88ea6476eccee4acf362030ba2d2e5710215bc4f13cde7de6d71ae"},"package":"06a3d1b4a575ffb873679402b2aedb3117555eb65c27b1b86c8a91e574bc2a2a"}
|
2
third_party/rust/wasm-encoder/Cargo.toml
vendored
2
third_party/rust/wasm-encoder/Cargo.toml
vendored
@ -12,7 +12,7 @@
|
||||
[package]
|
||||
edition = "2021"
|
||||
name = "wasm-encoder"
|
||||
version = "0.29.0"
|
||||
version = "0.31.0"
|
||||
authors = ["Nick Fitzgerald <fitzgen@gmail.com>"]
|
||||
description = """
|
||||
A low-level WebAssembly encoder.
|
||||
|
@ -20,7 +20,7 @@ pub use self::names::*;
|
||||
pub use self::start::*;
|
||||
pub use self::types::*;
|
||||
|
||||
use crate::{CustomSection, Encode, ProducersSection};
|
||||
use crate::{CustomSection, Encode, ProducersSection, RawCustomSection};
|
||||
|
||||
// Core sorts extended by the component model
|
||||
const CORE_TYPE_SORT: u8 = 0x10;
|
||||
@ -153,6 +153,12 @@ impl ComponentSection for CustomSection<'_> {
|
||||
}
|
||||
}
|
||||
|
||||
impl ComponentSection for RawCustomSection<'_> {
|
||||
fn id(&self) -> u8 {
|
||||
ComponentSectionId::CoreCustom.into()
|
||||
}
|
||||
}
|
||||
|
||||
impl ComponentSection for ProducersSection {
|
||||
fn id(&self) -> u8 {
|
||||
ComponentSectionId::CoreCustom.into()
|
||||
|
@ -1,4 +1,4 @@
|
||||
use crate::{encode_section, ComponentSection, ComponentSectionId, ComponentValType, Encode};
|
||||
use crate::{encode_section, ComponentSection, ComponentSectionId, Encode};
|
||||
|
||||
/// Represents options for canonical function definitions.
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
@ -129,9 +129,9 @@ impl CanonicalFunctionSection {
|
||||
}
|
||||
|
||||
/// Defines a function which will drop the specified type of handle.
|
||||
pub fn resource_drop(&mut self, ty: ComponentValType) -> &mut Self {
|
||||
pub fn resource_drop(&mut self, ty_index: u32) -> &mut Self {
|
||||
self.bytes.push(0x03);
|
||||
ty.encode(&mut self.bytes);
|
||||
ty_index.encode(&mut self.bytes);
|
||||
self.num_added += 1;
|
||||
self
|
||||
}
|
||||
|
@ -744,6 +744,12 @@ impl ComponentTypeSection {
|
||||
pub fn defined_type(&mut self) -> ComponentDefinedTypeEncoder<'_> {
|
||||
self.ty().defined_type()
|
||||
}
|
||||
|
||||
/// Defines a new resource type.
|
||||
pub fn resource(&mut self, rep: ValType, dtor: Option<u32>) -> &mut Self {
|
||||
self.ty().resource(rep, dtor);
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl Encode for ComponentTypeSection {
|
||||
|
18
third_party/rust/wasm-encoder/src/core/custom.rs
vendored
18
third_party/rust/wasm-encoder/src/core/custom.rs
vendored
@ -26,6 +26,24 @@ impl Section for CustomSection<'_> {
|
||||
}
|
||||
}
|
||||
|
||||
/// A raw custom section where the bytes specified contain the leb-encoded
|
||||
/// length of the custom section, the custom section's name, and the custom
|
||||
/// section's data.
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct RawCustomSection<'a>(pub &'a [u8]);
|
||||
|
||||
impl Encode for RawCustomSection<'_> {
|
||||
fn encode(&self, sink: &mut Vec<u8>) {
|
||||
sink.extend(self.0);
|
||||
}
|
||||
}
|
||||
|
||||
impl Section for RawCustomSection<'_> {
|
||||
fn id(&self) -> u8 {
|
||||
SectionId::Custom.into()
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
@ -22,11 +22,10 @@ use crate::{encode_section, ConstExpr, Encode, RefType, Section, SectionId};
|
||||
/// let mut elements = ElementSection::new();
|
||||
/// let table_index = 0;
|
||||
/// let offset = ConstExpr::i32_const(42);
|
||||
/// let element_type = RefType::FUNCREF;
|
||||
/// let functions = Elements::Functions(&[
|
||||
/// // Function indices...
|
||||
/// ]);
|
||||
/// elements.active(Some(table_index), &offset, element_type, functions);
|
||||
/// elements.active(Some(table_index), &offset, functions);
|
||||
///
|
||||
/// let mut module = Module::new();
|
||||
/// module
|
||||
@ -47,7 +46,7 @@ pub enum Elements<'a> {
|
||||
/// A sequences of references to functions by their indices.
|
||||
Functions(&'a [u32]),
|
||||
/// A sequence of reference expressions.
|
||||
Expressions(&'a [ConstExpr]),
|
||||
Expressions(RefType, &'a [ConstExpr]),
|
||||
}
|
||||
|
||||
/// An element segment's mode.
|
||||
@ -79,8 +78,6 @@ pub enum ElementMode<'a> {
|
||||
pub struct ElementSegment<'a> {
|
||||
/// The element segment's mode.
|
||||
pub mode: ElementMode<'a>,
|
||||
/// The element segment's type.
|
||||
pub element_type: RefType,
|
||||
/// This segment's elements.
|
||||
pub elements: Elements<'a>,
|
||||
}
|
||||
@ -104,50 +101,53 @@ impl ElementSection {
|
||||
/// Define an element segment.
|
||||
pub fn segment<'a>(&mut self, segment: ElementSegment<'a>) -> &mut Self {
|
||||
let expr_bit = match segment.elements {
|
||||
Elements::Expressions(_) => 0b100u32,
|
||||
Elements::Expressions(..) => 0b100u32,
|
||||
Elements::Functions(_) => 0b000u32,
|
||||
};
|
||||
let mut encode_type = false;
|
||||
match &segment.mode {
|
||||
ElementMode::Active {
|
||||
table: None,
|
||||
offset,
|
||||
} if segment.element_type == RefType::FUNCREF => {
|
||||
(/* 0x00 | */expr_bit).encode(&mut self.bytes);
|
||||
offset.encode(&mut self.bytes);
|
||||
}
|
||||
ElementMode::Passive => {
|
||||
(0x01 | expr_bit).encode(&mut self.bytes);
|
||||
if expr_bit == 0 {
|
||||
self.bytes.push(0x00); // elemkind == funcref
|
||||
} else {
|
||||
segment.element_type.encode(&mut self.bytes);
|
||||
}
|
||||
encode_type = true;
|
||||
}
|
||||
ElementMode::Active { table, offset } => {
|
||||
(0x02 | expr_bit).encode(&mut self.bytes);
|
||||
table.unwrap_or(0).encode(&mut self.bytes);
|
||||
offset.encode(&mut self.bytes);
|
||||
if expr_bit == 0 {
|
||||
self.bytes.push(0x00); // elemkind == funcref
|
||||
} else {
|
||||
segment.element_type.encode(&mut self.bytes);
|
||||
match (table, &segment.elements) {
|
||||
// If the `table` is not specified then the 0x00 encoding
|
||||
// can be used with either function indices or expressions
|
||||
// that have a `funcref` type.
|
||||
(None, Elements::Functions(_) | Elements::Expressions(RefType::FUNCREF, _)) => {
|
||||
(/* 0x00 | */expr_bit).encode(&mut self.bytes);
|
||||
}
|
||||
|
||||
// ... otherwise fall through for all other expressions here
|
||||
// with table 0 or an explicitly specified table to the 0x02
|
||||
// encoding.
|
||||
(None, Elements::Expressions(..)) | (Some(_), _) => {
|
||||
(0x02 | expr_bit).encode(&mut self.bytes);
|
||||
table.unwrap_or(0).encode(&mut self.bytes);
|
||||
encode_type = true;
|
||||
}
|
||||
}
|
||||
offset.encode(&mut self.bytes);
|
||||
}
|
||||
ElementMode::Declared => {
|
||||
(0x03 | expr_bit).encode(&mut self.bytes);
|
||||
if expr_bit == 0 {
|
||||
self.bytes.push(0x00); // elemkind == funcref
|
||||
} else {
|
||||
segment.element_type.encode(&mut self.bytes);
|
||||
}
|
||||
encode_type = true;
|
||||
}
|
||||
}
|
||||
|
||||
match segment.elements {
|
||||
Elements::Functions(fs) => {
|
||||
if encode_type {
|
||||
// elemkind == funcref
|
||||
self.bytes.push(0x00);
|
||||
}
|
||||
fs.encode(&mut self.bytes);
|
||||
}
|
||||
Elements::Expressions(e) => {
|
||||
Elements::Expressions(ty, e) => {
|
||||
if encode_type {
|
||||
ty.encode(&mut self.bytes);
|
||||
}
|
||||
e.len().encode(&mut self.bytes);
|
||||
for expr in e {
|
||||
expr.encode(&mut self.bytes);
|
||||
@ -168,7 +168,6 @@ impl ElementSection {
|
||||
&mut self,
|
||||
table_index: Option<u32>,
|
||||
offset: &ConstExpr,
|
||||
element_type: RefType,
|
||||
elements: Elements<'_>,
|
||||
) -> &mut Self {
|
||||
self.segment(ElementSegment {
|
||||
@ -176,7 +175,6 @@ impl ElementSection {
|
||||
table: table_index,
|
||||
offset,
|
||||
},
|
||||
element_type,
|
||||
elements,
|
||||
})
|
||||
}
|
||||
@ -184,10 +182,9 @@ impl ElementSection {
|
||||
/// Encode a passive element segment.
|
||||
///
|
||||
/// Passive segments are part of the bulk memory proposal.
|
||||
pub fn passive<'a>(&mut self, element_type: RefType, elements: Elements<'a>) -> &mut Self {
|
||||
pub fn passive<'a>(&mut self, elements: Elements<'a>) -> &mut Self {
|
||||
self.segment(ElementSegment {
|
||||
mode: ElementMode::Passive,
|
||||
element_type,
|
||||
elements,
|
||||
})
|
||||
}
|
||||
@ -195,10 +192,9 @@ impl ElementSection {
|
||||
/// Encode a declared element segment.
|
||||
///
|
||||
/// Declared segments are part of the bulk memory proposal.
|
||||
pub fn declared<'a>(&mut self, element_type: RefType, elements: Elements<'a>) -> &mut Self {
|
||||
pub fn declared<'a>(&mut self, elements: Elements<'a>) -> &mut Self {
|
||||
self.segment(ElementSegment {
|
||||
mode: ElementMode::Declared,
|
||||
element_type,
|
||||
elements,
|
||||
})
|
||||
}
|
||||
|
130
third_party/rust/wasm-encoder/src/core/types.rs
vendored
130
third_party/rust/wasm-encoder/src/core/types.rs
vendored
@ -1,6 +1,57 @@
|
||||
use crate::{encode_section, Encode, Section, SectionId};
|
||||
|
||||
/// Array or struct field type.
|
||||
/// Represents a subtype of possible other types in a WebAssembly module.
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct SubType {
|
||||
/// Is the subtype final.
|
||||
pub is_final: bool,
|
||||
/// The list of supertype indexes. As of GC MVP, there can be at most one supertype.
|
||||
pub supertype_idx: Option<u32>,
|
||||
/// The structural type of the subtype.
|
||||
pub structural_type: StructuralType,
|
||||
}
|
||||
|
||||
/// Represents a structural type in a WebAssembly module.
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum StructuralType {
|
||||
/// The type is for a function.
|
||||
Func(FuncType),
|
||||
/// The type is for an array.
|
||||
Array(ArrayType),
|
||||
/// The type is for a struct.
|
||||
Struct(StructType),
|
||||
}
|
||||
|
||||
/// Represents a type of a function in a WebAssembly module.
|
||||
#[derive(Debug, Clone, Eq, PartialEq, Hash)]
|
||||
pub struct FuncType {
|
||||
/// The combined parameters and result types.
|
||||
params_results: Box<[ValType]>,
|
||||
/// The number of parameter types.
|
||||
len_params: usize,
|
||||
}
|
||||
|
||||
/// Represents a type of an array in a WebAssembly module.
|
||||
#[derive(Debug, Clone, Eq, PartialEq, Hash)]
|
||||
pub struct ArrayType(pub FieldType);
|
||||
|
||||
/// Represents a type of a struct in a WebAssembly module.
|
||||
#[derive(Debug, Clone, Eq, PartialEq, Hash)]
|
||||
pub struct StructType {
|
||||
/// Struct fields.
|
||||
pub fields: Box<[FieldType]>,
|
||||
}
|
||||
|
||||
/// Field type in structural types (structs, arrays).
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Ord, PartialOrd)]
|
||||
pub struct FieldType {
|
||||
/// Storage type of the field.
|
||||
pub element_type: StorageType,
|
||||
/// Is the field mutable.
|
||||
pub mutable: bool,
|
||||
}
|
||||
|
||||
/// Storage type for structural type fields.
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Ord, PartialOrd)]
|
||||
pub enum StorageType {
|
||||
/// The `i8` type.
|
||||
@ -34,6 +85,35 @@ pub enum ValType {
|
||||
Ref(RefType),
|
||||
}
|
||||
|
||||
impl FuncType {
|
||||
/// Creates a new [`FuncType`] from the given `params` and `results`.
|
||||
pub fn new<P, R>(params: P, results: R) -> Self
|
||||
where
|
||||
P: IntoIterator<Item = ValType>,
|
||||
R: IntoIterator<Item = ValType>,
|
||||
{
|
||||
let mut buffer = params.into_iter().collect::<Vec<_>>();
|
||||
let len_params = buffer.len();
|
||||
buffer.extend(results);
|
||||
Self {
|
||||
params_results: buffer.into(),
|
||||
len_params,
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns a shared slice to the parameter types of the [`FuncType`].
|
||||
#[inline]
|
||||
pub fn params(&self) -> &[ValType] {
|
||||
&self.params_results[..self.len_params]
|
||||
}
|
||||
|
||||
/// Returns a shared slice to the result types of the [`FuncType`].
|
||||
#[inline]
|
||||
pub fn results(&self) -> &[ValType] {
|
||||
&self.params_results[self.len_params..]
|
||||
}
|
||||
}
|
||||
|
||||
impl ValType {
|
||||
/// Alias for the `funcref` type in WebAssembly
|
||||
pub const FUNCREF: ValType = ValType::Ref(RefType::FUNCREF);
|
||||
@ -224,13 +304,59 @@ impl TypeSection {
|
||||
}
|
||||
|
||||
/// Define an array type in this type section.
|
||||
pub fn array(&mut self, ty: StorageType, mutable: bool) -> &mut Self {
|
||||
pub fn array(&mut self, ty: &StorageType, mutable: bool) -> &mut Self {
|
||||
self.bytes.push(0x5e);
|
||||
self.field(ty, mutable);
|
||||
self.num_added += 1;
|
||||
self
|
||||
}
|
||||
|
||||
fn field(&mut self, ty: &StorageType, mutable: bool) -> &mut Self {
|
||||
ty.encode(&mut self.bytes);
|
||||
self.bytes.push(mutable as u8);
|
||||
self
|
||||
}
|
||||
|
||||
/// Define a struct type in this type section.
|
||||
pub fn struct_(&mut self, fields: Vec<FieldType>) -> &mut Self {
|
||||
self.bytes.push(0x5f);
|
||||
fields.len().encode(&mut self.bytes);
|
||||
for f in fields.iter() {
|
||||
self.field(&f.element_type, f.mutable);
|
||||
}
|
||||
self.num_added += 1;
|
||||
self
|
||||
}
|
||||
|
||||
/// Define an explicit subtype in this type section.
|
||||
pub fn subtype(&mut self, ty: &SubType) -> &mut Self {
|
||||
// In the GC spec, supertypes is a vector, not an option.
|
||||
let st = match ty.supertype_idx {
|
||||
Some(idx) => vec![idx],
|
||||
None => vec![],
|
||||
};
|
||||
if ty.is_final {
|
||||
self.bytes.push(0x4e);
|
||||
st.encode(&mut self.bytes);
|
||||
} else if !st.is_empty() {
|
||||
self.bytes.push(0x50);
|
||||
st.encode(&mut self.bytes);
|
||||
}
|
||||
|
||||
match &ty.structural_type {
|
||||
StructuralType::Func(ty) => {
|
||||
self.function(ty.params().iter().copied(), ty.results().iter().copied());
|
||||
}
|
||||
StructuralType::Array(ArrayType(ty)) => {
|
||||
self.array(&ty.element_type, ty.mutable);
|
||||
}
|
||||
StructuralType::Struct(ty) => {
|
||||
self.struct_(ty.fields.to_vec());
|
||||
}
|
||||
}
|
||||
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl Encode for TypeSection {
|
||||
|
@ -1 +1 @@
|
||||
{"files":{"Cargo.toml":"f896f021b268aca35dc7d09e988612fc7651c586e38a9b074f3532674eb4e341","LICENSE":"268872b9816f90fd8e85db5a28d33f8150ebb8dd016653fb39ef1f94f2686bc5","README.md":"9202d01e78acf04e38e23e162a91c20ece8968f6172c87bfa6f18bf0b3f27d74","benches/corpus.rs":"2df29556be0799f0cb1f32c8d0ae5ba0c4b9815cf4d59a8b71744d926c0693a0","src/component.rs":"f11ed5adb46a746d875c15a7152e44e5ea1ba6bd270e160ce3b854e50d6ffc18","src/component/encode.rs":"b8625f9daa3eab0f405e6c4361b076e5ff7f2ebeb8beb6b7c22af35b8aadbf47","src/config.rs":"009364da9fb55ebe2625e2fa9a9fdc9033952f40304e353582e7bb22b10da4bf","src/core.rs":"cb38f2771d495f3af7d83e52750270bf781b49238821fb4a9e663d65fc8e35a5","src/core/code_builder.rs":"60e407a758ff58aafdcf4eb4e9141aca2ab7c7fe09d6644bc6e31043f88d0d69","src/core/code_builder/no_traps.rs":"e595dbde06551f5f8b23e03cfac0634beacab08e6243c66d6ffda95079212b24","src/core/encode.rs":"b4cc82895e3c3afe26e2e62bbdd63c44e7c1f091133e49f0eaf7e7ec22400e40","src/core/terminate.rs":"d24af5206a13aee7d6a6ea900ccdf088c09d053c36026cf1607cc38c972b3ba9","src/lib.rs":"07641b625f69b57e6e3275a6bdeb015fe68e5e1582cfd21c33395294caf0a84b","tests/component.rs":"44684e990e832590a0b348ce33fadf39ee55dec52fdfa9353570edcbf65325ee","tests/core.rs":"eafed78cccad968e64283505bb6d8ce905af5e1cabed3bd36abeba6eec2a0a9b"},"package":"027ec1c470cd5d56c43b8e02040250b136ddb5975dd76a1c16915137f5f17e76"}
|
||||
{"files":{"Cargo.toml":"8588d7b930072bf0ac18ec62cd296f0eca3f8dab2c4cf261c14f6ac597e19236","LICENSE":"268872b9816f90fd8e85db5a28d33f8150ebb8dd016653fb39ef1f94f2686bc5","README.md":"9202d01e78acf04e38e23e162a91c20ece8968f6172c87bfa6f18bf0b3f27d74","benches/corpus.rs":"2df29556be0799f0cb1f32c8d0ae5ba0c4b9815cf4d59a8b71744d926c0693a0","src/component.rs":"f11ed5adb46a746d875c15a7152e44e5ea1ba6bd270e160ce3b854e50d6ffc18","src/component/encode.rs":"b8625f9daa3eab0f405e6c4361b076e5ff7f2ebeb8beb6b7c22af35b8aadbf47","src/config.rs":"009364da9fb55ebe2625e2fa9a9fdc9033952f40304e353582e7bb22b10da4bf","src/core.rs":"d3717407f0982a2c1e20856874d347d3a2824b84bf0c5885d883a5e5cf165b5c","src/core/code_builder.rs":"60e407a758ff58aafdcf4eb4e9141aca2ab7c7fe09d6644bc6e31043f88d0d69","src/core/code_builder/no_traps.rs":"e595dbde06551f5f8b23e03cfac0634beacab08e6243c66d6ffda95079212b24","src/core/encode.rs":"1c3a76cb46511bfe91e01e5cd430fa145593f7986ff4f0041c854759b391d153","src/core/terminate.rs":"d24af5206a13aee7d6a6ea900ccdf088c09d053c36026cf1607cc38c972b3ba9","src/lib.rs":"07641b625f69b57e6e3275a6bdeb015fe68e5e1582cfd21c33395294caf0a84b","tests/component.rs":"44684e990e832590a0b348ce33fadf39ee55dec52fdfa9353570edcbf65325ee","tests/core.rs":"75e79b0ec56baa2fcb0e67ba61a3202f4265c99008ac2b4a52d882221c12048d"},"package":"706fc2c6fb0af287ea9147d343485536b5857b72cd32b1d4091619583b334103"}
|
16
third_party/rust/wasm-smith/Cargo.toml
vendored
16
third_party/rust/wasm-smith/Cargo.toml
vendored
@ -12,7 +12,7 @@
|
||||
[package]
|
||||
edition = "2021"
|
||||
name = "wasm-smith"
|
||||
version = "0.12.10"
|
||||
version = "0.12.12"
|
||||
authors = ["Nick Fitzgerald <fitzgen@gmail.com>"]
|
||||
exclude = ["/benches/corpus"]
|
||||
description = "A WebAssembly test case generator"
|
||||
@ -39,28 +39,25 @@ features = ["derive"]
|
||||
version = "0.4"
|
||||
|
||||
[dependencies.indexmap]
|
||||
version = "1.9.1"
|
||||
version = "2.0.0"
|
||||
|
||||
[dependencies.leb128]
|
||||
version = "0.2.4"
|
||||
|
||||
[dependencies.serde]
|
||||
version = "1.0.137"
|
||||
version = "1.0.166"
|
||||
features = ["derive"]
|
||||
optional = true
|
||||
|
||||
[dependencies.wasm-encoder]
|
||||
version = "0.29.0"
|
||||
version = "0.31.0"
|
||||
|
||||
[dependencies.wasmparser]
|
||||
version = "0.107.0"
|
||||
version = "0.109.0"
|
||||
|
||||
[dev-dependencies.criterion]
|
||||
version = "0.3.3"
|
||||
|
||||
[dev-dependencies.libfuzzer-sys]
|
||||
version = "0.4.0"
|
||||
|
||||
[dev-dependencies.rand]
|
||||
version = "0.8.4"
|
||||
features = ["small_rng"]
|
||||
@ -70,3 +67,6 @@ _internal_cli = [
|
||||
"serde",
|
||||
"flagset/serde",
|
||||
]
|
||||
|
||||
[target."cfg(not(target_family = \"wasm\"))".dev-dependencies.libfuzzer-sys]
|
||||
version = "0.4.0"
|
||||
|
13
third_party/rust/wasm-smith/src/core.rs
vendored
13
third_party/rust/wasm-smith/src/core.rs
vendored
@ -547,14 +547,14 @@ impl Module {
|
||||
// index in our newly generated module. Initially the option is `None` and will become a
|
||||
// `Some` when we encounter an import that uses this signature in the next portion of this
|
||||
// function. See also the `make_func_type` closure below.
|
||||
let mut available_types = Vec::<(wasmparser::Type, Option<u32>)>::new();
|
||||
let mut available_types = Vec::<(wasmparser::StructuralType, Option<u32>)>::new();
|
||||
let mut available_imports = Vec::<wasmparser::Import>::new();
|
||||
for payload in wasmparser::Parser::new(0).parse_all(&example_module) {
|
||||
match payload.expect("could not parse the available import payload") {
|
||||
wasmparser::Payload::TypeSection(type_reader) => {
|
||||
for ty in type_reader {
|
||||
let ty = ty.expect("could not parse type section");
|
||||
available_types.push((ty, None));
|
||||
available_types.push((ty.structural_type, None));
|
||||
}
|
||||
}
|
||||
wasmparser::Payload::ImportSection(import_reader) => {
|
||||
@ -587,7 +587,7 @@ impl Module {
|
||||
let serialized_sig_idx = match available_types.get_mut(parsed_sig_idx as usize) {
|
||||
None => panic!("signature index refers to a type out of bounds"),
|
||||
Some((_, Some(idx))) => *idx as usize,
|
||||
Some((wasmparser::Type::Func(func_type), index_store)) => {
|
||||
Some((wasmparser::StructuralType::Func(func_type), index_store)) => {
|
||||
let multi_value_required = func_type.results().len() > 1;
|
||||
let new_index = first_type_index + new_types.len();
|
||||
if new_index >= max_types || (multi_value_required && !multi_value_enabled) {
|
||||
@ -609,8 +609,11 @@ impl Module {
|
||||
new_types.push(Type::Func(Rc::clone(&func_type)));
|
||||
new_index
|
||||
}
|
||||
Some((wasmparser::Type::Array(_array_type), _index_store)) => {
|
||||
unimplemented!("Array and struct types are not supported yet.");
|
||||
Some((wasmparser::StructuralType::Array(_array_type), _index_store)) => {
|
||||
unimplemented!("Array types are not supported yet.");
|
||||
}
|
||||
Some((wasmparser::StructuralType::Struct(_struct_type), _index_store)) => {
|
||||
unimplemented!("Struct types are not supported yet.");
|
||||
}
|
||||
};
|
||||
match &new_types[serialized_sig_idx - first_type_index] {
|
||||
|
@ -158,7 +158,7 @@ impl Module {
|
||||
None => wasm_encoder::ConstExpr::ref_null(el.ty.heap_type),
|
||||
}
|
||||
}));
|
||||
wasm_encoder::Elements::Expressions(&exps)
|
||||
wasm_encoder::Elements::Expressions(el.ty, &exps)
|
||||
}
|
||||
Elements::Functions(fs) => wasm_encoder::Elements::Functions(fs),
|
||||
};
|
||||
@ -169,13 +169,13 @@ impl Module {
|
||||
Offset::Const64(n) => ConstExpr::i64_const(n),
|
||||
Offset::Global(g) => ConstExpr::global_get(g),
|
||||
};
|
||||
elems.active(*table, &offset, el.ty, elements);
|
||||
elems.active(*table, &offset, elements);
|
||||
}
|
||||
ElementKind::Passive => {
|
||||
elems.passive(el.ty, elements);
|
||||
elems.passive(elements);
|
||||
}
|
||||
ElementKind::Declared => {
|
||||
elems.declared(el.ty, elements);
|
||||
elems.declared(elements);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
11
third_party/rust/wasm-smith/tests/core.rs
vendored
11
third_party/rust/wasm-smith/tests/core.rs
vendored
@ -130,10 +130,13 @@ fn smoke_test_imports_config() {
|
||||
if let wasmparser::Payload::TypeSection(rdr) = payload {
|
||||
// Gather the signature types to later check function types against.
|
||||
for ty in rdr {
|
||||
match ty.unwrap() {
|
||||
wasmparser::Type::Func(ft) => sig_types.push(ft),
|
||||
wasmparser::Type::Array(_) => {
|
||||
unimplemented!("Array and struct types are not supported yet.")
|
||||
match ty.unwrap().structural_type {
|
||||
wasmparser::StructuralType::Func(ft) => sig_types.push(ft),
|
||||
wasmparser::StructuralType::Array(_) => {
|
||||
unimplemented!("Array types are not supported yet.")
|
||||
}
|
||||
wasmparser::StructuralType::Struct(_) => {
|
||||
unimplemented!("Struct types are not supported yet.")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1 +1 @@
|
||||
{"files":{"Cargo.lock":"0094a4caa360684ecf8dba191e832d04ea783f722bb3d7203a861ab5f1b6652b","Cargo.toml":"f9969ee73f9611dd62ba995630b919e1d81d2ba2af3cd2e9813d73778d734614","LICENSE":"268872b9816f90fd8e85db5a28d33f8150ebb8dd016653fb39ef1f94f2686bc5","README.md":"1c3b4f8db61a673ee2f7dc66118b1008ce8d1a7d0f5197fbe87f1271b23de3bd","benches/benchmark.rs":"12b94c2a8ba04c5362b86ff36cdedb3596507a5606ce22a275cac2632f5d35ad","examples/simple.rs":"e9eb076367cc0932e2a32651372defa4a27ef800f47fad28c0ef840ba8ea7e08","src/binary_reader.rs":"0c346c4248b39ab3d7c9908834442ef6f3aa5dc921804c3e89e7bf46d49dbe15","src/lib.rs":"b7fbf8cdd67033c61c1b3a3c25823ef4518458eda6cbfd44d1c80b20cf0c5076","src/limits.rs":"93b8ae6ce2f95c14b62e41fd6dc3ab3869a6879af46bd0c560b43193cea0b496","src/parser.rs":"c69c24f2308b05e0a5072bbd07084d2002e0ae291afd669361b5a4bb8c7fcad4","src/readers.rs":"406bf0cf694ed364c9c53cd25eb27a8e3fa97d099994f3e2a640747c49abf74b","src/readers/component.rs":"c259628ca3f09ff904f7e920aeec261b657f7a197c99b520a6a7d3e918b9fb3b","src/readers/component/aliases.rs":"72f3339cb452c1b055bd080281fe4923d132c280da112fcd1182594811b87494","src/readers/component/canonicals.rs":"45b8c54e842bc698d180b7396579b93e16fddb9a055c753482fc03bf5cd443b4","src/readers/component/exports.rs":"96cc2f65666da77b6230335378550d9b45a193795ee939d75808cc49cc1c06f4","src/readers/component/imports.rs":"5c6a0066adb143455b92b5ef1b773184ccf62923c8a35b26262e6a80058971d2","src/readers/component/instances.rs":"5f3ef2b8424a3beff2c34d118f1c9f168d1beee589c0e87dabab94ba726a8f1d","src/readers/component/names.rs":"3f5dac9db8668b18cd6721cd780e6aba9b223b404c9d1173d09efe4e6b4d3a8a","src/readers/component/start.rs":"8e1e5d8aa5ece26d42251449cadcce0546c4d995f1641941b8a31ed4bc6ac761","src/readers/component/types.rs":"6579bb3131570f35415fc47ab35efbfc2688b970052425741ad3a1aa89588b86","src/readers/core.rs":"c2536abe2a3305b4aa3d91f7fcea9c89e65a5c94af74e4f6a1b19bbe09f8fb2c","src/readers/core/code.rs":"53f49986febb27f4cb67f4495e7b369fc80e2f70908e1e831750698dd15fe37f","src/readers/core/coredumps.rs":"7cde14b700bdf2459fa57e2cbb5a520a4d1d8547f075c1440db74b19ecf74764","src/readers/core/custom.rs":"f80d3a994e8778a912319834228cbb772c65a4b6b1f25b41fe00d220d388831f","src/readers/core/data.rs":"c1fcda7b548b15be40b3dd1f667d97c30c543867f2dc4734b590846beefe3ae3","src/readers/core/elements.rs":"c7fdde45032eec293d69b8bce5519391db84117aa33a98dad35b12c68a532c9f","src/readers/core/exports.rs":"50dc1ee51b73f03f24077f7c290bca756966563cedbad9e49d735d60f60c91db","src/readers/core/functions.rs":"b5bbc7f7b7a429187376f63c695a9f1cbf92e515dba840ac876fa60f7290da34","src/readers/core/globals.rs":"d23f99a3adc9593652a5efd4dc81e8f014f57e776b49717dabbdcd0a811a96b1","src/readers/core/imports.rs":"4d247e8cac0b3cef7425d93f7a7f2412b2ae8979da944080d565415499e27e87","src/readers/core/init.rs":"ec6717063b0b7f2e9aa17ae52083019cee52594bf5a8b6858f2d77b10d7a0639","src/readers/core/memories.rs":"351f816d663b7d17546dc3b19ce0e43f406ce743289219a3758f7c837903fa6d","src/readers/core/names.rs":"408ebf052170bf0dc874b3158bb31089a891c3735cb35df2976e0b1e9791febb","src/readers/core/operators.rs":"46e927f6db9db9097217c5485da3a7b89e638730def809d177897f39356f5f52","src/readers/core/producers.rs":"5b53d0979a68008f9aec0bb9bca64c071e49a6a1879d8459f1114fa666e661c5","src/readers/core/tables.rs":"cbe5b35893bd3929354b4487b344062ce6b540e6a70bde6eddf05a07a68574e9","src/readers/core/tags.rs":"c1dcfeb973195da9708549bcc2df4dd8ff282fe802c15a603bebc8a856f70949","src/readers/core/types.rs":"e644d7fce8a8a4cab0b617d2d4000f2979375e5b0389b0511ad1aeff7eab6cd3","src/resources.rs":"e3bf138ef8fc94d2773fc6159bbd7f47611b5d9121c12e724cbbb824d8278411","src/validator.rs":"fda1d806231f3e714c538d0f23aab0c6e1f6790df591c11903a716514373eec3","src/validator/component.rs":"1920424f9dacf904ad6112ce5bc0d272e3aa60fd88895ae06b44294341ec904f","src/validator/core.rs":"268e88fed44d03c09cc2a500d292d676cc234748f64a00c95757a2349d24e91e","src/validator/func.rs":"63b66b7bb274be4115d8a26bce9b73128de0c079bd3318423288fadc1361fdb4","src/validator/names.rs":"0beae05cae3bf6d8fe2d0ebea1c5dd993fc8ce1116b454aca2a79a41a8e1c9d8","src/validator/operators.rs":"d488964a60fcb44c03b41b7f9fa3c7cafdfc30be2e2d9fef87aac73273056f8f","src/validator/types.rs":"e50497731c493205965e2f1cb8aee40287f00abff8f671034733960e81e42c03","tests/big-module.rs":"1f9241a4504d0421f6a5c759e3c688c87994fe04668b1d4e8912cedd98f2bd17"},"package":"29e3ac9b780c7dda0cac7a52a5d6d2d6707cc6e3451c9db209b6c758f40d7acb"}
|
||||
{"files":{"Cargo.lock":"77ee2d9359018953cfd5bc20e037058aee2c38900f822a8f264fcaf2cee82368","Cargo.toml":"b1347320791d977fb2b3f173a3520117d1ee5e8f8ddcb8e8f8c9c98bdbd98979","LICENSE":"268872b9816f90fd8e85db5a28d33f8150ebb8dd016653fb39ef1f94f2686bc5","README.md":"1c3b4f8db61a673ee2f7dc66118b1008ce8d1a7d0f5197fbe87f1271b23de3bd","benches/benchmark.rs":"dd6e7eb5f196d9ffe330873c8d68538a29a648075775f520678fc889f2bf8b4b","examples/simple.rs":"e9eb076367cc0932e2a32651372defa4a27ef800f47fad28c0ef840ba8ea7e08","src/binary_reader.rs":"0c346c4248b39ab3d7c9908834442ef6f3aa5dc921804c3e89e7bf46d49dbe15","src/lib.rs":"b7fbf8cdd67033c61c1b3a3c25823ef4518458eda6cbfd44d1c80b20cf0c5076","src/limits.rs":"cda435bb60b635320d5890f02acd0889ff399712c234ffad2d2fda31080b6ed7","src/parser.rs":"c69c24f2308b05e0a5072bbd07084d2002e0ae291afd669361b5a4bb8c7fcad4","src/readers.rs":"406bf0cf694ed364c9c53cd25eb27a8e3fa97d099994f3e2a640747c49abf74b","src/readers/component.rs":"c259628ca3f09ff904f7e920aeec261b657f7a197c99b520a6a7d3e918b9fb3b","src/readers/component/aliases.rs":"72f3339cb452c1b055bd080281fe4923d132c280da112fcd1182594811b87494","src/readers/component/canonicals.rs":"d3b844d177be69c40644d924271588718685511fafcc46ee1d9d0f6942b9dccb","src/readers/component/exports.rs":"96cc2f65666da77b6230335378550d9b45a193795ee939d75808cc49cc1c06f4","src/readers/component/imports.rs":"5c6a0066adb143455b92b5ef1b773184ccf62923c8a35b26262e6a80058971d2","src/readers/component/instances.rs":"5f3ef2b8424a3beff2c34d118f1c9f168d1beee589c0e87dabab94ba726a8f1d","src/readers/component/names.rs":"3f5dac9db8668b18cd6721cd780e6aba9b223b404c9d1173d09efe4e6b4d3a8a","src/readers/component/start.rs":"8e1e5d8aa5ece26d42251449cadcce0546c4d995f1641941b8a31ed4bc6ac761","src/readers/component/types.rs":"bf511a8201af9e84e04e83041451a419520cd2d0f8024add18e36d78e985e065","src/readers/core.rs":"c2536abe2a3305b4aa3d91f7fcea9c89e65a5c94af74e4f6a1b19bbe09f8fb2c","src/readers/core/code.rs":"53f49986febb27f4cb67f4495e7b369fc80e2f70908e1e831750698dd15fe37f","src/readers/core/coredumps.rs":"7cde14b700bdf2459fa57e2cbb5a520a4d1d8547f075c1440db74b19ecf74764","src/readers/core/custom.rs":"f80d3a994e8778a912319834228cbb772c65a4b6b1f25b41fe00d220d388831f","src/readers/core/data.rs":"c1fcda7b548b15be40b3dd1f667d97c30c543867f2dc4734b590846beefe3ae3","src/readers/core/elements.rs":"7f05cbe94402bb2e591c8dd8f0be45309044c80f242568c66c1b2ea0011b7f50","src/readers/core/exports.rs":"50dc1ee51b73f03f24077f7c290bca756966563cedbad9e49d735d60f60c91db","src/readers/core/functions.rs":"b5bbc7f7b7a429187376f63c695a9f1cbf92e515dba840ac876fa60f7290da34","src/readers/core/globals.rs":"d23f99a3adc9593652a5efd4dc81e8f014f57e776b49717dabbdcd0a811a96b1","src/readers/core/imports.rs":"4d247e8cac0b3cef7425d93f7a7f2412b2ae8979da944080d565415499e27e87","src/readers/core/init.rs":"ec6717063b0b7f2e9aa17ae52083019cee52594bf5a8b6858f2d77b10d7a0639","src/readers/core/memories.rs":"351f816d663b7d17546dc3b19ce0e43f406ce743289219a3758f7c837903fa6d","src/readers/core/names.rs":"408ebf052170bf0dc874b3158bb31089a891c3735cb35df2976e0b1e9791febb","src/readers/core/operators.rs":"46e927f6db9db9097217c5485da3a7b89e638730def809d177897f39356f5f52","src/readers/core/producers.rs":"5b53d0979a68008f9aec0bb9bca64c071e49a6a1879d8459f1114fa666e661c5","src/readers/core/tables.rs":"cbe5b35893bd3929354b4487b344062ce6b540e6a70bde6eddf05a07a68574e9","src/readers/core/tags.rs":"c1dcfeb973195da9708549bcc2df4dd8ff282fe802c15a603bebc8a856f70949","src/readers/core/types.rs":"7d932e4939748cc856c8ae5b551336bb646c032253e4e03b2780dd57d7972cae","src/resources.rs":"e3bf138ef8fc94d2773fc6159bbd7f47611b5d9121c12e724cbbb824d8278411","src/validator.rs":"cab135ab8c4d32389fb38e514fc757fa440c3f8a82dda6e3d68ea5e83ce9a97d","src/validator/component.rs":"b771ab4604d895d0dc4b942cc9669b19b2a4aa07cfb5de3f0ce0c7f02df84dd2","src/validator/core.rs":"2b624b04176551dbf0af762376313a4dd941c9bca0e6f7b7760afb5b137d085d","src/validator/func.rs":"63b66b7bb274be4115d8a26bce9b73128de0c079bd3318423288fadc1361fdb4","src/validator/names.rs":"0beae05cae3bf6d8fe2d0ebea1c5dd993fc8ce1116b454aca2a79a41a8e1c9d8","src/validator/operators.rs":"a0cc09ba25b85f769647d0ecf2754f779648dbf86210b6d2a36ce8a9739f0423","src/validator/types.rs":"a7156e0bb5b59a53b08606d9ef2f1f67c01b94f159ceefbf909d31eab900e302","tests/big-module.rs":"2d956dedf1a9f0b1e976dd63c97d3707cd726da10166cad2f16ae33000ed13b3"},"package":"8bf9564f29de2890ee34406af52d2a92dec6ef044c8ddfc5add5db8dcfd36e6c"}
|
177
third_party/rust/wasmparser/Cargo.lock
generated
vendored
177
third_party/rust/wasmparser/Cargo.lock
generated
vendored
@ -2,6 +2,15 @@
|
||||
# It is not intended for manual editing.
|
||||
version = 3
|
||||
|
||||
[[package]]
|
||||
name = "aho-corasick"
|
||||
version = "1.0.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "43f6cb1bf222025340178f382c426f13757b2960e89779dfcb319c32542a5a41"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "anyhow"
|
||||
version = "1.0.71"
|
||||
@ -33,9 +42,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
|
||||
|
||||
[[package]]
|
||||
name = "bumpalo"
|
||||
version = "3.12.2"
|
||||
version = "3.13.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3c6ed94e98ecff0c12dd1b04c15ec0d7d9458ca8fe806cea6f12954efe74c63b"
|
||||
checksum = "a3e2c3daef883ecc1b5d58c15adae93470a91d425f3532ba1695849656af3fc1"
|
||||
|
||||
[[package]]
|
||||
name = "cast"
|
||||
@ -119,9 +128,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-epoch"
|
||||
version = "0.9.14"
|
||||
version = "0.9.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "46bd5f3f85273295a9d14aedfb86f6aadbff6d8f5295c4a9edb08e819dcf5695"
|
||||
checksum = "ae211234986c545741a7dc064309f67ee1e5ad243d0e48335adc0484d960bcc7"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"cfg-if",
|
||||
@ -132,18 +141,18 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-utils"
|
||||
version = "0.8.15"
|
||||
version = "0.8.16"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3c063cd8cc95f5c377ed0d4b49a4b21f632396ff690e8470c29b3359b346984b"
|
||||
checksum = "5a22b2d63d4d1dc0b7f1b6b2747dd0088008a9be28b6ddf0b1e7d335e3037294"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "csv"
|
||||
version = "1.2.1"
|
||||
version = "1.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0b015497079b9a9d69c02ad25de6c0a6edef051ea6360a327d0bd05802ef64ad"
|
||||
checksum = "626ae34994d3d8d668f4269922248239db4ae42d538b14c398b74a52208e8086"
|
||||
dependencies = [
|
||||
"csv-core",
|
||||
"itoa",
|
||||
@ -166,6 +175,12 @@ version = "1.8.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7fcaabb2fef8c910e7f4c7ce9f67a1283a1715879a7c230ca9d6d1ae31f16d91"
|
||||
|
||||
[[package]]
|
||||
name = "equivalent"
|
||||
version = "1.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5"
|
||||
|
||||
[[package]]
|
||||
name = "half"
|
||||
version = "1.8.2"
|
||||
@ -174,9 +189,9 @@ checksum = "eabb4a44450da02c90444cf74558da904edde8fb4e9035a9a6a4e15445af0bd7"
|
||||
|
||||
[[package]]
|
||||
name = "hashbrown"
|
||||
version = "0.12.3"
|
||||
version = "0.14.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888"
|
||||
checksum = "2c6201b9ff9fd90a5a3bac2e56a830d0caa509576f0e503818ee82c181b3437a"
|
||||
|
||||
[[package]]
|
||||
name = "hermit-abi"
|
||||
@ -189,20 +204,17 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "hermit-abi"
|
||||
version = "0.2.6"
|
||||
version = "0.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ee512640fe35acbfb4bb779db6f0d80704c2cacfa2e39b601ef3e3f47d1ae4c7"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
checksum = "443144c8cdadd93ebf52ddb4056d257f5b52c04d3c804e657d19eb73fc33668b"
|
||||
|
||||
[[package]]
|
||||
name = "indexmap"
|
||||
version = "1.9.3"
|
||||
version = "2.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99"
|
||||
checksum = "d5477fe2230a79769d8dc68e0eabf5437907c0457a5614a9e8dddb67f65eb65d"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"equivalent",
|
||||
"hashbrown",
|
||||
]
|
||||
|
||||
@ -217,15 +229,15 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "itoa"
|
||||
version = "1.0.6"
|
||||
version = "1.0.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "453ad9f582a441959e5f0d088b02ce04cfe8d51a8eaf077f12ac6d3e94164ca6"
|
||||
checksum = "62b02a5381cc465bd3041d84623d0fa3b66738b52b8e2fc3bab8ad63ab032f4a"
|
||||
|
||||
[[package]]
|
||||
name = "js-sys"
|
||||
version = "0.3.62"
|
||||
version = "0.3.64"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "68c16e1bfd491478ab155fd8b4896b86f9ede344949b641e61501e07c2b8b4d5"
|
||||
checksum = "c5f195fe497f702db0f318b07fdd68edb16955aed830df8363d837542f8f935a"
|
||||
dependencies = [
|
||||
"wasm-bindgen",
|
||||
]
|
||||
@ -244,18 +256,15 @@ checksum = "884e2677b40cc8c339eaefcb701c32ef1fd2493d71118dc0ca4b6a736c93bd67"
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.144"
|
||||
version = "0.2.147"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2b00cc1c228a6782d0f076e7b232802e0c5689d41bb5df366f2a6b6621cfdfe1"
|
||||
checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3"
|
||||
|
||||
[[package]]
|
||||
name = "log"
|
||||
version = "0.4.17"
|
||||
version = "0.4.19"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
]
|
||||
checksum = "b06a4cde4c0f271a446782e3eff8de789548ce57dbc8eca9292c27f4a42004b4"
|
||||
|
||||
[[package]]
|
||||
name = "memchr"
|
||||
@ -265,9 +274,9 @@ checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d"
|
||||
|
||||
[[package]]
|
||||
name = "memoffset"
|
||||
version = "0.8.0"
|
||||
version = "0.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d61c719bcfbcf5d62b3a09efa6088de8c54bc0bfcd3ea7ae39fcc186108b8de1"
|
||||
checksum = "5a634b1c61a95585bd15607c6ab0c4e5b226e695ff2800ba0cdccddf208c406c"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
]
|
||||
@ -283,19 +292,19 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "num_cpus"
|
||||
version = "1.15.0"
|
||||
version = "1.16.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0fac9e2da13b5eb447a6ce3d392f23a29d8694bff781bf03a16cd9ac8697593b"
|
||||
checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43"
|
||||
dependencies = [
|
||||
"hermit-abi 0.2.6",
|
||||
"hermit-abi 0.3.2",
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "once_cell"
|
||||
version = "1.17.1"
|
||||
version = "1.18.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b7e5500299e16ebb147ae15a00a942af264cf3688f47923b8fc2cd5858f23ad3"
|
||||
checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d"
|
||||
|
||||
[[package]]
|
||||
name = "oorandom"
|
||||
@ -305,9 +314,9 @@ checksum = "0ab1bc2a289d34bd04a330323ac98a1b4bc82c9d9fcb1e66b63caa84da26b575"
|
||||
|
||||
[[package]]
|
||||
name = "plotters"
|
||||
version = "0.3.4"
|
||||
version = "0.3.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2538b639e642295546c50fcd545198c9d64ee2a38620a628724a3b266d5fbf97"
|
||||
checksum = "d2c224ba00d7cadd4d5c660deaf2098e5e80e07846537c51f9cfa4be50c1fd45"
|
||||
dependencies = [
|
||||
"num-traits",
|
||||
"plotters-backend",
|
||||
@ -318,33 +327,33 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "plotters-backend"
|
||||
version = "0.3.4"
|
||||
version = "0.3.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "193228616381fecdc1224c62e96946dfbc73ff4384fba576e052ff8c1bea8142"
|
||||
checksum = "9e76628b4d3a7581389a35d5b6e2139607ad7c75b17aed325f210aa91f4a9609"
|
||||
|
||||
[[package]]
|
||||
name = "plotters-svg"
|
||||
version = "0.3.3"
|
||||
version = "0.3.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f9a81d2759aae1dae668f783c308bc5c8ebd191ff4184aaa1b37f65a6ae5a56f"
|
||||
checksum = "38f6d39893cca0701371e3c27294f09797214b86f1fb951b89ade8ec04e2abab"
|
||||
dependencies = [
|
||||
"plotters-backend",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.57"
|
||||
version = "1.0.64"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c4ec6d5fe0b140acb27c9a0444118cf55bfbb4e0b259739429abb4521dd67c16"
|
||||
checksum = "78803b62cbf1f46fde80d7c0e803111524b9877184cfe7c3033659490ac7a7da"
|
||||
dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.27"
|
||||
version = "1.0.29"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8f4f29d145265ec1c483c7c654450edde0bfe043d3938d6972630663356d9500"
|
||||
checksum = "573015e8ab27661678357f27dc26460738fd2b6c86e46f386fde94cb5d913105"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
@ -373,24 +382,38 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "regex"
|
||||
version = "1.8.1"
|
||||
version = "1.9.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "af83e617f331cc6ae2da5443c602dfa5af81e517212d9d611a5b3ba1777b5370"
|
||||
checksum = "b2eae68fc220f7cf2532e4494aded17545fce192d59cd996e0fe7887f4ceb575"
|
||||
dependencies = [
|
||||
"aho-corasick",
|
||||
"memchr",
|
||||
"regex-automata",
|
||||
"regex-syntax",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex-automata"
|
||||
version = "0.3.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "39354c10dd07468c2e73926b23bb9c2caca74c5501e38a35da70406f1d923310"
|
||||
dependencies = [
|
||||
"aho-corasick",
|
||||
"memchr",
|
||||
"regex-syntax",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex-syntax"
|
||||
version = "0.7.1"
|
||||
version = "0.7.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a5996294f19bd3aae0453a862ad728f60e6600695733dd5df01da90c54363a3c"
|
||||
checksum = "e5ea92a5b6195c6ef2a0295ea818b312502c6fc94dde986c5553242e18fd4ce2"
|
||||
|
||||
[[package]]
|
||||
name = "ryu"
|
||||
version = "1.0.13"
|
||||
version = "1.0.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f91339c0467de62360649f8d3e185ca8de4224ff281f66000de5eb2a77a79041"
|
||||
checksum = "fe232bdf6be8c8de797b22184ee71118d63780ea42ac85b61d1baa6d3b782ae9"
|
||||
|
||||
[[package]]
|
||||
name = "same-file"
|
||||
@ -415,9 +438,9 @@ checksum = "bebd363326d05ec3e2f532ab7660680f3b02130d780c299bca73469d521bc0ed"
|
||||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.163"
|
||||
version = "1.0.171"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2113ab51b87a539ae008b5c6c02dc020ffa39afd2d83cffcb3f4eb2722cebec2"
|
||||
checksum = "30e27d1e4fd7659406c492fd6cfaf2066ba8773de45ca75e855590f856dc34a9"
|
||||
|
||||
[[package]]
|
||||
name = "serde_cbor"
|
||||
@ -431,9 +454,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "serde_derive"
|
||||
version = "1.0.163"
|
||||
version = "1.0.171"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8c805777e3930c8883389c602315a24224bcc738b63905ef87cd1420353ea93e"
|
||||
checksum = "389894603bd18c46fa56231694f8d827779c0951a667087194cf9de94ed24682"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
@ -442,9 +465,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "serde_json"
|
||||
version = "1.0.96"
|
||||
version = "1.0.102"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "057d394a50403bcac12672b2b18fb387ab6d289d957dab67dd201875391e52f1"
|
||||
checksum = "b5062a995d481b2308b6064e9af76011f2921c35f97b0468811ed9f6cd91dfed"
|
||||
dependencies = [
|
||||
"itoa",
|
||||
"ryu",
|
||||
@ -453,9 +476,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "2.0.16"
|
||||
version = "2.0.25"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a6f671d4b5ffdb8eadec19c0ae67fe2639df8684bd7bc4b83d986b8db549cf01"
|
||||
checksum = "15e3fc8c0c74267e2df136e5e5fb656a464158aa57624053375eb9c8c6e25ae2"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
@ -483,9 +506,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "unicode-ident"
|
||||
version = "1.0.8"
|
||||
version = "1.0.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e5464a87b239f13a63a501f2701565754bae92d243d4bb7eb12f6d57d2269bf4"
|
||||
checksum = "22049a19f4a68748a168c0fc439f9516686aa045927ff767eca0a85101fb6e73"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-width"
|
||||
@ -505,9 +528,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen"
|
||||
version = "0.2.85"
|
||||
version = "0.2.87"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5b6cb788c4e39112fbe1822277ef6fb3c55cd86b95cb3d3c4c1c9597e4ac74b4"
|
||||
checksum = "7706a72ab36d8cb1f80ffbf0e071533974a60d0a308d01a5d0375bf60499a342"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"wasm-bindgen-macro",
|
||||
@ -515,9 +538,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-backend"
|
||||
version = "0.2.85"
|
||||
version = "0.2.87"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "35e522ed4105a9d626d885b35d62501b30d9666283a5c8be12c14a8bdafe7822"
|
||||
checksum = "5ef2b6d3c510e9625e5fe6f509ab07d66a760f0885d858736483c32ed7809abd"
|
||||
dependencies = [
|
||||
"bumpalo",
|
||||
"log",
|
||||
@ -530,9 +553,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-macro"
|
||||
version = "0.2.85"
|
||||
version = "0.2.87"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "358a79a0cb89d21db8120cbfb91392335913e4890665b1a7981d9e956903b434"
|
||||
checksum = "dee495e55982a3bd48105a7b947fd2a9b4a8ae3010041b9e0faab3f9cd028f1d"
|
||||
dependencies = [
|
||||
"quote",
|
||||
"wasm-bindgen-macro-support",
|
||||
@ -540,9 +563,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-macro-support"
|
||||
version = "0.2.85"
|
||||
version = "0.2.87"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4783ce29f09b9d93134d41297aded3a712b7b979e9c6f28c32cb88c973a94869"
|
||||
checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
@ -553,22 +576,22 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-shared"
|
||||
version = "0.2.85"
|
||||
version = "0.2.87"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a901d592cafaa4d711bc324edfaff879ac700b19c3dfd60058d2b445be2691eb"
|
||||
checksum = "ca6ad05a4870b2bf5fe995117d3728437bd27d7cd5f06f13c17443ef369775a1"
|
||||
|
||||
[[package]]
|
||||
name = "wasm-encoder"
|
||||
version = "0.29.0"
|
||||
version = "0.31.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "18c41dbd92eaebf3612a39be316540b8377c871cb9bde6b064af962984912881"
|
||||
checksum = "06a3d1b4a575ffb873679402b2aedb3117555eb65c27b1b86c8a91e574bc2a2a"
|
||||
dependencies = [
|
||||
"leb128",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasmparser"
|
||||
version = "0.107.0"
|
||||
version = "0.109.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"criterion",
|
||||
@ -581,9 +604,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "web-sys"
|
||||
version = "0.3.62"
|
||||
version = "0.3.64"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "16b5f940c7edfdc6d12126d98c9ef4d1b3d470011c47c76a6581df47ad9ba721"
|
||||
checksum = "9b85cbef8c220a6abc02aefd892dfc0fc23afb1c6a426316ec33253a3877249b"
|
||||
dependencies = [
|
||||
"js-sys",
|
||||
"wasm-bindgen",
|
||||
|
6
third_party/rust/wasmparser/Cargo.toml
vendored
6
third_party/rust/wasmparser/Cargo.toml
vendored
@ -12,7 +12,7 @@
|
||||
[package]
|
||||
edition = "2021"
|
||||
name = "wasmparser"
|
||||
version = "0.107.0"
|
||||
version = "0.109.0"
|
||||
authors = ["Yury Delendik <ydelendik@mozilla.com>"]
|
||||
exclude = ["benches/*.wasm"]
|
||||
description = """
|
||||
@ -33,7 +33,7 @@ name = "benchmark"
|
||||
harness = false
|
||||
|
||||
[dependencies.indexmap]
|
||||
version = "1.9.1"
|
||||
version = "2.0.0"
|
||||
|
||||
[dependencies.semver]
|
||||
version = "1.0.0"
|
||||
@ -51,4 +51,4 @@ version = "1.13.0"
|
||||
version = "1.3"
|
||||
|
||||
[dev-dependencies.wasm-encoder]
|
||||
version = "0.29.0"
|
||||
version = "0.31.0"
|
||||
|
@ -4,10 +4,7 @@ use once_cell::unsync::Lazy;
|
||||
use std::fs;
|
||||
use std::path::Path;
|
||||
use std::path::PathBuf;
|
||||
use wasmparser::{
|
||||
DataKind, ElementKind, HeapType, Parser, Payload, ValType, Validator, VisitOperator,
|
||||
WasmFeatures,
|
||||
};
|
||||
use wasmparser::{DataKind, ElementKind, Parser, Payload, Validator, VisitOperator, WasmFeatures};
|
||||
|
||||
/// A benchmark input.
|
||||
pub struct BenchmarkInput {
|
||||
@ -139,7 +136,7 @@ fn read_all_wasm(wasm: &[u8]) -> Result<()> {
|
||||
op?;
|
||||
}
|
||||
}
|
||||
wasmparser::ElementItems::Expressions(r) => {
|
||||
wasmparser::ElementItems::Expressions(_, r) => {
|
||||
for op in r {
|
||||
op?;
|
||||
}
|
||||
|
2
third_party/rust/wasmparser/src/limits.rs
vendored
2
third_party/rust/wasmparser/src/limits.rs
vendored
@ -16,6 +16,7 @@
|
||||
// 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 = 1_000_000;
|
||||
pub const MAX_WASM_SUPERTYPES: usize = 1;
|
||||
pub const MAX_WASM_FUNCTIONS: usize = 1_000_000;
|
||||
pub const MAX_WASM_EXPORTS: usize = 100_000;
|
||||
pub const MAX_WASM_GLOBALS: usize = 1_000_000;
|
||||
@ -34,6 +35,7 @@ pub const MAX_WASM_TABLES: usize = 100;
|
||||
pub const MAX_WASM_MEMORIES: usize = 100;
|
||||
pub const MAX_WASM_TAGS: usize = 1_000_000;
|
||||
pub const MAX_WASM_BR_TABLE_SIZE: usize = MAX_WASM_FUNCTION_SIZE;
|
||||
pub const MAX_WASM_STRUCT_FIELDS: usize = 10_000;
|
||||
|
||||
// Component-related limits
|
||||
pub const MAX_WASM_MODULE_SIZE: usize = 1024 * 1024 * 1024; //= 1 GiB
|
||||
|
@ -1,5 +1,5 @@
|
||||
use crate::limits::MAX_WASM_CANONICAL_OPTIONS;
|
||||
use crate::{BinaryReader, ComponentValType, FromReader, Result, SectionLimited};
|
||||
use crate::{BinaryReader, FromReader, Result, SectionLimited};
|
||||
|
||||
/// Represents options for component functions.
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
@ -50,9 +50,8 @@ pub enum CanonicalFunction {
|
||||
},
|
||||
/// A function which is used to drop resource handles of the specified type.
|
||||
ResourceDrop {
|
||||
/// The type of the resource that's being dropped, either an (own T) or
|
||||
/// a (borrow T)
|
||||
ty: ComponentValType,
|
||||
/// The type index of the resource that's being dropped.
|
||||
resource: u32,
|
||||
},
|
||||
/// A function which returns the underlying i32-based representation of the
|
||||
/// specified resource.
|
||||
@ -95,7 +94,9 @@ impl<'a> FromReader<'a> for CanonicalFunction {
|
||||
0x02 => CanonicalFunction::ResourceNew {
|
||||
resource: reader.read()?,
|
||||
},
|
||||
0x03 => CanonicalFunction::ResourceDrop { ty: reader.read()? },
|
||||
0x03 => CanonicalFunction::ResourceDrop {
|
||||
resource: reader.read()?,
|
||||
},
|
||||
0x04 => CanonicalFunction::ResourceRep {
|
||||
resource: reader.read()?,
|
||||
},
|
||||
|
@ -1,7 +1,7 @@
|
||||
use crate::limits::*;
|
||||
use crate::{
|
||||
BinaryReader, ComponentAlias, ComponentExternName, ComponentImport, ComponentTypeRef,
|
||||
FromReader, FuncType, Import, Result, SectionLimited, Type, TypeRef, ValType,
|
||||
FromReader, FuncType, Import, Result, SectionLimited, SubType, TypeRef, ValType,
|
||||
};
|
||||
use std::fmt;
|
||||
|
||||
@ -39,7 +39,7 @@ impl<'a> FromReader<'a> for CoreType<'a> {
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum ModuleTypeDeclaration<'a> {
|
||||
/// The module type definition is for a type.
|
||||
Type(Type),
|
||||
Type(SubType),
|
||||
/// The module type definition is for an export.
|
||||
Export {
|
||||
/// The name of the exported item.
|
||||
|
@ -26,8 +26,6 @@ pub struct Element<'a> {
|
||||
pub kind: ElementKind<'a>,
|
||||
/// The initial elements of the element segment.
|
||||
pub items: ElementItems<'a>,
|
||||
/// The type of the elements.
|
||||
pub ty: RefType,
|
||||
/// The range of the the element segment.
|
||||
pub range: Range<usize>,
|
||||
}
|
||||
@ -54,7 +52,7 @@ pub enum ElementItems<'a> {
|
||||
/// This element contains function indices.
|
||||
Functions(SectionLimited<'a, u32>),
|
||||
/// This element contains constant expressions used to initialize the table.
|
||||
Expressions(SectionLimited<'a, ConstExpr<'a>>),
|
||||
Expressions(RefType, SectionLimited<'a, ConstExpr<'a>>),
|
||||
}
|
||||
|
||||
/// A reader for the element section of a WebAssembly module.
|
||||
@ -104,10 +102,10 @@ impl<'a> FromReader<'a> for Element<'a> {
|
||||
let exprs = flags & 0b100 != 0;
|
||||
let ty = if flags & 0b011 != 0 {
|
||||
if exprs {
|
||||
reader.read()?
|
||||
Some(reader.read()?)
|
||||
} else {
|
||||
match reader.read()? {
|
||||
ExternalKind::Func => RefType::FUNCREF,
|
||||
ExternalKind::Func => None,
|
||||
_ => {
|
||||
return Err(BinaryReaderError::new(
|
||||
"only the function external type is supported in elem segment",
|
||||
@ -117,7 +115,7 @@ impl<'a> FromReader<'a> for Element<'a> {
|
||||
}
|
||||
}
|
||||
} else {
|
||||
RefType::FUNCREF
|
||||
None
|
||||
};
|
||||
// FIXME(#188) ideally wouldn't have to do skips here
|
||||
let data = reader.skip(|reader| {
|
||||
@ -134,11 +132,12 @@ impl<'a> FromReader<'a> for Element<'a> {
|
||||
Ok(())
|
||||
})?;
|
||||
let items = if exprs {
|
||||
ElementItems::Expressions(SectionLimited::new(
|
||||
data.remaining_buffer(),
|
||||
data.original_position(),
|
||||
)?)
|
||||
ElementItems::Expressions(
|
||||
ty.unwrap_or(RefType::FUNCREF),
|
||||
SectionLimited::new(data.remaining_buffer(), data.original_position())?,
|
||||
)
|
||||
} else {
|
||||
assert!(ty.is_none());
|
||||
ElementItems::Functions(SectionLimited::new(
|
||||
data.remaining_buffer(),
|
||||
data.original_position(),
|
||||
@ -148,11 +147,6 @@ impl<'a> FromReader<'a> for Element<'a> {
|
||||
let elem_end = reader.original_position();
|
||||
let range = elem_start..elem_end;
|
||||
|
||||
Ok(Element {
|
||||
kind,
|
||||
items,
|
||||
ty,
|
||||
range,
|
||||
})
|
||||
Ok(Element { kind, items, range })
|
||||
}
|
||||
}
|
||||
|
@ -13,8 +13,11 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
use crate::limits::{MAX_WASM_FUNCTION_PARAMS, MAX_WASM_FUNCTION_RETURNS};
|
||||
use crate::{BinaryReader, FromReader, Result, SectionLimited};
|
||||
use crate::limits::{
|
||||
MAX_WASM_FUNCTION_PARAMS, MAX_WASM_FUNCTION_RETURNS, MAX_WASM_STRUCT_FIELDS,
|
||||
MAX_WASM_SUPERTYPES,
|
||||
};
|
||||
use crate::{BinaryReader, BinaryReaderError, FromReader, Result, SectionLimited};
|
||||
use std::fmt::{self, Debug, Write};
|
||||
|
||||
/// Represents the types of values in a WebAssembly module.
|
||||
@ -50,6 +53,12 @@ const _: () = {
|
||||
assert!(std::mem::size_of::<ValType>() == 4);
|
||||
};
|
||||
|
||||
pub(crate) trait Inherits {
|
||||
fn inherits<'a, F>(&self, other: &Self, type_at: &F) -> bool
|
||||
where
|
||||
F: Fn(u32) -> &'a SubType;
|
||||
}
|
||||
|
||||
impl From<RefType> for ValType {
|
||||
fn from(ty: RefType) -> ValType {
|
||||
ValType::Ref(ty)
|
||||
@ -89,6 +98,21 @@ impl ValType {
|
||||
}
|
||||
}
|
||||
|
||||
impl Inherits for ValType {
|
||||
fn inherits<'a, F>(&self, other: &Self, type_at: &F) -> bool
|
||||
where
|
||||
F: Fn(u32) -> &'a SubType,
|
||||
{
|
||||
match (self, other) {
|
||||
(Self::Ref(r1), Self::Ref(r2)) => r1.inherits(r2, type_at),
|
||||
(
|
||||
s @ (Self::I32 | Self::I64 | Self::F32 | Self::F64 | Self::V128 | Self::Ref(_)),
|
||||
o,
|
||||
) => s == o,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> FromReader<'a> for StorageType {
|
||||
fn from_reader(reader: &mut BinaryReader<'a>) -> Result<Self> {
|
||||
match reader.peek()? {
|
||||
@ -510,6 +534,17 @@ impl RefType {
|
||||
}
|
||||
}
|
||||
|
||||
impl Inherits for RefType {
|
||||
fn inherits<'a, F>(&self, other: &Self, type_at: &F) -> bool
|
||||
where
|
||||
F: Fn(u32) -> &'a SubType,
|
||||
{
|
||||
self == other
|
||||
|| ((other.is_nullable() || !self.is_nullable())
|
||||
&& self.heap_type().inherits(&other.heap_type(), type_at))
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> FromReader<'a> for RefType {
|
||||
fn from_reader(reader: &mut BinaryReader<'a>) -> Result<Self> {
|
||||
match reader.read()? {
|
||||
@ -595,6 +630,69 @@ pub enum HeapType {
|
||||
I31,
|
||||
}
|
||||
|
||||
impl Inherits for HeapType {
|
||||
fn inherits<'a, F>(&self, other: &Self, type_at: &F) -> bool
|
||||
where
|
||||
F: Fn(u32) -> &'a SubType,
|
||||
{
|
||||
match (self, other) {
|
||||
(HeapType::Indexed(a), HeapType::Indexed(b)) => {
|
||||
a == b || type_at(*a).inherits(type_at(*b), type_at)
|
||||
}
|
||||
(HeapType::Indexed(a), HeapType::Func) => match type_at(*a).structural_type {
|
||||
StructuralType::Func(_) => true,
|
||||
_ => false,
|
||||
},
|
||||
(HeapType::Indexed(a), HeapType::Array) => match type_at(*a).structural_type {
|
||||
StructuralType::Array(_) => true,
|
||||
_ => false,
|
||||
},
|
||||
(HeapType::Indexed(a), HeapType::Struct) => match type_at(*a).structural_type {
|
||||
StructuralType::Struct(_) => true,
|
||||
_ => false,
|
||||
},
|
||||
(HeapType::Indexed(a), HeapType::Eq | HeapType::Any) => {
|
||||
match type_at(*a).structural_type {
|
||||
StructuralType::Array(_) | StructuralType::Struct(_) => true,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
(HeapType::Eq, HeapType::Any) => true,
|
||||
(HeapType::I31 | HeapType::Array | HeapType::Struct, HeapType::Eq | HeapType::Any) => {
|
||||
true
|
||||
}
|
||||
(HeapType::None, HeapType::Indexed(a)) => match type_at(*a).structural_type {
|
||||
StructuralType::Array(_) | StructuralType::Struct(_) => true,
|
||||
_ => false,
|
||||
},
|
||||
(
|
||||
HeapType::None,
|
||||
HeapType::I31 | HeapType::Eq | HeapType::Any | HeapType::Array | HeapType::Struct,
|
||||
) => true,
|
||||
(HeapType::NoExtern, HeapType::Extern) => true,
|
||||
(HeapType::NoFunc, HeapType::Func) => true,
|
||||
(HeapType::NoFunc, HeapType::Indexed(a)) => match type_at(*a).structural_type {
|
||||
StructuralType::Func(_) => true,
|
||||
_ => false,
|
||||
},
|
||||
(
|
||||
a @ (HeapType::Func
|
||||
| HeapType::Extern
|
||||
| HeapType::Any
|
||||
| HeapType::Indexed(_)
|
||||
| HeapType::None
|
||||
| HeapType::NoExtern
|
||||
| HeapType::NoFunc
|
||||
| HeapType::Eq
|
||||
| HeapType::Struct
|
||||
| HeapType::Array
|
||||
| HeapType::I31),
|
||||
b,
|
||||
) => a == b,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> FromReader<'a> for HeapType {
|
||||
fn from_reader(reader: &mut BinaryReader<'a>) -> Result<Self> {
|
||||
match reader.peek()? {
|
||||
@ -651,14 +749,38 @@ impl<'a> FromReader<'a> for HeapType {
|
||||
}
|
||||
}
|
||||
|
||||
/// Represents a type in a WebAssembly module.
|
||||
/// Represents a structural type in a WebAssembly module.
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum Type {
|
||||
pub enum StructuralType {
|
||||
/// The type is for a function.
|
||||
Func(FuncType),
|
||||
/// The type is for an array.
|
||||
Array(ArrayType),
|
||||
// Struct(StructType),
|
||||
/// The type is for a struct.
|
||||
Struct(StructType),
|
||||
}
|
||||
|
||||
/// Represents a subtype of possible other types in a WebAssembly module.
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct SubType {
|
||||
/// Is the subtype final.
|
||||
pub is_final: bool,
|
||||
/// The list of supertype indexes. As of GC MVP, there can be at most one supertype.
|
||||
pub supertype_idx: Option<u32>,
|
||||
/// The structural type of the subtype.
|
||||
pub structural_type: StructuralType,
|
||||
}
|
||||
|
||||
impl Inherits for SubType {
|
||||
fn inherits<'a, F>(&self, other: &Self, type_at: &F) -> bool
|
||||
where
|
||||
F: Fn(u32) -> &'a SubType,
|
||||
{
|
||||
!other.is_final
|
||||
&& self
|
||||
.structural_type
|
||||
.inherits(&other.structural_type, type_at)
|
||||
}
|
||||
}
|
||||
|
||||
/// Represents a type of a function in a WebAssembly module.
|
||||
@ -672,13 +794,40 @@ pub struct FuncType {
|
||||
|
||||
/// Represents a type of an array in a WebAssembly module.
|
||||
#[derive(Debug, Clone, Eq, PartialEq, Hash)]
|
||||
pub struct ArrayType {
|
||||
pub struct ArrayType(pub FieldType);
|
||||
|
||||
/// Represents a field type of an array or a struct.
|
||||
#[derive(Debug, Clone, Eq, PartialEq, Hash)]
|
||||
pub struct FieldType {
|
||||
/// Array element type.
|
||||
pub element_type: StorageType,
|
||||
/// Are elements mutable.
|
||||
pub mutable: bool,
|
||||
}
|
||||
|
||||
/// Represents a type of a struct in a WebAssembly module.
|
||||
#[derive(Debug, Clone, Eq, PartialEq, Hash)]
|
||||
pub struct StructType {
|
||||
/// Struct fields.
|
||||
pub fields: Box<[FieldType]>,
|
||||
}
|
||||
|
||||
impl Inherits for StructuralType {
|
||||
fn inherits<'a, F>(&self, other: &Self, type_at: &F) -> bool
|
||||
where
|
||||
F: Fn(u32) -> &'a SubType,
|
||||
{
|
||||
match (self, other) {
|
||||
(StructuralType::Func(a), StructuralType::Func(b)) => a.inherits(b, type_at),
|
||||
(StructuralType::Array(a), StructuralType::Array(b)) => a.inherits(b, type_at),
|
||||
(StructuralType::Struct(a), StructuralType::Struct(b)) => a.inherits(b, type_at),
|
||||
(StructuralType::Func(_), _) => false,
|
||||
(StructuralType::Array(_), _) => false,
|
||||
(StructuralType::Struct(_), _) => false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Debug for FuncType {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
f.debug_struct("FuncType")
|
||||
@ -750,6 +899,73 @@ impl FuncType {
|
||||
}
|
||||
}
|
||||
|
||||
impl Inherits for FuncType {
|
||||
fn inherits<'a, F>(&self, other: &Self, type_at: &F) -> bool
|
||||
where
|
||||
F: Fn(u32) -> &'a SubType,
|
||||
{
|
||||
self.params().len() == other.params().len()
|
||||
&& self.results().len() == other.results().len()
|
||||
// Note: per GC spec, function subtypes are contravariant in their parameter types.
|
||||
// Also see https://en.wikipedia.org/wiki/Covariance_and_contravariance_(computer_science)
|
||||
&& self
|
||||
.params()
|
||||
.iter()
|
||||
.zip(other.params())
|
||||
.fold(true, |r, (a, b)| r && b.inherits(a, type_at))
|
||||
&& self
|
||||
.results()
|
||||
.iter()
|
||||
.zip(other.results())
|
||||
.fold(true, |r, (a, b)| r && a.inherits(b, type_at))
|
||||
}
|
||||
}
|
||||
|
||||
impl Inherits for ArrayType {
|
||||
fn inherits<'a, F>(&self, other: &Self, type_at: &F) -> bool
|
||||
where
|
||||
F: Fn(u32) -> &'a SubType,
|
||||
{
|
||||
self.0.inherits(&other.0, type_at)
|
||||
}
|
||||
}
|
||||
|
||||
impl Inherits for FieldType {
|
||||
fn inherits<'a, F>(&self, other: &Self, type_at: &F) -> bool
|
||||
where
|
||||
F: Fn(u32) -> &'a SubType,
|
||||
{
|
||||
(other.mutable || !self.mutable) && self.element_type.inherits(&other.element_type, type_at)
|
||||
}
|
||||
}
|
||||
|
||||
impl Inherits for StorageType {
|
||||
fn inherits<'a, F>(&self, other: &Self, type_at: &F) -> bool
|
||||
where
|
||||
F: Fn(u32) -> &'a SubType,
|
||||
{
|
||||
match (self, other) {
|
||||
(Self::Val(a), Self::Val(b)) => a.inherits(b, type_at),
|
||||
(a @ (Self::I8 | Self::I16 | Self::Val(_)), b) => a == b,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Inherits for StructType {
|
||||
fn inherits<'a, F>(&self, other: &Self, type_at: &F) -> bool
|
||||
where
|
||||
F: Fn(u32) -> &'a SubType,
|
||||
{
|
||||
// Note: Structure types support width and depth subtyping.
|
||||
self.fields.len() >= other.fields.len()
|
||||
&& self
|
||||
.fields
|
||||
.iter()
|
||||
.zip(other.fields.iter())
|
||||
.fold(true, |r, (a, b)| r && a.inherits(b, type_at))
|
||||
}
|
||||
}
|
||||
|
||||
/// Represents a table's type.
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
|
||||
pub struct TableType {
|
||||
@ -828,14 +1044,50 @@ pub struct TagType {
|
||||
}
|
||||
|
||||
/// A reader for the type section of a WebAssembly module.
|
||||
pub type TypeSectionReader<'a> = SectionLimited<'a, Type>;
|
||||
pub type TypeSectionReader<'a> = SectionLimited<'a, SubType>;
|
||||
|
||||
impl<'a> FromReader<'a> for Type {
|
||||
impl<'a> FromReader<'a> for StructuralType {
|
||||
fn from_reader(reader: &mut BinaryReader<'a>) -> Result<Self> {
|
||||
read_structural_type(reader.read_u8()?, reader)
|
||||
}
|
||||
}
|
||||
|
||||
fn read_structural_type(
|
||||
opcode: u8,
|
||||
reader: &mut BinaryReader,
|
||||
) -> Result<StructuralType, BinaryReaderError> {
|
||||
Ok(match opcode {
|
||||
0x60 => StructuralType::Func(reader.read()?),
|
||||
0x5e => StructuralType::Array(reader.read()?),
|
||||
0x5f => StructuralType::Struct(reader.read()?),
|
||||
x => return reader.invalid_leading_byte(x, "type"),
|
||||
})
|
||||
}
|
||||
|
||||
impl<'a> FromReader<'a> for SubType {
|
||||
fn from_reader(reader: &mut BinaryReader<'a>) -> Result<Self> {
|
||||
let pos = reader.original_position();
|
||||
Ok(match reader.read_u8()? {
|
||||
0x60 => Type::Func(reader.read()?),
|
||||
0x5e => Type::Array(reader.read()?),
|
||||
x => return reader.invalid_leading_byte(x, "type"),
|
||||
opcode @ (0x4e | 0x50) => {
|
||||
let idx_iter = reader.read_iter(MAX_WASM_SUPERTYPES, "supertype idxs")?;
|
||||
let idxs = idx_iter.collect::<Result<Vec<u32>>>()?;
|
||||
if idxs.len() > 1 {
|
||||
return Err(BinaryReaderError::new(
|
||||
"multiple supertypes not supported",
|
||||
pos,
|
||||
));
|
||||
}
|
||||
SubType {
|
||||
is_final: opcode == 0x4e,
|
||||
supertype_idx: idxs.first().copied(),
|
||||
structural_type: read_structural_type(reader.read_u8()?, reader)?,
|
||||
}
|
||||
}
|
||||
opcode => SubType {
|
||||
is_final: false,
|
||||
supertype_idx: None,
|
||||
structural_type: read_structural_type(opcode, reader)?,
|
||||
},
|
||||
})
|
||||
}
|
||||
}
|
||||
@ -855,11 +1107,11 @@ impl<'a> FromReader<'a> for FuncType {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> FromReader<'a> for ArrayType {
|
||||
impl<'a> FromReader<'a> for FieldType {
|
||||
fn from_reader(reader: &mut BinaryReader<'a>) -> Result<Self> {
|
||||
let element_type = reader.read()?;
|
||||
let mutable = reader.read_u8()?;
|
||||
Ok(ArrayType {
|
||||
Ok(FieldType {
|
||||
element_type,
|
||||
mutable: match mutable {
|
||||
0 => false,
|
||||
@ -872,3 +1124,18 @@ impl<'a> FromReader<'a> for ArrayType {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> FromReader<'a> for ArrayType {
|
||||
fn from_reader(reader: &mut BinaryReader<'a>) -> Result<Self> {
|
||||
Ok(ArrayType(FieldType::from_reader(reader)?))
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> FromReader<'a> for StructType {
|
||||
fn from_reader(reader: &mut BinaryReader<'a>) -> Result<Self> {
|
||||
let fields = reader.read_iter(MAX_WASM_STRUCT_FIELDS, "struct fields")?;
|
||||
Ok(StructType {
|
||||
fields: fields.collect::<Result<_>>()?,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
92
third_party/rust/wasmparser/src/validator.rs
vendored
92
third_party/rust/wasmparser/src/validator.rs
vendored
@ -1156,8 +1156,8 @@ impl Validator {
|
||||
crate::CanonicalFunction::ResourceNew { resource } => {
|
||||
current.resource_new(resource, types, offset)
|
||||
}
|
||||
crate::CanonicalFunction::ResourceDrop { ty } => {
|
||||
current.resource_drop(ty, types, offset)
|
||||
crate::CanonicalFunction::ResourceDrop { resource } => {
|
||||
current.resource_drop(resource, types, offset)
|
||||
}
|
||||
crate::CanonicalFunction::ResourceRep { resource } => {
|
||||
current.resource_rep(resource, types, offset)
|
||||
@ -1441,66 +1441,52 @@ mod tests {
|
||||
assert_eq!(types.instance_count(), 0);
|
||||
assert_eq!(types.value_count(), 0);
|
||||
|
||||
match types.func_type_at(0) {
|
||||
Some(ty) => {
|
||||
assert_eq!(ty.params(), [ValType::I32, ValType::I64]);
|
||||
assert_eq!(ty.results(), [ValType::I32]);
|
||||
}
|
||||
_ => unreachable!(),
|
||||
}
|
||||
let ty = types[types.core_type_at(0)].unwrap_func();
|
||||
assert_eq!(ty.params(), [ValType::I32, ValType::I64]);
|
||||
assert_eq!(ty.results(), [ValType::I32]);
|
||||
|
||||
match types.func_type_at(1) {
|
||||
Some(ty) => {
|
||||
assert_eq!(ty.params(), [ValType::I64, ValType::I32]);
|
||||
assert_eq!(ty.results(), []);
|
||||
}
|
||||
_ => unreachable!(),
|
||||
}
|
||||
let ty = types[types.core_type_at(1)].unwrap_func();
|
||||
assert_eq!(ty.params(), [ValType::I64, ValType::I32]);
|
||||
assert_eq!(ty.results(), []);
|
||||
|
||||
assert_eq!(
|
||||
types.memory_at(0),
|
||||
Some(MemoryType {
|
||||
MemoryType {
|
||||
memory64: false,
|
||||
shared: false,
|
||||
initial: 1,
|
||||
maximum: Some(5)
|
||||
})
|
||||
}
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
types.table_at(0),
|
||||
Some(TableType {
|
||||
TableType {
|
||||
initial: 10,
|
||||
maximum: None,
|
||||
element_type: RefType::FUNCREF,
|
||||
})
|
||||
}
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
types.global_at(0),
|
||||
Some(GlobalType {
|
||||
GlobalType {
|
||||
content_type: ValType::I32,
|
||||
mutable: true
|
||||
})
|
||||
}
|
||||
);
|
||||
|
||||
match types.function_at(0) {
|
||||
Some(ty) => {
|
||||
assert_eq!(ty.params(), [ValType::I32, ValType::I64]);
|
||||
assert_eq!(ty.results(), [ValType::I32]);
|
||||
}
|
||||
_ => unreachable!(),
|
||||
}
|
||||
let id = types.function_at(0);
|
||||
let ty = types[id].unwrap_func();
|
||||
assert_eq!(ty.params(), [ValType::I32, ValType::I64]);
|
||||
assert_eq!(ty.results(), [ValType::I32]);
|
||||
|
||||
match types.tag_at(0) {
|
||||
Some(ty) => {
|
||||
assert_eq!(ty.params(), [ValType::I64, ValType::I32]);
|
||||
assert_eq!(ty.results(), []);
|
||||
}
|
||||
_ => unreachable!(),
|
||||
}
|
||||
let ty = types.tag_at(0);
|
||||
let ty = types[ty].unwrap_func();
|
||||
assert_eq!(ty.params(), [ValType::I64, ValType::I32]);
|
||||
assert_eq!(ty.results(), []);
|
||||
|
||||
assert_eq!(types.element_at(0), Some(RefType::FUNCREF));
|
||||
assert_eq!(types.element_at(0), RefType::FUNCREF);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@ -1524,9 +1510,9 @@ mod tests {
|
||||
|
||||
let types = validator.validate_all(&bytes)?;
|
||||
|
||||
let t_id = types.id_from_type_index(0, false).unwrap();
|
||||
let a1_id = types.id_from_type_index(1, false).unwrap();
|
||||
let a2_id = types.id_from_type_index(2, false).unwrap();
|
||||
let t_id = types.component_type_at(0);
|
||||
let a1_id = types.component_type_at(1);
|
||||
let a2_id = types.component_type_at(2);
|
||||
|
||||
// The ids should all be the same
|
||||
assert!(t_id == a1_id);
|
||||
@ -1534,14 +1520,8 @@ mod tests {
|
||||
assert!(a1_id == a2_id);
|
||||
|
||||
// However, they should all point to the same type
|
||||
assert!(std::ptr::eq(
|
||||
types.type_from_id(t_id).unwrap(),
|
||||
types.type_from_id(a1_id).unwrap()
|
||||
));
|
||||
assert!(std::ptr::eq(
|
||||
types.type_from_id(t_id).unwrap(),
|
||||
types.type_from_id(a2_id).unwrap()
|
||||
));
|
||||
assert!(std::ptr::eq(&types[t_id], &types[a1_id],));
|
||||
assert!(std::ptr::eq(&types[t_id], &types[a2_id],));
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@ -1565,9 +1545,9 @@ mod tests {
|
||||
|
||||
let types = validator.validate_all(&bytes)?;
|
||||
|
||||
let t_id = types.id_from_type_index(0, false).unwrap();
|
||||
let a1_id = types.id_from_type_index(1, false).unwrap();
|
||||
let a2_id = types.id_from_type_index(2, false).unwrap();
|
||||
let t_id = types.component_type_at(0);
|
||||
let a1_id = types.component_type_at(1);
|
||||
let a2_id = types.component_type_at(2);
|
||||
|
||||
// The ids should all be the same
|
||||
assert!(t_id != a1_id);
|
||||
@ -1575,14 +1555,8 @@ mod tests {
|
||||
assert!(a1_id != a2_id);
|
||||
|
||||
// However, they should all point to the same type
|
||||
assert!(std::ptr::eq(
|
||||
types.type_from_id(t_id).unwrap(),
|
||||
types.type_from_id(a1_id).unwrap()
|
||||
));
|
||||
assert!(std::ptr::eq(
|
||||
types.type_from_id(t_id).unwrap(),
|
||||
types.type_from_id(a2_id).unwrap()
|
||||
));
|
||||
assert!(std::ptr::eq(&types[t_id], &types[a1_id],));
|
||||
assert!(std::ptr::eq(&types[t_id], &types[a2_id],));
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
@ -18,7 +18,8 @@ use crate::{
|
||||
},
|
||||
BinaryReaderError, CanonicalOption, ComponentExternName, ComponentExternalKind,
|
||||
ComponentOuterAliasKind, ComponentTypeRef, ExternalKind, FuncType, GlobalType,
|
||||
InstantiationArgKind, MemoryType, Result, TableType, TypeBounds, ValType, WasmFeatures,
|
||||
InstantiationArgKind, MemoryType, Result, StructuralType, SubType, TableType, TypeBounds,
|
||||
ValType, WasmFeatures,
|
||||
};
|
||||
use indexmap::{map::Entry, IndexMap, IndexSet};
|
||||
use std::collections::{HashMap, HashSet};
|
||||
@ -257,7 +258,11 @@ impl ComponentState {
|
||||
check_limit: bool,
|
||||
) -> Result<()> {
|
||||
let ty = match ty {
|
||||
crate::CoreType::Func(ty) => Type::Func(ty),
|
||||
crate::CoreType::Func(ty) => Type::Sub(SubType {
|
||||
is_final: false,
|
||||
supertype_idx: None,
|
||||
structural_type: StructuralType::Func(ty),
|
||||
}),
|
||||
crate::CoreType::Module(decls) => Type::Module(Box::new(Self::create_module_type(
|
||||
components,
|
||||
decls.into_vec(),
|
||||
@ -371,7 +376,7 @@ impl ComponentState {
|
||||
// function and has the correct signature.
|
||||
if let Some(dtor) = dtor {
|
||||
let ty = component.core_function_at(dtor, offset)?;
|
||||
let ty = types[ty].as_func_type().unwrap();
|
||||
let ty = types[ty].unwrap_func();
|
||||
if ty.params() != [rep] || ty.results() != [] {
|
||||
bail!(
|
||||
offset,
|
||||
@ -555,6 +560,21 @@ impl ComponentState {
|
||||
ty: &ComponentEntityType,
|
||||
types: &TypeAlloc,
|
||||
) -> bool {
|
||||
if let ComponentEntityType::Type { created, .. } = ty {
|
||||
// If this is a top-level resource then register it in the
|
||||
// appropriate context so later validation of method-like-names
|
||||
// works out.
|
||||
if let Some(name) = toplevel_name {
|
||||
if let Type::Resource(_) = types[*created] {
|
||||
let cx = match kind {
|
||||
ExternKind::Import => &mut self.toplevel_imported_resources,
|
||||
ExternKind::Export => &mut self.toplevel_exported_resources,
|
||||
};
|
||||
cx.register(name, *created);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
match self.kind {
|
||||
ComponentKind::Component | ComponentKind::ComponentType => {}
|
||||
ComponentKind::InstanceType => return true,
|
||||
@ -589,19 +609,6 @@ impl ComponentState {
|
||||
}
|
||||
}
|
||||
|
||||
// If this is a top-level resource then register it in the
|
||||
// appropriate context so later validation of method-like-names
|
||||
// works out.
|
||||
if let Some(name) = toplevel_name {
|
||||
if let Type::Resource(_) = types[*created] {
|
||||
let cx = match kind {
|
||||
ExternKind::Import => &mut self.toplevel_imported_resources,
|
||||
ExternKind::Export => &mut self.toplevel_exported_resources,
|
||||
};
|
||||
cx.register(name, *created);
|
||||
}
|
||||
}
|
||||
|
||||
true
|
||||
}
|
||||
|
||||
@ -618,7 +625,7 @@ impl ComponentState {
|
||||
// captured, and everything is appropriately added to the right
|
||||
// imported/exported set.
|
||||
ComponentEntityType::Instance(i) => {
|
||||
let ty = types[*i].as_component_instance_type().unwrap();
|
||||
let ty = types[*i].unwrap_component_instance();
|
||||
ty.exports
|
||||
.values()
|
||||
.all(|ty| self.validate_and_register_named_types(None, kind, ty, types))
|
||||
@ -680,7 +687,7 @@ impl ComponentState {
|
||||
|
||||
// Core wasm constructs are always valid with respect to
|
||||
// exported types, since they have none.
|
||||
Type::Module(_) | Type::Instance(_) | Type::Func(_) | Type::Array(_) => true,
|
||||
Type::Module(_) | Type::Instance(_) | Type::Sub(_) => true,
|
||||
|
||||
// Resource types, in isolation, are always valid to import
|
||||
// or export since they're either attached to an import or
|
||||
@ -733,7 +740,7 @@ impl ComponentState {
|
||||
/// do not share resource types despite sharing the same original instance
|
||||
/// type.
|
||||
fn prepare_instance_import(&mut self, id: &mut TypeId, types: &mut TypeAlloc) {
|
||||
let ty = types[*id].as_component_instance_type().unwrap();
|
||||
let ty = types[*id].unwrap_component_instance();
|
||||
|
||||
// No special treatment for imports of instances which themselves have
|
||||
// no defined resources
|
||||
@ -767,7 +774,7 @@ impl ComponentState {
|
||||
// path for where they're imported is updated as well with
|
||||
// `self.next_import_index` as the import-to-be soon.
|
||||
let mut mapping = Remapping::default();
|
||||
let ty = types[*id].as_component_instance_type().unwrap();
|
||||
let ty = types[*id].unwrap_component_instance();
|
||||
for (old, new) in ty.defined_resources.iter().zip(&resources) {
|
||||
let prev = mapping.resources.insert(*old, *new);
|
||||
assert!(prev.is_none());
|
||||
@ -804,7 +811,7 @@ impl ComponentState {
|
||||
// encapsulates. This means that the instance type
|
||||
// recorded for this export will itself have no
|
||||
// defined resources.
|
||||
let ty = types[*id].as_component_instance_type().unwrap();
|
||||
let ty = types[*id].unwrap_component_instance();
|
||||
|
||||
// Check to see if `defined_resources` is non-empty, and if so then
|
||||
// "freshen" all the resources and inherit them to our own defined
|
||||
@ -837,9 +844,8 @@ impl ComponentState {
|
||||
types.remap_component_entity(ty, &mut mapping);
|
||||
}
|
||||
for (id, path) in mem::take(&mut new_ty.explicit_resources) {
|
||||
new_ty
|
||||
.explicit_resources
|
||||
.insert(mapping.resources[&id], path);
|
||||
let id = mapping.resources.get(&id).copied().unwrap_or(id);
|
||||
new_ty.explicit_resources.insert(id, path);
|
||||
}
|
||||
*id = types.push_ty(Type::ComponentInstance(Box::new(new_ty)));
|
||||
}
|
||||
@ -850,7 +856,7 @@ impl ComponentState {
|
||||
// The path to each explicit resources gets one element prepended which
|
||||
// is `self.next_export_index`, the index of the export about to be
|
||||
// generated.
|
||||
let ty = types[*id].as_component_instance_type().unwrap();
|
||||
let ty = types[*id].unwrap_component_instance();
|
||||
for (id, path) in ty.explicit_resources.iter() {
|
||||
let mut new_path = vec![self.exports.len()];
|
||||
new_path.extend(path);
|
||||
@ -897,9 +903,7 @@ impl ComponentState {
|
||||
offset: usize,
|
||||
) -> Result<()> {
|
||||
let ty = self.function_type_at(type_index, types, offset)?;
|
||||
let core_ty = types[self.core_function_at(core_func_index, offset)?]
|
||||
.as_func_type()
|
||||
.unwrap();
|
||||
let core_ty = types[self.core_function_at(core_func_index, offset)?].unwrap_func();
|
||||
|
||||
// Lifting a function is for an export, so match the expected canonical ABI
|
||||
// export signature
|
||||
@ -938,9 +942,7 @@ impl ComponentState {
|
||||
types: &mut TypeAlloc,
|
||||
offset: usize,
|
||||
) -> Result<()> {
|
||||
let ty = types[self.function_at(func_index, offset)?]
|
||||
.as_component_func_type()
|
||||
.unwrap();
|
||||
let ty = types[self.function_at(func_index, offset)?].unwrap_component_func();
|
||||
|
||||
// Lowering a function is for an import, so use a function type that matches
|
||||
// the expected canonical ABI import signature.
|
||||
@ -948,7 +950,11 @@ impl ComponentState {
|
||||
|
||||
self.check_options(None, &info, &options, types, offset)?;
|
||||
|
||||
let lowered_ty = Type::Func(info.into_func_type());
|
||||
let lowered_ty = Type::Sub(SubType {
|
||||
is_final: false,
|
||||
supertype_idx: None,
|
||||
structural_type: StructuralType::Func(info.into_func_type()),
|
||||
});
|
||||
|
||||
let id = types.push_ty(lowered_ty);
|
||||
self.core_funcs.push(id);
|
||||
@ -963,29 +969,27 @@ impl ComponentState {
|
||||
offset: usize,
|
||||
) -> Result<()> {
|
||||
let rep = self.check_local_resource(resource, types, offset)?;
|
||||
let core_ty = Type::Func(FuncType::new([rep], [ValType::I32]));
|
||||
let core_ty = Type::Sub(SubType {
|
||||
is_final: false,
|
||||
supertype_idx: None,
|
||||
structural_type: StructuralType::Func(FuncType::new([rep], [ValType::I32])),
|
||||
});
|
||||
self.core_funcs.push(types.push_ty(core_ty));
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn resource_drop(
|
||||
&mut self,
|
||||
ty: crate::ComponentValType,
|
||||
resource: u32,
|
||||
types: &mut TypeAlloc,
|
||||
offset: usize,
|
||||
) -> Result<()> {
|
||||
let idx = match ty {
|
||||
crate::ComponentValType::Primitive(_) => {
|
||||
bail!(offset, "type-to-drop must be an own or borrow type")
|
||||
}
|
||||
crate::ComponentValType::Type(idx) => idx,
|
||||
};
|
||||
let ty = self.defined_type_at(idx, types, offset)?;
|
||||
match types[ty].as_defined_type().unwrap() {
|
||||
ComponentDefinedType::Own(_) | ComponentDefinedType::Borrow(_) => {}
|
||||
_ => bail!(offset, "type-to-drop must be an own or borrow type"),
|
||||
}
|
||||
let core_ty = Type::Func(FuncType::new([ValType::I32], []));
|
||||
self.resource_at(resource, types, offset)?;
|
||||
let core_ty = Type::Sub(SubType {
|
||||
is_final: false,
|
||||
supertype_idx: None,
|
||||
structural_type: StructuralType::Func(FuncType::new([ValType::I32], [])),
|
||||
});
|
||||
self.core_funcs.push(types.push_ty(core_ty));
|
||||
Ok(())
|
||||
}
|
||||
@ -997,14 +1001,18 @@ impl ComponentState {
|
||||
offset: usize,
|
||||
) -> Result<()> {
|
||||
let rep = self.check_local_resource(resource, types, offset)?;
|
||||
let core_ty = Type::Func(FuncType::new([ValType::I32], [rep]));
|
||||
let core_ty = Type::Sub(SubType {
|
||||
is_final: false,
|
||||
supertype_idx: None,
|
||||
structural_type: StructuralType::Func(FuncType::new([ValType::I32], [rep])),
|
||||
});
|
||||
self.core_funcs.push(types.push_ty(core_ty));
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn check_local_resource(&self, idx: u32, types: &TypeList, offset: usize) -> Result<ValType> {
|
||||
let id = self.resource_at(idx, types, offset)?;
|
||||
let resource = types[id].as_resource().unwrap();
|
||||
let resource = types[id].unwrap_resource();
|
||||
match self.defined_resources.get(&resource).and_then(|rep| *rep) {
|
||||
Some(ty) => Ok(ty),
|
||||
None => bail!(offset, "type {idx} is not a local resource"),
|
||||
@ -1108,9 +1116,7 @@ impl ComponentState {
|
||||
));
|
||||
}
|
||||
|
||||
let ft = types[self.function_at(func_index, offset)?]
|
||||
.as_component_func_type()
|
||||
.unwrap();
|
||||
let ft = types[self.function_at(func_index, offset)?].unwrap_component_func();
|
||||
|
||||
if ft.params.len() != args.len() {
|
||||
bail!(
|
||||
@ -1204,9 +1210,7 @@ impl ComponentState {
|
||||
CanonicalOption::Realloc(idx) => {
|
||||
realloc = match realloc {
|
||||
None => {
|
||||
let ty = types[self.core_function_at(*idx, offset)?]
|
||||
.as_func_type()
|
||||
.unwrap();
|
||||
let ty = types[self.core_function_at(*idx, offset)?].unwrap_func();
|
||||
if ty.params()
|
||||
!= [ValType::I32, ValType::I32, ValType::I32, ValType::I32]
|
||||
|| ty.results() != [ValType::I32]
|
||||
@ -1236,9 +1240,7 @@ impl ComponentState {
|
||||
)
|
||||
})?;
|
||||
|
||||
let ty = types[self.core_function_at(*idx, offset)?]
|
||||
.as_func_type()
|
||||
.unwrap();
|
||||
let ty = types[self.core_function_at(*idx, offset)?].unwrap_func();
|
||||
|
||||
if ty.params() != core_ty.results() || !ty.results().is_empty() {
|
||||
return Err(BinaryReaderError::new(
|
||||
@ -1285,16 +1287,18 @@ impl ComponentState {
|
||||
Ok(match ty {
|
||||
ComponentTypeRef::Module(index) => {
|
||||
let id = self.type_at(*index, true, offset)?;
|
||||
types[id].as_module_type().ok_or_else(|| {
|
||||
format_err!(offset, "core type index {index} is not a module type")
|
||||
})?;
|
||||
match &types[id] {
|
||||
Type::Module(_) => {}
|
||||
_ => bail!(offset, "core type index {index} is not a module type"),
|
||||
}
|
||||
ComponentEntityType::Module(id)
|
||||
}
|
||||
ComponentTypeRef::Func(index) => {
|
||||
let id = self.type_at(*index, false, offset)?;
|
||||
types[id].as_component_func_type().ok_or_else(|| {
|
||||
format_err!(offset, "type index {index} is not a function type")
|
||||
})?;
|
||||
match &types[id] {
|
||||
Type::ComponentFunc(_) => {}
|
||||
_ => bail!(offset, "type index {index} is not a function type"),
|
||||
}
|
||||
ComponentEntityType::Func(id)
|
||||
}
|
||||
ComponentTypeRef::Value(ty) => {
|
||||
@ -1324,16 +1328,18 @@ impl ComponentState {
|
||||
}
|
||||
ComponentTypeRef::Instance(index) => {
|
||||
let id = self.type_at(*index, false, offset)?;
|
||||
types[id].as_component_instance_type().ok_or_else(|| {
|
||||
format_err!(offset, "type index {index} is not an instance type")
|
||||
})?;
|
||||
match &types[id] {
|
||||
Type::ComponentInstance(_) => {}
|
||||
_ => bail!(offset, "type index {index} is not an instance type"),
|
||||
}
|
||||
ComponentEntityType::Instance(id)
|
||||
}
|
||||
ComponentTypeRef::Component(index) => {
|
||||
let id = self.type_at(*index, false, offset)?;
|
||||
types[id].as_component_type().ok_or_else(|| {
|
||||
format_err!(offset, "type index {index} is not a component type")
|
||||
})?;
|
||||
match &types[id] {
|
||||
Type::Component(_) => {}
|
||||
_ => bail!(offset, "type index {index} is not a component type"),
|
||||
}
|
||||
ComponentEntityType::Component(id)
|
||||
}
|
||||
})
|
||||
@ -1632,16 +1638,15 @@ impl ComponentState {
|
||||
for module_arg in module_args {
|
||||
match module_arg.kind {
|
||||
InstantiationArgKind::Instance => {
|
||||
let instance_type = types[self.core_instance_at(module_arg.index, offset)?]
|
||||
.as_instance_type()
|
||||
.unwrap();
|
||||
let instance_type =
|
||||
types[self.core_instance_at(module_arg.index, offset)?].unwrap_instance();
|
||||
insert_arg(module_arg.name, instance_type, &mut args, offset)?;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Validate the arguments
|
||||
let module_type = types[module_type_id].as_module_type().unwrap();
|
||||
let module_type = types[module_type_id].unwrap_module();
|
||||
let cx = SubtypeCx::new(types, types);
|
||||
for ((module, name), expected) in module_type.imports.iter() {
|
||||
let instance = args.get(module.as_str()).ok_or_else(|| {
|
||||
@ -1811,7 +1816,7 @@ impl ComponentState {
|
||||
// comments are hopefully enough when augmented with communication with
|
||||
// the authors.
|
||||
|
||||
let component_type = types[component_type_id].as_component_type().unwrap();
|
||||
let component_type = types[component_type_id].unwrap_component();
|
||||
let mut exports = component_type.exports.clone();
|
||||
let type_size = component_type
|
||||
.exports
|
||||
@ -1856,7 +1861,7 @@ impl ComponentState {
|
||||
let fresh_defined_resources = (0..component_type.defined_resources.len())
|
||||
.map(|_| types.alloc_resource_id())
|
||||
.collect::<IndexSet<_>>();
|
||||
let component_type = types[component_type_id].as_component_type().unwrap();
|
||||
let component_type = types[component_type_id].unwrap_component();
|
||||
for ((old, _path), new) in component_type
|
||||
.defined_resources
|
||||
.iter()
|
||||
@ -1879,7 +1884,7 @@ impl ComponentState {
|
||||
for entity in exports.values_mut() {
|
||||
types.remap_component_entity(entity, &mut mapping);
|
||||
}
|
||||
let component_type = types[component_type_id].as_component_type().unwrap();
|
||||
let component_type = types[component_type_id].unwrap_component();
|
||||
let explicit_resources = component_type
|
||||
.explicit_resources
|
||||
.iter()
|
||||
@ -1983,8 +1988,7 @@ impl ComponentState {
|
||||
// instance, just with one more element in their path.
|
||||
explicit_resources.extend(
|
||||
types[ty]
|
||||
.as_component_instance_type()
|
||||
.unwrap()
|
||||
.unwrap_component_instance()
|
||||
.explicit_resources
|
||||
.iter()
|
||||
.map(|(id, path)| {
|
||||
@ -2229,8 +2233,7 @@ impl ComponentState {
|
||||
offset: usize,
|
||||
) -> Result<()> {
|
||||
let mut ty = match types[self.instance_at(instance_index, offset)?]
|
||||
.as_component_instance_type()
|
||||
.unwrap()
|
||||
.unwrap_component_instance()
|
||||
.exports
|
||||
.get(name)
|
||||
{
|
||||
@ -2647,9 +2650,10 @@ impl ComponentState {
|
||||
types: &'a TypeList,
|
||||
offset: usize,
|
||||
) -> Result<&'a ComponentFuncType> {
|
||||
types[self.type_at(idx, false, offset)?]
|
||||
.as_component_func_type()
|
||||
.ok_or_else(|| format_err!(offset, "type index {idx} is not a function type"))
|
||||
match &types[self.type_at(idx, false, offset)?] {
|
||||
Type::ComponentFunc(f) => Ok(f),
|
||||
_ => bail!(offset, "type index {idx} is not a function type"),
|
||||
}
|
||||
}
|
||||
|
||||
fn function_at(&self, idx: u32, offset: usize) -> Result<TypeId> {
|
||||
@ -2733,8 +2737,7 @@ impl ComponentState {
|
||||
offset: usize,
|
||||
) -> Result<&'a EntityType> {
|
||||
match types[self.core_instance_at(instance_index, offset)?]
|
||||
.as_instance_type()
|
||||
.unwrap()
|
||||
.unwrap_instance()
|
||||
.internal_exports(types)
|
||||
.get(name)
|
||||
{
|
||||
@ -2944,7 +2947,7 @@ impl KebabNameContext {
|
||||
ComponentEntityType::Func(id) => *id,
|
||||
_ => bail!(offset, "item is not a func"),
|
||||
};
|
||||
Ok(types[id].as_component_func_type().unwrap())
|
||||
Ok(types[id].unwrap_component_func())
|
||||
};
|
||||
match name.kind() {
|
||||
// Normal kebab name or id? No validation necessary.
|
||||
|
282
third_party/rust/wasmparser/src/validator/core.rs
vendored
282
third_party/rust/wasmparser/src/validator/core.rs
vendored
@ -6,11 +6,12 @@ use super::{
|
||||
types::{EntityType, Type, TypeAlloc, TypeId, TypeList},
|
||||
};
|
||||
use crate::limits::*;
|
||||
use crate::readers::Inherits;
|
||||
use crate::validator::core::arc::MaybeOwned;
|
||||
use crate::{
|
||||
BinaryReaderError, ConstExpr, Data, DataKind, Element, ElementKind, ExternalKind, FuncType,
|
||||
Global, GlobalType, HeapType, MemoryType, RefType, Result, StorageType, Table, TableInit,
|
||||
TableType, TagType, TypeRef, ValType, VisitOperator, WasmFeatures, WasmFuncType,
|
||||
Global, GlobalType, HeapType, MemoryType, RefType, Result, StorageType, StructuralType,
|
||||
SubType, Table, TableInit, TableType, TagType, TypeRef, ValType, VisitOperator, WasmFeatures,
|
||||
WasmModuleResources,
|
||||
};
|
||||
use indexmap::IndexMap;
|
||||
@ -198,24 +199,30 @@ impl ModuleState {
|
||||
) -> Result<()> {
|
||||
// the `funcref` value type is allowed all the way back to the MVP, so
|
||||
// don't check it here
|
||||
if e.ty != RefType::FUNCREF {
|
||||
self.module
|
||||
.check_value_type(ValType::Ref(e.ty), features, offset)?;
|
||||
}
|
||||
let element_ty = match &e.items {
|
||||
crate::ElementItems::Functions(_) => RefType::FUNC,
|
||||
crate::ElementItems::Expressions(ty, _) => {
|
||||
self.module
|
||||
.check_value_type(ValType::Ref(*ty), features, offset)?;
|
||||
*ty
|
||||
}
|
||||
};
|
||||
|
||||
match e.kind {
|
||||
ElementKind::Active {
|
||||
table_index,
|
||||
offset_expr,
|
||||
} => {
|
||||
let table = self.module.table_at(table_index.unwrap_or(0), offset)?;
|
||||
if !self
|
||||
.module
|
||||
.matches(ValType::Ref(e.ty), ValType::Ref(table.element_type), types)
|
||||
{
|
||||
if !self.module.matches(
|
||||
ValType::Ref(element_ty),
|
||||
ValType::Ref(table.element_type),
|
||||
types,
|
||||
) {
|
||||
return Err(BinaryReaderError::new(
|
||||
format!(
|
||||
"type mismatch: invalid element type `{}` for table type `{}`",
|
||||
ty_to_str(e.ty.into()),
|
||||
ty_to_str(element_ty.into()),
|
||||
ty_to_str(table.element_type.into()),
|
||||
),
|
||||
offset,
|
||||
@ -247,12 +254,6 @@ impl ModuleState {
|
||||
match e.items {
|
||||
crate::ElementItems::Functions(reader) => {
|
||||
let count = reader.count();
|
||||
if !e.ty.is_nullable() && count <= 0 {
|
||||
return Err(BinaryReaderError::new(
|
||||
"a non-nullable element must come with an initialization expression",
|
||||
offset,
|
||||
));
|
||||
}
|
||||
validate_count(count)?;
|
||||
for f in reader.into_iter_with_offsets() {
|
||||
let (offset, f) = f?;
|
||||
@ -260,14 +261,14 @@ impl ModuleState {
|
||||
self.module.assert_mut().function_references.insert(f);
|
||||
}
|
||||
}
|
||||
crate::ElementItems::Expressions(reader) => {
|
||||
crate::ElementItems::Expressions(ty, reader) => {
|
||||
validate_count(reader.count())?;
|
||||
for expr in reader {
|
||||
self.check_const_expr(&expr?, ValType::Ref(e.ty), features, types)?;
|
||||
self.check_const_expr(&expr?, ValType::Ref(ty), features, types)?;
|
||||
}
|
||||
}
|
||||
}
|
||||
self.module.assert_mut().element_types.push(e.ty);
|
||||
self.module.assert_mut().element_types.push(element_ty);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@ -494,14 +495,79 @@ pub(crate) struct Module {
|
||||
impl Module {
|
||||
pub fn add_type(
|
||||
&mut self,
|
||||
ty: crate::Type,
|
||||
ty: SubType,
|
||||
features: &WasmFeatures,
|
||||
types: &mut TypeAlloc,
|
||||
offset: usize,
|
||||
check_limit: bool,
|
||||
) -> Result<()> {
|
||||
let ty = match ty {
|
||||
crate::Type::Func(t) => {
|
||||
if check_limit {
|
||||
check_max(self.types.len(), 1, MAX_WASM_TYPES, "types", offset)?;
|
||||
}
|
||||
let ty = self.check_subtype(ty, features, types, offset)?;
|
||||
|
||||
let id = types.push_ty(ty);
|
||||
self.types.push(id);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn check_subtype(
|
||||
&mut self,
|
||||
ty: SubType,
|
||||
features: &WasmFeatures,
|
||||
types: &mut TypeAlloc,
|
||||
offset: usize,
|
||||
) -> Result<Type> {
|
||||
if !features.gc && (ty.is_final || ty.supertype_idx.is_some()) {
|
||||
return Err(BinaryReaderError::new(
|
||||
"gc proposal must be enabled to use subtypes",
|
||||
offset,
|
||||
));
|
||||
}
|
||||
|
||||
self.check_structural_type(&ty.structural_type, features, offset)?;
|
||||
|
||||
if let Some(type_index) = ty.supertype_idx {
|
||||
// Check the supertype exists, is not final, and the subtype matches it.
|
||||
match self.type_at(types, type_index, offset)? {
|
||||
Type::Sub(st) => {
|
||||
if !&ty.inherits(st, &|idx| self.subtype_at(types, idx, offset).unwrap()) {
|
||||
return Err(BinaryReaderError::new(
|
||||
"subtype must match supertype",
|
||||
offset,
|
||||
));
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
return Err(BinaryReaderError::new(
|
||||
"supertype must be a non-final subtype itself",
|
||||
offset,
|
||||
));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
Ok(Type::Sub(ty))
|
||||
}
|
||||
|
||||
fn subtype_at<'a>(&self, types: &'a TypeList, idx: u32, offset: usize) -> Result<&'a SubType> {
|
||||
match self.type_at(types, idx, offset)? {
|
||||
Type::Sub(ty) => Ok(ty),
|
||||
_ => bail!(
|
||||
offset,
|
||||
"subtype with index {idx} not found, offset: {offset}"
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
fn check_structural_type(
|
||||
&mut self,
|
||||
ty: &StructuralType,
|
||||
features: &WasmFeatures,
|
||||
offset: usize,
|
||||
) -> Result<()> {
|
||||
match ty {
|
||||
StructuralType::Func(t) => {
|
||||
for ty in t.params().iter().chain(t.results()) {
|
||||
self.check_value_type(*ty, features, offset)?;
|
||||
}
|
||||
@ -511,31 +577,33 @@ impl Module {
|
||||
offset,
|
||||
));
|
||||
}
|
||||
Type::Func(t)
|
||||
}
|
||||
crate::Type::Array(t) => {
|
||||
StructuralType::Array(t) => {
|
||||
if !features.gc {
|
||||
return Err(BinaryReaderError::new(
|
||||
"array indexed types not supported without the gc feature",
|
||||
offset,
|
||||
));
|
||||
}
|
||||
match t.element_type {
|
||||
crate::StorageType::I8 | crate::StorageType::I16 => {}
|
||||
crate::StorageType::Val(value_type) => {
|
||||
match t.0.element_type {
|
||||
StorageType::I8 | StorageType::I16 => {}
|
||||
StorageType::Val(value_type) => {
|
||||
self.check_value_type(value_type, features, offset)?;
|
||||
}
|
||||
};
|
||||
Type::Array(t)
|
||||
}
|
||||
};
|
||||
|
||||
if check_limit {
|
||||
check_max(self.types.len(), 1, MAX_WASM_TYPES, "types", offset)?;
|
||||
StructuralType::Struct(t) => {
|
||||
if !features.gc {
|
||||
return Err(BinaryReaderError::new(
|
||||
"struct indexed types not supported without the gc feature",
|
||||
offset,
|
||||
));
|
||||
}
|
||||
for ty in t.fields.iter() {
|
||||
self.check_storage_type(ty.element_type, features, offset)?;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let id = types.push_ty(ty);
|
||||
self.types.push(id);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@ -671,9 +739,13 @@ impl Module {
|
||||
types: &'a TypeList,
|
||||
offset: usize,
|
||||
) -> Result<&'a FuncType> {
|
||||
types[self.type_id_at(type_index, offset)?]
|
||||
.as_func_type()
|
||||
.ok_or_else(|| format_err!(offset, "type index {type_index} is not a function type"))
|
||||
match &types[self.type_id_at(type_index, offset)?] {
|
||||
Type::Sub(SubType {
|
||||
structural_type: StructuralType::Func(f),
|
||||
..
|
||||
}) => Ok(f),
|
||||
_ => bail!(offset, "type index {type_index} is not a function type"),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn check_type_ref(
|
||||
@ -798,6 +870,21 @@ impl Module {
|
||||
.collect::<Result<_>>()
|
||||
}
|
||||
|
||||
fn check_storage_type(
|
||||
&self,
|
||||
ty: StorageType,
|
||||
features: &WasmFeatures,
|
||||
offset: usize,
|
||||
) -> Result<()> {
|
||||
match ty {
|
||||
StorageType::I8 | StorageType::I16 => {}
|
||||
StorageType::Val(value_type) => {
|
||||
self.check_value_type(value_type, features, offset)?;
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn check_value_type(&self, ty: ValType, features: &WasmFeatures, offset: usize) -> Result<()> {
|
||||
match features.check_value_type(ty) {
|
||||
Ok(()) => Ok(()),
|
||||
@ -835,102 +922,11 @@ impl Module {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn eq_valtypes(&self, ty1: ValType, ty2: ValType, types: &TypeList) -> bool {
|
||||
match (ty1, ty2) {
|
||||
(ValType::Ref(rt1), ValType::Ref(rt2)) => {
|
||||
rt1.is_nullable() == rt2.is_nullable()
|
||||
&& match (rt1.heap_type(), rt2.heap_type()) {
|
||||
(HeapType::Indexed(n1), HeapType::Indexed(n2)) => {
|
||||
self.eq_indexed_types(n1, n2, types)
|
||||
}
|
||||
(h1, h2) => h1 == h2,
|
||||
}
|
||||
}
|
||||
_ => ty1 == ty2,
|
||||
}
|
||||
}
|
||||
|
||||
fn eq_indexed_types(&self, n1: u32, n2: u32, types: &TypeList) -> bool {
|
||||
let n1 = self.type_at(types, n1.into(), 0).unwrap();
|
||||
let n2 = self.type_at(types, n2.into(), 0).unwrap();
|
||||
match (n1, n2) {
|
||||
(Type::Func(f1), Type::Func(f2)) => self.eq_fns(f1, f2, types),
|
||||
(Type::Array(a1), Type::Array(a2)) => {
|
||||
a1.mutable == a2.mutable
|
||||
&& match (a1.element_type, a2.element_type) {
|
||||
(StorageType::Val(vt1), StorageType::Val(vt2)) => {
|
||||
self.eq_valtypes(vt1, vt2, types)
|
||||
}
|
||||
(st1, st2) => st1 == st2,
|
||||
}
|
||||
}
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
||||
fn eq_fns(&self, f1: &impl WasmFuncType, f2: &impl WasmFuncType, types: &TypeList) -> bool {
|
||||
f1.len_inputs() == f2.len_inputs()
|
||||
&& f2.len_outputs() == f2.len_outputs()
|
||||
&& f1
|
||||
.inputs()
|
||||
.zip(f2.inputs())
|
||||
.all(|(t1, t2)| self.eq_valtypes(t1, t2, types))
|
||||
&& f1
|
||||
.outputs()
|
||||
.zip(f2.outputs())
|
||||
.all(|(t1, t2)| self.eq_valtypes(t1, t2, types))
|
||||
}
|
||||
|
||||
/// Check that a value of type ty1 is assignable to a variable / table element of type ty2.
|
||||
/// E.g. a non-nullable reference can be assigned to a nullable reference, but not vice versa.
|
||||
/// Or an indexed func ref is assignable to a generic func ref, but not vice versa.
|
||||
pub(crate) fn matches(&self, ty1: ValType, ty2: ValType, types: &TypeList) -> bool {
|
||||
fn matches_null(null1: bool, null2: bool) -> bool {
|
||||
(null1 == null2) || null2
|
||||
}
|
||||
|
||||
let matches_heap = |ty1: HeapType, ty2: HeapType, types: &TypeList| -> bool {
|
||||
match (ty1, ty2) {
|
||||
(HeapType::Indexed(n1), HeapType::Indexed(n2)) => {
|
||||
// Check whether the defined types are (structurally) equivalent.
|
||||
let n1 = self.type_at(types, n1.into(), 0);
|
||||
let n2 = self.type_at(types, n2.into(), 0);
|
||||
match (n1, n2) {
|
||||
(Ok(Type::Func(n1)), Ok(Type::Func(n2))) => self.eq_fns(n1, n2, types),
|
||||
(Ok(Type::Array(n1)), Ok(Type::Array(n2))) => {
|
||||
(n1.mutable == n2.mutable || n2.mutable)
|
||||
&& match (n1.element_type, n2.element_type) {
|
||||
(StorageType::Val(vt1), StorageType::Val(vt2)) => {
|
||||
self.matches(vt1, vt2, types)
|
||||
}
|
||||
(st1, st2) => st1 == st2,
|
||||
}
|
||||
}
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
(HeapType::Indexed(n1), HeapType::Func) => {
|
||||
self.func_type_at(n1.into(), types, 0).is_ok()
|
||||
}
|
||||
(HeapType::Indexed(n1), HeapType::Array) => {
|
||||
match self.type_at(types, n1.into(), 0) {
|
||||
Ok(Type::Array(_)) => true,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
(_, _) => ty1 == ty2,
|
||||
}
|
||||
};
|
||||
|
||||
let matches_ref = |ty1: RefType, ty2: RefType, types: &TypeList| -> bool {
|
||||
matches_heap(ty1.heap_type(), ty2.heap_type(), types)
|
||||
&& matches_null(ty1.is_nullable(), ty2.is_nullable())
|
||||
};
|
||||
|
||||
match (ty1, ty2) {
|
||||
(ValType::Ref(rt1), ValType::Ref(rt2)) => matches_ref(rt1, rt2, types),
|
||||
(_, _) => ty1 == ty2,
|
||||
}
|
||||
ty1.inherits(&ty2, &|idx| self.subtype_at(types, idx, 0).unwrap())
|
||||
}
|
||||
|
||||
fn check_tag_type(
|
||||
@ -1122,11 +1118,7 @@ impl WasmModuleResources for OperatorValidatorResources<'_> {
|
||||
}
|
||||
|
||||
fn tag_at(&self, at: u32) -> Option<&Self::FuncType> {
|
||||
Some(
|
||||
self.types[*self.module.tags.get(at as usize)?]
|
||||
.as_func_type()
|
||||
.unwrap(),
|
||||
)
|
||||
Some(self.types[*self.module.tags.get(at as usize)?].unwrap_func())
|
||||
}
|
||||
|
||||
fn global_at(&self, at: u32) -> Option<GlobalType> {
|
||||
@ -1134,11 +1126,7 @@ impl WasmModuleResources for OperatorValidatorResources<'_> {
|
||||
}
|
||||
|
||||
fn func_type_at(&self, at: u32) -> Option<&Self::FuncType> {
|
||||
Some(
|
||||
self.types[*self.module.types.get(at as usize)?]
|
||||
.as_func_type()
|
||||
.unwrap(),
|
||||
)
|
||||
Some(self.types[*self.module.types.get(at as usize)?].unwrap_func())
|
||||
}
|
||||
|
||||
fn type_index_of_function(&self, at: u32) -> Option<u32> {
|
||||
@ -1190,11 +1178,7 @@ impl WasmModuleResources for ValidatorResources {
|
||||
}
|
||||
|
||||
fn tag_at(&self, at: u32) -> Option<&Self::FuncType> {
|
||||
Some(
|
||||
self.0.snapshot.as_ref().unwrap()[*self.0.tags.get(at as usize)?]
|
||||
.as_func_type()
|
||||
.unwrap(),
|
||||
)
|
||||
Some(self.0.snapshot.as_ref().unwrap()[*self.0.tags.get(at as usize)?].unwrap_func())
|
||||
}
|
||||
|
||||
fn global_at(&self, at: u32) -> Option<GlobalType> {
|
||||
@ -1202,11 +1186,7 @@ impl WasmModuleResources for ValidatorResources {
|
||||
}
|
||||
|
||||
fn func_type_at(&self, at: u32) -> Option<&Self::FuncType> {
|
||||
Some(
|
||||
self.0.snapshot.as_ref().unwrap()[*self.0.types.get(at as usize)?]
|
||||
.as_func_type()
|
||||
.unwrap(),
|
||||
)
|
||||
Some(self.0.snapshot.as_ref().unwrap()[*self.0.types.get(at as usize)?].unwrap_func())
|
||||
}
|
||||
|
||||
fn type_index_of_function(&self, at: u32) -> Option<u32> {
|
||||
|
@ -3252,7 +3252,10 @@ where
|
||||
segment
|
||||
),
|
||||
};
|
||||
if segment_ty != table.element_type {
|
||||
if !self
|
||||
.resources
|
||||
.matches(ValType::Ref(segment_ty), ValType::Ref(table.element_type))
|
||||
{
|
||||
bail!(self.offset, "type mismatch");
|
||||
}
|
||||
self.pop_operand(Some(ValType::I32))?;
|
||||
|
723
third_party/rust/wasmparser/src/validator/types.rs
vendored
723
third_party/rust/wasmparser/src/validator/types.rs
vendored
File diff suppressed because it is too large
Load Diff
@ -1,4 +1,5 @@
|
||||
use wasm_encoder::*;
|
||||
|
||||
#[test]
|
||||
fn big_type_indices() {
|
||||
const N: u32 = 100_000;
|
||||
@ -13,7 +14,7 @@ fn big_type_indices() {
|
||||
module.section(&funcs);
|
||||
|
||||
let mut elems = ElementSection::new();
|
||||
elems.declared(RefType::FUNCREF, Elements::Functions(&[0]));
|
||||
elems.declared(Elements::Functions(&[0]));
|
||||
module.section(&elems);
|
||||
|
||||
let mut code = CodeSection::new();
|
||||
|
2
third_party/rust/wast/.cargo-checksum.json
vendored
2
third_party/rust/wast/.cargo-checksum.json
vendored
File diff suppressed because one or more lines are too long
4
third_party/rust/wast/Cargo.toml
vendored
4
third_party/rust/wast/Cargo.toml
vendored
@ -12,7 +12,7 @@
|
||||
[package]
|
||||
edition = "2021"
|
||||
name = "wast"
|
||||
version = "60.0.0"
|
||||
version = "62.0.0"
|
||||
authors = ["Alex Crichton <alex@alexcrichton.com>"]
|
||||
description = """
|
||||
Customizable Rust parsers for the WebAssembly Text formats WAT and WAST
|
||||
@ -37,7 +37,7 @@ version = "2.4.1"
|
||||
version = "0.1.9"
|
||||
|
||||
[dependencies.wasm-encoder]
|
||||
version = "0.29.0"
|
||||
version = "0.31.0"
|
||||
|
||||
[dev-dependencies.anyhow]
|
||||
version = "1.0.58"
|
||||
|
30
third_party/rust/wast/src/component/alias.rs
vendored
30
third_party/rust/wast/src/component/alias.rs
vendored
@ -79,7 +79,7 @@ impl<'a> Parse<'a> for Alias<'a> {
|
||||
|
||||
let mut l = parser.lookahead1();
|
||||
|
||||
let (target, id, name) = if l.peek::<kw::outer>() {
|
||||
let (target, id, name) = if l.peek::<kw::outer>()? {
|
||||
parser.parse::<kw::outer>()?;
|
||||
let outer = parser.parse()?;
|
||||
let index = parser.parse()?;
|
||||
@ -87,7 +87,7 @@ impl<'a> Parse<'a> for Alias<'a> {
|
||||
parser.parens(|parser| Ok((parser.parse()?, parser.parse()?, parser.parse()?)))?;
|
||||
|
||||
(AliasTarget::Outer { outer, index, kind }, id, name)
|
||||
} else if l.peek::<kw::export>() {
|
||||
} else if l.peek::<kw::export>()? {
|
||||
parser.parse::<kw::export>()?;
|
||||
let instance = parser.parse()?;
|
||||
let export_name = parser.parse()?;
|
||||
@ -103,7 +103,7 @@ impl<'a> Parse<'a> for Alias<'a> {
|
||||
id,
|
||||
name,
|
||||
)
|
||||
} else if l.peek::<kw::core>() {
|
||||
} else if l.peek::<kw::core>()? {
|
||||
parser.parse::<kw::core>()?;
|
||||
parser.parse::<kw::export>()?;
|
||||
let instance = parser.parse()?;
|
||||
@ -155,28 +155,28 @@ pub enum ComponentExportAliasKind {
|
||||
impl<'a> Parse<'a> for ComponentExportAliasKind {
|
||||
fn parse(parser: Parser<'a>) -> Result<Self> {
|
||||
let mut l = parser.lookahead1();
|
||||
if l.peek::<kw::core>() {
|
||||
if l.peek::<kw::core>()? {
|
||||
parser.parse::<kw::core>()?;
|
||||
let mut l = parser.lookahead1();
|
||||
if l.peek::<kw::module>() {
|
||||
if l.peek::<kw::module>()? {
|
||||
parser.parse::<kw::module>()?;
|
||||
Ok(Self::CoreModule)
|
||||
} else {
|
||||
Err(l.error())
|
||||
}
|
||||
} else if l.peek::<kw::func>() {
|
||||
} else if l.peek::<kw::func>()? {
|
||||
parser.parse::<kw::func>()?;
|
||||
Ok(Self::Func)
|
||||
} else if l.peek::<kw::value>() {
|
||||
} else if l.peek::<kw::value>()? {
|
||||
parser.parse::<kw::value>()?;
|
||||
Ok(Self::Value)
|
||||
} else if l.peek::<kw::r#type>() {
|
||||
} else if l.peek::<kw::r#type>()? {
|
||||
parser.parse::<kw::r#type>()?;
|
||||
Ok(Self::Type)
|
||||
} else if l.peek::<kw::component>() {
|
||||
} else if l.peek::<kw::component>()? {
|
||||
parser.parse::<kw::component>()?;
|
||||
Ok(Self::Component)
|
||||
} else if l.peek::<kw::instance>() {
|
||||
} else if l.peek::<kw::instance>()? {
|
||||
parser.parse::<kw::instance>()?;
|
||||
Ok(Self::Instance)
|
||||
} else {
|
||||
@ -201,22 +201,22 @@ pub enum ComponentOuterAliasKind {
|
||||
impl<'a> Parse<'a> for ComponentOuterAliasKind {
|
||||
fn parse(parser: Parser<'a>) -> Result<Self> {
|
||||
let mut l = parser.lookahead1();
|
||||
if l.peek::<kw::core>() {
|
||||
if l.peek::<kw::core>()? {
|
||||
parser.parse::<kw::core>()?;
|
||||
let mut l = parser.lookahead1();
|
||||
if l.peek::<kw::module>() {
|
||||
if l.peek::<kw::module>()? {
|
||||
parser.parse::<kw::module>()?;
|
||||
Ok(Self::CoreModule)
|
||||
} else if l.peek::<kw::r#type>() {
|
||||
} else if l.peek::<kw::r#type>()? {
|
||||
parser.parse::<kw::r#type>()?;
|
||||
Ok(Self::CoreType)
|
||||
} else {
|
||||
Err(l.error())
|
||||
}
|
||||
} else if l.peek::<kw::r#type>() {
|
||||
} else if l.peek::<kw::r#type>()? {
|
||||
parser.parse::<kw::r#type>()?;
|
||||
Ok(Self::Type)
|
||||
} else if l.peek::<kw::component>() {
|
||||
} else if l.peek::<kw::component>()? {
|
||||
parser.parse::<kw::component>()?;
|
||||
Ok(Self::Component)
|
||||
} else {
|
||||
|
17
third_party/rust/wast/src/component/binary.rs
vendored
17
third_party/rust/wast/src/component/binary.rs
vendored
@ -1,6 +1,6 @@
|
||||
use crate::component::*;
|
||||
use crate::core;
|
||||
use crate::token::{Id, Index, NameAnnotation};
|
||||
use crate::token::{Id, Index, NameAnnotation, Span};
|
||||
use wasm_encoder::{
|
||||
CanonicalFunctionSection, ComponentAliasSection, ComponentDefinedTypeEncoder,
|
||||
ComponentExportSection, ComponentImportSection, ComponentInstanceSection, ComponentNameSection,
|
||||
@ -43,6 +43,7 @@ fn encode_fields(
|
||||
ComponentField::Import(i) => e.encode_import(i),
|
||||
ComponentField::Export(ex) => e.encode_export(ex),
|
||||
ComponentField::Custom(c) => e.encode_custom(c),
|
||||
ComponentField::Producers(c) => e.encode_producers(c),
|
||||
}
|
||||
}
|
||||
|
||||
@ -179,6 +180,18 @@ impl<'a> Encoder<'a> {
|
||||
self.component.section(custom);
|
||||
}
|
||||
|
||||
fn encode_producers(&mut self, custom: &core::Producers) {
|
||||
use crate::encode::Encode;
|
||||
|
||||
let mut data = Vec::new();
|
||||
custom.encode(&mut data);
|
||||
self.encode_custom(&Custom {
|
||||
name: "producers",
|
||||
span: Span::from_offset(0),
|
||||
data: vec![&data],
|
||||
})
|
||||
}
|
||||
|
||||
fn encode_core_module(&mut self, module: &CoreModule<'a>) {
|
||||
// Flush any in-progress section before encoding the module
|
||||
self.flush(None);
|
||||
@ -327,7 +340,7 @@ impl<'a> Encoder<'a> {
|
||||
}
|
||||
CanonicalFuncKind::ResourceDrop(info) => {
|
||||
self.core_func_names.push(name);
|
||||
self.funcs.resource_drop((&info.ty).into());
|
||||
self.funcs.resource_drop(info.ty.into());
|
||||
}
|
||||
CanonicalFuncKind::ResourceRep(info) => {
|
||||
self.core_func_names.push(name);
|
||||
|
41
third_party/rust/wast/src/component/component.rs
vendored
41
third_party/rust/wast/src/component/component.rs
vendored
@ -1,5 +1,6 @@
|
||||
use crate::annotation;
|
||||
use crate::component::*;
|
||||
use crate::core::Producers;
|
||||
use crate::kw;
|
||||
use crate::parser::{Parse, Parser, Result};
|
||||
use crate::token::Index;
|
||||
@ -108,12 +109,14 @@ impl<'a> Component<'a> {
|
||||
impl<'a> Parse<'a> for Component<'a> {
|
||||
fn parse(parser: Parser<'a>) -> Result<Self> {
|
||||
let _r = parser.register_annotation("custom");
|
||||
let _r = parser.register_annotation("producers");
|
||||
let _r = parser.register_annotation("name");
|
||||
|
||||
let span = parser.parse::<kw::component>()?.0;
|
||||
let id = parser.parse()?;
|
||||
let name = parser.parse()?;
|
||||
|
||||
let kind = if parser.peek::<kw::binary>() {
|
||||
let kind = if parser.peek::<kw::binary>()? {
|
||||
parser.parse::<kw::binary>()?;
|
||||
let mut data = Vec::new();
|
||||
while !parser.is_empty() {
|
||||
@ -150,6 +153,7 @@ pub enum ComponentField<'a> {
|
||||
Import(ComponentImport<'a>),
|
||||
Export(ComponentExport<'a>),
|
||||
Custom(Custom<'a>),
|
||||
Producers(Producers<'a>),
|
||||
}
|
||||
|
||||
impl<'a> ComponentField<'a> {
|
||||
@ -164,47 +168,50 @@ impl<'a> ComponentField<'a> {
|
||||
|
||||
impl<'a> Parse<'a> for ComponentField<'a> {
|
||||
fn parse(parser: Parser<'a>) -> Result<Self> {
|
||||
if parser.peek::<kw::core>() {
|
||||
if parser.peek2::<kw::module>() {
|
||||
if parser.peek::<kw::core>()? {
|
||||
if parser.peek2::<kw::module>()? {
|
||||
return Ok(Self::CoreModule(parser.parse()?));
|
||||
}
|
||||
if parser.peek2::<kw::instance>() {
|
||||
if parser.peek2::<kw::instance>()? {
|
||||
return Ok(Self::CoreInstance(parser.parse()?));
|
||||
}
|
||||
if parser.peek2::<kw::r#type>() {
|
||||
if parser.peek2::<kw::r#type>()? {
|
||||
return Ok(Self::CoreType(parser.parse()?));
|
||||
}
|
||||
if parser.peek2::<kw::func>() {
|
||||
if parser.peek2::<kw::func>()? {
|
||||
return Ok(Self::CoreFunc(parser.parse()?));
|
||||
}
|
||||
} else {
|
||||
if parser.peek::<kw::component>() {
|
||||
if parser.peek::<kw::component>()? {
|
||||
return Ok(Self::Component(parser.parse()?));
|
||||
}
|
||||
if parser.peek::<kw::instance>() {
|
||||
if parser.peek::<kw::instance>()? {
|
||||
return Ok(Self::Instance(parser.parse()?));
|
||||
}
|
||||
if parser.peek::<kw::alias>() {
|
||||
if parser.peek::<kw::alias>()? {
|
||||
return Ok(Self::Alias(parser.parse()?));
|
||||
}
|
||||
if parser.peek::<kw::r#type>() {
|
||||
if parser.peek::<kw::r#type>()? {
|
||||
return Ok(Self::Type(Type::parse_maybe_with_inline_exports(parser)?));
|
||||
}
|
||||
if parser.peek::<kw::import>() {
|
||||
if parser.peek::<kw::import>()? {
|
||||
return Ok(Self::Import(parser.parse()?));
|
||||
}
|
||||
if parser.peek::<kw::func>() {
|
||||
if parser.peek::<kw::func>()? {
|
||||
return Ok(Self::Func(parser.parse()?));
|
||||
}
|
||||
if parser.peek::<kw::export>() {
|
||||
if parser.peek::<kw::export>()? {
|
||||
return Ok(Self::Export(parser.parse()?));
|
||||
}
|
||||
if parser.peek::<kw::start>() {
|
||||
if parser.peek::<kw::start>()? {
|
||||
return Ok(Self::Start(parser.parse()?));
|
||||
}
|
||||
if parser.peek::<annotation::custom>() {
|
||||
if parser.peek::<annotation::custom>()? {
|
||||
return Ok(Self::Custom(parser.parse()?));
|
||||
}
|
||||
if parser.peek::<annotation::producers>()? {
|
||||
return Ok(Self::Producers(parser.parse()?));
|
||||
}
|
||||
}
|
||||
Err(parser.error("expected valid component field"))
|
||||
}
|
||||
@ -226,12 +233,12 @@ impl<'a> Parse<'a> for Start<'a> {
|
||||
parser.parse::<kw::start>()?;
|
||||
let func = parser.parse()?;
|
||||
let mut args = Vec::new();
|
||||
while !parser.is_empty() && !parser.peek2::<kw::result>() {
|
||||
while !parser.is_empty() && !parser.peek2::<kw::result>()? {
|
||||
args.push(parser.parens(|parser| parser.parse())?);
|
||||
}
|
||||
|
||||
let mut results = Vec::new();
|
||||
while !parser.is_empty() && parser.peek2::<kw::result>() {
|
||||
while !parser.is_empty() && parser.peek2::<kw::result>()? {
|
||||
results.push(parser.parens(|parser| {
|
||||
parser.parse::<kw::result>()?;
|
||||
parser.parens(|parser| {
|
||||
|
13
third_party/rust/wast/src/component/expand.rs
vendored
13
third_party/rust/wast/src/component/expand.rs
vendored
@ -127,7 +127,10 @@ impl<'a> Expander<'a> {
|
||||
}
|
||||
None
|
||||
}
|
||||
ComponentField::Start(_) | ComponentField::Alias(_) | ComponentField::Custom(_) => None,
|
||||
ComponentField::Start(_)
|
||||
| ComponentField::Alias(_)
|
||||
| ComponentField::Custom(_)
|
||||
| ComponentField::Producers(_) => None,
|
||||
};
|
||||
|
||||
if let Some(expanded) = expanded {
|
||||
@ -259,11 +262,8 @@ impl<'a> Expander<'a> {
|
||||
}
|
||||
CanonicalFuncKind::Lower(_)
|
||||
| CanonicalFuncKind::ResourceNew(_)
|
||||
| CanonicalFuncKind::ResourceRep(_) => {}
|
||||
|
||||
CanonicalFuncKind::ResourceDrop(info) => {
|
||||
self.expand_component_val_ty(&mut info.ty);
|
||||
}
|
||||
| CanonicalFuncKind::ResourceRep(_)
|
||||
| CanonicalFuncKind::ResourceDrop(_) => {}
|
||||
}
|
||||
}
|
||||
|
||||
@ -292,7 +292,6 @@ impl<'a> Expander<'a> {
|
||||
kind: CanonicalFuncKind::ResourceNew(mem::take(info)),
|
||||
})),
|
||||
CoreFuncKind::ResourceDrop(info) => {
|
||||
self.expand_component_val_ty(&mut info.ty);
|
||||
Some(ComponentField::CanonicalFunc(CanonicalFunc {
|
||||
span: func.span,
|
||||
id: func.id,
|
||||
|
60
third_party/rust/wast/src/component/export.rs
vendored
60
third_party/rust/wast/src/component/export.rs
vendored
@ -119,19 +119,19 @@ impl<'a> Parse<'a> for ComponentExportKind<'a> {
|
||||
fn parse(parser: Parser<'a>) -> Result<Self> {
|
||||
parser.parens(|parser| {
|
||||
let mut l = parser.lookahead1();
|
||||
if l.peek::<kw::core>() {
|
||||
if l.peek::<kw::core>()? {
|
||||
// Remove core prefix
|
||||
parser.parse::<kw::core>()?;
|
||||
Ok(Self::CoreModule(parser.parse()?))
|
||||
} else if l.peek::<kw::func>() {
|
||||
} else if l.peek::<kw::func>()? {
|
||||
Ok(Self::Func(parser.parse()?))
|
||||
} else if l.peek::<kw::value>() {
|
||||
} else if l.peek::<kw::value>()? {
|
||||
Ok(Self::Value(parser.parse()?))
|
||||
} else if l.peek::<kw::r#type>() {
|
||||
} else if l.peek::<kw::r#type>()? {
|
||||
Ok(Self::Type(parser.parse()?))
|
||||
} else if l.peek::<kw::component>() {
|
||||
} else if l.peek::<kw::component>()? {
|
||||
Ok(Self::Component(parser.parse()?))
|
||||
} else if l.peek::<kw::instance>() {
|
||||
} else if l.peek::<kw::instance>()? {
|
||||
Ok(Self::Instance(parser.parse()?))
|
||||
} else {
|
||||
Err(l.error())
|
||||
@ -141,23 +141,23 @@ impl<'a> Parse<'a> for ComponentExportKind<'a> {
|
||||
}
|
||||
|
||||
impl Peek for ComponentExportKind<'_> {
|
||||
fn peek(cursor: Cursor) -> bool {
|
||||
let cursor = match cursor.lparen() {
|
||||
fn peek(cursor: Cursor) -> Result<bool> {
|
||||
let cursor = match cursor.lparen()? {
|
||||
Some(c) => c,
|
||||
None => return false,
|
||||
None => return Ok(false),
|
||||
};
|
||||
|
||||
let cursor = match cursor.keyword() {
|
||||
Some(("core", c)) => match c.keyword() {
|
||||
let cursor = match cursor.keyword()? {
|
||||
Some(("core", c)) => match c.keyword()? {
|
||||
Some(("module", c)) => c,
|
||||
_ => return false,
|
||||
_ => return Ok(false),
|
||||
},
|
||||
Some(("func", c))
|
||||
| Some(("value", c))
|
||||
| Some(("type", c))
|
||||
| Some(("component", c))
|
||||
| Some(("instance", c)) => c,
|
||||
_ => return false,
|
||||
_ => return Ok(false),
|
||||
};
|
||||
|
||||
Index::peek(cursor)
|
||||
@ -179,7 +179,7 @@ pub struct InlineExport<'a> {
|
||||
impl<'a> Parse<'a> for InlineExport<'a> {
|
||||
fn parse(parser: Parser<'a>) -> Result<Self> {
|
||||
let mut names = Vec::new();
|
||||
while parser.peek::<Self>() {
|
||||
while parser.peek::<Self>()? {
|
||||
names.push(parser.parens(|p| {
|
||||
p.parse::<kw::export>()?;
|
||||
p.parse()
|
||||
@ -190,39 +190,39 @@ impl<'a> Parse<'a> for InlineExport<'a> {
|
||||
}
|
||||
|
||||
impl Peek for InlineExport<'_> {
|
||||
fn peek(cursor: Cursor<'_>) -> bool {
|
||||
let cursor = match cursor.lparen() {
|
||||
fn peek(cursor: Cursor<'_>) -> Result<bool> {
|
||||
let cursor = match cursor.lparen()? {
|
||||
Some(cursor) => cursor,
|
||||
None => return false,
|
||||
None => return Ok(false),
|
||||
};
|
||||
let cursor = match cursor.keyword() {
|
||||
let cursor = match cursor.keyword()? {
|
||||
Some(("export", cursor)) => cursor,
|
||||
_ => return false,
|
||||
_ => return Ok(false),
|
||||
};
|
||||
|
||||
// (export "foo")
|
||||
if let Some((_, cursor)) = cursor.string() {
|
||||
return cursor.rparen().is_some();
|
||||
if let Some((_, cursor)) = cursor.string()? {
|
||||
return Ok(cursor.rparen()?.is_some());
|
||||
}
|
||||
|
||||
// (export (interface "foo"))
|
||||
let cursor = match cursor.lparen() {
|
||||
let cursor = match cursor.lparen()? {
|
||||
Some(cursor) => cursor,
|
||||
None => return false,
|
||||
None => return Ok(false),
|
||||
};
|
||||
let cursor = match cursor.keyword() {
|
||||
let cursor = match cursor.keyword()? {
|
||||
Some(("interface", cursor)) => cursor,
|
||||
_ => return false,
|
||||
_ => return Ok(false),
|
||||
};
|
||||
let cursor = match cursor.string() {
|
||||
let cursor = match cursor.string()? {
|
||||
Some((_, cursor)) => cursor,
|
||||
_ => return false,
|
||||
_ => return Ok(false),
|
||||
};
|
||||
let cursor = match cursor.rparen() {
|
||||
let cursor = match cursor.rparen()? {
|
||||
Some(cursor) => cursor,
|
||||
_ => return false,
|
||||
_ => return Ok(false),
|
||||
};
|
||||
cursor.rparen().is_some()
|
||||
Ok(cursor.rparen()?.is_some())
|
||||
}
|
||||
|
||||
fn display() -> &'static str {
|
||||
|
44
third_party/rust/wast/src/component/func.rs
vendored
44
third_party/rust/wast/src/component/func.rs
vendored
@ -57,21 +57,21 @@ impl<'a> Parse<'a> for CoreFuncKind<'a> {
|
||||
fn parse(parser: Parser<'a>) -> Result<Self> {
|
||||
parser.parens(|parser| {
|
||||
let mut l = parser.lookahead1();
|
||||
if l.peek::<kw::canon>() {
|
||||
if l.peek::<kw::canon>()? {
|
||||
parser.parse::<kw::canon>()?;
|
||||
} else if l.peek::<kw::alias>() {
|
||||
} else if l.peek::<kw::alias>()? {
|
||||
return Ok(Self::Alias(parser.parse()?));
|
||||
} else {
|
||||
return Err(l.error());
|
||||
}
|
||||
let mut l = parser.lookahead1();
|
||||
if l.peek::<kw::lower>() {
|
||||
if l.peek::<kw::lower>()? {
|
||||
Ok(CoreFuncKind::Lower(parser.parse()?))
|
||||
} else if l.peek::<kw::resource_new>() {
|
||||
} else if l.peek::<kw::resource_new>()? {
|
||||
Ok(CoreFuncKind::ResourceNew(parser.parse()?))
|
||||
} else if l.peek::<kw::resource_drop>() {
|
||||
} else if l.peek::<kw::resource_drop>()? {
|
||||
Ok(CoreFuncKind::ResourceDrop(parser.parse()?))
|
||||
} else if l.peek::<kw::resource_rep>() {
|
||||
} else if l.peek::<kw::resource_rep>()? {
|
||||
Ok(CoreFuncKind::ResourceRep(parser.parse()?))
|
||||
} else {
|
||||
Err(l.error())
|
||||
@ -153,7 +153,7 @@ impl<'a> Parse<'a> for FuncKind<'a> {
|
||||
import,
|
||||
ty: parser.parse()?,
|
||||
})
|
||||
} else if parser.peek::<LParen>() && parser.peek2::<kw::alias>() {
|
||||
} else if parser.peek::<LParen>()? && parser.peek2::<kw::alias>()? {
|
||||
parser.parens(|parser| Ok(Self::Alias(parser.parse()?)))
|
||||
} else {
|
||||
Ok(Self::Lift {
|
||||
@ -187,7 +187,7 @@ impl<'a> Parse<'a> for CanonicalFunc<'a> {
|
||||
fn parse(parser: Parser<'a>) -> Result<Self> {
|
||||
let span = parser.parse::<kw::canon>()?.0;
|
||||
|
||||
if parser.peek::<kw::lift>() {
|
||||
if parser.peek::<kw::lift>()? {
|
||||
let info = parser.parse()?;
|
||||
let (id, name, ty) = parser.parens(|parser| {
|
||||
parser.parse::<kw::func>()?;
|
||||
@ -203,13 +203,13 @@ impl<'a> Parse<'a> for CanonicalFunc<'a> {
|
||||
name,
|
||||
kind: CanonicalFuncKind::Lift { info, ty },
|
||||
})
|
||||
} else if parser.peek::<kw::lower>() {
|
||||
} else if parser.peek::<kw::lower>()? {
|
||||
Self::parse_core_func(span, parser, CanonicalFuncKind::Lower)
|
||||
} else if parser.peek::<kw::resource_new>() {
|
||||
} else if parser.peek::<kw::resource_new>()? {
|
||||
Self::parse_core_func(span, parser, CanonicalFuncKind::ResourceNew)
|
||||
} else if parser.peek::<kw::resource_drop>() {
|
||||
} else if parser.peek::<kw::resource_drop>()? {
|
||||
Self::parse_core_func(span, parser, CanonicalFuncKind::ResourceDrop)
|
||||
} else if parser.peek::<kw::resource_rep>() {
|
||||
} else if parser.peek::<kw::resource_rep>()? {
|
||||
Self::parse_core_func(span, parser, CanonicalFuncKind::ResourceRep)
|
||||
} else {
|
||||
Err(parser.error("expected `canon lift` or `canon lower`"))
|
||||
@ -362,8 +362,8 @@ impl Default for CanonResourceNew<'_> {
|
||||
/// Information relating to the `resource.drop` intrinsic.
|
||||
#[derive(Debug)]
|
||||
pub struct CanonResourceDrop<'a> {
|
||||
/// The type that this intrinsic is dropping, either (borrow T) or (own T)
|
||||
pub ty: ComponentValType<'a>,
|
||||
/// The resource type that this intrinsic is dropping.
|
||||
pub ty: Index<'a>,
|
||||
}
|
||||
|
||||
impl<'a> Parse<'a> for CanonResourceDrop<'a> {
|
||||
@ -379,7 +379,7 @@ impl<'a> Parse<'a> for CanonResourceDrop<'a> {
|
||||
impl Default for CanonResourceDrop<'_> {
|
||||
fn default() -> Self {
|
||||
CanonResourceDrop {
|
||||
ty: ComponentValType::Ref(Index::Num(0, Span::from_offset(0))),
|
||||
ty: Index::Num(0, Span::from_offset(0)),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -429,30 +429,30 @@ pub enum CanonOpt<'a> {
|
||||
impl<'a> Parse<'a> for CanonOpt<'a> {
|
||||
fn parse(parser: Parser<'a>) -> Result<Self> {
|
||||
let mut l = parser.lookahead1();
|
||||
if l.peek::<kw::string_utf8>() {
|
||||
if l.peek::<kw::string_utf8>()? {
|
||||
parser.parse::<kw::string_utf8>()?;
|
||||
Ok(Self::StringUtf8)
|
||||
} else if l.peek::<kw::string_utf16>() {
|
||||
} else if l.peek::<kw::string_utf16>()? {
|
||||
parser.parse::<kw::string_utf16>()?;
|
||||
Ok(Self::StringUtf16)
|
||||
} else if l.peek::<kw::string_latin1_utf16>() {
|
||||
} else if l.peek::<kw::string_latin1_utf16>()? {
|
||||
parser.parse::<kw::string_latin1_utf16>()?;
|
||||
Ok(Self::StringLatin1Utf16)
|
||||
} else if l.peek::<LParen>() {
|
||||
} else if l.peek::<LParen>()? {
|
||||
parser.parens(|parser| {
|
||||
let mut l = parser.lookahead1();
|
||||
if l.peek::<kw::memory>() {
|
||||
if l.peek::<kw::memory>()? {
|
||||
let span = parser.parse::<kw::memory>()?.0;
|
||||
Ok(CanonOpt::Memory(parse_trailing_item_ref(
|
||||
kw::memory(span),
|
||||
parser,
|
||||
)?))
|
||||
} else if l.peek::<kw::realloc>() {
|
||||
} else if l.peek::<kw::realloc>()? {
|
||||
parser.parse::<kw::realloc>()?;
|
||||
Ok(CanonOpt::Realloc(
|
||||
parser.parse::<IndexOrCoreRef<'_, _>>()?.0,
|
||||
))
|
||||
} else if l.peek::<kw::post_return>() {
|
||||
} else if l.peek::<kw::post_return>()? {
|
||||
parser.parse::<kw::post_return>()?;
|
||||
Ok(CanonOpt::PostReturn(
|
||||
parser.parse::<IndexOrCoreRef<'_, _>>()?.0,
|
||||
|
50
third_party/rust/wast/src/component/import.rs
vendored
50
third_party/rust/wast/src/component/import.rs
vendored
@ -34,7 +34,7 @@ pub enum ComponentExternName<'a> {
|
||||
|
||||
impl<'a> Parse<'a> for ComponentExternName<'a> {
|
||||
fn parse(parser: Parser<'a>) -> Result<Self> {
|
||||
if parser.peek::<LParen>() {
|
||||
if parser.peek::<LParen>()? {
|
||||
Ok(ComponentExternName::Interface(parser.parens(|p| {
|
||||
p.parse::<kw::interface>()?;
|
||||
p.parse()
|
||||
@ -78,23 +78,23 @@ impl<'a> Parse<'a> for ItemSigNoName<'a> {
|
||||
|
||||
fn parse_item_sig<'a>(parser: Parser<'a>, name: bool) -> Result<ItemSig<'a>> {
|
||||
let mut l = parser.lookahead1();
|
||||
let (span, parse_kind): (_, fn(Parser<'a>) -> Result<ItemSigKind>) = if l.peek::<kw::core>() {
|
||||
let (span, parse_kind): (_, fn(Parser<'a>) -> Result<ItemSigKind>) = if l.peek::<kw::core>()? {
|
||||
let span = parser.parse::<kw::core>()?.0;
|
||||
parser.parse::<kw::module>()?;
|
||||
(span, |parser| Ok(ItemSigKind::CoreModule(parser.parse()?)))
|
||||
} else if l.peek::<kw::func>() {
|
||||
} else if l.peek::<kw::func>()? {
|
||||
let span = parser.parse::<kw::func>()?.0;
|
||||
(span, |parser| Ok(ItemSigKind::Func(parser.parse()?)))
|
||||
} else if l.peek::<kw::component>() {
|
||||
} else if l.peek::<kw::component>()? {
|
||||
let span = parser.parse::<kw::component>()?.0;
|
||||
(span, |parser| Ok(ItemSigKind::Component(parser.parse()?)))
|
||||
} else if l.peek::<kw::instance>() {
|
||||
} else if l.peek::<kw::instance>()? {
|
||||
let span = parser.parse::<kw::instance>()?.0;
|
||||
(span, |parser| Ok(ItemSigKind::Instance(parser.parse()?)))
|
||||
} else if l.peek::<kw::value>() {
|
||||
} else if l.peek::<kw::value>()? {
|
||||
let span = parser.parse::<kw::value>()?.0;
|
||||
(span, |parser| Ok(ItemSigKind::Value(parser.parse()?)))
|
||||
} else if l.peek::<kw::r#type>() {
|
||||
} else if l.peek::<kw::r#type>()? {
|
||||
let span = parser.parse::<kw::r#type>()?.0;
|
||||
(span, |parser| {
|
||||
Ok(ItemSigKind::Type(parser.parens(|parser| parser.parse())?))
|
||||
@ -139,10 +139,10 @@ pub enum TypeBounds<'a> {
|
||||
impl<'a> Parse<'a> for TypeBounds<'a> {
|
||||
fn parse(parser: Parser<'a>) -> Result<Self> {
|
||||
let mut l = parser.lookahead1();
|
||||
if l.peek::<kw::eq>() {
|
||||
if l.peek::<kw::eq>()? {
|
||||
parser.parse::<kw::eq>()?;
|
||||
Ok(Self::Eq(parser.parse()?))
|
||||
} else if l.peek::<kw::sub>() {
|
||||
} else if l.peek::<kw::sub>()? {
|
||||
parser.parse::<kw::sub>()?;
|
||||
parser.parse::<kw::resource>()?;
|
||||
Ok(Self::SubResource)
|
||||
@ -172,39 +172,39 @@ impl<'a> Parse<'a> for InlineImport<'a> {
|
||||
}
|
||||
|
||||
impl Peek for InlineImport<'_> {
|
||||
fn peek(cursor: Cursor<'_>) -> bool {
|
||||
let cursor = match cursor.lparen() {
|
||||
fn peek(cursor: Cursor<'_>) -> Result<bool> {
|
||||
let cursor = match cursor.lparen()? {
|
||||
Some(cursor) => cursor,
|
||||
None => return false,
|
||||
None => return Ok(false),
|
||||
};
|
||||
let cursor = match cursor.keyword() {
|
||||
let cursor = match cursor.keyword()? {
|
||||
Some(("import", cursor)) => cursor,
|
||||
_ => return false,
|
||||
_ => return Ok(false),
|
||||
};
|
||||
|
||||
// (import "foo")
|
||||
if let Some((_, cursor)) = cursor.string() {
|
||||
return cursor.rparen().is_some();
|
||||
if let Some((_, cursor)) = cursor.string()? {
|
||||
return Ok(cursor.rparen()?.is_some());
|
||||
}
|
||||
|
||||
// (import (interface "foo"))
|
||||
let cursor = match cursor.lparen() {
|
||||
let cursor = match cursor.lparen()? {
|
||||
Some(cursor) => cursor,
|
||||
None => return false,
|
||||
None => return Ok(false),
|
||||
};
|
||||
let cursor = match cursor.keyword() {
|
||||
let cursor = match cursor.keyword()? {
|
||||
Some(("interface", cursor)) => cursor,
|
||||
_ => return false,
|
||||
_ => return Ok(false),
|
||||
};
|
||||
let cursor = match cursor.string() {
|
||||
let cursor = match cursor.string()? {
|
||||
Some((_, cursor)) => cursor,
|
||||
_ => return false,
|
||||
_ => return Ok(false),
|
||||
};
|
||||
let cursor = match cursor.rparen() {
|
||||
let cursor = match cursor.rparen()? {
|
||||
Some(cursor) => cursor,
|
||||
_ => return false,
|
||||
_ => return Ok(false),
|
||||
};
|
||||
cursor.rparen().is_some()
|
||||
Ok(cursor.rparen()?.is_some())
|
||||
}
|
||||
|
||||
fn display() -> &'static str {
|
||||
|
@ -51,7 +51,7 @@ pub enum CoreInstanceKind<'a> {
|
||||
|
||||
impl<'a> Parse<'a> for CoreInstanceKind<'a> {
|
||||
fn parse(parser: Parser<'a>) -> Result<Self> {
|
||||
if parser.peek::<LParen>() && parser.peek2::<kw::instantiate>() {
|
||||
if parser.peek::<LParen>()? && parser.peek2::<kw::instantiate>()? {
|
||||
parser.parens(|parser| {
|
||||
parser.parse::<kw::instantiate>()?;
|
||||
Ok(Self::Instantiate {
|
||||
@ -221,7 +221,7 @@ impl<'a> Parse<'a> for InstanceKind<'a> {
|
||||
});
|
||||
}
|
||||
|
||||
if parser.peek::<LParen>() && parser.peek2::<kw::instantiate>() {
|
||||
if parser.peek::<LParen>()? && parser.peek2::<kw::instantiate>()? {
|
||||
parser.parens(|parser| {
|
||||
parser.parse::<kw::instantiate>()?;
|
||||
Ok(Self::Instantiate {
|
||||
|
32
third_party/rust/wast/src/component/item_ref.rs
vendored
32
third_party/rust/wast/src/component/item_ref.rs
vendored
@ -1,7 +1,7 @@
|
||||
use crate::parser::{Cursor, Parse, Parser, Peek, Result};
|
||||
use crate::token::Index;
|
||||
|
||||
fn peek<K: Peek>(cursor: Cursor) -> bool {
|
||||
fn peek<K: Peek>(cursor: Cursor) -> Result<bool> {
|
||||
// This is a little fancy because when parsing something like:
|
||||
//
|
||||
// (type (component (type $foo)))
|
||||
@ -16,25 +16,25 @@ fn peek<K: Peek>(cursor: Cursor) -> bool {
|
||||
// strings.
|
||||
|
||||
// Peek for the given keyword type
|
||||
if !K::peek(cursor) {
|
||||
return false;
|
||||
if !K::peek(cursor)? {
|
||||
return Ok(false);
|
||||
}
|
||||
|
||||
// Move past the given keyword
|
||||
let cursor = match cursor.keyword() {
|
||||
let cursor = match cursor.keyword()? {
|
||||
Some((_, c)) => c,
|
||||
_ => return false,
|
||||
_ => return Ok(false),
|
||||
};
|
||||
|
||||
// Peek an id or integer index, followed by `)` or string to disambiguate
|
||||
match cursor
|
||||
.id()
|
||||
.map(|p| p.1)
|
||||
.or_else(|| cursor.integer().map(|p| p.1))
|
||||
{
|
||||
Some(cursor) => cursor.rparen().is_some() || cursor.string().is_some(),
|
||||
let cursor = match cursor.id()? {
|
||||
Some((_, cursor)) => Some(cursor),
|
||||
None => cursor.integer()?.map(|p| p.1),
|
||||
};
|
||||
Ok(match cursor {
|
||||
Some(cursor) => cursor.rparen()?.is_some() || cursor.string()?.is_some(),
|
||||
None => false,
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/// Parses core item references.
|
||||
@ -65,7 +65,7 @@ impl<'a, K: Parse<'a>> Parse<'a> for CoreItemRef<'a, K> {
|
||||
}
|
||||
|
||||
impl<'a, K: Peek> Peek for CoreItemRef<'a, K> {
|
||||
fn peek(cursor: Cursor<'_>) -> bool {
|
||||
fn peek(cursor: Cursor<'_>) -> Result<bool> {
|
||||
peek::<K>(cursor)
|
||||
}
|
||||
|
||||
@ -102,7 +102,7 @@ impl<'a, K: Parse<'a>> Parse<'a> for ItemRef<'a, K> {
|
||||
}
|
||||
|
||||
impl<'a, K: Peek> Peek for ItemRef<'a, K> {
|
||||
fn peek(cursor: Cursor<'_>) -> bool {
|
||||
fn peek(cursor: Cursor<'_>) -> Result<bool> {
|
||||
peek::<K>(cursor)
|
||||
}
|
||||
|
||||
@ -120,7 +120,7 @@ where
|
||||
K: Parse<'a> + Default,
|
||||
{
|
||||
fn parse(parser: Parser<'a>) -> Result<Self> {
|
||||
if parser.peek::<Index<'_>>() {
|
||||
if parser.peek::<Index<'_>>()? {
|
||||
Ok(IndexOrRef(ItemRef {
|
||||
kind: K::default(),
|
||||
idx: parser.parse()?,
|
||||
@ -141,7 +141,7 @@ where
|
||||
K: Parse<'a> + Default,
|
||||
{
|
||||
fn parse(parser: Parser<'a>) -> Result<Self> {
|
||||
if parser.peek::<Index<'_>>() {
|
||||
if parser.peek::<Index<'_>>()? {
|
||||
Ok(IndexOrCoreRef(CoreItemRef {
|
||||
kind: K::default(),
|
||||
idx: parser.parse()?,
|
||||
|
@ -170,7 +170,7 @@ impl<'a> Resolver<'a> {
|
||||
}
|
||||
self.export(&mut e.kind)
|
||||
}
|
||||
ComponentField::Custom(_) => Ok(()),
|
||||
ComponentField::Custom(_) | ComponentField::Producers(_) => Ok(()),
|
||||
}
|
||||
}
|
||||
|
||||
@ -375,7 +375,9 @@ impl<'a> Resolver<'a> {
|
||||
}
|
||||
CanonicalFuncKind::ResourceNew(info) => return self.resolve_ns(&mut info.ty, Ns::Type),
|
||||
CanonicalFuncKind::ResourceRep(info) => return self.resolve_ns(&mut info.ty, Ns::Type),
|
||||
CanonicalFuncKind::ResourceDrop(info) => return self.component_val_type(&mut info.ty),
|
||||
CanonicalFuncKind::ResourceDrop(info) => {
|
||||
return self.resolve_ns(&mut info.ty, Ns::Type)
|
||||
}
|
||||
};
|
||||
|
||||
for opt in opts {
|
||||
@ -845,7 +847,7 @@ impl<'a> ComponentState<'a> {
|
||||
ComponentExportKind::Component(_) => self.components.register(e.id, "component")?,
|
||||
ComponentExportKind::Type(_) => self.types.register(e.id, "type")?,
|
||||
},
|
||||
ComponentField::Custom(_) => return Ok(()),
|
||||
ComponentField::Custom(_) | ComponentField::Producers(_) => return Ok(()),
|
||||
};
|
||||
|
||||
Ok(())
|
||||
|
124
third_party/rust/wast/src/component/types.rs
vendored
124
third_party/rust/wast/src/component/types.rs
vendored
@ -53,7 +53,7 @@ pub enum CoreTypeDef<'a> {
|
||||
|
||||
impl<'a> Parse<'a> for CoreTypeDef<'a> {
|
||||
fn parse(parser: Parser<'a>) -> Result<Self> {
|
||||
if parser.peek::<kw::module>() {
|
||||
if parser.peek::<kw::module>()? {
|
||||
parser.parse::<kw::module>()?;
|
||||
Ok(Self::Module(parser.parse()?))
|
||||
} else {
|
||||
@ -94,13 +94,13 @@ pub enum ModuleTypeDecl<'a> {
|
||||
impl<'a> Parse<'a> for ModuleTypeDecl<'a> {
|
||||
fn parse(parser: Parser<'a>) -> Result<Self> {
|
||||
let mut l = parser.lookahead1();
|
||||
if l.peek::<kw::r#type>() {
|
||||
if l.peek::<kw::r#type>()? {
|
||||
Ok(Self::Type(parser.parse()?))
|
||||
} else if l.peek::<kw::alias>() {
|
||||
} else if l.peek::<kw::alias>()? {
|
||||
Ok(Self::Alias(Alias::parse_outer_core_type_alias(parser)?))
|
||||
} else if l.peek::<kw::import>() {
|
||||
} else if l.peek::<kw::import>()? {
|
||||
Ok(Self::Import(parser.parse()?))
|
||||
} else if l.peek::<kw::export>() {
|
||||
} else if l.peek::<kw::export>()? {
|
||||
parser.parse::<kw::export>()?;
|
||||
let name = parser.parse()?;
|
||||
let et = parser.parens(|parser| parser.parse())?;
|
||||
@ -187,19 +187,19 @@ pub enum TypeDef<'a> {
|
||||
|
||||
impl<'a> Parse<'a> for TypeDef<'a> {
|
||||
fn parse(parser: Parser<'a>) -> Result<Self> {
|
||||
if parser.peek::<LParen>() {
|
||||
if parser.peek::<LParen>()? {
|
||||
parser.parens(|parser| {
|
||||
let mut l = parser.lookahead1();
|
||||
if l.peek::<kw::func>() {
|
||||
if l.peek::<kw::func>()? {
|
||||
parser.parse::<kw::func>()?;
|
||||
Ok(Self::Func(parser.parse()?))
|
||||
} else if l.peek::<kw::component>() {
|
||||
} else if l.peek::<kw::component>()? {
|
||||
parser.parse::<kw::component>()?;
|
||||
Ok(Self::Component(parser.parse()?))
|
||||
} else if l.peek::<kw::instance>() {
|
||||
} else if l.peek::<kw::instance>()? {
|
||||
parser.parse::<kw::instance>()?;
|
||||
Ok(Self::Instance(parser.parse()?))
|
||||
} else if l.peek::<kw::resource>() {
|
||||
} else if l.peek::<kw::resource>()? {
|
||||
parser.parse::<kw::resource>()?;
|
||||
Ok(Self::Resource(parser.parse()?))
|
||||
} else {
|
||||
@ -239,43 +239,43 @@ pub enum PrimitiveValType {
|
||||
impl<'a> Parse<'a> for PrimitiveValType {
|
||||
fn parse(parser: Parser<'a>) -> Result<Self> {
|
||||
let mut l = parser.lookahead1();
|
||||
if l.peek::<kw::bool_>() {
|
||||
if l.peek::<kw::bool_>()? {
|
||||
parser.parse::<kw::bool_>()?;
|
||||
Ok(Self::Bool)
|
||||
} else if l.peek::<kw::s8>() {
|
||||
} else if l.peek::<kw::s8>()? {
|
||||
parser.parse::<kw::s8>()?;
|
||||
Ok(Self::S8)
|
||||
} else if l.peek::<kw::u8>() {
|
||||
} else if l.peek::<kw::u8>()? {
|
||||
parser.parse::<kw::u8>()?;
|
||||
Ok(Self::U8)
|
||||
} else if l.peek::<kw::s16>() {
|
||||
} else if l.peek::<kw::s16>()? {
|
||||
parser.parse::<kw::s16>()?;
|
||||
Ok(Self::S16)
|
||||
} else if l.peek::<kw::u16>() {
|
||||
} else if l.peek::<kw::u16>()? {
|
||||
parser.parse::<kw::u16>()?;
|
||||
Ok(Self::U16)
|
||||
} else if l.peek::<kw::s32>() {
|
||||
} else if l.peek::<kw::s32>()? {
|
||||
parser.parse::<kw::s32>()?;
|
||||
Ok(Self::S32)
|
||||
} else if l.peek::<kw::u32>() {
|
||||
} else if l.peek::<kw::u32>()? {
|
||||
parser.parse::<kw::u32>()?;
|
||||
Ok(Self::U32)
|
||||
} else if l.peek::<kw::s64>() {
|
||||
} else if l.peek::<kw::s64>()? {
|
||||
parser.parse::<kw::s64>()?;
|
||||
Ok(Self::S64)
|
||||
} else if l.peek::<kw::u64>() {
|
||||
} else if l.peek::<kw::u64>()? {
|
||||
parser.parse::<kw::u64>()?;
|
||||
Ok(Self::U64)
|
||||
} else if l.peek::<kw::float32>() {
|
||||
} else if l.peek::<kw::float32>()? {
|
||||
parser.parse::<kw::float32>()?;
|
||||
Ok(Self::Float32)
|
||||
} else if l.peek::<kw::float64>() {
|
||||
} else if l.peek::<kw::float64>()? {
|
||||
parser.parse::<kw::float64>()?;
|
||||
Ok(Self::Float64)
|
||||
} else if l.peek::<kw::char>() {
|
||||
} else if l.peek::<kw::char>()? {
|
||||
parser.parse::<kw::char>()?;
|
||||
Ok(Self::Char)
|
||||
} else if l.peek::<kw::string>() {
|
||||
} else if l.peek::<kw::string>()? {
|
||||
parser.parse::<kw::string>()?;
|
||||
Ok(Self::String)
|
||||
} else {
|
||||
@ -285,9 +285,9 @@ impl<'a> Parse<'a> for PrimitiveValType {
|
||||
}
|
||||
|
||||
impl Peek for PrimitiveValType {
|
||||
fn peek(cursor: crate::parser::Cursor<'_>) -> bool {
|
||||
matches!(
|
||||
cursor.keyword(),
|
||||
fn peek(cursor: crate::parser::Cursor<'_>) -> Result<bool> {
|
||||
Ok(matches!(
|
||||
cursor.keyword()?,
|
||||
Some(("bool", _))
|
||||
| Some(("s8", _))
|
||||
| Some(("u8", _))
|
||||
@ -301,7 +301,7 @@ impl Peek for PrimitiveValType {
|
||||
| Some(("float64", _))
|
||||
| Some(("char", _))
|
||||
| Some(("string", _))
|
||||
)
|
||||
))
|
||||
}
|
||||
|
||||
fn display() -> &'static str {
|
||||
@ -321,7 +321,7 @@ pub enum ComponentValType<'a> {
|
||||
|
||||
impl<'a> Parse<'a> for ComponentValType<'a> {
|
||||
fn parse(parser: Parser<'a>) -> Result<Self> {
|
||||
if parser.peek::<Index<'_>>() {
|
||||
if parser.peek::<Index<'_>>()? {
|
||||
Ok(Self::Ref(parser.parse()?))
|
||||
} else {
|
||||
Ok(Self::Inline(InlineComponentValType::parse(parser)?.0))
|
||||
@ -330,8 +330,8 @@ impl<'a> Parse<'a> for ComponentValType<'a> {
|
||||
}
|
||||
|
||||
impl Peek for ComponentValType<'_> {
|
||||
fn peek(cursor: crate::parser::Cursor<'_>) -> bool {
|
||||
Index::peek(cursor) || ComponentDefinedType::peek(cursor)
|
||||
fn peek(cursor: crate::parser::Cursor<'_>) -> Result<bool> {
|
||||
Ok(Index::peek(cursor)? || ComponentDefinedType::peek(cursor)?)
|
||||
}
|
||||
|
||||
fn display() -> &'static str {
|
||||
@ -348,7 +348,7 @@ pub struct InlineComponentValType<'a>(ComponentDefinedType<'a>);
|
||||
|
||||
impl<'a> Parse<'a> for InlineComponentValType<'a> {
|
||||
fn parse(parser: Parser<'a>) -> Result<Self> {
|
||||
if parser.peek::<LParen>() {
|
||||
if parser.peek::<LParen>()? {
|
||||
parser.parens(|parser| {
|
||||
Ok(Self(ComponentDefinedType::parse_non_primitive(
|
||||
parser,
|
||||
@ -382,28 +382,28 @@ pub enum ComponentDefinedType<'a> {
|
||||
impl<'a> ComponentDefinedType<'a> {
|
||||
fn parse_non_primitive(parser: Parser<'a>, mut l: Lookahead1<'a>) -> Result<Self> {
|
||||
parser.depth_check()?;
|
||||
if l.peek::<kw::record>() {
|
||||
if l.peek::<kw::record>()? {
|
||||
Ok(Self::Record(parser.parse()?))
|
||||
} else if l.peek::<kw::variant>() {
|
||||
} else if l.peek::<kw::variant>()? {
|
||||
Ok(Self::Variant(parser.parse()?))
|
||||
} else if l.peek::<kw::list>() {
|
||||
} else if l.peek::<kw::list>()? {
|
||||
Ok(Self::List(parser.parse()?))
|
||||
} else if l.peek::<kw::tuple>() {
|
||||
} else if l.peek::<kw::tuple>()? {
|
||||
Ok(Self::Tuple(parser.parse()?))
|
||||
} else if l.peek::<kw::flags>() {
|
||||
} else if l.peek::<kw::flags>()? {
|
||||
Ok(Self::Flags(parser.parse()?))
|
||||
} else if l.peek::<kw::enum_>() {
|
||||
} else if l.peek::<kw::enum_>()? {
|
||||
Ok(Self::Enum(parser.parse()?))
|
||||
} else if l.peek::<kw::union>() {
|
||||
} else if l.peek::<kw::union>()? {
|
||||
Ok(Self::Union(parser.parse()?))
|
||||
} else if l.peek::<kw::option>() {
|
||||
} else if l.peek::<kw::option>()? {
|
||||
Ok(Self::Option(parser.parse()?))
|
||||
} else if l.peek::<kw::result>() {
|
||||
} else if l.peek::<kw::result>()? {
|
||||
Ok(Self::Result(parser.parse()?))
|
||||
} else if l.peek::<kw::own>() {
|
||||
} else if l.peek::<kw::own>()? {
|
||||
parser.parse::<kw::own>()?;
|
||||
Ok(Self::Own(parser.parse()?))
|
||||
} else if l.peek::<kw::borrow>() {
|
||||
} else if l.peek::<kw::borrow>()? {
|
||||
parser.parse::<kw::borrow>()?;
|
||||
Ok(Self::Borrow(parser.parse()?))
|
||||
} else {
|
||||
@ -419,14 +419,14 @@ impl Default for ComponentDefinedType<'_> {
|
||||
}
|
||||
|
||||
impl Peek for ComponentDefinedType<'_> {
|
||||
fn peek(cursor: crate::parser::Cursor<'_>) -> bool {
|
||||
if PrimitiveValType::peek(cursor) {
|
||||
return true;
|
||||
fn peek(cursor: crate::parser::Cursor<'_>) -> Result<bool> {
|
||||
if PrimitiveValType::peek(cursor)? {
|
||||
return Ok(true);
|
||||
}
|
||||
|
||||
match cursor.lparen() {
|
||||
Ok(match cursor.lparen()? {
|
||||
Some(cursor) => matches!(
|
||||
cursor.keyword(),
|
||||
cursor.keyword()?,
|
||||
Some(("record", _))
|
||||
| Some(("variant", _))
|
||||
| Some(("list", _))
|
||||
@ -440,7 +440,7 @@ impl Peek for ComponentDefinedType<'_> {
|
||||
| Some(("borrow", _))
|
||||
),
|
||||
None => false,
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
fn display() -> &'static str {
|
||||
@ -678,7 +678,7 @@ impl<'a> Parse<'a> for ResultType<'a> {
|
||||
parser.parse::<kw::result>()?;
|
||||
|
||||
let ok: Option<ComponentValType> = parser.parse()?;
|
||||
let err: Option<ComponentValType> = if parser.peek::<LParen>() {
|
||||
let err: Option<ComponentValType> = if parser.peek::<LParen>()? {
|
||||
Some(parser.parens(|parser| {
|
||||
parser.parse::<kw::error>()?;
|
||||
parser.parse()
|
||||
@ -708,12 +708,12 @@ pub struct ComponentFunctionType<'a> {
|
||||
impl<'a> Parse<'a> for ComponentFunctionType<'a> {
|
||||
fn parse(parser: Parser<'a>) -> Result<Self> {
|
||||
let mut params: Vec<ComponentFunctionParam> = Vec::new();
|
||||
while parser.peek2::<kw::param>() {
|
||||
while parser.peek2::<kw::param>()? {
|
||||
params.push(parser.parens(|p| p.parse())?);
|
||||
}
|
||||
|
||||
let mut results: Vec<ComponentFunctionResult> = Vec::new();
|
||||
while parser.peek2::<kw::result>() {
|
||||
while parser.peek2::<kw::result>()? {
|
||||
results.push(parser.parens(|p| p.parse())?);
|
||||
}
|
||||
|
||||
@ -823,15 +823,15 @@ pub enum ComponentTypeDecl<'a> {
|
||||
impl<'a> Parse<'a> for ComponentTypeDecl<'a> {
|
||||
fn parse(parser: Parser<'a>) -> Result<Self> {
|
||||
let mut l = parser.lookahead1();
|
||||
if l.peek::<kw::core>() {
|
||||
if l.peek::<kw::core>()? {
|
||||
Ok(Self::CoreType(parser.parse()?))
|
||||
} else if l.peek::<kw::r#type>() {
|
||||
} else if l.peek::<kw::r#type>()? {
|
||||
Ok(Self::Type(Type::parse_no_inline_exports(parser)?))
|
||||
} else if l.peek::<kw::alias>() {
|
||||
} else if l.peek::<kw::alias>()? {
|
||||
Ok(Self::Alias(parser.parse()?))
|
||||
} else if l.peek::<kw::import>() {
|
||||
} else if l.peek::<kw::import>()? {
|
||||
Ok(Self::Import(parser.parse()?))
|
||||
} else if l.peek::<kw::export>() {
|
||||
} else if l.peek::<kw::export>()? {
|
||||
Ok(Self::Export(parser.parse()?))
|
||||
} else {
|
||||
Err(l.error())
|
||||
@ -881,13 +881,13 @@ pub enum InstanceTypeDecl<'a> {
|
||||
impl<'a> Parse<'a> for InstanceTypeDecl<'a> {
|
||||
fn parse(parser: Parser<'a>) -> Result<Self> {
|
||||
let mut l = parser.lookahead1();
|
||||
if l.peek::<kw::core>() {
|
||||
if l.peek::<kw::core>()? {
|
||||
Ok(Self::CoreType(parser.parse()?))
|
||||
} else if l.peek::<kw::r#type>() {
|
||||
} else if l.peek::<kw::r#type>()? {
|
||||
Ok(Self::Type(Type::parse_no_inline_exports(parser)?))
|
||||
} else if l.peek::<kw::alias>() {
|
||||
} else if l.peek::<kw::alias>()? {
|
||||
Ok(Self::Alias(parser.parse()?))
|
||||
} else if l.peek::<kw::export>() {
|
||||
} else if l.peek::<kw::export>()? {
|
||||
Ok(Self::Export(parser.parse()?))
|
||||
} else {
|
||||
Err(l.error())
|
||||
@ -960,7 +960,7 @@ pub enum CoreTypeUse<'a, T> {
|
||||
impl<'a, T: Parse<'a>> Parse<'a> for CoreTypeUse<'a, T> {
|
||||
fn parse(parser: Parser<'a>) -> Result<Self> {
|
||||
// Here the core context is assumed, so no core prefix is expected
|
||||
if parser.peek::<LParen>() && parser.peek2::<CoreItemRef<'a, kw::r#type>>() {
|
||||
if parser.peek::<LParen>()? && parser.peek2::<CoreItemRef<'a, kw::r#type>>()? {
|
||||
Ok(Self::Ref(parser.parens(|parser| parser.parse())?))
|
||||
} else {
|
||||
Ok(Self::Inline(parser.parse()?))
|
||||
@ -993,7 +993,7 @@ pub enum ComponentTypeUse<'a, T> {
|
||||
|
||||
impl<'a, T: Parse<'a>> Parse<'a> for ComponentTypeUse<'a, T> {
|
||||
fn parse(parser: Parser<'a>) -> Result<Self> {
|
||||
if parser.peek::<LParen>() && parser.peek2::<ItemRef<'a, kw::r#type>>() {
|
||||
if parser.peek::<LParen>()? && parser.peek2::<ItemRef<'a, kw::r#type>>()? {
|
||||
Ok(Self::Ref(parser.parens(|parser| parser.parse())?))
|
||||
} else {
|
||||
Ok(Self::Inline(parser.parse()?))
|
||||
|
14
third_party/rust/wast/src/component/wast.rs
vendored
14
third_party/rust/wast/src/component/wast.rs
vendored
@ -36,10 +36,10 @@ static CASES: &[(&str, fn(Parser<'_>) -> Result<WastVal<'_>>)] = {
|
||||
&[
|
||||
("bool.const", |p| {
|
||||
let mut l = p.lookahead1();
|
||||
if l.peek::<kw::true_>() {
|
||||
if l.peek::<kw::true_>()? {
|
||||
p.parse::<kw::true_>()?;
|
||||
Ok(Bool(true))
|
||||
} else if l.peek::<kw::false_>() {
|
||||
} else if l.peek::<kw::false_>()? {
|
||||
p.parse::<kw::false_>()?;
|
||||
Ok(Bool(false))
|
||||
} else {
|
||||
@ -140,7 +140,7 @@ impl<'a> Parse<'a> for WastVal<'a> {
|
||||
fn parse(parser: Parser<'a>) -> Result<Self> {
|
||||
parser.depth_check()?;
|
||||
let parse = parser.step(|c| {
|
||||
if let Some((kw, rest)) = c.keyword() {
|
||||
if let Some((kw, rest)) = c.keyword()? {
|
||||
if let Some(i) = CASES.iter().position(|(name, _)| *name == kw) {
|
||||
return Ok((CASES[i].1, rest));
|
||||
}
|
||||
@ -152,12 +152,12 @@ impl<'a> Parse<'a> for WastVal<'a> {
|
||||
}
|
||||
|
||||
impl Peek for WastVal<'_> {
|
||||
fn peek(cursor: Cursor<'_>) -> bool {
|
||||
let kw = match cursor.keyword() {
|
||||
fn peek(cursor: Cursor<'_>) -> Result<bool> {
|
||||
let kw = match cursor.keyword()? {
|
||||
Some((kw, _)) => kw,
|
||||
None => return false,
|
||||
None => return Ok(false),
|
||||
};
|
||||
CASES.iter().any(|(name, _)| *name == kw)
|
||||
Ok(CASES.iter().any(|(name, _)| *name == kw))
|
||||
}
|
||||
|
||||
fn display() -> &'static str {
|
||||
|
23
third_party/rust/wast/src/core/binary.rs
vendored
23
third_party/rust/wast/src/core/binary.rs
vendored
@ -545,6 +545,10 @@ impl Encode for Elem<'_> {
|
||||
offset.encode(e);
|
||||
e.push(0x00); // extern_kind
|
||||
}
|
||||
(ElemKind::Declared, ElemPayload::Indices(_)) => {
|
||||
e.push(0x03); // flags
|
||||
e.push(0x00); // extern_kind
|
||||
}
|
||||
(
|
||||
ElemKind::Active {
|
||||
table: Index::Num(0, _),
|
||||
@ -572,10 +576,6 @@ impl Encode for Elem<'_> {
|
||||
offset.encode(e);
|
||||
ty.encode(e);
|
||||
}
|
||||
(ElemKind::Declared, ElemPayload::Indices(_)) => {
|
||||
e.push(0x03); // flags
|
||||
e.push(0x00); // extern_kind
|
||||
}
|
||||
(ElemKind::Declared, ElemPayload::Exprs { ty, .. }) => {
|
||||
e.push(0x07); // flags
|
||||
ty.encode(e);
|
||||
@ -641,10 +641,10 @@ impl Encode for Func<'_> {
|
||||
}
|
||||
}
|
||||
|
||||
impl Encode for Vec<Local<'_>> {
|
||||
impl Encode for Box<[Local<'_>]> {
|
||||
fn encode(&self, e: &mut Vec<u8>) {
|
||||
let mut locals_compressed = Vec::<(u32, ValType)>::new();
|
||||
for local in self {
|
||||
for local in self.iter() {
|
||||
if let Some((cnt, prev)) = locals_compressed.last_mut() {
|
||||
if *prev == local.ty {
|
||||
*cnt += 1;
|
||||
@ -919,7 +919,7 @@ fn find_names<'a>(
|
||||
locals, expression, ..
|
||||
} = &f.kind
|
||||
{
|
||||
for local in locals {
|
||||
for local in locals.iter() {
|
||||
if let Some(name) = get_name(&local.id, &local.name) {
|
||||
local_names.push((local_idx, name));
|
||||
}
|
||||
@ -1173,7 +1173,7 @@ impl Encode for RefCast<'_> {
|
||||
}
|
||||
}
|
||||
|
||||
fn br_on_cast_flags(on_fail: bool, from_nullable: bool, to_nullable: bool) -> u8 {
|
||||
fn br_on_cast_flags(from_nullable: bool, to_nullable: bool) -> u8 {
|
||||
let mut flag = 0;
|
||||
if from_nullable {
|
||||
flag |= 1 << 0;
|
||||
@ -1181,18 +1181,14 @@ fn br_on_cast_flags(on_fail: bool, from_nullable: bool, to_nullable: bool) -> u8
|
||||
if to_nullable {
|
||||
flag |= 1 << 1;
|
||||
}
|
||||
if on_fail {
|
||||
flag |= 1 << 2;
|
||||
}
|
||||
flag
|
||||
}
|
||||
|
||||
impl Encode for BrOnCast<'_> {
|
||||
fn encode(&self, e: &mut Vec<u8>) {
|
||||
e.push(0xfb);
|
||||
e.push(0x4f);
|
||||
e.push(0x4e);
|
||||
e.push(br_on_cast_flags(
|
||||
false,
|
||||
self.from_type.nullable,
|
||||
self.to_type.nullable,
|
||||
));
|
||||
@ -1207,7 +1203,6 @@ impl Encode for BrOnCastFail<'_> {
|
||||
e.push(0xfb);
|
||||
e.push(0x4f);
|
||||
e.push(br_on_cast_flags(
|
||||
true,
|
||||
self.from_type.nullable,
|
||||
self.to_type.nullable,
|
||||
));
|
||||
|
42
third_party/rust/wast/src/core/custom.rs
vendored
42
third_party/rust/wast/src/core/custom.rs
vendored
@ -31,7 +31,7 @@ impl Custom<'_> {
|
||||
|
||||
impl<'a> Parse<'a> for Custom<'a> {
|
||||
fn parse(parser: Parser<'a>) -> Result<Self> {
|
||||
if parser.peek::<annotation::producers>() {
|
||||
if parser.peek::<annotation::producers>()? {
|
||||
Ok(Custom::Producers(parser.parse()?))
|
||||
} else {
|
||||
Ok(Custom::Raw(parser.parse()?))
|
||||
@ -90,7 +90,7 @@ impl<'a> Parse<'a> for RawCustomSection<'a> {
|
||||
fn parse(parser: Parser<'a>) -> Result<Self> {
|
||||
let span = parser.parse::<annotation::custom>()?.0;
|
||||
let name = parser.parse()?;
|
||||
let place = if parser.peek::<token::LParen>() {
|
||||
let place = if parser.peek::<token::LParen>()? {
|
||||
parser.parens(|p| p.parse())?
|
||||
} else {
|
||||
CustomPlace::AfterLast
|
||||
@ -111,16 +111,16 @@ impl<'a> Parse<'a> for RawCustomSection<'a> {
|
||||
impl<'a> Parse<'a> for CustomPlace {
|
||||
fn parse(parser: Parser<'a>) -> Result<Self> {
|
||||
let mut l = parser.lookahead1();
|
||||
let ctor = if l.peek::<kw::before>() {
|
||||
let ctor = if l.peek::<kw::before>()? {
|
||||
parser.parse::<kw::before>()?;
|
||||
if l.peek::<kw::first>() {
|
||||
if l.peek::<kw::first>()? {
|
||||
parser.parse::<kw::first>()?;
|
||||
return Ok(CustomPlace::BeforeFirst);
|
||||
}
|
||||
CustomPlace::Before as fn(CustomPlaceAnchor) -> _
|
||||
} else if l.peek::<kw::after>() {
|
||||
} else if l.peek::<kw::after>()? {
|
||||
parser.parse::<kw::after>()?;
|
||||
if l.peek::<kw::last>() {
|
||||
if l.peek::<kw::last>()? {
|
||||
parser.parse::<kw::last>()?;
|
||||
return Ok(CustomPlace::AfterLast);
|
||||
}
|
||||
@ -134,51 +134,51 @@ impl<'a> Parse<'a> for CustomPlace {
|
||||
|
||||
impl<'a> Parse<'a> for CustomPlaceAnchor {
|
||||
fn parse(parser: Parser<'a>) -> Result<Self> {
|
||||
if parser.peek::<kw::r#type>() {
|
||||
if parser.peek::<kw::r#type>()? {
|
||||
parser.parse::<kw::r#type>()?;
|
||||
return Ok(CustomPlaceAnchor::Type);
|
||||
}
|
||||
if parser.peek::<kw::import>() {
|
||||
if parser.peek::<kw::import>()? {
|
||||
parser.parse::<kw::import>()?;
|
||||
return Ok(CustomPlaceAnchor::Import);
|
||||
}
|
||||
if parser.peek::<kw::func>() {
|
||||
if parser.peek::<kw::func>()? {
|
||||
parser.parse::<kw::func>()?;
|
||||
return Ok(CustomPlaceAnchor::Func);
|
||||
}
|
||||
if parser.peek::<kw::table>() {
|
||||
if parser.peek::<kw::table>()? {
|
||||
parser.parse::<kw::table>()?;
|
||||
return Ok(CustomPlaceAnchor::Table);
|
||||
}
|
||||
if parser.peek::<kw::memory>() {
|
||||
if parser.peek::<kw::memory>()? {
|
||||
parser.parse::<kw::memory>()?;
|
||||
return Ok(CustomPlaceAnchor::Memory);
|
||||
}
|
||||
if parser.peek::<kw::global>() {
|
||||
if parser.peek::<kw::global>()? {
|
||||
parser.parse::<kw::global>()?;
|
||||
return Ok(CustomPlaceAnchor::Global);
|
||||
}
|
||||
if parser.peek::<kw::export>() {
|
||||
if parser.peek::<kw::export>()? {
|
||||
parser.parse::<kw::export>()?;
|
||||
return Ok(CustomPlaceAnchor::Export);
|
||||
}
|
||||
if parser.peek::<kw::start>() {
|
||||
if parser.peek::<kw::start>()? {
|
||||
parser.parse::<kw::start>()?;
|
||||
return Ok(CustomPlaceAnchor::Start);
|
||||
}
|
||||
if parser.peek::<kw::elem>() {
|
||||
if parser.peek::<kw::elem>()? {
|
||||
parser.parse::<kw::elem>()?;
|
||||
return Ok(CustomPlaceAnchor::Elem);
|
||||
}
|
||||
if parser.peek::<kw::code>() {
|
||||
if parser.peek::<kw::code>()? {
|
||||
parser.parse::<kw::code>()?;
|
||||
return Ok(CustomPlaceAnchor::Code);
|
||||
}
|
||||
if parser.peek::<kw::data>() {
|
||||
if parser.peek::<kw::data>()? {
|
||||
parser.parse::<kw::data>()?;
|
||||
return Ok(CustomPlaceAnchor::Data);
|
||||
}
|
||||
if parser.peek::<kw::tag>() {
|
||||
if parser.peek::<kw::tag>()? {
|
||||
parser.parse::<kw::tag>()?;
|
||||
return Ok(CustomPlaceAnchor::Tag);
|
||||
}
|
||||
@ -203,13 +203,13 @@ impl<'a> Parse<'a> for Producers<'a> {
|
||||
while !parser.is_empty() {
|
||||
parser.parens(|parser| {
|
||||
let mut l = parser.lookahead1();
|
||||
let dst = if l.peek::<kw::language>() {
|
||||
let dst = if l.peek::<kw::language>()? {
|
||||
parser.parse::<kw::language>()?;
|
||||
&mut languages
|
||||
} else if l.peek::<kw::sdk>() {
|
||||
} else if l.peek::<kw::sdk>()? {
|
||||
parser.parse::<kw::sdk>()?;
|
||||
&mut sdks
|
||||
} else if l.peek::<kw::processed_by>() {
|
||||
} else if l.peek::<kw::processed_by>()? {
|
||||
parser.parse::<kw::processed_by>()?;
|
||||
&mut processed_by
|
||||
} else {
|
||||
|
40
third_party/rust/wast/src/core/export.rs
vendored
40
third_party/rust/wast/src/core/export.rs
vendored
@ -44,19 +44,19 @@ impl<'a> Parse<'a> for Export<'a> {
|
||||
impl<'a> Parse<'a> for ExportKind {
|
||||
fn parse(parser: Parser<'a>) -> Result<Self> {
|
||||
let mut l = parser.lookahead1();
|
||||
if l.peek::<kw::func>() {
|
||||
if l.peek::<kw::func>()? {
|
||||
parser.parse::<kw::func>()?;
|
||||
Ok(ExportKind::Func)
|
||||
} else if l.peek::<kw::table>() {
|
||||
} else if l.peek::<kw::table>()? {
|
||||
parser.parse::<kw::table>()?;
|
||||
Ok(ExportKind::Table)
|
||||
} else if l.peek::<kw::memory>() {
|
||||
} else if l.peek::<kw::memory>()? {
|
||||
parser.parse::<kw::memory>()?;
|
||||
Ok(ExportKind::Memory)
|
||||
} else if l.peek::<kw::global>() {
|
||||
} else if l.peek::<kw::global>()? {
|
||||
parser.parse::<kw::global>()?;
|
||||
Ok(ExportKind::Global)
|
||||
} else if l.peek::<kw::tag>() {
|
||||
} else if l.peek::<kw::tag>()? {
|
||||
parser.parse::<kw::tag>()?;
|
||||
Ok(ExportKind::Tag)
|
||||
} else {
|
||||
@ -66,12 +66,12 @@ impl<'a> Parse<'a> for ExportKind {
|
||||
}
|
||||
|
||||
impl Peek for ExportKind {
|
||||
fn peek(cursor: Cursor<'_>) -> bool {
|
||||
kw::func::peek(cursor)
|
||||
|| kw::table::peek(cursor)
|
||||
|| kw::memory::peek(cursor)
|
||||
|| kw::global::peek(cursor)
|
||||
|| kw::tag::peek(cursor)
|
||||
fn peek(cursor: Cursor<'_>) -> Result<bool> {
|
||||
Ok(kw::func::peek(cursor)?
|
||||
|| kw::table::peek(cursor)?
|
||||
|| kw::memory::peek(cursor)?
|
||||
|| kw::global::peek(cursor)?
|
||||
|| kw::tag::peek(cursor)?)
|
||||
}
|
||||
fn display() -> &'static str {
|
||||
"export kind"
|
||||
@ -113,7 +113,7 @@ pub struct InlineExport<'a> {
|
||||
impl<'a> Parse<'a> for InlineExport<'a> {
|
||||
fn parse(parser: Parser<'a>) -> Result<Self> {
|
||||
let mut names = Vec::new();
|
||||
while parser.peek::<Self>() {
|
||||
while parser.peek::<Self>()? {
|
||||
names.push(parser.parens(|p| {
|
||||
p.parse::<kw::export>()?;
|
||||
p.parse::<&str>()
|
||||
@ -124,20 +124,20 @@ impl<'a> Parse<'a> for InlineExport<'a> {
|
||||
}
|
||||
|
||||
impl Peek for InlineExport<'_> {
|
||||
fn peek(cursor: Cursor<'_>) -> bool {
|
||||
let cursor = match cursor.lparen() {
|
||||
fn peek(cursor: Cursor<'_>) -> Result<bool> {
|
||||
let cursor = match cursor.lparen()? {
|
||||
Some(cursor) => cursor,
|
||||
None => return false,
|
||||
None => return Ok(false),
|
||||
};
|
||||
let cursor = match cursor.keyword() {
|
||||
let cursor = match cursor.keyword()? {
|
||||
Some(("export", cursor)) => cursor,
|
||||
_ => return false,
|
||||
_ => return Ok(false),
|
||||
};
|
||||
let cursor = match cursor.string() {
|
||||
let cursor = match cursor.string()? {
|
||||
Some((_, cursor)) => cursor,
|
||||
None => return false,
|
||||
None => return Ok(false),
|
||||
};
|
||||
cursor.rparen().is_some()
|
||||
Ok(cursor.rparen()?.is_some())
|
||||
}
|
||||
|
||||
fn display() -> &'static str {
|
||||
|
72
third_party/rust/wast/src/core/expr.rs
vendored
72
third_party/rust/wast/src/core/expr.rs
vendored
@ -117,7 +117,7 @@ impl<'a> ExpressionParser<'a> {
|
||||
// of an `if block then we require that all sub-components are
|
||||
// s-expressions surrounded by `(` and `)`, so verify that here.
|
||||
if let Some(Level::If(_)) | Some(Level::Try(_)) = self.stack.last() {
|
||||
if !parser.is_empty() && !parser.peek::<LParen>() {
|
||||
if !parser.is_empty() && !parser.peek::<LParen>()? {
|
||||
return Err(parser.error("expected `(`"));
|
||||
}
|
||||
}
|
||||
@ -220,10 +220,10 @@ impl<'a> ExpressionParser<'a> {
|
||||
/// Parses either `(`, `)`, or nothing.
|
||||
fn paren(&self, parser: Parser<'a>) -> Result<Paren> {
|
||||
parser.step(|cursor| {
|
||||
Ok(match cursor.lparen() {
|
||||
Ok(match cursor.lparen()? {
|
||||
Some(rest) => (Paren::Left, rest),
|
||||
None if self.stack.is_empty() => (Paren::None, cursor),
|
||||
None => match cursor.rparen() {
|
||||
None => match cursor.rparen()? {
|
||||
Some(rest) => (Paren::Right, rest),
|
||||
None => (Paren::None, cursor),
|
||||
},
|
||||
@ -265,7 +265,7 @@ impl<'a> ExpressionParser<'a> {
|
||||
if let If::Clause(if_instr) = i {
|
||||
let instr = mem::replace(if_instr, Instruction::End(None));
|
||||
*i = If::Then(instr);
|
||||
if !parser.peek::<kw::then>() {
|
||||
if !parser.peek::<kw::then>()? {
|
||||
return Ok(false);
|
||||
}
|
||||
}
|
||||
@ -426,7 +426,7 @@ macro_rules! instructions {
|
||||
}
|
||||
)*
|
||||
let parse_remainder = parser.step(|c| {
|
||||
let (kw, rest) = match c.keyword() {
|
||||
let (kw, rest) = match c.keyword() ?{
|
||||
Some(pair) => pair,
|
||||
None => return Err(c.error("expected an instruction")),
|
||||
};
|
||||
@ -502,10 +502,10 @@ macro_rules! instructions {
|
||||
|
||||
instructions! {
|
||||
pub enum Instruction<'a> {
|
||||
Block(BlockType<'a>) : [0x02] : "block",
|
||||
If(BlockType<'a>) : [0x04] : "if",
|
||||
Block(Box<BlockType<'a>>) : [0x02] : "block",
|
||||
If(Box<BlockType<'a>>) : [0x04] : "if",
|
||||
Else(Option<Id<'a>>) : [0x05] : "else",
|
||||
Loop(BlockType<'a>) : [0x03] : "loop",
|
||||
Loop(Box<BlockType<'a>>) : [0x03] : "loop",
|
||||
End(Option<Id<'a>>) : [0x0b] : "end",
|
||||
|
||||
Unreachable : [0x00] : "unreachable",
|
||||
@ -515,11 +515,11 @@ instructions! {
|
||||
BrTable(BrTableIndices<'a>) : [0x0e] : "br_table",
|
||||
Return : [0x0f] : "return",
|
||||
Call(Index<'a>) : [0x10] : "call",
|
||||
CallIndirect(CallIndirect<'a>) : [0x11] : "call_indirect",
|
||||
CallIndirect(Box<CallIndirect<'a>>) : [0x11] : "call_indirect",
|
||||
|
||||
// tail-call proposal
|
||||
ReturnCall(Index<'a>) : [0x12] : "return_call",
|
||||
ReturnCallIndirect(CallIndirect<'a>) : [0x13] : "return_call_indirect",
|
||||
ReturnCallIndirect(Box<CallIndirect<'a>>) : [0x13] : "return_call_indirect",
|
||||
|
||||
// function-references proposal
|
||||
CallRef(Index<'a>) : [0x14] : "call_ref",
|
||||
@ -621,8 +621,8 @@ instructions! {
|
||||
// gc proposal, concrete casting
|
||||
RefTest(RefTest<'a>) : [] : "ref.test",
|
||||
RefCast(RefCast<'a>) : [] : "ref.cast",
|
||||
BrOnCast(BrOnCast<'a>) : [] : "br_on_cast",
|
||||
BrOnCastFail(BrOnCastFail<'a>) : [] : "br_on_cast_fail",
|
||||
BrOnCast(Box<BrOnCast<'a>>) : [] : "br_on_cast",
|
||||
BrOnCastFail(Box<BrOnCastFail<'a>>) : [] : "br_on_cast_fail",
|
||||
|
||||
// gc proposal extern/any coercion operations
|
||||
ExternInternalize : [0xfb, 0x70] : "extern.internalize",
|
||||
@ -1118,7 +1118,7 @@ instructions! {
|
||||
F64x2PromoteLowF32x4 : [0xfd, 95] : "f64x2.promote_low_f32x4",
|
||||
|
||||
// Exception handling proposal
|
||||
Try(BlockType<'a>) : [0x06] : "try",
|
||||
Try(Box<BlockType<'a>>) : [0x06] : "try",
|
||||
Catch(Index<'a>) : [0x07] : "catch",
|
||||
Throw(Index<'a>) : [0x08] : "throw",
|
||||
Rethrow(Index<'a>) : [0x09] : "rethrow",
|
||||
@ -1149,6 +1149,16 @@ instructions! {
|
||||
}
|
||||
}
|
||||
|
||||
// As shown in #1095 the size of this variant is somewhat performance-sensitive
|
||||
// since big `*.wat` files will have a lot of these. This is a small ratchet to
|
||||
// make sure that this enum doesn't become larger than it already is, although
|
||||
// ideally it also wouldn't be as large as it is now.
|
||||
const _: () = {
|
||||
let size = std::mem::size_of::<Instruction<'_>>();
|
||||
let pointer = std::mem::size_of::<u64>();
|
||||
assert!(size <= pointer * 10);
|
||||
};
|
||||
|
||||
impl<'a> Instruction<'a> {
|
||||
pub(crate) fn needs_data_count(&self) -> bool {
|
||||
match self {
|
||||
@ -1205,15 +1215,15 @@ impl<'a> Parse<'a> for FuncBindType<'a> {
|
||||
#[derive(Debug)]
|
||||
#[allow(missing_docs)]
|
||||
pub struct LetType<'a> {
|
||||
pub block: BlockType<'a>,
|
||||
pub locals: Vec<Local<'a>>,
|
||||
pub block: Box<BlockType<'a>>,
|
||||
pub locals: Box<[Local<'a>]>,
|
||||
}
|
||||
|
||||
impl<'a> Parse<'a> for LetType<'a> {
|
||||
fn parse(parser: Parser<'a>) -> Result<Self> {
|
||||
Ok(LetType {
|
||||
block: parser.parse()?,
|
||||
locals: Local::parse_remainder(parser)?,
|
||||
locals: Local::parse_remainder(parser)?.into(),
|
||||
})
|
||||
}
|
||||
}
|
||||
@ -1229,7 +1239,7 @@ pub struct BrTableIndices<'a> {
|
||||
impl<'a> Parse<'a> for BrTableIndices<'a> {
|
||||
fn parse(parser: Parser<'a>) -> Result<Self> {
|
||||
let mut labels = vec![parser.parse()?];
|
||||
while parser.peek::<Index>() {
|
||||
while parser.peek::<Index>()? {
|
||||
labels.push(parser.parse()?);
|
||||
}
|
||||
let default = labels.pop().unwrap();
|
||||
@ -1247,7 +1257,7 @@ pub struct LaneArg {
|
||||
impl<'a> Parse<'a> for LaneArg {
|
||||
fn parse(parser: Parser<'a>) -> Result<Self> {
|
||||
let lane = parser.step(|c| {
|
||||
if let Some((i, rest)) = c.integer() {
|
||||
if let Some((i, rest)) = c.integer()? {
|
||||
if i.sign() == None {
|
||||
let (src, radix) = i.val();
|
||||
let val = u8::from_str_radix(src, radix)
|
||||
@ -1287,7 +1297,7 @@ impl<'a> MemArg<'a> {
|
||||
f: impl FnOnce(Cursor<'_>, &str, u32) -> Result<T>,
|
||||
) -> Result<Option<T>> {
|
||||
parser.step(|c| {
|
||||
let (kw, rest) = match c.keyword() {
|
||||
let (kw, rest) = match c.keyword()? {
|
||||
Some(p) => p,
|
||||
None => return Ok((None, c)),
|
||||
};
|
||||
@ -1354,17 +1364,17 @@ impl<'a> LoadOrStoreLane<'a> {
|
||||
// This is sort of funky. The first integer we see could be the lane
|
||||
// index, but it could also be the memory index. To determine what it is
|
||||
// then if we see a second integer we need to look further.
|
||||
let has_memarg = parser.step(|c| match c.integer() {
|
||||
let has_memarg = parser.step(|c| match c.integer()? {
|
||||
Some((_, after_int)) => {
|
||||
// Two integers in a row? That means that the first one is the
|
||||
// memory index and the second must be the lane index.
|
||||
if after_int.integer().is_some() {
|
||||
if after_int.integer()?.is_some() {
|
||||
return Ok((true, c));
|
||||
}
|
||||
|
||||
// If the first integer is trailed by `offset=...` or
|
||||
// `align=...` then this is definitely a memarg.
|
||||
if let Some((kw, _)) = after_int.keyword() {
|
||||
if let Some((kw, _)) = after_int.keyword()? {
|
||||
if kw.starts_with("offset=") || kw.starts_with("align=") {
|
||||
return Ok((true, c));
|
||||
}
|
||||
@ -1427,7 +1437,7 @@ pub struct TableInit<'a> {
|
||||
impl<'a> Parse<'a> for TableInit<'a> {
|
||||
fn parse(parser: Parser<'a>) -> Result<Self> {
|
||||
let prev_span = parser.prev_span();
|
||||
let (elem, table) = if parser.peek2::<Index>() {
|
||||
let (elem, table) = if parser.peek2::<Index>()? {
|
||||
let table = parser.parse()?;
|
||||
(parser.parse()?, table)
|
||||
} else {
|
||||
@ -1507,7 +1517,7 @@ pub struct MemoryInit<'a> {
|
||||
impl<'a> Parse<'a> for MemoryInit<'a> {
|
||||
fn parse(parser: Parser<'a>) -> Result<Self> {
|
||||
let prev_span = parser.prev_span();
|
||||
let (data, mem) = if parser.peek2::<Index>() {
|
||||
let (data, mem) = if parser.peek2::<Index>()? {
|
||||
let memory = parser.parse()?;
|
||||
(parser.parse()?, memory)
|
||||
} else {
|
||||
@ -1840,7 +1850,7 @@ impl V128Const {
|
||||
impl<'a> Parse<'a> for V128Const {
|
||||
fn parse(parser: Parser<'a>) -> Result<Self> {
|
||||
let mut l = parser.lookahead1();
|
||||
if l.peek::<kw::i8x16>() {
|
||||
if l.peek::<kw::i8x16>()? {
|
||||
parser.parse::<kw::i8x16>()?;
|
||||
Ok(V128Const::I8x16([
|
||||
parser.parse()?,
|
||||
@ -1860,7 +1870,7 @@ impl<'a> Parse<'a> for V128Const {
|
||||
parser.parse()?,
|
||||
parser.parse()?,
|
||||
]))
|
||||
} else if l.peek::<kw::i16x8>() {
|
||||
} else if l.peek::<kw::i16x8>()? {
|
||||
parser.parse::<kw::i16x8>()?;
|
||||
Ok(V128Const::I16x8([
|
||||
parser.parse()?,
|
||||
@ -1872,7 +1882,7 @@ impl<'a> Parse<'a> for V128Const {
|
||||
parser.parse()?,
|
||||
parser.parse()?,
|
||||
]))
|
||||
} else if l.peek::<kw::i32x4>() {
|
||||
} else if l.peek::<kw::i32x4>()? {
|
||||
parser.parse::<kw::i32x4>()?;
|
||||
Ok(V128Const::I32x4([
|
||||
parser.parse()?,
|
||||
@ -1880,10 +1890,10 @@ impl<'a> Parse<'a> for V128Const {
|
||||
parser.parse()?,
|
||||
parser.parse()?,
|
||||
]))
|
||||
} else if l.peek::<kw::i64x2>() {
|
||||
} else if l.peek::<kw::i64x2>()? {
|
||||
parser.parse::<kw::i64x2>()?;
|
||||
Ok(V128Const::I64x2([parser.parse()?, parser.parse()?]))
|
||||
} else if l.peek::<kw::f32x4>() {
|
||||
} else if l.peek::<kw::f32x4>()? {
|
||||
parser.parse::<kw::f32x4>()?;
|
||||
Ok(V128Const::F32x4([
|
||||
parser.parse()?,
|
||||
@ -1891,7 +1901,7 @@ impl<'a> Parse<'a> for V128Const {
|
||||
parser.parse()?,
|
||||
parser.parse()?,
|
||||
]))
|
||||
} else if l.peek::<kw::f64x2>() {
|
||||
} else if l.peek::<kw::f64x2>()? {
|
||||
parser.parse::<kw::f64x2>()?;
|
||||
Ok(V128Const::F64x2([parser.parse()?, parser.parse()?]))
|
||||
} else {
|
||||
@ -1943,7 +1953,7 @@ impl<'a> Parse<'a> for SelectTypes<'a> {
|
||||
fn parse(parser: Parser<'a>) -> Result<Self> {
|
||||
let mut found = false;
|
||||
let mut list = Vec::new();
|
||||
while parser.peek2::<kw::result>() {
|
||||
while parser.peek2::<kw::result>()? {
|
||||
found = true;
|
||||
parser.parens(|p| {
|
||||
p.parse::<kw::result>()?;
|
||||
|
6
third_party/rust/wast/src/core/func.rs
vendored
6
third_party/rust/wast/src/core/func.rs
vendored
@ -38,7 +38,7 @@ pub enum FuncKind<'a> {
|
||||
/// Almost all functions, those defined inline in a wasm module.
|
||||
Inline {
|
||||
/// The list of locals, if any, for this function.
|
||||
locals: Vec<Local<'a>>,
|
||||
locals: Box<[Local<'a>]>,
|
||||
|
||||
/// The instructions of the function.
|
||||
expression: Expression<'a>,
|
||||
@ -56,7 +56,7 @@ impl<'a> Parse<'a> for Func<'a> {
|
||||
(parser.parse()?, FuncKind::Import(import))
|
||||
} else {
|
||||
let ty = parser.parse()?;
|
||||
let locals = Local::parse_remainder(parser)?;
|
||||
let locals = Local::parse_remainder(parser)?.into();
|
||||
(
|
||||
ty,
|
||||
FuncKind::Inline {
|
||||
@ -95,7 +95,7 @@ pub struct Local<'a> {
|
||||
impl<'a> Local<'a> {
|
||||
pub(crate) fn parse_remainder(parser: Parser<'a>) -> Result<Vec<Local<'a>>> {
|
||||
let mut locals = Vec::new();
|
||||
while parser.peek2::<kw::local>() {
|
||||
while parser.peek2::<kw::local>()? {
|
||||
parser.parens(|p| {
|
||||
p.parse::<kw::local>()?;
|
||||
if p.is_empty() {
|
||||
|
30
third_party/rust/wast/src/core/import.rs
vendored
30
third_party/rust/wast/src/core/import.rs
vendored
@ -59,7 +59,7 @@ pub enum ItemKind<'a> {
|
||||
impl<'a> Parse<'a> for ItemSig<'a> {
|
||||
fn parse(parser: Parser<'a>) -> Result<Self> {
|
||||
let mut l = parser.lookahead1();
|
||||
if l.peek::<kw::func>() {
|
||||
if l.peek::<kw::func>()? {
|
||||
let span = parser.parse::<kw::func>()?.0;
|
||||
Ok(ItemSig {
|
||||
span,
|
||||
@ -67,7 +67,7 @@ impl<'a> Parse<'a> for ItemSig<'a> {
|
||||
name: parser.parse()?,
|
||||
kind: ItemKind::Func(parser.parse()?),
|
||||
})
|
||||
} else if l.peek::<kw::table>() {
|
||||
} else if l.peek::<kw::table>()? {
|
||||
let span = parser.parse::<kw::table>()?.0;
|
||||
Ok(ItemSig {
|
||||
span,
|
||||
@ -75,7 +75,7 @@ impl<'a> Parse<'a> for ItemSig<'a> {
|
||||
name: None,
|
||||
kind: ItemKind::Table(parser.parse()?),
|
||||
})
|
||||
} else if l.peek::<kw::memory>() {
|
||||
} else if l.peek::<kw::memory>()? {
|
||||
let span = parser.parse::<kw::memory>()?.0;
|
||||
Ok(ItemSig {
|
||||
span,
|
||||
@ -83,7 +83,7 @@ impl<'a> Parse<'a> for ItemSig<'a> {
|
||||
name: None,
|
||||
kind: ItemKind::Memory(parser.parse()?),
|
||||
})
|
||||
} else if l.peek::<kw::global>() {
|
||||
} else if l.peek::<kw::global>()? {
|
||||
let span = parser.parse::<kw::global>()?.0;
|
||||
Ok(ItemSig {
|
||||
span,
|
||||
@ -91,7 +91,7 @@ impl<'a> Parse<'a> for ItemSig<'a> {
|
||||
name: None,
|
||||
kind: ItemKind::Global(parser.parse()?),
|
||||
})
|
||||
} else if l.peek::<kw::tag>() {
|
||||
} else if l.peek::<kw::tag>()? {
|
||||
let span = parser.parse::<kw::tag>()?.0;
|
||||
Ok(ItemSig {
|
||||
span,
|
||||
@ -131,25 +131,25 @@ impl<'a> Parse<'a> for InlineImport<'a> {
|
||||
}
|
||||
|
||||
impl Peek for InlineImport<'_> {
|
||||
fn peek(cursor: Cursor<'_>) -> bool {
|
||||
let cursor = match cursor.lparen() {
|
||||
fn peek(cursor: Cursor<'_>) -> Result<bool> {
|
||||
let cursor = match cursor.lparen()? {
|
||||
Some(cursor) => cursor,
|
||||
None => return false,
|
||||
None => return Ok(false),
|
||||
};
|
||||
let cursor = match cursor.keyword() {
|
||||
let cursor = match cursor.keyword()? {
|
||||
Some(("import", cursor)) => cursor,
|
||||
_ => return false,
|
||||
_ => return Ok(false),
|
||||
};
|
||||
let cursor = match cursor.string() {
|
||||
let cursor = match cursor.string()? {
|
||||
Some((_, cursor)) => cursor,
|
||||
None => return false,
|
||||
None => return Ok(false),
|
||||
};
|
||||
let cursor = match cursor.string() {
|
||||
let cursor = match cursor.string()? {
|
||||
Some((_, cursor)) => cursor,
|
||||
None => return false,
|
||||
None => return Ok(false),
|
||||
};
|
||||
|
||||
cursor.rparen().is_some()
|
||||
Ok(cursor.rparen()?.is_some())
|
||||
}
|
||||
|
||||
fn display() -> &'static str {
|
||||
|
16
third_party/rust/wast/src/core/memory.rs
vendored
16
third_party/rust/wast/src/core/memory.rs
vendored
@ -59,7 +59,7 @@ impl<'a> Parse<'a> for Memory<'a> {
|
||||
import,
|
||||
ty: parser.parse()?,
|
||||
}
|
||||
} else if l.peek::<LParen>() || parser.peek2::<LParen>() {
|
||||
} else if l.peek::<LParen>()? || parser.peek2::<LParen>()? {
|
||||
let is_32 = if parser.parse::<Option<kw::i32>>()?.is_some() {
|
||||
true
|
||||
} else {
|
||||
@ -74,7 +74,7 @@ impl<'a> Parse<'a> for Memory<'a> {
|
||||
Ok(data)
|
||||
})?;
|
||||
MemoryKind::Inline { data, is_32 }
|
||||
} else if l.peek::<u32>() || l.peek::<kw::i32>() || l.peek::<kw::i64>() {
|
||||
} else if l.peek::<u32>()? || l.peek::<kw::i32>()? || l.peek::<kw::i64>()? {
|
||||
MemoryKind::Normal(parser.parse()?)
|
||||
} else {
|
||||
return Err(l.error());
|
||||
@ -133,19 +133,19 @@ impl<'a> Parse<'a> for Data<'a> {
|
||||
let id = parser.parse()?;
|
||||
let name = parser.parse()?;
|
||||
|
||||
let kind = if parser.peek::<&[u8]>() {
|
||||
let kind = if parser.peek::<&[u8]>()? {
|
||||
DataKind::Passive
|
||||
|
||||
// ... and otherwise we must be attached to a particular memory as well
|
||||
// as having an initialization offset.
|
||||
} else {
|
||||
let memory = if parser.peek::<u32>() {
|
||||
let memory = if parser.peek::<u32>()? {
|
||||
// FIXME: this is only here to accomodate
|
||||
// proposals/threads/imports.wast at this current moment in
|
||||
// time, this probably should get removed when the threads
|
||||
// proposal is rebased on the current spec.
|
||||
Index::Num(parser.parse()?, span)
|
||||
} else if parser.peek2::<kw::memory>() {
|
||||
} else if parser.peek2::<kw::memory>()? {
|
||||
parser.parens(|p| {
|
||||
p.parse::<kw::memory>()?;
|
||||
p.parse()
|
||||
@ -154,7 +154,7 @@ impl<'a> Parse<'a> for Data<'a> {
|
||||
Index::Num(0, span)
|
||||
};
|
||||
let offset = parser.parens(|parser| {
|
||||
if parser.peek::<kw::offset>() {
|
||||
if parser.peek::<kw::offset>()? {
|
||||
parser.parse::<kw::offset>()?;
|
||||
parser.parse()
|
||||
} else {
|
||||
@ -233,7 +233,7 @@ impl DataVal<'_> {
|
||||
|
||||
impl<'a> Parse<'a> for DataVal<'a> {
|
||||
fn parse(parser: Parser<'a>) -> Result<Self> {
|
||||
if !parser.peek::<LParen>() {
|
||||
if !parser.peek::<LParen>()? {
|
||||
return Ok(DataVal::String(parser.parse()?));
|
||||
}
|
||||
|
||||
@ -265,7 +265,7 @@ impl<'a> Parse<'a> for DataVal<'a> {
|
||||
where
|
||||
F: Fn(U, &mut Vec<u8>),
|
||||
{
|
||||
if !lookahead.peek::<T>() {
|
||||
if !lookahead.peek::<T>()? {
|
||||
return Ok(false);
|
||||
}
|
||||
parser.parse::<T>()?;
|
||||
|
34
third_party/rust/wast/src/core/module.rs
vendored
34
third_party/rust/wast/src/core/module.rs
vendored
@ -110,11 +110,15 @@ impl<'a> Module<'a> {
|
||||
|
||||
impl<'a> Parse<'a> for Module<'a> {
|
||||
fn parse(parser: Parser<'a>) -> Result<Self> {
|
||||
let _r = parser.register_annotation("custom");
|
||||
let _r = parser.register_annotation("producers");
|
||||
let _r = parser.register_annotation("name");
|
||||
|
||||
let span = parser.parse::<kw::module>()?.0;
|
||||
let id = parser.parse()?;
|
||||
let name = parser.parse()?;
|
||||
|
||||
let kind = if parser.peek::<kw::binary>() {
|
||||
let kind = if parser.peek::<kw::binary>()? {
|
||||
parser.parse::<kw::binary>()?;
|
||||
let mut data = Vec::new();
|
||||
while !parser.is_empty() {
|
||||
@ -154,8 +158,6 @@ pub enum ModuleField<'a> {
|
||||
|
||||
impl<'a> ModuleField<'a> {
|
||||
pub(crate) fn parse_remaining(parser: Parser<'a>) -> Result<Vec<ModuleField>> {
|
||||
let _r = parser.register_annotation("custom");
|
||||
let _r = parser.register_annotation("producers");
|
||||
let mut fields = Vec::new();
|
||||
while !parser.is_empty() {
|
||||
fields.push(parser.parens(ModuleField::parse)?);
|
||||
@ -166,44 +168,44 @@ impl<'a> ModuleField<'a> {
|
||||
|
||||
impl<'a> Parse<'a> for ModuleField<'a> {
|
||||
fn parse(parser: Parser<'a>) -> Result<Self> {
|
||||
if parser.peek::<Type<'a>>() {
|
||||
if parser.peek::<Type<'a>>()? {
|
||||
return Ok(ModuleField::Type(parser.parse()?));
|
||||
}
|
||||
if parser.peek::<kw::rec>() {
|
||||
if parser.peek::<kw::rec>()? {
|
||||
return Ok(ModuleField::Rec(parser.parse()?));
|
||||
}
|
||||
if parser.peek::<kw::import>() {
|
||||
if parser.peek::<kw::import>()? {
|
||||
return Ok(ModuleField::Import(parser.parse()?));
|
||||
}
|
||||
if parser.peek::<kw::func>() {
|
||||
if parser.peek::<kw::func>()? {
|
||||
return Ok(ModuleField::Func(parser.parse()?));
|
||||
}
|
||||
if parser.peek::<kw::table>() {
|
||||
if parser.peek::<kw::table>()? {
|
||||
return Ok(ModuleField::Table(parser.parse()?));
|
||||
}
|
||||
if parser.peek::<kw::memory>() {
|
||||
if parser.peek::<kw::memory>()? {
|
||||
return Ok(ModuleField::Memory(parser.parse()?));
|
||||
}
|
||||
if parser.peek::<kw::global>() {
|
||||
if parser.peek::<kw::global>()? {
|
||||
return Ok(ModuleField::Global(parser.parse()?));
|
||||
}
|
||||
if parser.peek::<kw::export>() {
|
||||
if parser.peek::<kw::export>()? {
|
||||
return Ok(ModuleField::Export(parser.parse()?));
|
||||
}
|
||||
if parser.peek::<kw::start>() {
|
||||
if parser.peek::<kw::start>()? {
|
||||
parser.parse::<kw::start>()?;
|
||||
return Ok(ModuleField::Start(parser.parse()?));
|
||||
}
|
||||
if parser.peek::<kw::elem>() {
|
||||
if parser.peek::<kw::elem>()? {
|
||||
return Ok(ModuleField::Elem(parser.parse()?));
|
||||
}
|
||||
if parser.peek::<kw::data>() {
|
||||
if parser.peek::<kw::data>()? {
|
||||
return Ok(ModuleField::Data(parser.parse()?));
|
||||
}
|
||||
if parser.peek::<kw::tag>() {
|
||||
if parser.peek::<kw::tag>()? {
|
||||
return Ok(ModuleField::Tag(parser.parse()?));
|
||||
}
|
||||
if parser.peek::<annotation::custom>() || parser.peek::<annotation::producers>() {
|
||||
if parser.peek::<annotation::custom>()? || parser.peek::<annotation::producers>()? {
|
||||
return Ok(ModuleField::Custom(parser.parse()?));
|
||||
}
|
||||
Err(parser.error("expected valid module field"))
|
||||
|
34
third_party/rust/wast/src/core/resolve/names.rs
vendored
34
third_party/rust/wast/src/core/resolve/names.rs
vendored
@ -3,6 +3,7 @@ use crate::core::*;
|
||||
use crate::names::{resolve_error, Namespace};
|
||||
use crate::token::{Id, Index};
|
||||
use crate::Error;
|
||||
use std::collections::HashMap;
|
||||
|
||||
pub fn resolve<'a>(fields: &mut Vec<ModuleField<'a>>) -> Result<Resolver<'a>, Error> {
|
||||
let mut resolver = Resolver::default();
|
||||
@ -25,7 +26,7 @@ pub struct Resolver<'a> {
|
||||
tags: Namespace<'a>,
|
||||
datas: Namespace<'a>,
|
||||
elems: Namespace<'a>,
|
||||
fields: Namespace<'a>,
|
||||
fields: HashMap<u32, Namespace<'a>>,
|
||||
type_info: Vec<TypeInfo<'a>>,
|
||||
}
|
||||
|
||||
@ -46,16 +47,20 @@ impl<'a> Resolver<'a> {
|
||||
}
|
||||
|
||||
fn register_type(&mut self, ty: &Type<'a>) -> Result<(), Error> {
|
||||
let type_index = self.types.register(ty.id, "type")?;
|
||||
|
||||
match &ty.def {
|
||||
// For GC structure types we need to be sure to populate the
|
||||
// field namespace here as well.
|
||||
//
|
||||
// The field namespace is global, but the resolved indices
|
||||
// are relative to the struct they are defined in
|
||||
// The field namespace is relative to the struct fields are defined in
|
||||
TypeDef::Struct(r#struct) => {
|
||||
for (i, field) in r#struct.fields.iter().enumerate() {
|
||||
if let Some(id) = field.id {
|
||||
self.fields.register_specific(id, i as u32, "field")?;
|
||||
self.fields
|
||||
.entry(type_index)
|
||||
.or_insert(Namespace::default())
|
||||
.register_specific(id, i as u32, "field")?;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -75,7 +80,6 @@ impl<'a> Resolver<'a> {
|
||||
_ => self.type_info.push(TypeInfo::Other),
|
||||
}
|
||||
|
||||
self.types.register(ty.id, "type")?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@ -176,7 +180,7 @@ impl<'a> Resolver<'a> {
|
||||
}
|
||||
|
||||
// .. followed by locals themselves
|
||||
for local in locals {
|
||||
for local in locals.iter() {
|
||||
scope.register(local.id, "local")?;
|
||||
}
|
||||
|
||||
@ -492,13 +496,13 @@ impl<'a, 'b> ExprResolver<'a, 'b> {
|
||||
|
||||
Let(t) => {
|
||||
// Resolve (ref T) in locals
|
||||
for local in &mut t.locals {
|
||||
for local in t.locals.iter_mut() {
|
||||
self.resolver.resolve_valtype(&mut local.ty)?;
|
||||
}
|
||||
|
||||
// Register all locals defined in this let
|
||||
let mut scope = Namespace::default();
|
||||
for local in &t.locals {
|
||||
for local in t.locals.iter() {
|
||||
scope.register(local.id, "local")?;
|
||||
}
|
||||
self.scopes.push(scope);
|
||||
@ -604,14 +608,20 @@ impl<'a, 'b> ExprResolver<'a, 'b> {
|
||||
self.resolver.resolve_reftype(&mut i.from_type)?;
|
||||
}
|
||||
|
||||
StructNew(i) | StructNewDefault(i) | ArrayNew(i)
|
||||
| ArrayNewDefault(i) | ArrayGet(i) | ArrayGetS(i) | ArrayGetU(i) | ArraySet(i) => {
|
||||
StructNew(i) | StructNewDefault(i) | ArrayNew(i) | ArrayNewDefault(i) | ArrayGet(i)
|
||||
| ArrayGetS(i) | ArrayGetU(i) | ArraySet(i) => {
|
||||
self.resolver.resolve(i, Ns::Type)?;
|
||||
}
|
||||
|
||||
StructSet(s) | StructGet(s) | StructGetS(s) | StructGetU(s) => {
|
||||
self.resolver.resolve(&mut s.r#struct, Ns::Type)?;
|
||||
self.resolver.fields.resolve(&mut s.field, "field")?;
|
||||
let type_index = self.resolver.resolve(&mut s.r#struct, Ns::Type)?;
|
||||
if let Index::Id(field_id) = s.field {
|
||||
self.resolver
|
||||
.fields
|
||||
.get(&type_index)
|
||||
.ok_or(Error::new(field_id.span(), format!("accessing a named field `{}` in a struct without named fields, type index {}", field_id.name(), type_index)))?
|
||||
.resolve(&mut s.field, "field")?;
|
||||
}
|
||||
}
|
||||
|
||||
ArrayNewFixed(a) => {
|
||||
|
162
third_party/rust/wast/src/core/table.rs
vendored
162
third_party/rust/wast/src/core/table.rs
vendored
@ -1,6 +1,6 @@
|
||||
use crate::core::*;
|
||||
use crate::kw;
|
||||
use crate::parser::{Parse, Parser, Result};
|
||||
use crate::parser::{Parse, Parser, Peek, Result};
|
||||
use crate::token::{Id, Index, LParen, NameAnnotation, Span};
|
||||
|
||||
/// A WebAssembly `table` directive in a module.
|
||||
@ -56,23 +56,22 @@ impl<'a> Parse<'a> for Table<'a> {
|
||||
|
||||
// Afterwards figure out which style this is, either:
|
||||
//
|
||||
// * `elemtype (elem ...)`
|
||||
// * `(import "a" "b") limits`
|
||||
// * `limits`
|
||||
// * `elemtype (elem ...)`
|
||||
// * `(import "a" "b") limits`
|
||||
// * `limits`
|
||||
let mut l = parser.lookahead1();
|
||||
let kind = if l.peek::<RefType>() {
|
||||
let kind = if l.peek::<RefType>()? {
|
||||
let elem = parser.parse()?;
|
||||
let payload = parser.parens(|p| {
|
||||
p.parse::<kw::elem>()?;
|
||||
let ty = if parser.peek::<LParen>() {
|
||||
Some(elem)
|
||||
if p.peek::<LParen>()? {
|
||||
ElemPayload::parse_exprs(p, elem)
|
||||
} else {
|
||||
None
|
||||
};
|
||||
ElemPayload::parse_tail(parser, ty)
|
||||
ElemPayload::parse_indices(p, Some(elem))
|
||||
}
|
||||
})?;
|
||||
TableKind::Inline { elem, payload }
|
||||
} else if l.peek::<u32>() {
|
||||
} else if l.peek::<u32>()? {
|
||||
TableKind::Normal {
|
||||
ty: parser.parse()?,
|
||||
init_expr: if !parser.is_empty() {
|
||||
@ -156,26 +155,47 @@ impl<'a> Parse<'a> for Elem<'a> {
|
||||
let id = parser.parse()?;
|
||||
let name = parser.parse()?;
|
||||
|
||||
let kind = if parser.peek::<kw::declare>() {
|
||||
// Element segments can start in a number of different ways:
|
||||
//
|
||||
// * `(elem ...`
|
||||
// * `(elem declare ...`
|
||||
// * `(elem (table ...`
|
||||
// * `(elem (offset ...`
|
||||
// * `(elem (<instr> ...`
|
||||
let mut table_omitted = false;
|
||||
let kind = if parser.peek::<kw::declare>()? {
|
||||
parser.parse::<kw::declare>()?;
|
||||
ElemKind::Declared
|
||||
} else if parser.peek::<u32>() || (parser.peek::<LParen>() && !parser.peek::<RefType>()) {
|
||||
let table = if parser.peek::<u32>() {
|
||||
} else if parser.peek::<u32>()?
|
||||
|| (parser.peek::<LParen>()? && !parser.peek::<RefType>()?)
|
||||
{
|
||||
let table = if parser.peek::<u32>()? {
|
||||
// FIXME: this is only here to accomodate
|
||||
// proposals/threads/imports.wast at this current moment in
|
||||
// time, this probably should get removed when the threads
|
||||
// proposal is rebased on the current spec.
|
||||
table_omitted = true;
|
||||
Index::Num(parser.parse()?, span)
|
||||
} else if parser.peek2::<kw::table>() {
|
||||
} else if parser.peek2::<kw::table>()? {
|
||||
parser.parens(|p| {
|
||||
p.parse::<kw::table>()?;
|
||||
p.parse()
|
||||
})?
|
||||
} else {
|
||||
table_omitted = true;
|
||||
Index::Num(0, span)
|
||||
};
|
||||
|
||||
// NB: this is technically not spec-compliant where the spec says
|
||||
// that `(instr)` is equivalent to `(offset instr)` for
|
||||
// single-element offsets. The test suite, however, has offsets of
|
||||
// the form `(instr (instr-arg))` which doesn't seem to follow this.
|
||||
// I don't know whether the test is correct or the spec is correct
|
||||
// so we're left with this for now.
|
||||
//
|
||||
// In theory though this should use `parse_expr_or_single_instr`.
|
||||
let offset = parser.parens(|parser| {
|
||||
if parser.peek::<kw::offset>() {
|
||||
if parser.peek::<kw::offset>()? {
|
||||
parser.parse::<kw::offset>()?;
|
||||
}
|
||||
parser.parse()
|
||||
@ -184,7 +204,31 @@ impl<'a> Parse<'a> for Elem<'a> {
|
||||
} else {
|
||||
ElemKind::Passive
|
||||
};
|
||||
let payload = parser.parse()?;
|
||||
|
||||
// Element segments can have a number of ways to specify their element
|
||||
// lists:
|
||||
//
|
||||
// * `func 0 1 ...` - list of indices
|
||||
// * `<reftype> (ref.null func) ...` - list of expressions
|
||||
// * `0 1 ...` - list of indices, only if the table was omitted for the
|
||||
// legacy way tables were printed.
|
||||
let indices = if parser.peek::<kw::func>()? {
|
||||
parser.parse::<kw::func>()?;
|
||||
true
|
||||
} else if parser.peek::<RefType>()? {
|
||||
false
|
||||
} else if table_omitted {
|
||||
true
|
||||
} else {
|
||||
false // this will fall through to failing to parse a `RefType`
|
||||
};
|
||||
let payload = if indices {
|
||||
ElemPayload::parse_indices(parser, None)?
|
||||
} else {
|
||||
let ty = parser.parse()?;
|
||||
ElemPayload::parse_exprs(parser, ty)?
|
||||
};
|
||||
|
||||
Ok(Elem {
|
||||
span,
|
||||
id,
|
||||
@ -195,47 +239,67 @@ impl<'a> Parse<'a> for Elem<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Parse<'a> for ElemPayload<'a> {
|
||||
fn parse(parser: Parser<'a>) -> Result<Self> {
|
||||
ElemPayload::parse_tail(parser, parser.parse()?)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> ElemPayload<'a> {
|
||||
fn parse_tail(parser: Parser<'a>, ty: Option<RefType<'a>>) -> Result<Self> {
|
||||
let (must_use_indices, ty) = match ty {
|
||||
None => {
|
||||
parser.parse::<Option<kw::func>>()?;
|
||||
(true, RefType::func())
|
||||
}
|
||||
Some(ty) => (false, ty),
|
||||
fn parse_indices(parser: Parser<'a>, ty: Option<RefType<'a>>) -> Result<Self> {
|
||||
let mut ret = match ty {
|
||||
// If there is no requested type, then it's ok to parse a list of
|
||||
// indices.
|
||||
None => ElemPayload::Indices(Vec::new()),
|
||||
|
||||
// If the requested type is a `funcref` type then a list of indices
|
||||
// can be parsed. This is because the list-of-indices encoding in
|
||||
// the binary format can only accomodate the `funcref` type.
|
||||
Some(ty) if ty == RefType::func() => ElemPayload::Indices(Vec::new()),
|
||||
|
||||
// Otherwise silently translate this list-of-indices into a
|
||||
// list-of-expressions because that's the only way to accomodate a
|
||||
// non-funcref type.
|
||||
Some(ty) => ElemPayload::Exprs {
|
||||
ty,
|
||||
exprs: Vec::new(),
|
||||
},
|
||||
};
|
||||
if let HeapType::Func = ty.heap {
|
||||
if must_use_indices || parser.peek::<Index<'_>>() {
|
||||
let mut elems = Vec::new();
|
||||
while !parser.is_empty() {
|
||||
elems.push(parser.parse()?);
|
||||
while !parser.is_empty() {
|
||||
let func = parser.parse()?;
|
||||
match &mut ret {
|
||||
ElemPayload::Indices(list) => list.push(func),
|
||||
ElemPayload::Exprs { exprs, .. } => {
|
||||
let expr = Expression {
|
||||
instrs: [Instruction::RefFunc(func)].into(),
|
||||
};
|
||||
exprs.push(expr);
|
||||
}
|
||||
return Ok(ElemPayload::Indices(elems));
|
||||
}
|
||||
}
|
||||
Ok(ret)
|
||||
}
|
||||
|
||||
fn parse_exprs(parser: Parser<'a>, ty: RefType<'a>) -> Result<Self> {
|
||||
let mut exprs = Vec::new();
|
||||
while !parser.is_empty() {
|
||||
let expr = parser.parens(|parser| {
|
||||
if parser.peek::<kw::item>() {
|
||||
parser.parse::<kw::item>()?;
|
||||
parser.parse()
|
||||
} else {
|
||||
// Without `item` this is "sugar" for a single-instruction
|
||||
// expression.
|
||||
let insn = parser.parse()?;
|
||||
Ok(Expression {
|
||||
instrs: [insn].into(),
|
||||
})
|
||||
}
|
||||
})?;
|
||||
let expr = parse_expr_or_single_instr::<kw::item>(parser)?;
|
||||
exprs.push(expr);
|
||||
}
|
||||
Ok(ElemPayload::Exprs { exprs, ty })
|
||||
}
|
||||
}
|
||||
|
||||
// Parses either `(T expr)` or `(instr)`, returning the resulting expression.
|
||||
fn parse_expr_or_single_instr<'a, T>(parser: Parser<'a>) -> Result<Expression<'a>>
|
||||
where
|
||||
T: Parse<'a> + Peek,
|
||||
{
|
||||
parser.parens(|parser| {
|
||||
if parser.peek::<T>()? {
|
||||
parser.parse::<T>()?;
|
||||
parser.parse()
|
||||
} else {
|
||||
// Without `item` this is "sugar" for a single-instruction
|
||||
// expression.
|
||||
let insn = parser.parse()?;
|
||||
Ok(Expression {
|
||||
instrs: [insn].into(),
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
183
third_party/rust/wast/src/core/types.rs
vendored
183
third_party/rust/wast/src/core/types.rs
vendored
@ -19,22 +19,22 @@ pub enum ValType<'a> {
|
||||
impl<'a> Parse<'a> for ValType<'a> {
|
||||
fn parse(parser: Parser<'a>) -> Result<Self> {
|
||||
let mut l = parser.lookahead1();
|
||||
if l.peek::<kw::i32>() {
|
||||
if l.peek::<kw::i32>()? {
|
||||
parser.parse::<kw::i32>()?;
|
||||
Ok(ValType::I32)
|
||||
} else if l.peek::<kw::i64>() {
|
||||
} else if l.peek::<kw::i64>()? {
|
||||
parser.parse::<kw::i64>()?;
|
||||
Ok(ValType::I64)
|
||||
} else if l.peek::<kw::f32>() {
|
||||
} else if l.peek::<kw::f32>()? {
|
||||
parser.parse::<kw::f32>()?;
|
||||
Ok(ValType::F32)
|
||||
} else if l.peek::<kw::f64>() {
|
||||
} else if l.peek::<kw::f64>()? {
|
||||
parser.parse::<kw::f64>()?;
|
||||
Ok(ValType::F64)
|
||||
} else if l.peek::<kw::v128>() {
|
||||
} else if l.peek::<kw::v128>()? {
|
||||
parser.parse::<kw::v128>()?;
|
||||
Ok(ValType::V128)
|
||||
} else if l.peek::<RefType>() {
|
||||
} else if l.peek::<RefType>()? {
|
||||
Ok(ValType::Ref(parser.parse()?))
|
||||
} else {
|
||||
Err(l.error())
|
||||
@ -43,13 +43,13 @@ impl<'a> Parse<'a> for ValType<'a> {
|
||||
}
|
||||
|
||||
impl<'a> Peek for ValType<'a> {
|
||||
fn peek(cursor: Cursor<'_>) -> bool {
|
||||
kw::i32::peek(cursor)
|
||||
|| kw::i64::peek(cursor)
|
||||
|| kw::f32::peek(cursor)
|
||||
|| kw::f64::peek(cursor)
|
||||
|| kw::v128::peek(cursor)
|
||||
|| RefType::peek(cursor)
|
||||
fn peek(cursor: Cursor<'_>) -> Result<bool> {
|
||||
Ok(kw::i32::peek(cursor)?
|
||||
|| kw::i64::peek(cursor)?
|
||||
|| kw::f32::peek(cursor)?
|
||||
|| kw::f64::peek(cursor)?
|
||||
|| kw::v128::peek(cursor)?
|
||||
|| RefType::peek(cursor)?)
|
||||
}
|
||||
fn display() -> &'static str {
|
||||
"valtype"
|
||||
@ -92,37 +92,37 @@ pub enum HeapType<'a> {
|
||||
impl<'a> Parse<'a> for HeapType<'a> {
|
||||
fn parse(parser: Parser<'a>) -> Result<Self> {
|
||||
let mut l = parser.lookahead1();
|
||||
if l.peek::<kw::func>() {
|
||||
if l.peek::<kw::func>()? {
|
||||
parser.parse::<kw::func>()?;
|
||||
Ok(HeapType::Func)
|
||||
} else if l.peek::<kw::r#extern>() {
|
||||
} else if l.peek::<kw::r#extern>()? {
|
||||
parser.parse::<kw::r#extern>()?;
|
||||
Ok(HeapType::Extern)
|
||||
} else if l.peek::<kw::r#any>() {
|
||||
} else if l.peek::<kw::r#any>()? {
|
||||
parser.parse::<kw::r#any>()?;
|
||||
Ok(HeapType::Any)
|
||||
} else if l.peek::<kw::eq>() {
|
||||
} else if l.peek::<kw::eq>()? {
|
||||
parser.parse::<kw::eq>()?;
|
||||
Ok(HeapType::Eq)
|
||||
} else if l.peek::<kw::r#struct>() {
|
||||
} else if l.peek::<kw::r#struct>()? {
|
||||
parser.parse::<kw::r#struct>()?;
|
||||
Ok(HeapType::Struct)
|
||||
} else if l.peek::<kw::array>() {
|
||||
} else if l.peek::<kw::array>()? {
|
||||
parser.parse::<kw::array>()?;
|
||||
Ok(HeapType::Array)
|
||||
} else if l.peek::<kw::i31>() {
|
||||
} else if l.peek::<kw::i31>()? {
|
||||
parser.parse::<kw::i31>()?;
|
||||
Ok(HeapType::I31)
|
||||
} else if l.peek::<kw::nofunc>() {
|
||||
} else if l.peek::<kw::nofunc>()? {
|
||||
parser.parse::<kw::nofunc>()?;
|
||||
Ok(HeapType::NoFunc)
|
||||
} else if l.peek::<kw::noextern>() {
|
||||
} else if l.peek::<kw::noextern>()? {
|
||||
parser.parse::<kw::noextern>()?;
|
||||
Ok(HeapType::NoExtern)
|
||||
} else if l.peek::<kw::none>() {
|
||||
} else if l.peek::<kw::none>()? {
|
||||
parser.parse::<kw::none>()?;
|
||||
Ok(HeapType::None)
|
||||
} else if l.peek::<Index>() {
|
||||
} else if l.peek::<Index>()? {
|
||||
Ok(HeapType::Index(parser.parse()?))
|
||||
} else {
|
||||
Err(l.error())
|
||||
@ -131,18 +131,18 @@ impl<'a> Parse<'a> for HeapType<'a> {
|
||||
}
|
||||
|
||||
impl<'a> Peek for HeapType<'a> {
|
||||
fn peek(cursor: Cursor<'_>) -> bool {
|
||||
kw::func::peek(cursor)
|
||||
|| kw::r#extern::peek(cursor)
|
||||
|| kw::any::peek(cursor)
|
||||
|| kw::eq::peek(cursor)
|
||||
|| kw::r#struct::peek(cursor)
|
||||
|| kw::array::peek(cursor)
|
||||
|| kw::i31::peek(cursor)
|
||||
|| kw::nofunc::peek(cursor)
|
||||
|| kw::noextern::peek(cursor)
|
||||
|| kw::none::peek(cursor)
|
||||
|| (LParen::peek(cursor) && kw::r#type::peek2(cursor))
|
||||
fn peek(cursor: Cursor<'_>) -> Result<bool> {
|
||||
Ok(kw::func::peek(cursor)?
|
||||
|| kw::r#extern::peek(cursor)?
|
||||
|| kw::any::peek(cursor)?
|
||||
|| kw::eq::peek(cursor)?
|
||||
|| kw::r#struct::peek(cursor)?
|
||||
|| kw::array::peek(cursor)?
|
||||
|| kw::i31::peek(cursor)?
|
||||
|| kw::nofunc::peek(cursor)?
|
||||
|| kw::noextern::peek(cursor)?
|
||||
|| kw::none::peek(cursor)?
|
||||
|| (LParen::peek(cursor)? && kw::r#type::peek2(cursor)?))
|
||||
}
|
||||
fn display() -> &'static str {
|
||||
"heaptype"
|
||||
@ -242,47 +242,47 @@ impl<'a> RefType<'a> {
|
||||
impl<'a> Parse<'a> for RefType<'a> {
|
||||
fn parse(parser: Parser<'a>) -> Result<Self> {
|
||||
let mut l = parser.lookahead1();
|
||||
if l.peek::<kw::funcref>() {
|
||||
if l.peek::<kw::funcref>()? {
|
||||
parser.parse::<kw::funcref>()?;
|
||||
Ok(RefType::func())
|
||||
} else if l.peek::<kw::anyfunc>() {
|
||||
} else if l.peek::<kw::anyfunc>()? {
|
||||
parser.parse::<kw::anyfunc>()?;
|
||||
Ok(RefType::func())
|
||||
} else if l.peek::<kw::externref>() {
|
||||
} else if l.peek::<kw::externref>()? {
|
||||
parser.parse::<kw::externref>()?;
|
||||
Ok(RefType::r#extern())
|
||||
} else if l.peek::<kw::anyref>() {
|
||||
} else if l.peek::<kw::anyref>()? {
|
||||
parser.parse::<kw::anyref>()?;
|
||||
Ok(RefType::any())
|
||||
} else if l.peek::<kw::eqref>() {
|
||||
} else if l.peek::<kw::eqref>()? {
|
||||
parser.parse::<kw::eqref>()?;
|
||||
Ok(RefType::eq())
|
||||
} else if l.peek::<kw::structref>() {
|
||||
} else if l.peek::<kw::structref>()? {
|
||||
parser.parse::<kw::structref>()?;
|
||||
Ok(RefType::r#struct())
|
||||
} else if l.peek::<kw::arrayref>() {
|
||||
} else if l.peek::<kw::arrayref>()? {
|
||||
parser.parse::<kw::arrayref>()?;
|
||||
Ok(RefType::array())
|
||||
} else if l.peek::<kw::i31ref>() {
|
||||
} else if l.peek::<kw::i31ref>()? {
|
||||
parser.parse::<kw::i31ref>()?;
|
||||
Ok(RefType::i31())
|
||||
} else if l.peek::<kw::nullfuncref>() {
|
||||
} else if l.peek::<kw::nullfuncref>()? {
|
||||
parser.parse::<kw::nullfuncref>()?;
|
||||
Ok(RefType::nullfuncref())
|
||||
} else if l.peek::<kw::nullexternref>() {
|
||||
} else if l.peek::<kw::nullexternref>()? {
|
||||
parser.parse::<kw::nullexternref>()?;
|
||||
Ok(RefType::nullexternref())
|
||||
} else if l.peek::<kw::nullref>() {
|
||||
} else if l.peek::<kw::nullref>()? {
|
||||
parser.parse::<kw::nullref>()?;
|
||||
Ok(RefType::nullref())
|
||||
} else if l.peek::<LParen>() {
|
||||
} else if l.peek::<LParen>()? {
|
||||
parser.parens(|p| {
|
||||
let mut l = parser.lookahead1();
|
||||
if l.peek::<kw::r#ref>() {
|
||||
if l.peek::<kw::r#ref>()? {
|
||||
p.parse::<kw::r#ref>()?;
|
||||
|
||||
let mut nullable = false;
|
||||
if parser.peek::<kw::null>() {
|
||||
if parser.peek::<kw::null>()? {
|
||||
parser.parse::<kw::null>()?;
|
||||
nullable = true;
|
||||
}
|
||||
@ -302,19 +302,19 @@ impl<'a> Parse<'a> for RefType<'a> {
|
||||
}
|
||||
|
||||
impl<'a> Peek for RefType<'a> {
|
||||
fn peek(cursor: Cursor<'_>) -> bool {
|
||||
kw::funcref::peek(cursor)
|
||||
|| /* legacy */ kw::anyfunc::peek(cursor)
|
||||
|| kw::externref::peek(cursor)
|
||||
|| kw::anyref::peek(cursor)
|
||||
|| kw::eqref::peek(cursor)
|
||||
|| kw::structref::peek(cursor)
|
||||
|| kw::arrayref::peek(cursor)
|
||||
|| kw::i31ref::peek(cursor)
|
||||
|| kw::nullfuncref::peek(cursor)
|
||||
|| kw::nullexternref::peek(cursor)
|
||||
|| kw::nullref::peek(cursor)
|
||||
|| (LParen::peek(cursor) && kw::r#ref::peek2(cursor))
|
||||
fn peek(cursor: Cursor<'_>) -> Result<bool> {
|
||||
Ok(kw::funcref::peek(cursor)?
|
||||
|| /* legacy */ kw::anyfunc::peek(cursor)?
|
||||
|| kw::externref::peek(cursor)?
|
||||
|| kw::anyref::peek(cursor)?
|
||||
|| kw::eqref::peek(cursor)?
|
||||
|| kw::structref::peek(cursor)?
|
||||
|| kw::arrayref::peek(cursor)?
|
||||
|| kw::i31ref::peek(cursor)?
|
||||
|| kw::nullfuncref::peek(cursor)?
|
||||
|| kw::nullexternref::peek(cursor)?
|
||||
|| kw::nullref::peek(cursor)?
|
||||
|| (LParen::peek(cursor)? && kw::r#ref::peek2(cursor)?))
|
||||
}
|
||||
fn display() -> &'static str {
|
||||
"reftype"
|
||||
@ -333,13 +333,13 @@ pub enum StorageType<'a> {
|
||||
impl<'a> Parse<'a> for StorageType<'a> {
|
||||
fn parse(parser: Parser<'a>) -> Result<Self> {
|
||||
let mut l = parser.lookahead1();
|
||||
if l.peek::<kw::i8>() {
|
||||
if l.peek::<kw::i8>()? {
|
||||
parser.parse::<kw::i8>()?;
|
||||
Ok(StorageType::I8)
|
||||
} else if l.peek::<kw::i16>() {
|
||||
} else if l.peek::<kw::i16>()? {
|
||||
parser.parse::<kw::i16>()?;
|
||||
Ok(StorageType::I16)
|
||||
} else if l.peek::<ValType>() {
|
||||
} else if l.peek::<ValType>()? {
|
||||
Ok(StorageType::Val(parser.parse()?))
|
||||
} else {
|
||||
Err(l.error())
|
||||
@ -358,7 +358,7 @@ pub struct GlobalType<'a> {
|
||||
|
||||
impl<'a> Parse<'a> for GlobalType<'a> {
|
||||
fn parse(parser: Parser<'a>) -> Result<Self> {
|
||||
if parser.peek2::<kw::r#mut>() {
|
||||
if parser.peek2::<kw::r#mut>()? {
|
||||
parser.parens(|p| {
|
||||
p.parse::<kw::r#mut>()?;
|
||||
Ok(GlobalType {
|
||||
@ -387,7 +387,7 @@ pub struct Limits {
|
||||
impl<'a> Parse<'a> for Limits {
|
||||
fn parse(parser: Parser<'a>) -> Result<Self> {
|
||||
let min = parser.parse()?;
|
||||
let max = if parser.peek::<u32>() {
|
||||
let max = if parser.peek::<u32>()? {
|
||||
Some(parser.parse()?)
|
||||
} else {
|
||||
None
|
||||
@ -408,7 +408,7 @@ pub struct Limits64 {
|
||||
impl<'a> Parse<'a> for Limits64 {
|
||||
fn parse(parser: Parser<'a>) -> Result<Self> {
|
||||
let min = parser.parse()?;
|
||||
let max = if parser.peek::<u64>() {
|
||||
let max = if parser.peek::<u64>()? {
|
||||
Some(parser.parse()?)
|
||||
} else {
|
||||
None
|
||||
@ -456,7 +456,7 @@ pub enum MemoryType {
|
||||
|
||||
impl<'a> Parse<'a> for MemoryType {
|
||||
fn parse(parser: Parser<'a>) -> Result<Self> {
|
||||
if parser.peek::<kw::i64>() {
|
||||
if parser.peek::<kw::i64>()? {
|
||||
parser.parse::<kw::i64>()?;
|
||||
let limits = parser.parse()?;
|
||||
let shared = parser.parse::<Option<kw::shared>>()?.is_some();
|
||||
@ -484,10 +484,10 @@ impl<'a> FunctionType<'a> {
|
||||
fn finish_parse(&mut self, allow_names: bool, parser: Parser<'a>) -> Result<()> {
|
||||
let mut params = Vec::from(mem::take(&mut self.params));
|
||||
let mut results = Vec::from(mem::take(&mut self.results));
|
||||
while parser.peek2::<kw::param>() || parser.peek2::<kw::result>() {
|
||||
while parser.peek2::<kw::param>()? || parser.peek2::<kw::result>()? {
|
||||
parser.parens(|p| {
|
||||
let mut l = p.lookahead1();
|
||||
if l.peek::<kw::param>() {
|
||||
if l.peek::<kw::param>()? {
|
||||
if results.len() > 0 {
|
||||
return Err(p.error(
|
||||
"result before parameter (or unexpected token): \
|
||||
@ -509,7 +509,7 @@ impl<'a> FunctionType<'a> {
|
||||
while parse_more && !p.is_empty() {
|
||||
params.push((None, None, p.parse()?));
|
||||
}
|
||||
} else if l.peek::<kw::result>() {
|
||||
} else if l.peek::<kw::result>()? {
|
||||
p.parse::<kw::result>()?;
|
||||
while !p.is_empty() {
|
||||
results.push(p.parse()?);
|
||||
@ -538,15 +538,15 @@ impl<'a> Parse<'a> for FunctionType<'a> {
|
||||
}
|
||||
|
||||
impl<'a> Peek for FunctionType<'a> {
|
||||
fn peek(cursor: Cursor<'_>) -> bool {
|
||||
if let Some(next) = cursor.lparen() {
|
||||
match next.keyword() {
|
||||
Some(("param", _)) | Some(("result", _)) => return true,
|
||||
fn peek(cursor: Cursor<'_>) -> Result<bool> {
|
||||
if let Some(next) = cursor.lparen()? {
|
||||
match next.keyword()? {
|
||||
Some(("param", _)) | Some(("result", _)) => return Ok(true),
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
false
|
||||
Ok(false)
|
||||
}
|
||||
|
||||
fn display() -> &'static str {
|
||||
@ -570,7 +570,7 @@ impl<'a> Parse<'a> for FunctionTypeNoNames<'a> {
|
||||
}
|
||||
|
||||
impl<'a> Peek for FunctionTypeNoNames<'a> {
|
||||
fn peek(cursor: Cursor<'_>) -> bool {
|
||||
fn peek(cursor: Cursor<'_>) -> Result<bool> {
|
||||
FunctionType::peek(cursor)
|
||||
}
|
||||
|
||||
@ -596,7 +596,7 @@ impl<'a> Parse<'a> for StructType<'a> {
|
||||
fn parse(parser: Parser<'a>) -> Result<Self> {
|
||||
let mut ret = StructType { fields: Vec::new() };
|
||||
while !parser.is_empty() {
|
||||
let field = if parser.peek2::<kw::field>() {
|
||||
let field = if parser.peek2::<kw::field>()? {
|
||||
parser.parens(|parser| {
|
||||
parser.parse::<kw::field>()?;
|
||||
StructField::parse(parser, true)
|
||||
@ -624,7 +624,7 @@ pub struct StructField<'a> {
|
||||
impl<'a> StructField<'a> {
|
||||
fn parse(parser: Parser<'a>, with_id: bool) -> Result<Self> {
|
||||
let id = if with_id { parser.parse()? } else { None };
|
||||
let (ty, mutable) = if parser.peek2::<kw::r#mut>() {
|
||||
let (ty, mutable) = if parser.peek2::<kw::r#mut>()? {
|
||||
let ty = parser.parens(|parser| {
|
||||
parser.parse::<kw::r#mut>()?;
|
||||
parser.parse()
|
||||
@ -648,7 +648,7 @@ pub struct ArrayType<'a> {
|
||||
|
||||
impl<'a> Parse<'a> for ArrayType<'a> {
|
||||
fn parse(parser: Parser<'a>) -> Result<Self> {
|
||||
let (ty, mutable) = if parser.peek2::<kw::r#mut>() {
|
||||
let (ty, mutable) = if parser.peek2::<kw::r#mut>()? {
|
||||
let ty = parser.parens(|parser| {
|
||||
parser.parse::<kw::r#mut>()?;
|
||||
parser.parse()
|
||||
@ -695,13 +695,13 @@ pub enum TypeDef<'a> {
|
||||
impl<'a> Parse<'a> for TypeDef<'a> {
|
||||
fn parse(parser: Parser<'a>) -> Result<Self> {
|
||||
let mut l = parser.lookahead1();
|
||||
if l.peek::<kw::func>() {
|
||||
if l.peek::<kw::func>()? {
|
||||
parser.parse::<kw::func>()?;
|
||||
Ok(TypeDef::Func(parser.parse()?))
|
||||
} else if l.peek::<kw::r#struct>() {
|
||||
} else if l.peek::<kw::r#struct>()? {
|
||||
parser.parse::<kw::r#struct>()?;
|
||||
Ok(TypeDef::Struct(parser.parse()?))
|
||||
} else if l.peek::<kw::array>() {
|
||||
} else if l.peek::<kw::array>()? {
|
||||
parser.parse::<kw::array>()?;
|
||||
Ok(TypeDef::Array(parser.parse()?))
|
||||
} else {
|
||||
@ -729,7 +729,7 @@ pub struct Type<'a> {
|
||||
}
|
||||
|
||||
impl<'a> Peek for Type<'a> {
|
||||
fn peek(cursor: Cursor<'_>) -> bool {
|
||||
fn peek(cursor: Cursor<'_>) -> Result<bool> {
|
||||
kw::r#type::peek(cursor)
|
||||
}
|
||||
fn display() -> &'static str {
|
||||
@ -743,19 +743,18 @@ impl<'a> Parse<'a> for Type<'a> {
|
||||
let id = parser.parse()?;
|
||||
let name = parser.parse()?;
|
||||
|
||||
let (parent, def, final_type) = if parser.peek2::<kw::sub>() {
|
||||
let (parent, def, final_type) = if parser.peek2::<kw::sub>()? {
|
||||
parser.parens(|parser| {
|
||||
parser.parse::<kw::sub>()?;
|
||||
|
||||
let final_type: Option<bool> =
|
||||
if parser.peek::<kw::r#final>() {
|
||||
let final_type: Option<bool> = if parser.peek::<kw::r#final>()? {
|
||||
parser.parse::<kw::r#final>()?;
|
||||
Some(true)
|
||||
} else {
|
||||
Some(false)
|
||||
};
|
||||
|
||||
let parent = if parser.peek::<Index<'a>>() {
|
||||
let parent = if parser.peek::<Index<'a>>()? {
|
||||
parser.parse()?
|
||||
} else {
|
||||
None
|
||||
@ -791,7 +790,7 @@ impl<'a> Parse<'a> for Rec<'a> {
|
||||
fn parse(parser: Parser<'a>) -> Result<Self> {
|
||||
let span = parser.parse::<kw::r#rec>()?.0;
|
||||
let mut types = Vec::new();
|
||||
while parser.peek2::<Type<'a>>() {
|
||||
while parser.peek2::<Type<'a>>()? {
|
||||
types.push(parser.parens(|p| p.parse())?);
|
||||
}
|
||||
Ok(Rec { span, types })
|
||||
@ -820,7 +819,7 @@ impl<'a, T> TypeUse<'a, T> {
|
||||
|
||||
impl<'a, T: Peek + Parse<'a>> Parse<'a> for TypeUse<'a, T> {
|
||||
fn parse(parser: Parser<'a>) -> Result<Self> {
|
||||
let index = if parser.peek2::<kw::r#type>() {
|
||||
let index = if parser.peek2::<kw::r#type>()? {
|
||||
Some(parser.parens(|p| {
|
||||
p.parse::<kw::r#type>()?;
|
||||
p.parse()
|
||||
|
36
third_party/rust/wast/src/core/wast.rs
vendored
36
third_party/rust/wast/src/core/wast.rs
vendored
@ -33,7 +33,7 @@ static ARGS: &[(&str, fn(Parser<'_>) -> Result<WastArgCore<'_>>)] = {
|
||||
impl<'a> Parse<'a> for WastArgCore<'a> {
|
||||
fn parse(parser: Parser<'a>) -> Result<Self> {
|
||||
let parse = parser.step(|c| {
|
||||
if let Some((kw, rest)) = c.keyword() {
|
||||
if let Some((kw, rest)) = c.keyword()? {
|
||||
if let Some(i) = ARGS.iter().position(|(name, _)| *name == kw) {
|
||||
return Ok((ARGS[i].1, rest));
|
||||
}
|
||||
@ -45,12 +45,12 @@ impl<'a> Parse<'a> for WastArgCore<'a> {
|
||||
}
|
||||
|
||||
impl Peek for WastArgCore<'_> {
|
||||
fn peek(cursor: Cursor<'_>) -> bool {
|
||||
let kw = match cursor.keyword() {
|
||||
fn peek(cursor: Cursor<'_>) -> Result<bool> {
|
||||
let kw = match cursor.keyword()? {
|
||||
Some((kw, _)) => kw,
|
||||
None => return false,
|
||||
None => return Ok(false),
|
||||
};
|
||||
ARGS.iter().find(|(name, _)| *name == kw).is_some()
|
||||
Ok(ARGS.iter().find(|(name, _)| *name == kw).is_some())
|
||||
}
|
||||
|
||||
fn display() -> &'static str {
|
||||
@ -105,7 +105,7 @@ static RETS: &[(&str, fn(Parser<'_>) -> Result<WastRetCore<'_>>)] = {
|
||||
impl<'a> Parse<'a> for WastRetCore<'a> {
|
||||
fn parse(parser: Parser<'a>) -> Result<Self> {
|
||||
let parse = parser.step(|c| {
|
||||
if let Some((kw, rest)) = c.keyword() {
|
||||
if let Some((kw, rest)) = c.keyword()? {
|
||||
if let Some(i) = RETS.iter().position(|(name, _)| *name == kw) {
|
||||
return Ok((RETS[i].1, rest));
|
||||
}
|
||||
@ -117,12 +117,12 @@ impl<'a> Parse<'a> for WastRetCore<'a> {
|
||||
}
|
||||
|
||||
impl Peek for WastRetCore<'_> {
|
||||
fn peek(cursor: Cursor<'_>) -> bool {
|
||||
let kw = match cursor.keyword() {
|
||||
fn peek(cursor: Cursor<'_>) -> Result<bool> {
|
||||
let kw = match cursor.keyword()? {
|
||||
Some((kw, _)) => kw,
|
||||
None => return false,
|
||||
None => return Ok(false),
|
||||
};
|
||||
RETS.iter().find(|(name, _)| *name == kw).is_some()
|
||||
Ok(RETS.iter().find(|(name, _)| *name == kw).is_some())
|
||||
}
|
||||
|
||||
fn display() -> &'static str {
|
||||
@ -144,10 +144,10 @@ where
|
||||
T: Parse<'a>,
|
||||
{
|
||||
fn parse(parser: Parser<'a>) -> Result<Self> {
|
||||
if parser.peek::<kw::nan_canonical>() {
|
||||
if parser.peek::<kw::nan_canonical>()? {
|
||||
parser.parse::<kw::nan_canonical>()?;
|
||||
Ok(NanPattern::CanonicalNan)
|
||||
} else if parser.peek::<kw::nan_arithmetic>() {
|
||||
} else if parser.peek::<kw::nan_arithmetic>()? {
|
||||
parser.parse::<kw::nan_arithmetic>()?;
|
||||
Ok(NanPattern::ArithmeticNan)
|
||||
} else {
|
||||
@ -175,7 +175,7 @@ pub enum V128Pattern {
|
||||
impl<'a> Parse<'a> for V128Pattern {
|
||||
fn parse(parser: Parser<'a>) -> Result<Self> {
|
||||
let mut l = parser.lookahead1();
|
||||
if l.peek::<kw::i8x16>() {
|
||||
if l.peek::<kw::i8x16>()? {
|
||||
parser.parse::<kw::i8x16>()?;
|
||||
Ok(V128Pattern::I8x16([
|
||||
parser.parse()?,
|
||||
@ -195,7 +195,7 @@ impl<'a> Parse<'a> for V128Pattern {
|
||||
parser.parse()?,
|
||||
parser.parse()?,
|
||||
]))
|
||||
} else if l.peek::<kw::i16x8>() {
|
||||
} else if l.peek::<kw::i16x8>()? {
|
||||
parser.parse::<kw::i16x8>()?;
|
||||
Ok(V128Pattern::I16x8([
|
||||
parser.parse()?,
|
||||
@ -207,7 +207,7 @@ impl<'a> Parse<'a> for V128Pattern {
|
||||
parser.parse()?,
|
||||
parser.parse()?,
|
||||
]))
|
||||
} else if l.peek::<kw::i32x4>() {
|
||||
} else if l.peek::<kw::i32x4>()? {
|
||||
parser.parse::<kw::i32x4>()?;
|
||||
Ok(V128Pattern::I32x4([
|
||||
parser.parse()?,
|
||||
@ -215,10 +215,10 @@ impl<'a> Parse<'a> for V128Pattern {
|
||||
parser.parse()?,
|
||||
parser.parse()?,
|
||||
]))
|
||||
} else if l.peek::<kw::i64x2>() {
|
||||
} else if l.peek::<kw::i64x2>()? {
|
||||
parser.parse::<kw::i64x2>()?;
|
||||
Ok(V128Pattern::I64x2([parser.parse()?, parser.parse()?]))
|
||||
} else if l.peek::<kw::f32x4>() {
|
||||
} else if l.peek::<kw::f32x4>()? {
|
||||
parser.parse::<kw::f32x4>()?;
|
||||
Ok(V128Pattern::F32x4([
|
||||
parser.parse()?,
|
||||
@ -226,7 +226,7 @@ impl<'a> Parse<'a> for V128Pattern {
|
||||
parser.parse()?,
|
||||
parser.parse()?,
|
||||
]))
|
||||
} else if l.peek::<kw::f64x2>() {
|
||||
} else if l.peek::<kw::f64x2>()? {
|
||||
parser.parse::<kw::f64x2>()?;
|
||||
Ok(V128Pattern::F64x2([parser.parse()?, parser.parse()?]))
|
||||
} else {
|
||||
|
6
third_party/rust/wast/src/encode.rs
vendored
6
third_party/rust/wast/src/encode.rs
vendored
@ -8,6 +8,12 @@ impl<T: Encode + ?Sized> Encode for &'_ T {
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Encode + ?Sized> Encode for Box<T> {
|
||||
fn encode(&self, e: &mut Vec<u8>) {
|
||||
T::encode(self, e)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Encode> Encode for [T] {
|
||||
fn encode(&self, e: &mut Vec<u8>) {
|
||||
self.len().encode(e);
|
||||
|
801
third_party/rust/wast/src/lexer.rs
vendored
801
third_party/rust/wast/src/lexer.rs
vendored
File diff suppressed because it is too large
Load Diff
32
third_party/rust/wast/src/lib.rs
vendored
32
third_party/rust/wast/src/lib.rs
vendored
@ -101,7 +101,7 @@ macro_rules! custom_keyword {
|
||||
impl<'a> $crate::parser::Parse<'a> for $name {
|
||||
fn parse(parser: $crate::parser::Parser<'a>) -> $crate::parser::Result<Self> {
|
||||
parser.step(|c| {
|
||||
if let Some((kw, rest)) = c.keyword() {
|
||||
if let Some((kw, rest)) = c.keyword()? {
|
||||
if kw == $kw {
|
||||
return Ok(($name(c.cur_span()), rest));
|
||||
}
|
||||
@ -112,12 +112,12 @@ macro_rules! custom_keyword {
|
||||
}
|
||||
|
||||
impl $crate::parser::Peek for $name {
|
||||
fn peek(cursor: $crate::parser::Cursor<'_>) -> bool {
|
||||
if let Some((kw, _rest)) = cursor.keyword() {
|
||||
fn peek(cursor: $crate::parser::Cursor<'_>) -> $crate::parser::Result<bool> {
|
||||
Ok(if let Some((kw, _rest)) = cursor.keyword()? {
|
||||
kw == $kw
|
||||
} else {
|
||||
false
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
fn display() -> &'static str {
|
||||
@ -168,7 +168,7 @@ macro_rules! custom_reserved {
|
||||
impl<'a> $crate::parser::Parse<'a> for $name {
|
||||
fn parse(parser: $crate::parser::Parser<'a>) -> $crate::parser::Result<Self> {
|
||||
parser.step(|c| {
|
||||
if let Some((rsv, rest)) = c.reserved() {
|
||||
if let Some((rsv, rest)) = c.reserved()? {
|
||||
if rsv == $rsv {
|
||||
return Ok(($name(c.cur_span()), rest));
|
||||
}
|
||||
@ -179,11 +179,11 @@ macro_rules! custom_reserved {
|
||||
}
|
||||
|
||||
impl $crate::parser::Peek for $name {
|
||||
fn peek(cursor: $crate::parser::Cursor<'_>) -> bool {
|
||||
if let Some((rsv, _rest)) = cursor.reserved() {
|
||||
rsv == $rsv
|
||||
fn peek(cursor: $crate::parser::Cursor<'_>) -> Result<bool> {
|
||||
if let Some((rsv, _rest)) = cursor.reserved()? {
|
||||
Ok(rsv == $rsv)
|
||||
} else {
|
||||
false
|
||||
Ok(false)
|
||||
}
|
||||
}
|
||||
|
||||
@ -290,7 +290,7 @@ macro_rules! custom_reserved {
|
||||
/// fn parse(parser: Parser<'a>) -> Result<Self> {
|
||||
/// // and here `peek` works and our delegated parsing works because the
|
||||
/// // annotation has been registered.
|
||||
/// if parser.peek::<annotation::producer>() {
|
||||
/// if parser.peek::<annotation::producer>()? {
|
||||
/// return Ok(ModuleField::Producer(parser.parse()?));
|
||||
/// }
|
||||
///
|
||||
@ -317,8 +317,8 @@ macro_rules! annotation {
|
||||
impl<'a> $crate::parser::Parse<'a> for $name {
|
||||
fn parse(parser: $crate::parser::Parser<'a>) -> $crate::parser::Result<Self> {
|
||||
parser.step(|c| {
|
||||
if let Some((a, rest)) = c.annotation() {
|
||||
if a == $annotation {
|
||||
if let Some((a, rest)) = c.reserved()? {
|
||||
if a == concat!("@", $annotation) {
|
||||
return Ok(($name(c.cur_span()), rest));
|
||||
}
|
||||
}
|
||||
@ -328,12 +328,12 @@ macro_rules! annotation {
|
||||
}
|
||||
|
||||
impl $crate::parser::Peek for $name {
|
||||
fn peek(cursor: $crate::parser::Cursor<'_>) -> bool {
|
||||
if let Some((a, _rest)) = cursor.annotation() {
|
||||
a == $annotation
|
||||
fn peek(cursor: $crate::parser::Cursor<'_>) -> $crate::parser::Result<bool> {
|
||||
Ok(if let Some((a, _rest)) = cursor.reserved()? {
|
||||
a == concat!("@", $annotation)
|
||||
} else {
|
||||
false
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
fn display() -> &'static str {
|
||||
|
2
third_party/rust/wast/src/names.rs
vendored
2
third_party/rust/wast/src/names.rs
vendored
@ -54,7 +54,7 @@ impl<'a> Namespace<'a> {
|
||||
if let Some(_prev) = self.names.insert(name, index) {
|
||||
return Err(Error::new(
|
||||
name.span(),
|
||||
format!("duplicate identifier for {}", desc),
|
||||
format!("duplicate identifier `{}` for {}", name.name(), desc),
|
||||
));
|
||||
}
|
||||
Ok(())
|
||||
|
691
third_party/rust/wast/src/parser.rs
vendored
691
third_party/rust/wast/src/parser.rs
vendored
@ -42,7 +42,7 @@
|
||||
//! // parentheses. The `parens` function here ensures that what we
|
||||
//! // parse inside of it is surrounded by `(` and `)`.
|
||||
//! let mut imports = Vec::new();
|
||||
//! while parser.peek2::<kw::import>() {
|
||||
//! while parser.peek2::<kw::import>()? {
|
||||
//! let import = parser.parens(|p| p.parse())?;
|
||||
//! imports.push(import);
|
||||
//! }
|
||||
@ -64,9 +64,10 @@
|
||||
//! This module is heavily inspired by [`syn`](https://docs.rs/syn) so you can
|
||||
//! likely also draw inspiration from the excellent examples in the `syn` crate.
|
||||
|
||||
use crate::lexer::{Float, Integer, Lexer, Token};
|
||||
use crate::lexer::{Float, Integer, Lexer, Token, TokenKind};
|
||||
use crate::token::Span;
|
||||
use crate::Error;
|
||||
use std::borrow::Cow;
|
||||
use std::cell::{Cell, RefCell};
|
||||
use std::collections::HashMap;
|
||||
use std::fmt;
|
||||
@ -120,7 +121,7 @@ pub(crate) const MAX_PARENS_DEPTH: usize = 100;
|
||||
pub fn parse<'a, T: Parse<'a>>(buf: &'a ParseBuffer<'a>) -> Result<T> {
|
||||
let parser = buf.parser();
|
||||
let result = parser.parse()?;
|
||||
if parser.cursor().advance_token().is_none() {
|
||||
if parser.cursor().token()?.is_none() {
|
||||
Ok(result)
|
||||
} else {
|
||||
Err(parser.error("extra tokens remaining after parse"))
|
||||
@ -202,7 +203,7 @@ pub fn parse<'a, T: Parse<'a>>(buf: &'a ParseBuffer<'a>) -> Result<T> {
|
||||
/// // parentheses. The `parens` function here ensures that what we
|
||||
/// // parse inside of it is surrounded by `(` and `)`.
|
||||
/// let mut imports = Vec::new();
|
||||
/// while parser.peek2::<kw::import>() {
|
||||
/// while parser.peek2::<kw::import>()? {
|
||||
/// let import = parser.parens(|p| p.parse())?;
|
||||
/// imports.push(import);
|
||||
/// }
|
||||
@ -243,6 +244,15 @@ pub trait Parse<'a>: Sized {
|
||||
fn parse(parser: Parser<'a>) -> Result<Self>;
|
||||
}
|
||||
|
||||
impl<'a, T> Parse<'a> for Box<T>
|
||||
where
|
||||
T: Parse<'a>,
|
||||
{
|
||||
fn parse(parser: Parser<'a>) -> Result<Self> {
|
||||
Ok(Box::new(parser.parse()?))
|
||||
}
|
||||
}
|
||||
|
||||
/// A trait for types which be used to "peek" to see if they're the next token
|
||||
/// in an input stream of [`Parser`].
|
||||
///
|
||||
@ -264,16 +274,16 @@ pub trait Peek {
|
||||
/// Returns `true` if [`Parse`] for this type is highly likely to succeed
|
||||
/// failing no other error conditions happening (like an integer literal
|
||||
/// being too big).
|
||||
fn peek(cursor: Cursor<'_>) -> bool;
|
||||
fn peek(cursor: Cursor<'_>) -> Result<bool>;
|
||||
|
||||
/// The same as `peek`, except it checks the token immediately following
|
||||
/// the current token.
|
||||
fn peek2(mut cursor: Cursor<'_>) -> bool {
|
||||
if cursor.advance_token().is_some() {
|
||||
Self::peek(cursor)
|
||||
} else {
|
||||
false
|
||||
fn peek2(mut cursor: Cursor<'_>) -> Result<bool> {
|
||||
match cursor.token()? {
|
||||
Some(token) => cursor.advance_past(&token),
|
||||
None => return Ok(false),
|
||||
}
|
||||
Self::peek(cursor)
|
||||
}
|
||||
|
||||
/// Returns a human-readable name of this token to display when generating
|
||||
@ -291,24 +301,30 @@ pub type Result<T, E = Error> = std::result::Result<T, E>;
|
||||
/// tokens internally. A `ParseBuffer` only used to pass to the top-level
|
||||
/// [`parse`] function.
|
||||
pub struct ParseBuffer<'a> {
|
||||
// list of tokens from the tokenized source (including whitespace and
|
||||
// comments), and the second element is how to skip this token, if it can be
|
||||
// skipped.
|
||||
tokens: Box<[(Token<'a>, Cell<NextTokenAt>)]>,
|
||||
input: &'a str,
|
||||
cur: Cell<usize>,
|
||||
lexer: Lexer<'a>,
|
||||
cur: Cell<Position>,
|
||||
known_annotations: RefCell<HashMap<String, usize>>,
|
||||
depth: Cell<usize>,
|
||||
strings: RefCell<Vec<Box<[u8]>>>,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
enum NextTokenAt {
|
||||
/// Haven't computed where the next token is yet.
|
||||
Unknown,
|
||||
/// Previously computed the index of the next token.
|
||||
Index(usize),
|
||||
/// There is no next token, this is the last token.
|
||||
Eof,
|
||||
/// The current position within a `Lexer` that we're at. This simultaneously
|
||||
/// stores the byte position that the lexer was last positioned at as well as
|
||||
/// the next significant token.
|
||||
///
|
||||
/// Note that "significant" here does not mean that `token` is the next token
|
||||
/// to be lexed at `offset`. Instead it's the next non-whitespace,
|
||||
/// non-annotation, non-coment token. This simple cache-of-sorts avoids
|
||||
/// re-parsing tokens the majority of the time, or at least that's the
|
||||
/// intention.
|
||||
///
|
||||
/// If `token` is set to `None` then it means that either it hasn't been
|
||||
/// calculated at or the lexer is at EOF. Basically it means go talk to the
|
||||
/// lexer.
|
||||
#[derive(Copy, Clone)]
|
||||
struct Position {
|
||||
offset: usize,
|
||||
token: Option<Token>,
|
||||
}
|
||||
|
||||
/// An in-progress parser for the tokens of a WebAssembly text file.
|
||||
@ -341,7 +357,7 @@ pub struct Lookahead1<'a> {
|
||||
#[derive(Copy, Clone)]
|
||||
pub struct Cursor<'a> {
|
||||
parser: Parser<'a>,
|
||||
cur: usize,
|
||||
pos: Position,
|
||||
}
|
||||
|
||||
impl ParseBuffer<'_> {
|
||||
@ -360,80 +376,100 @@ impl ParseBuffer<'_> {
|
||||
///
|
||||
/// Returns an error if `input` fails to lex.
|
||||
pub fn new_with_lexer(lexer: Lexer<'_>) -> Result<ParseBuffer<'_>> {
|
||||
let mut tokens = Vec::new();
|
||||
let input = lexer.input();
|
||||
for token in lexer {
|
||||
tokens.push((token?, Cell::new(NextTokenAt::Unknown)));
|
||||
}
|
||||
let ret = ParseBuffer {
|
||||
tokens: tokens.into_boxed_slice(),
|
||||
cur: Cell::new(0),
|
||||
Ok(ParseBuffer {
|
||||
lexer,
|
||||
depth: Cell::new(0),
|
||||
input,
|
||||
cur: Cell::new(Position {
|
||||
offset: 0,
|
||||
token: None,
|
||||
}),
|
||||
known_annotations: Default::default(),
|
||||
};
|
||||
ret.validate_annotations()?;
|
||||
Ok(ret)
|
||||
strings: Default::default(),
|
||||
})
|
||||
}
|
||||
|
||||
fn parser(&self) -> Parser<'_> {
|
||||
Parser { buf: self }
|
||||
}
|
||||
|
||||
// Validates that all annotations properly parse in that they have balanced
|
||||
// delimiters. This is required since while parsing we generally skip
|
||||
// annotations and there's no real opportunity to return a parse error.
|
||||
fn validate_annotations(&self) -> Result<()> {
|
||||
use crate::lexer::Token::*;
|
||||
enum State {
|
||||
None,
|
||||
LParen,
|
||||
Annotation { depth: usize, span: Span },
|
||||
}
|
||||
let mut state = State::None;
|
||||
for token in self.tokens.iter() {
|
||||
state = match (&token.0, state) {
|
||||
// From nothing, a `(` starts the search for an annotation
|
||||
(LParen(_), State::None) => State::LParen,
|
||||
// ... otherwise in nothing we always preserve that state.
|
||||
(_, State::None) => State::None,
|
||||
|
||||
// If the previous state was an `LParen`, we may have an
|
||||
// annotation if the next keyword is reserved
|
||||
(Reserved(s), State::LParen) if s.starts_with('@') && !s.is_empty() => {
|
||||
let offset = self.input_pos(s);
|
||||
State::Annotation {
|
||||
span: Span { offset },
|
||||
depth: 1,
|
||||
}
|
||||
}
|
||||
// ... otherwise anything after an `LParen` kills the lparen
|
||||
// state.
|
||||
(_, State::LParen) => State::None,
|
||||
|
||||
// Once we're in an annotation we need to balance parentheses,
|
||||
// so handle the depth changes.
|
||||
(LParen(_), State::Annotation { span, depth }) => State::Annotation {
|
||||
span,
|
||||
depth: depth + 1,
|
||||
},
|
||||
(RParen(_), State::Annotation { depth: 1, .. }) => State::None,
|
||||
(RParen(_), State::Annotation { span, depth }) => State::Annotation {
|
||||
span,
|
||||
depth: depth - 1,
|
||||
},
|
||||
// ... and otherwise all tokens are allowed in annotations.
|
||||
(_, s @ State::Annotation { .. }) => s,
|
||||
};
|
||||
}
|
||||
if let State::Annotation { span, .. } = state {
|
||||
return Err(Error::new(span, "unclosed annotation".to_string()));
|
||||
}
|
||||
Ok(())
|
||||
/// Stores an owned allocation in this `Parser` to attach the lifetime of
|
||||
/// the vector to `self`.
|
||||
///
|
||||
/// This will return a reference to `s`, but one that's safely rooted in the
|
||||
/// `Parser`.
|
||||
fn push_str(&self, s: Vec<u8>) -> &[u8] {
|
||||
let s = Box::from(s);
|
||||
let ret = &*s as *const [u8];
|
||||
self.strings.borrow_mut().push(s);
|
||||
// This should be safe in that the address of `ret` isn't changing as
|
||||
// it's on the heap itself. Additionally the lifetime of this return
|
||||
// value is tied to the lifetime of `self` (nothing is deallocated
|
||||
// early), so it should be safe to say the two have the same lifetime.
|
||||
unsafe { &*ret }
|
||||
}
|
||||
|
||||
fn input_pos(&self, src: &str) -> usize {
|
||||
src.as_ptr() as usize - self.input.as_ptr() as usize
|
||||
/// Lexes the next "significant" token from the `pos` specified.
|
||||
///
|
||||
/// This will skip irrelevant tokens such as whitespace, comments, and
|
||||
/// unknown annotations.
|
||||
fn advance_token(&self, mut pos: usize) -> Result<Option<Token>> {
|
||||
let token = loop {
|
||||
let token = match self.lexer.parse(&mut pos)? {
|
||||
Some(token) => token,
|
||||
None => return Ok(None),
|
||||
};
|
||||
match token.kind {
|
||||
// Always skip whitespace and comments.
|
||||
TokenKind::Whitespace | TokenKind::LineComment | TokenKind::BlockComment => {
|
||||
continue
|
||||
}
|
||||
|
||||
// If an lparen is seen then this may be skipped if it's an
|
||||
// annotation of the form `(@foo ...)`. In this situation
|
||||
// everything up to and including the closing rparen is skipped.
|
||||
//
|
||||
// Note that the annotation is only skipped if it's an unknown
|
||||
// annotation as known annotations are specifically registered
|
||||
// as "someone's gonna parse this".
|
||||
TokenKind::LParen => {
|
||||
if let Some(annotation) = self.lexer.annotation(pos) {
|
||||
match self.known_annotations.borrow().get(annotation) {
|
||||
Some(0) | None => {
|
||||
self.skip_annotation(&mut pos)?;
|
||||
continue;
|
||||
}
|
||||
Some(_) => {}
|
||||
}
|
||||
}
|
||||
break token;
|
||||
}
|
||||
_ => break token,
|
||||
}
|
||||
};
|
||||
Ok(Some(token))
|
||||
}
|
||||
|
||||
fn skip_annotation(&self, pos: &mut usize) -> Result<()> {
|
||||
let mut depth = 1;
|
||||
let span = Span { offset: *pos };
|
||||
loop {
|
||||
let token = match self.lexer.parse(pos)? {
|
||||
Some(token) => token,
|
||||
None => {
|
||||
break Err(Error::new(span, "unclosed annotation".to_string()));
|
||||
}
|
||||
};
|
||||
match token.kind {
|
||||
TokenKind::LParen => depth += 1,
|
||||
TokenKind::RParen => {
|
||||
depth -= 1;
|
||||
if depth == 0 {
|
||||
break Ok(());
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -448,18 +484,20 @@ impl<'a> Parser<'a> {
|
||||
/// Note that if `false` is returned there *may* be more comments. Comments
|
||||
/// and whitespace are not considered for whether this parser is empty.
|
||||
pub fn is_empty(self) -> bool {
|
||||
match self.cursor().advance_token() {
|
||||
Some(Token::RParen(_)) | None => true,
|
||||
Some(_) => false, // more tokens to parse!
|
||||
match self.cursor().token() {
|
||||
Ok(Some(token)) => matches!(token.kind, TokenKind::RParen),
|
||||
Ok(None) => true,
|
||||
Err(_) => false,
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn has_meaningful_tokens(self) -> bool {
|
||||
self.buf.tokens[self.cursor().cur..].iter().any(|(t, _)| {
|
||||
!matches!(
|
||||
t,
|
||||
Token::Whitespace(_) | Token::LineComment(_) | Token::BlockComment(_)
|
||||
)
|
||||
self.buf.lexer.iter(0).any(|t| match t {
|
||||
Ok(token) => !matches!(
|
||||
token.kind,
|
||||
TokenKind::Whitespace | TokenKind::LineComment | TokenKind::BlockComment
|
||||
),
|
||||
Err(_) => true,
|
||||
})
|
||||
}
|
||||
|
||||
@ -555,7 +593,7 @@ impl<'a> Parser<'a> {
|
||||
/// let min = parser.parse()?;
|
||||
///
|
||||
/// // ... and then test if there's a second number before parsing
|
||||
/// let max = if parser.peek::<u32>() {
|
||||
/// let max = if parser.peek::<u32>()? {
|
||||
/// Some(parser.parse()?)
|
||||
/// } else {
|
||||
/// None
|
||||
@ -568,30 +606,29 @@ impl<'a> Parser<'a> {
|
||||
///
|
||||
/// [spec]: https://webassembly.github.io/spec/core/text/types.html#limits
|
||||
/// [`Limits`]: crate::core::Limits
|
||||
pub fn peek<T: Peek>(self) -> bool {
|
||||
pub fn peek<T: Peek>(self) -> Result<bool> {
|
||||
T::peek(self.cursor())
|
||||
}
|
||||
|
||||
/// Same as the [`Parser::peek`] method, except checks the next token, not
|
||||
/// the current token.
|
||||
pub fn peek2<T: Peek>(self) -> bool {
|
||||
let mut cursor = self.cursor();
|
||||
if cursor.advance_token().is_some() {
|
||||
T::peek(cursor)
|
||||
} else {
|
||||
false
|
||||
}
|
||||
pub fn peek2<T: Peek>(self) -> Result<bool> {
|
||||
T::peek2(self.cursor())
|
||||
}
|
||||
|
||||
/// Same as the [`Parser::peek2`] method, except checks the next next token,
|
||||
/// not the next token.
|
||||
pub fn peek3<T: Peek>(self) -> bool {
|
||||
pub fn peek3<T: Peek>(self) -> Result<bool> {
|
||||
let mut cursor = self.cursor();
|
||||
if cursor.advance_token().is_some() && cursor.advance_token().is_some() {
|
||||
T::peek(cursor)
|
||||
} else {
|
||||
false
|
||||
match cursor.token()? {
|
||||
Some(token) => cursor.advance_past(&token),
|
||||
None => return Ok(false),
|
||||
}
|
||||
match cursor.token()? {
|
||||
Some(token) => cursor.advance_past(&token),
|
||||
None => return Ok(false),
|
||||
}
|
||||
T::peek(cursor)
|
||||
}
|
||||
|
||||
/// A helper structure to perform a sequence of `peek` operations and if
|
||||
@ -628,9 +665,9 @@ impl<'a> Parser<'a> {
|
||||
/// impl<'a> Parse<'a> for Index<'a> {
|
||||
/// fn parse(parser: Parser<'a>) -> Result<Self> {
|
||||
/// let mut l = parser.lookahead1();
|
||||
/// if l.peek::<Id>() {
|
||||
/// if l.peek::<Id>()? {
|
||||
/// Ok(Index::Id(parser.parse()?))
|
||||
/// } else if l.peek::<u32>() {
|
||||
/// } else if l.peek::<u32>()? {
|
||||
/// Ok(Index::Num(parser.parse()?))
|
||||
/// } else {
|
||||
/// // produces error message of `expected identifier or u32`
|
||||
@ -698,14 +735,18 @@ impl<'a> Parser<'a> {
|
||||
self.buf.depth.set(self.buf.depth.get() + 1);
|
||||
let before = self.buf.cur.get();
|
||||
let res = self.step(|cursor| {
|
||||
let mut cursor = match cursor.lparen() {
|
||||
let mut cursor = match cursor.lparen()? {
|
||||
Some(rest) => rest,
|
||||
None => return Err(cursor.error("expected `(`")),
|
||||
};
|
||||
cursor.parser.buf.cur.set(cursor.cur);
|
||||
cursor.parser.buf.cur.set(cursor.pos);
|
||||
let result = f(cursor.parser)?;
|
||||
cursor.cur = cursor.parser.buf.cur.get();
|
||||
match cursor.rparen() {
|
||||
|
||||
// Reset our cursor's state to whatever the current state of the
|
||||
// parser is.
|
||||
cursor.pos = cursor.parser.buf.cur.get();
|
||||
|
||||
match cursor.rparen()? {
|
||||
Some(rest) => Ok((result, rest)),
|
||||
None => Err(cursor.error("expected `)`")),
|
||||
}
|
||||
@ -737,7 +778,7 @@ impl<'a> Parser<'a> {
|
||||
fn cursor(self) -> Cursor<'a> {
|
||||
Cursor {
|
||||
parser: self,
|
||||
cur: self.buf.cur.get(),
|
||||
pos: self.buf.cur.get(),
|
||||
}
|
||||
}
|
||||
|
||||
@ -752,7 +793,7 @@ impl<'a> Parser<'a> {
|
||||
F: FnOnce(Cursor<'a>) -> Result<(T, Cursor<'a>)>,
|
||||
{
|
||||
let (result, cursor) = f(self.cursor())?;
|
||||
self.buf.cur.set(cursor.cur);
|
||||
self.buf.cur.set(cursor.pos);
|
||||
Ok(result)
|
||||
}
|
||||
|
||||
@ -769,7 +810,7 @@ impl<'a> Parser<'a> {
|
||||
/// Creates an error whose line/column information is pointing at the
|
||||
/// given span.
|
||||
pub fn error_at(self, span: Span, msg: impl fmt::Display) -> Error {
|
||||
Error::parse(span, self.buf.input, msg.to_string())
|
||||
Error::parse(span, self.buf.lexer.input(), msg.to_string())
|
||||
}
|
||||
|
||||
/// Returns the span of the current token
|
||||
@ -902,7 +943,7 @@ impl<'a> Parser<'a> {
|
||||
/// // annotation with the parser we known that `peek` methods like
|
||||
/// // this, working on the annotation token, are enabled to ever
|
||||
/// // return `true`.
|
||||
/// if parser.peek::<annotation::custom>() {
|
||||
/// if parser.peek::<annotation::custom>()? {
|
||||
/// return Ok(ModuleField::Custom(parser.parse()?));
|
||||
/// }
|
||||
///
|
||||
@ -943,9 +984,10 @@ impl<'a> Cursor<'a> {
|
||||
///
|
||||
/// Does not take into account whitespace or comments.
|
||||
pub fn cur_span(&self) -> Span {
|
||||
let offset = match self.clone().advance_token() {
|
||||
Some(t) => self.parser.buf.input_pos(t.src()),
|
||||
None => self.parser.buf.input.len(),
|
||||
let offset = match self.token() {
|
||||
Ok(Some(t)) => t.offset,
|
||||
Ok(None) => self.parser.buf.lexer.input().len(),
|
||||
Err(_) => self.pos.offset,
|
||||
};
|
||||
Span { offset }
|
||||
}
|
||||
@ -954,10 +996,14 @@ impl<'a> Cursor<'a> {
|
||||
///
|
||||
/// Does not take into account whitespace or comments.
|
||||
pub(crate) fn prev_span(&self) -> Option<Span> {
|
||||
let (token, _) = self.parser.buf.tokens.get(self.cur.checked_sub(1)?)?;
|
||||
// TODO
|
||||
Some(Span {
|
||||
offset: self.parser.buf.input_pos(token.src()),
|
||||
offset: self.pos.offset,
|
||||
})
|
||||
// let (token, _) = self.parser.buf.tokens.get(self.cur.checked_sub(1)?)?;
|
||||
// Some(Span {
|
||||
// offset: token.offset,
|
||||
// })
|
||||
}
|
||||
|
||||
/// Same as [`Parser::error`], but works with the current token in this
|
||||
@ -966,6 +1012,94 @@ impl<'a> Cursor<'a> {
|
||||
self.parser.error_at(self.cur_span(), msg)
|
||||
}
|
||||
|
||||
/// Tests whether the next token is an lparen
|
||||
pub fn peek_lparen(self) -> Result<bool> {
|
||||
Ok(matches!(
|
||||
self.token()?,
|
||||
Some(Token {
|
||||
kind: TokenKind::LParen,
|
||||
..
|
||||
})
|
||||
))
|
||||
}
|
||||
|
||||
/// Tests whether the next token is an rparen
|
||||
pub fn peek_rparen(self) -> Result<bool> {
|
||||
Ok(matches!(
|
||||
self.token()?,
|
||||
Some(Token {
|
||||
kind: TokenKind::RParen,
|
||||
..
|
||||
})
|
||||
))
|
||||
}
|
||||
|
||||
/// Tests whether the next token is an id
|
||||
pub fn peek_id(self) -> Result<bool> {
|
||||
Ok(matches!(
|
||||
self.token()?,
|
||||
Some(Token {
|
||||
kind: TokenKind::Id,
|
||||
..
|
||||
})
|
||||
))
|
||||
}
|
||||
|
||||
/// Tests whether the next token is reserved
|
||||
pub fn peek_reserved(self) -> Result<bool> {
|
||||
Ok(matches!(
|
||||
self.token()?,
|
||||
Some(Token {
|
||||
kind: TokenKind::Reserved,
|
||||
..
|
||||
})
|
||||
))
|
||||
}
|
||||
|
||||
/// Tests whether the next token is a keyword
|
||||
pub fn peek_keyword(self) -> Result<bool> {
|
||||
Ok(matches!(
|
||||
self.token()?,
|
||||
Some(Token {
|
||||
kind: TokenKind::Keyword,
|
||||
..
|
||||
})
|
||||
))
|
||||
}
|
||||
|
||||
/// Tests whether the next token is an integer
|
||||
pub fn peek_integer(self) -> Result<bool> {
|
||||
Ok(matches!(
|
||||
self.token()?,
|
||||
Some(Token {
|
||||
kind: TokenKind::Integer(_),
|
||||
..
|
||||
})
|
||||
))
|
||||
}
|
||||
|
||||
/// Tests whether the next token is a float
|
||||
pub fn peek_float(self) -> Result<bool> {
|
||||
Ok(matches!(
|
||||
self.token()?,
|
||||
Some(Token {
|
||||
kind: TokenKind::Float(_),
|
||||
..
|
||||
})
|
||||
))
|
||||
}
|
||||
|
||||
/// Tests whether the next token is a string
|
||||
pub fn peek_string(self) -> Result<bool> {
|
||||
Ok(matches!(
|
||||
self.token()?,
|
||||
Some(Token {
|
||||
kind: TokenKind::String,
|
||||
..
|
||||
})
|
||||
))
|
||||
}
|
||||
|
||||
/// Attempts to advance this cursor if the current token is a `(`.
|
||||
///
|
||||
/// If the current token is `(`, returns a new [`Cursor`] pointing at the
|
||||
@ -973,11 +1107,17 @@ impl<'a> Cursor<'a> {
|
||||
///
|
||||
/// This function will automatically skip over any comments, whitespace, or
|
||||
/// unknown annotations.
|
||||
pub fn lparen(mut self) -> Option<Self> {
|
||||
match self.advance_token()? {
|
||||
Token::LParen(_) => Some(self),
|
||||
_ => None,
|
||||
pub fn lparen(mut self) -> Result<Option<Self>> {
|
||||
let token = match self.token()? {
|
||||
Some(token) => token,
|
||||
None => return Ok(None),
|
||||
};
|
||||
match token.kind {
|
||||
TokenKind::LParen => {}
|
||||
_ => return Ok(None),
|
||||
}
|
||||
self.advance_past(&token);
|
||||
Ok(Some(self))
|
||||
}
|
||||
|
||||
/// Attempts to advance this cursor if the current token is a `)`.
|
||||
@ -987,11 +1127,17 @@ impl<'a> Cursor<'a> {
|
||||
///
|
||||
/// This function will automatically skip over any comments, whitespace, or
|
||||
/// unknown annotations.
|
||||
pub fn rparen(mut self) -> Option<Self> {
|
||||
match self.advance_token()? {
|
||||
Token::RParen(_) => Some(self),
|
||||
_ => None,
|
||||
pub fn rparen(mut self) -> Result<Option<Self>> {
|
||||
let token = match self.token()? {
|
||||
Some(token) => token,
|
||||
None => return Ok(None),
|
||||
};
|
||||
match token.kind {
|
||||
TokenKind::RParen => {}
|
||||
_ => return Ok(None),
|
||||
}
|
||||
self.advance_past(&token);
|
||||
Ok(Some(self))
|
||||
}
|
||||
|
||||
/// Attempts to advance this cursor if the current token is a
|
||||
@ -1003,11 +1149,17 @@ impl<'a> Cursor<'a> {
|
||||
///
|
||||
/// This function will automatically skip over any comments, whitespace, or
|
||||
/// unknown annotations.
|
||||
pub fn id(mut self) -> Option<(&'a str, Self)> {
|
||||
match self.advance_token()? {
|
||||
Token::Id(id) => Some((&id[1..], self)),
|
||||
_ => None,
|
||||
pub fn id(mut self) -> Result<Option<(&'a str, Self)>> {
|
||||
let token = match self.token()? {
|
||||
Some(token) => token,
|
||||
None => return Ok(None),
|
||||
};
|
||||
match token.kind {
|
||||
TokenKind::Id => {}
|
||||
_ => return Ok(None),
|
||||
}
|
||||
self.advance_past(&token);
|
||||
Ok(Some((token.id(self.parser.buf.lexer.input()), self)))
|
||||
}
|
||||
|
||||
/// Attempts to advance this cursor if the current token is a
|
||||
@ -1019,11 +1171,17 @@ impl<'a> Cursor<'a> {
|
||||
///
|
||||
/// This function will automatically skip over any comments, whitespace, or
|
||||
/// unknown annotations.
|
||||
pub fn keyword(mut self) -> Option<(&'a str, Self)> {
|
||||
match self.advance_token()? {
|
||||
Token::Keyword(id) => Some((id, self)),
|
||||
_ => None,
|
||||
pub fn keyword(mut self) -> Result<Option<(&'a str, Self)>> {
|
||||
let token = match self.token()? {
|
||||
Some(token) => token,
|
||||
None => return Ok(None),
|
||||
};
|
||||
match token.kind {
|
||||
TokenKind::Keyword => {}
|
||||
_ => return Ok(None),
|
||||
}
|
||||
self.advance_past(&token);
|
||||
Ok(Some((token.keyword(self.parser.buf.lexer.input()), self)))
|
||||
}
|
||||
|
||||
/// Attempts to advance this cursor if the current token is a
|
||||
@ -1035,11 +1193,17 @@ impl<'a> Cursor<'a> {
|
||||
///
|
||||
/// This function will automatically skip over any comments, whitespace, or
|
||||
/// unknown annotations.
|
||||
pub fn reserved(mut self) -> Option<(&'a str, Self)> {
|
||||
match self.advance_token()? {
|
||||
Token::Reserved(id) => Some((id, self)),
|
||||
_ => None,
|
||||
pub fn reserved(mut self) -> Result<Option<(&'a str, Self)>> {
|
||||
let token = match self.token()? {
|
||||
Some(token) => token,
|
||||
None => return Ok(None),
|
||||
};
|
||||
match token.kind {
|
||||
TokenKind::Reserved => {}
|
||||
_ => return Ok(None),
|
||||
}
|
||||
self.advance_past(&token);
|
||||
Ok(Some((token.reserved(self.parser.buf.lexer.input()), self)))
|
||||
}
|
||||
|
||||
/// Attempts to advance this cursor if the current token is a
|
||||
@ -1051,11 +1215,20 @@ impl<'a> Cursor<'a> {
|
||||
///
|
||||
/// This function will automatically skip over any comments, whitespace, or
|
||||
/// unknown annotations.
|
||||
pub fn integer(mut self) -> Option<(&'a Integer<'a>, Self)> {
|
||||
match self.advance_token()? {
|
||||
Token::Integer(i) => Some((i, self)),
|
||||
_ => None,
|
||||
}
|
||||
pub fn integer(mut self) -> Result<Option<(Integer<'a>, Self)>> {
|
||||
let token = match self.token()? {
|
||||
Some(token) => token,
|
||||
None => return Ok(None),
|
||||
};
|
||||
let i = match token.kind {
|
||||
TokenKind::Integer(i) => i,
|
||||
_ => return Ok(None),
|
||||
};
|
||||
self.advance_past(&token);
|
||||
Ok(Some((
|
||||
token.integer(self.parser.buf.lexer.input(), i),
|
||||
self,
|
||||
)))
|
||||
}
|
||||
|
||||
/// Attempts to advance this cursor if the current token is a
|
||||
@ -1067,11 +1240,17 @@ impl<'a> Cursor<'a> {
|
||||
///
|
||||
/// This function will automatically skip over any comments, whitespace, or
|
||||
/// unknown annotations.
|
||||
pub fn float(mut self) -> Option<(&'a Float<'a>, Self)> {
|
||||
match self.advance_token()? {
|
||||
Token::Float(f) => Some((f, self)),
|
||||
_ => None,
|
||||
}
|
||||
pub fn float(mut self) -> Result<Option<(Float<'a>, Self)>> {
|
||||
let token = match self.token()? {
|
||||
Some(token) => token,
|
||||
None => return Ok(None),
|
||||
};
|
||||
let f = match token.kind {
|
||||
TokenKind::Float(f) => f,
|
||||
_ => return Ok(None),
|
||||
};
|
||||
self.advance_past(&token);
|
||||
Ok(Some((token.float(self.parser.buf.lexer.input(), f), self)))
|
||||
}
|
||||
|
||||
/// Attempts to advance this cursor if the current token is a
|
||||
@ -1083,42 +1262,21 @@ impl<'a> Cursor<'a> {
|
||||
///
|
||||
/// This function will automatically skip over any comments, whitespace, or
|
||||
/// unknown annotations.
|
||||
pub fn string(mut self) -> Option<(&'a [u8], Self)> {
|
||||
match self.advance_token()? {
|
||||
Token::String(s) => Some((s.val(), self)),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
/// Attempts to advance this cursor if the current token is a
|
||||
/// [`Token::Reserved`](crate::lexer::Token) and looks like the start of an
|
||||
/// annotation.
|
||||
///
|
||||
/// [Annotations][annotation] are a WebAssembly proposal for the text format
|
||||
/// which allows placing structured text inside of a text file, for example
|
||||
/// to specify the name section or other custom sections.
|
||||
///
|
||||
/// This function will attempt to see if the current token is the `@foo`
|
||||
/// part of the annotation. This requires the previous token to be `(` and
|
||||
/// the current token is `Reserved` which starts with `@` and has a nonzero
|
||||
/// length for the following name.
|
||||
///
|
||||
/// Note that this will skip *unknown* annotations. Only pre-registered
|
||||
/// annotations will be returned here.
|
||||
///
|
||||
/// This function will automatically skip over any comments, whitespace, or
|
||||
/// unknown annotations.
|
||||
///
|
||||
/// [annotation]: https://github.com/WebAssembly/annotations
|
||||
pub fn annotation(self) -> Option<(&'a str, Self)> {
|
||||
let (token, cursor) = self.reserved()?;
|
||||
if !token.starts_with('@') || token.len() <= 1 {
|
||||
return None;
|
||||
}
|
||||
match &self.parser.buf.tokens.get(self.cur.wrapping_sub(1))?.0 {
|
||||
Token::LParen(_) => Some((&token[1..], cursor)),
|
||||
_ => None,
|
||||
pub fn string(mut self) -> Result<Option<(&'a [u8], Self)>> {
|
||||
let token = match self.token()? {
|
||||
Some(token) => token,
|
||||
None => return Ok(None),
|
||||
};
|
||||
match token.kind {
|
||||
TokenKind::String => {}
|
||||
_ => return Ok(None),
|
||||
}
|
||||
let string = match token.string(self.parser.buf.lexer.input()) {
|
||||
Cow::Borrowed(s) => s,
|
||||
Cow::Owned(s) => self.parser.buf.push_str(s),
|
||||
};
|
||||
self.advance_past(&token);
|
||||
Ok(Some((string, self)))
|
||||
}
|
||||
|
||||
/// Attempts to advance this cursor if the current token is a
|
||||
@ -1126,133 +1284,42 @@ impl<'a> Cursor<'a> {
|
||||
/// [`Token::BlockComment`](crate::lexer::Token)
|
||||
///
|
||||
/// This function will only skip whitespace, no other tokens.
|
||||
pub fn comment(mut self) -> Option<(&'a str, Self)> {
|
||||
pub fn comment(mut self) -> Result<Option<(&'a str, Self)>> {
|
||||
let start = self.pos.offset;
|
||||
self.pos.token = None;
|
||||
let comment = loop {
|
||||
match &self.parser.buf.tokens.get(self.cur)?.0 {
|
||||
Token::LineComment(c) | Token::BlockComment(c) => {
|
||||
self.cur += 1;
|
||||
break c;
|
||||
let token = match self.parser.buf.lexer.parse(&mut self.pos.offset)? {
|
||||
Some(token) => token,
|
||||
None => return Ok(None),
|
||||
};
|
||||
match token.kind {
|
||||
TokenKind::LineComment | TokenKind::BlockComment => {
|
||||
break token.src(self.parser.buf.lexer.input());
|
||||
}
|
||||
Token::Whitespace(_) => {
|
||||
self.cur += 1;
|
||||
TokenKind::Whitespace => {}
|
||||
_ => {
|
||||
self.pos.offset = start;
|
||||
return Ok(None);
|
||||
}
|
||||
_ => return None,
|
||||
}
|
||||
};
|
||||
Some((comment, self))
|
||||
Ok(Some((comment, self)))
|
||||
}
|
||||
|
||||
fn advance_token(&mut self) -> Option<&'a Token<'a>> {
|
||||
let known_annotations = self.parser.buf.known_annotations.borrow();
|
||||
let is_known_annotation = |name: &str| match known_annotations.get(name) {
|
||||
Some(0) | None => false,
|
||||
Some(_) => true,
|
||||
};
|
||||
|
||||
loop {
|
||||
let (token, next) = self.parser.buf.tokens.get(self.cur)?;
|
||||
|
||||
// If we're currently pointing at a token, and it's not the start
|
||||
// of an annotation, then we return that token and advance
|
||||
// ourselves to just after that token.
|
||||
match token {
|
||||
Token::Whitespace(_) | Token::LineComment(_) | Token::BlockComment(_) => {}
|
||||
_ => match self.annotation_start() {
|
||||
Some(n) if !is_known_annotation(n) => {}
|
||||
_ => {
|
||||
self.cur += 1;
|
||||
return Some(token);
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
// ... otherwise we need to skip the current token, and possibly
|
||||
// more. Here we're skipping whitespace, comments, annotations, etc.
|
||||
// Basically stuff that's intended to not be that relevant to the
|
||||
// text format. This is a pretty common operation, though, and we
|
||||
// may do it multiple times through peeks and such. As a result
|
||||
// this is somewhat cached.
|
||||
//
|
||||
// The `next` field, if "unknown", means we haven't calculated the
|
||||
// next token. Otherwise it's an index of where to resume searching
|
||||
// for the next token.
|
||||
//
|
||||
// Note that this entire operation happens in a loop (hence the
|
||||
// "somewhat cached") because the set of known annotations is
|
||||
// dynamic and we can't cache which annotations are skipped. What we
|
||||
// can do though is cache the number of tokens in the annotation so
|
||||
// we know how to skip ahead of it.
|
||||
match next.get() {
|
||||
NextTokenAt::Unknown => match self.find_next() {
|
||||
Some(i) => {
|
||||
next.set(NextTokenAt::Index(i));
|
||||
self.cur = i;
|
||||
}
|
||||
None => {
|
||||
next.set(NextTokenAt::Eof);
|
||||
return None;
|
||||
}
|
||||
},
|
||||
NextTokenAt::Eof => return None,
|
||||
NextTokenAt::Index(i) => self.cur = i,
|
||||
}
|
||||
fn token(&self) -> Result<Option<Token>> {
|
||||
match self.pos.token {
|
||||
Some(token) => Ok(Some(token)),
|
||||
None => self.parser.buf.advance_token(self.pos.offset),
|
||||
}
|
||||
}
|
||||
|
||||
fn annotation_start(&self) -> Option<&'a str> {
|
||||
match self.parser.buf.tokens.get(self.cur).map(|p| &p.0) {
|
||||
Some(Token::LParen(_)) => {}
|
||||
_ => return None,
|
||||
}
|
||||
let reserved = match self.parser.buf.tokens.get(self.cur + 1).map(|p| &p.0) {
|
||||
Some(Token::Reserved(n)) => n,
|
||||
_ => return None,
|
||||
};
|
||||
if reserved.starts_with('@') && reserved.len() > 1 {
|
||||
Some(&reserved[1..])
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
/// Finds the next "real" token from the current position onwards.
|
||||
///
|
||||
/// This is a somewhat expensive operation to call quite a lot, so it's
|
||||
/// cached in the token list. See the comment above in `advance_token` for
|
||||
/// how this works.
|
||||
///
|
||||
/// Returns the index of the next relevant token to parse
|
||||
fn find_next(mut self) -> Option<usize> {
|
||||
// If we're pointing to the start of annotation we need to skip it
|
||||
// in its entirety, so match the parentheses and figure out where
|
||||
// the annotation ends.
|
||||
if self.annotation_start().is_some() {
|
||||
let mut depth = 1;
|
||||
self.cur += 1;
|
||||
while depth > 0 {
|
||||
match &self.parser.buf.tokens.get(self.cur)?.0 {
|
||||
Token::LParen(_) => depth += 1,
|
||||
Token::RParen(_) => depth -= 1,
|
||||
_ => {}
|
||||
}
|
||||
self.cur += 1;
|
||||
}
|
||||
return Some(self.cur);
|
||||
}
|
||||
|
||||
// ... otherwise we're pointing at whitespace/comments, so we need to
|
||||
// figure out how many of them we can skip.
|
||||
loop {
|
||||
let (token, _) = self.parser.buf.tokens.get(self.cur)?;
|
||||
// and otherwise we skip all comments/whitespace and only
|
||||
// get interested once a normal `Token` pops up.
|
||||
match token {
|
||||
Token::Whitespace(_) | Token::LineComment(_) | Token::BlockComment(_) => {
|
||||
self.cur += 1
|
||||
}
|
||||
_ => return Some(self.cur),
|
||||
}
|
||||
}
|
||||
fn advance_past(&mut self, token: &Token) {
|
||||
self.pos.offset = token.offset + (token.len as usize);
|
||||
self.pos.token = self
|
||||
.parser
|
||||
.buf
|
||||
.advance_token(self.pos.offset)
|
||||
.unwrap_or(None);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1261,13 +1328,13 @@ impl Lookahead1<'_> {
|
||||
/// [`Lookahead1`] references.
|
||||
///
|
||||
/// For more information see [`Parser::lookahead1`] and [`Parser::peek`]
|
||||
pub fn peek<T: Peek>(&mut self) -> bool {
|
||||
if self.parser.peek::<T>() {
|
||||
pub fn peek<T: Peek>(&mut self) -> Result<bool> {
|
||||
Ok(if self.parser.peek::<T>()? {
|
||||
true
|
||||
} else {
|
||||
self.attempts.push(T::display());
|
||||
false
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/// Generates an error message saying that one of the tokens passed to
|
||||
@ -1306,7 +1373,7 @@ impl Lookahead1<'_> {
|
||||
|
||||
impl<'a, T: Peek + Parse<'a>> Parse<'a> for Option<T> {
|
||||
fn parse(parser: Parser<'a>) -> Result<Option<T>> {
|
||||
if parser.peek::<T>() {
|
||||
if parser.peek::<T>()? {
|
||||
Ok(Some(parser.parse()?))
|
||||
} else {
|
||||
Ok(None)
|
||||
|
71
third_party/rust/wast/src/token.rs
vendored
71
third_party/rust/wast/src/token.rs
vendored
@ -3,7 +3,7 @@
|
||||
//! contexts too perhaps).
|
||||
|
||||
use crate::annotation;
|
||||
use crate::lexer::FloatVal;
|
||||
use crate::lexer::Float;
|
||||
use crate::parser::{Cursor, Parse, Parser, Peek, Result};
|
||||
use std::fmt;
|
||||
use std::hash::{Hash, Hasher};
|
||||
@ -105,7 +105,7 @@ impl<'a> Eq for Id<'a> {}
|
||||
impl<'a> Parse<'a> for Id<'a> {
|
||||
fn parse(parser: Parser<'a>) -> Result<Self> {
|
||||
parser.step(|c| {
|
||||
if let Some((name, rest)) = c.id() {
|
||||
if let Some((name, rest)) = c.id()? {
|
||||
return Ok((Id::new(name, c.cur_span()), rest));
|
||||
}
|
||||
Err(c.error("expected an identifier"))
|
||||
@ -124,8 +124,8 @@ impl fmt::Debug for Id<'_> {
|
||||
}
|
||||
|
||||
impl Peek for Id<'_> {
|
||||
fn peek(cursor: Cursor<'_>) -> bool {
|
||||
cursor.id().is_some()
|
||||
fn peek(cursor: Cursor<'_>) -> Result<bool> {
|
||||
cursor.peek_id()
|
||||
}
|
||||
|
||||
fn display() -> &'static str {
|
||||
@ -167,21 +167,22 @@ impl Index<'_> {
|
||||
|
||||
impl<'a> Parse<'a> for Index<'a> {
|
||||
fn parse(parser: Parser<'a>) -> Result<Self> {
|
||||
let mut l = parser.lookahead1();
|
||||
if l.peek::<Id>() {
|
||||
if parser.peek::<Id>()? {
|
||||
Ok(Index::Id(parser.parse()?))
|
||||
} else if l.peek::<u32>() {
|
||||
} else if parser.peek::<u32>()? {
|
||||
let (val, span) = parser.parse()?;
|
||||
Ok(Index::Num(val, span))
|
||||
} else {
|
||||
Err(l.error())
|
||||
Err(parser.error(format!(
|
||||
"unexpected token, expected an index or an identifier"
|
||||
)))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Peek for Index<'_> {
|
||||
fn peek(cursor: Cursor<'_>) -> bool {
|
||||
u32::peek(cursor) || Id::peek(cursor)
|
||||
fn peek(cursor: Cursor<'_>) -> Result<bool> {
|
||||
Ok(u32::peek(cursor)? || Id::peek(cursor)?)
|
||||
}
|
||||
|
||||
fn display() -> &'static str {
|
||||
@ -241,10 +242,10 @@ impl<'a, K: Parse<'a>> Parse<'a> for ItemRef<'a, K> {
|
||||
}
|
||||
|
||||
impl<'a, K: Peek> Peek for ItemRef<'a, K> {
|
||||
fn peek(cursor: Cursor<'_>) -> bool {
|
||||
match cursor.lparen() {
|
||||
fn peek(cursor: Cursor<'_>) -> Result<bool> {
|
||||
match cursor.lparen()? {
|
||||
Some(remaining) => K::peek(remaining),
|
||||
None => false,
|
||||
None => Ok(false),
|
||||
}
|
||||
}
|
||||
|
||||
@ -270,8 +271,7 @@ impl<'a> Parse<'a> for NameAnnotation<'a> {
|
||||
|
||||
impl<'a> Parse<'a> for Option<NameAnnotation<'a>> {
|
||||
fn parse(parser: Parser<'a>) -> Result<Self> {
|
||||
let _r = parser.register_annotation("name");
|
||||
Ok(if parser.peek2::<annotation::name>() {
|
||||
Ok(if parser.peek2::<annotation::name>()? {
|
||||
Some(parser.parens(|p| p.parse())?)
|
||||
} else {
|
||||
None
|
||||
@ -290,7 +290,7 @@ macro_rules! integers {
|
||||
impl<'a> Parse<'a> for ($i, Span) {
|
||||
fn parse(parser: Parser<'a>) -> Result<Self> {
|
||||
parser.step(|c| {
|
||||
if let Some((i, rest)) = c.integer() {
|
||||
if let Some((i, rest)) = c.integer()? {
|
||||
let (s, base) = i.val();
|
||||
let val = $i::from_str_radix(s, base)
|
||||
.or_else(|_| {
|
||||
@ -311,8 +311,8 @@ macro_rules! integers {
|
||||
}
|
||||
|
||||
impl Peek for $i {
|
||||
fn peek(cursor: Cursor<'_>) -> bool {
|
||||
cursor.integer().is_some()
|
||||
fn peek(cursor: Cursor<'_>) -> Result<bool> {
|
||||
cursor.peek_integer()
|
||||
}
|
||||
|
||||
fn display() -> &'static str {
|
||||
@ -330,7 +330,7 @@ integers! {
|
||||
impl<'a> Parse<'a> for &'a [u8] {
|
||||
fn parse(parser: Parser<'a>) -> Result<Self> {
|
||||
parser.step(|c| {
|
||||
if let Some((i, rest)) = c.string() {
|
||||
if let Some((i, rest)) = c.string()? {
|
||||
return Ok((i, rest));
|
||||
}
|
||||
Err(c.error("expected a string"))
|
||||
@ -339,8 +339,8 @@ impl<'a> Parse<'a> for &'a [u8] {
|
||||
}
|
||||
|
||||
impl Peek for &'_ [u8] {
|
||||
fn peek(cursor: Cursor<'_>) -> bool {
|
||||
cursor.string().is_some()
|
||||
fn peek(cursor: Cursor<'_>) -> Result<bool> {
|
||||
cursor.peek_string()
|
||||
}
|
||||
|
||||
fn display() -> &'static str {
|
||||
@ -362,7 +362,7 @@ impl Parse<'_> for String {
|
||||
}
|
||||
|
||||
impl Peek for &'_ str {
|
||||
fn peek(cursor: Cursor<'_>) -> bool {
|
||||
fn peek(cursor: Cursor<'_>) -> Result<bool> {
|
||||
<&[u8]>::peek(cursor)
|
||||
}
|
||||
|
||||
@ -388,12 +388,12 @@ macro_rules! float {
|
||||
impl<'a> Parse<'a> for $name {
|
||||
fn parse(parser: Parser<'a>) -> Result<Self> {
|
||||
parser.step(|c| {
|
||||
let (val, rest) = if let Some((f, rest)) = c.float() {
|
||||
($parse(f.val()), rest)
|
||||
} else if let Some((i, rest)) = c.integer() {
|
||||
let (val, rest) = if let Some((f, rest)) = c.float()? {
|
||||
($parse(&f), rest)
|
||||
} else if let Some((i, rest)) = c.integer()? {
|
||||
let (s, base) = i.val();
|
||||
(
|
||||
$parse(&FloatVal::Val {
|
||||
$parse(&Float::Val {
|
||||
hex: base == 16,
|
||||
integral: s.into(),
|
||||
decimal: None,
|
||||
@ -412,7 +412,7 @@ macro_rules! float {
|
||||
}
|
||||
}
|
||||
|
||||
fn $parse(val: &FloatVal<'_>) -> Option<$int> {
|
||||
fn $parse(val: &Float<'_>) -> Option<$int> {
|
||||
// Compute a few well-known constants about the float representation
|
||||
// given the parameters to the macro here.
|
||||
let width = std::mem::size_of::<$int>() * 8;
|
||||
@ -425,7 +425,7 @@ macro_rules! float {
|
||||
let (hex, integral, decimal, exponent_str) = match val {
|
||||
// Infinity is when the exponent bits are all set and
|
||||
// the significand is zero.
|
||||
FloatVal::Inf { negative } => {
|
||||
Float::Inf { negative } => {
|
||||
let exp_bits = (1 << $exp_bits) - 1;
|
||||
let neg_bit = *negative as $int;
|
||||
return Some(
|
||||
@ -437,10 +437,13 @@ macro_rules! float {
|
||||
// NaN is when the exponent bits are all set and
|
||||
// the significand is nonzero. The default of NaN is
|
||||
// when only the highest bit of the significand is set.
|
||||
FloatVal::Nan { negative, val } => {
|
||||
Float::Nan { negative, val } => {
|
||||
let exp_bits = (1 << $exp_bits) - 1;
|
||||
let neg_bit = *negative as $int;
|
||||
let signif = val.unwrap_or(1 << (signif_bits - 1)) as $int;
|
||||
let signif = match val {
|
||||
Some(val) => $int::from_str_radix(val,16).ok()?,
|
||||
None => 1 << (signif_bits - 1),
|
||||
};
|
||||
// If the significand is zero then this is actually infinity
|
||||
// so we fail to parse it.
|
||||
if signif & signif_mask == 0 {
|
||||
@ -454,7 +457,7 @@ macro_rules! float {
|
||||
}
|
||||
|
||||
// This is trickier, handle this below
|
||||
FloatVal::Val { hex, integral, decimal, exponent } => {
|
||||
Float::Val { hex, integral, decimal, exponent } => {
|
||||
(hex, integral, decimal, exponent)
|
||||
}
|
||||
};
|
||||
@ -645,8 +648,8 @@ pub struct LParen {
|
||||
}
|
||||
|
||||
impl Peek for LParen {
|
||||
fn peek(cursor: Cursor<'_>) -> bool {
|
||||
cursor.lparen().is_some()
|
||||
fn peek(cursor: Cursor<'_>) -> Result<bool> {
|
||||
cursor.peek_lparen()
|
||||
}
|
||||
|
||||
fn display() -> &'static str {
|
||||
@ -663,7 +666,7 @@ mod tests {
|
||||
($a:tt p $e:tt) => (f!(@mk $a, None, Some($e.into())));
|
||||
($a:tt . $b:tt) => (f!(@mk $a, Some($b.into()), None));
|
||||
($a:tt . $b:tt p $e:tt) => (f!(@mk $a, Some($b.into()), Some($e.into())));
|
||||
(@mk $a:tt, $b:expr, $e:expr) => (crate::lexer::FloatVal::Val {
|
||||
(@mk $a:tt, $b:expr, $e:expr) => (crate::lexer::Float::Val {
|
||||
hex: true,
|
||||
integral: $a.into(),
|
||||
decimal: $b,
|
||||
|
48
third_party/rust/wast/src/wast.rs
vendored
48
third_party/rust/wast/src/wast.rs
vendored
@ -22,7 +22,7 @@ impl<'a> Parse<'a> for Wast<'a> {
|
||||
|
||||
// If it looks like a directive token is in the stream then we parse a
|
||||
// bunch of directives, otherwise assume this is an inline module.
|
||||
if parser.peek2::<WastDirectiveToken>() {
|
||||
if parser.peek2::<WastDirectiveToken>()? {
|
||||
while !parser.is_empty() {
|
||||
directives.push(parser.parens(|p| p.parse())?);
|
||||
}
|
||||
@ -37,16 +37,16 @@ impl<'a> Parse<'a> for Wast<'a> {
|
||||
struct WastDirectiveToken;
|
||||
|
||||
impl Peek for WastDirectiveToken {
|
||||
fn peek(cursor: Cursor<'_>) -> bool {
|
||||
let kw = match cursor.keyword() {
|
||||
fn peek(cursor: Cursor<'_>) -> Result<bool> {
|
||||
let kw = match cursor.keyword()? {
|
||||
Some((kw, _)) => kw,
|
||||
None => return false,
|
||||
None => return Ok(false),
|
||||
};
|
||||
kw.starts_with("assert_")
|
||||
Ok(kw.starts_with("assert_")
|
||||
|| kw == "module"
|
||||
|| kw == "component"
|
||||
|| kw == "register"
|
||||
|| kw == "invoke"
|
||||
|| kw == "invoke")
|
||||
}
|
||||
|
||||
fn display() -> &'static str {
|
||||
@ -128,39 +128,39 @@ impl WastDirective<'_> {
|
||||
impl<'a> Parse<'a> for WastDirective<'a> {
|
||||
fn parse(parser: Parser<'a>) -> Result<Self> {
|
||||
let mut l = parser.lookahead1();
|
||||
if l.peek::<kw::module>() || l.peek::<kw::component>() {
|
||||
if l.peek::<kw::module>()? || l.peek::<kw::component>()? {
|
||||
Ok(WastDirective::Wat(parser.parse()?))
|
||||
} else if l.peek::<kw::assert_malformed>() {
|
||||
} else if l.peek::<kw::assert_malformed>()? {
|
||||
let span = parser.parse::<kw::assert_malformed>()?.0;
|
||||
Ok(WastDirective::AssertMalformed {
|
||||
span,
|
||||
module: parser.parens(|p| p.parse())?,
|
||||
message: parser.parse()?,
|
||||
})
|
||||
} else if l.peek::<kw::assert_invalid>() {
|
||||
} else if l.peek::<kw::assert_invalid>()? {
|
||||
let span = parser.parse::<kw::assert_invalid>()?.0;
|
||||
Ok(WastDirective::AssertInvalid {
|
||||
span,
|
||||
module: parser.parens(|p| p.parse())?,
|
||||
message: parser.parse()?,
|
||||
})
|
||||
} else if l.peek::<kw::register>() {
|
||||
} else if l.peek::<kw::register>()? {
|
||||
let span = parser.parse::<kw::register>()?.0;
|
||||
Ok(WastDirective::Register {
|
||||
span,
|
||||
name: parser.parse()?,
|
||||
module: parser.parse()?,
|
||||
})
|
||||
} else if l.peek::<kw::invoke>() {
|
||||
} else if l.peek::<kw::invoke>()? {
|
||||
Ok(WastDirective::Invoke(parser.parse()?))
|
||||
} else if l.peek::<kw::assert_trap>() {
|
||||
} else if l.peek::<kw::assert_trap>()? {
|
||||
let span = parser.parse::<kw::assert_trap>()?.0;
|
||||
Ok(WastDirective::AssertTrap {
|
||||
span,
|
||||
exec: parser.parens(|p| p.parse())?,
|
||||
message: parser.parse()?,
|
||||
})
|
||||
} else if l.peek::<kw::assert_return>() {
|
||||
} else if l.peek::<kw::assert_return>()? {
|
||||
let span = parser.parse::<kw::assert_return>()?.0;
|
||||
let exec = parser.parens(|p| p.parse())?;
|
||||
let mut results = Vec::new();
|
||||
@ -172,21 +172,21 @@ impl<'a> Parse<'a> for WastDirective<'a> {
|
||||
exec,
|
||||
results,
|
||||
})
|
||||
} else if l.peek::<kw::assert_exhaustion>() {
|
||||
} else if l.peek::<kw::assert_exhaustion>()? {
|
||||
let span = parser.parse::<kw::assert_exhaustion>()?.0;
|
||||
Ok(WastDirective::AssertExhaustion {
|
||||
span,
|
||||
call: parser.parens(|p| p.parse())?,
|
||||
message: parser.parse()?,
|
||||
})
|
||||
} else if l.peek::<kw::assert_unlinkable>() {
|
||||
} else if l.peek::<kw::assert_unlinkable>()? {
|
||||
let span = parser.parse::<kw::assert_unlinkable>()?.0;
|
||||
Ok(WastDirective::AssertUnlinkable {
|
||||
span,
|
||||
module: parser.parens(parse_wat)?,
|
||||
message: parser.parse()?,
|
||||
})
|
||||
} else if l.peek::<kw::assert_exception>() {
|
||||
} else if l.peek::<kw::assert_exception>()? {
|
||||
let span = parser.parse::<kw::assert_exception>()?.0;
|
||||
Ok(WastDirective::AssertException {
|
||||
span,
|
||||
@ -212,11 +212,11 @@ pub enum WastExecute<'a> {
|
||||
impl<'a> Parse<'a> for WastExecute<'a> {
|
||||
fn parse(parser: Parser<'a>) -> Result<Self> {
|
||||
let mut l = parser.lookahead1();
|
||||
if l.peek::<kw::invoke>() {
|
||||
if l.peek::<kw::invoke>()? {
|
||||
Ok(WastExecute::Invoke(parser.parse()?))
|
||||
} else if l.peek::<kw::module>() || l.peek::<kw::component>() {
|
||||
} else if l.peek::<kw::module>()? || l.peek::<kw::component>()? {
|
||||
Ok(WastExecute::Wat(parse_wat(parser)?))
|
||||
} else if l.peek::<kw::get>() {
|
||||
} else if l.peek::<kw::get>()? {
|
||||
parser.parse::<kw::get>()?;
|
||||
Ok(WastExecute::Get {
|
||||
module: parser.parse()?,
|
||||
@ -235,7 +235,7 @@ fn parse_wat(parser: Parser) -> Result<Wat> {
|
||||
// the parens. Instead we can skip the sugar that `Wat` has for simply a
|
||||
// list of fields (no `(module ...)` container) and just parse the `Module`
|
||||
// itself.
|
||||
if parser.peek::<kw::component>() {
|
||||
if parser.peek::<kw::component>()? {
|
||||
Ok(Wat::Component(parser.parse()?))
|
||||
} else {
|
||||
Ok(Wat::Module(parser.parse()?))
|
||||
@ -308,8 +308,8 @@ impl QuoteWat<'_> {
|
||||
|
||||
impl<'a> Parse<'a> for QuoteWat<'a> {
|
||||
fn parse(parser: Parser<'a>) -> Result<Self> {
|
||||
if parser.peek2::<kw::quote>() {
|
||||
let ctor = if parser.peek::<kw::component>() {
|
||||
if parser.peek2::<kw::quote>()? {
|
||||
let ctor = if parser.peek::<kw::component>()? {
|
||||
parser.parse::<kw::component>()?;
|
||||
QuoteWat::QuoteComponent
|
||||
} else {
|
||||
@ -339,7 +339,7 @@ pub enum WastArg<'a> {
|
||||
|
||||
impl<'a> Parse<'a> for WastArg<'a> {
|
||||
fn parse(parser: Parser<'a>) -> Result<Self> {
|
||||
if parser.peek::<WastArgCore<'_>>() {
|
||||
if parser.peek::<WastArgCore<'_>>()? {
|
||||
Ok(WastArg::Core(parser.parse()?))
|
||||
} else {
|
||||
Ok(WastArg::Component(parser.parse()?))
|
||||
@ -356,7 +356,7 @@ pub enum WastRet<'a> {
|
||||
|
||||
impl<'a> Parse<'a> for WastRet<'a> {
|
||||
fn parse(parser: Parser<'a>) -> Result<Self> {
|
||||
if parser.peek::<WastRetCore<'_>>() {
|
||||
if parser.peek::<WastRetCore<'_>>()? {
|
||||
Ok(WastRet::Core(parser.parse()?))
|
||||
} else {
|
||||
Ok(WastRet::Component(parser.parse()?))
|
||||
|
6
third_party/rust/wast/src/wat.rs
vendored
6
third_party/rust/wast/src/wat.rs
vendored
@ -41,9 +41,11 @@ impl<'a> Parse<'a> for Wat<'a> {
|
||||
}
|
||||
|
||||
let _r = parser.register_annotation("custom");
|
||||
let wat = if parser.peek2::<kw::module>() {
|
||||
let _r = parser.register_annotation("producers");
|
||||
let _r = parser.register_annotation("name");
|
||||
let wat = if parser.peek2::<kw::module>()? {
|
||||
Wat::Module(parser.parens(|parser| parser.parse())?)
|
||||
} else if parser.peek2::<kw::component>() {
|
||||
} else if parser.peek2::<kw::component>()? {
|
||||
Wat::Component(parser.parens(|parser| parser.parse())?)
|
||||
} else {
|
||||
let fields = ModuleField::parse_remaining(parser)?;
|
||||
|
2
third_party/rust/wast/tests/comments.rs
vendored
2
third_party/rust/wast/tests/comments.rs
vendored
@ -9,7 +9,7 @@ impl<'a> Parse<'a> for Comments<'a> {
|
||||
let comments = parser.step(|mut cursor| {
|
||||
let mut comments = Vec::new();
|
||||
loop {
|
||||
let (comment, c) = match cursor.comment() {
|
||||
let (comment, c) = match cursor.comment()? {
|
||||
Some(pair) => pair,
|
||||
None => break,
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user