Bug 1825088 - wasm: Bump crate versions for wast and wasm-smith. r=rhunt,supply-chain-reviewers
Differential Revision: https://phabricator.services.mozilla.com/D179127
This commit is contained in:
18
Cargo.lock
generated
18
Cargo.lock
generated
@@ -5858,18 +5858,18 @@ version = "0.2.100"
|
||||
|
||||
[[package]]
|
||||
name = "wasm-encoder"
|
||||
version = "0.25.0"
|
||||
version = "0.29.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4eff853c4f09eec94d76af527eddad4e9de13b11d6286a1ef7134bc30135a2b7"
|
||||
checksum = "18c41dbd92eaebf3612a39be316540b8377c871cb9bde6b064af962984912881"
|
||||
dependencies = [
|
||||
"leb128",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-smith"
|
||||
version = "0.12.5"
|
||||
version = "0.12.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "549cb78be46f43ad6746402871336cb6a989127fb847e93eb6ba0817647485a6"
|
||||
checksum = "027ec1c470cd5d56c43b8e02040250b136ddb5975dd76a1c16915137f5f17e76"
|
||||
dependencies = [
|
||||
"arbitrary",
|
||||
"flagset",
|
||||
@@ -5881,19 +5881,19 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "wasmparser"
|
||||
version = "0.102.0"
|
||||
version = "0.107.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "48134de3d7598219ab9eaf6b91b15d8e50d31da76b8519fe4ecfcec2cf35104b"
|
||||
checksum = "29e3ac9b780c7dda0cac7a52a5d6d2d6707cc6e3451c9db209b6c758f40d7acb"
|
||||
dependencies = [
|
||||
"indexmap",
|
||||
"url",
|
||||
"semver",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wast"
|
||||
version = "56.0.0"
|
||||
version = "60.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6b54185c051d7bbe23757d50fe575880a2426a2f06d2e9f6a10fd9a4a42920c0"
|
||||
checksum = "bd06cc744b536e30387e72a48fdd492105b9c938bb4f415c39c616a7a0a697ad"
|
||||
dependencies = [
|
||||
"leb128",
|
||||
"memchr",
|
||||
|
||||
@@ -5,6 +5,6 @@ authors = ["Christian Holler"]
|
||||
license = "MPL-2.0"
|
||||
|
||||
[dependencies]
|
||||
wasm-smith = "0.12.5"
|
||||
wasm-smith = "0.12.10"
|
||||
arbitrary = { version = "1.0.0", features = ["derive"] }
|
||||
libc = "0.2"
|
||||
|
||||
@@ -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 = "56.0.0"
|
||||
wast = "60.0.0"
|
||||
|
||||
@@ -539,6 +539,34 @@ user-id = 1
|
||||
user-login = "alexcrichton"
|
||||
user-name = "Alex Crichton"
|
||||
|
||||
[[publisher.wasm-encoder]]
|
||||
version = "0.29.0"
|
||||
when = "2023-05-26"
|
||||
user-id = 1
|
||||
user-login = "alexcrichton"
|
||||
user-name = "Alex Crichton"
|
||||
|
||||
[[publisher.wasm-smith]]
|
||||
version = "0.12.10"
|
||||
when = "2023-05-26"
|
||||
user-id = 1
|
||||
user-login = "alexcrichton"
|
||||
user-name = "Alex Crichton"
|
||||
|
||||
[[publisher.wasmparser]]
|
||||
version = "0.107.0"
|
||||
when = "2023-05-26"
|
||||
user-id = 1
|
||||
user-login = "alexcrichton"
|
||||
user-name = "Alex Crichton"
|
||||
|
||||
[[publisher.wast]]
|
||||
version = "60.0.0"
|
||||
when = "2023-05-26"
|
||||
user-id = 1
|
||||
user-login = "alexcrichton"
|
||||
user-name = "Alex Crichton"
|
||||
|
||||
[[publisher.winapi-util]]
|
||||
version = "0.1.5"
|
||||
when = "2020-04-20"
|
||||
@@ -569,6 +597,58 @@ start = "2020-01-14"
|
||||
end = "2024-04-27"
|
||||
notes = "I am an author of this crate"
|
||||
|
||||
[[audits.bytecode-alliance.wildcard-audits.wasm-encoder]]
|
||||
who = "Alex Crichton <alex@alexcrichton.com>"
|
||||
criteria = "safe-to-deploy"
|
||||
user-id = 1 # Alex Crichton (alexcrichton)
|
||||
start = "2020-12-11"
|
||||
end = "2024-04-14"
|
||||
notes = """
|
||||
This is a Bytecode Alliance authored crate maintained in the `wasm-tools`
|
||||
repository of which I'm one of the primary maintainers and publishers for.
|
||||
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.wildcard-audits.wasm-smith]]
|
||||
who = "Alex Crichton <alex@alexcrichton.com>"
|
||||
criteria = "safe-to-deploy"
|
||||
user-id = 1 # Alex Crichton (alexcrichton)
|
||||
start = "2020-09-03"
|
||||
end = "2024-04-14"
|
||||
notes = """
|
||||
This is a Bytecode Alliance authored crate maintained in the `wasm-tools`
|
||||
repository of which I'm one of the primary maintainers and publishers for.
|
||||
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.wildcard-audits.wasmparser]]
|
||||
who = "Alex Crichton <alex@alexcrichton.com>"
|
||||
criteria = "safe-to-deploy"
|
||||
user-id = 1 # Alex Crichton (alexcrichton)
|
||||
start = "2020-07-13"
|
||||
end = "2024-04-14"
|
||||
notes = """
|
||||
This is a Bytecode Alliance authored crate maintained in the `wasm-tools`
|
||||
repository of which I'm one of the primary maintainers and publishers for.
|
||||
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.wildcard-audits.wast]]
|
||||
who = "Alex Crichton <alex@alexcrichton.com>"
|
||||
criteria = "safe-to-deploy"
|
||||
user-id = 1 # Alex Crichton (alexcrichton)
|
||||
start = "2019-10-16"
|
||||
end = "2024-04-14"
|
||||
notes = """
|
||||
This is a Bytecode Alliance authored crate maintained in the `wasm-tools`
|
||||
repository of which I'm one of the primary maintainers and publishers for.
|
||||
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.arrayref]]
|
||||
who = "Nick Fitzgerald <fitzgen@gmail.com>"
|
||||
criteria = "safe-to-deploy"
|
||||
|
||||
@@ -1 +1 @@
|
||||
{"files":{"Cargo.toml":"b96ee82a5f62db5b6f57000e3f1fdab6872b1bed6d36350e9af08d90984b47af","LICENSE":"268872b9816f90fd8e85db5a28d33f8150ebb8dd016653fb39ef1f94f2686bc5","README.md":"ac016c4843a7e1a5737255b39418732783592222dc518020730edf9dd46a1c13","src/component.rs":"b07b239571c54100a258da3fb00d9155c85d3750f93cc24d408ebc17301f3e66","src/component/aliases.rs":"be5215154b872ed5664f3bfe2aa1391f36a2575aa9d53971ab61868a1c446e9d","src/component/canonicals.rs":"8b270caef4e0f1e2b62af5b27560ac370399d11ce411aae6b811dddeaedb7750","src/component/components.rs":"07b8cae3a400e1955cc39d142569910b4fef2136021053d0ddbd6404d810aa52","src/component/exports.rs":"9a685fb44af0cfefbb2e92ddb0259955766cf6d1c0022830a865f92426ce0f7b","src/component/imports.rs":"41414a4cb71d79404e8721a985dd1d3a7df287f6417b4cab017d12e9aef31c43","src/component/instances.rs":"75e0ec12a578aa22d78053add818a960373171ff10c3619ca1e8058ded277a41","src/component/modules.rs":"9e80907e72360fae4d8057b6b0e7a6b58edd7ba6aba6e63ba17346518e169617","src/component/names.rs":"7b651284ffdf147aabf1e01226f34ddc8bbe3d38a2dcd26ca0fc15ad24002b6f","src/component/start.rs":"4055553d5c99c99abbc01bb8abb928ecb8b909d148b647a9977fbd444bb464a3","src/component/types.rs":"02982d0b7962462f0b083ade9a639216cc040775a0426ad431afbf9fbedf664b","src/core.rs":"7b02ef53a430693cfadcfd83f3aa9f556062eb9b9408e661ead5364e2150cd5e","src/core/code.rs":"b340cb948d1e28e8bd369353c729674146bcc28508bbb427a8d249af4fd491fe","src/core/custom.rs":"df2d6a8c5a64603822301522e9df4344022226301df846941d95930f1f4d99c4","src/core/data.rs":"c9d59eab2ab811bd950da52e6766c7df2367986c7a3a0d94d7aeb47d86f203ac","src/core/elements.rs":"76ab78bed1956fad030821b267a115511a99c61f33f2c6e588b5a8d4ee9b4204","src/core/exports.rs":"f37351587cd0cfa7608f94e0fcbfa09d41c7df1d123c47825992c364d5d9ff11","src/core/functions.rs":"c18b9872ac0c21048a3ce32e5e44e8e702f97a57fa1b3a07bdd98c7f6c820f09","src/core/globals.rs":"560d8e8c818d968cd8a101ab3c639f723b1c754716aa1178d1c4570efd84d010","src/core/imports.rs":"782bbc2e70b379831f85716c0f50c0221d1487c8cba26e8845028b2ae1962c0c","src/core/linking.rs":"5c7d5bce822fad92dc096ceafde878c6d25869004ca26dde1378e78ae37071c9","src/core/memories.rs":"840d15fcd9bd4a668298491c6a91455b145c5c7ff1adf8c769aaf49d6c664d3a","src/core/names.rs":"1337a5ab769e1a1b83113041d6fc59652db34a01ef44f14a2641b3748c216dc1","src/core/producers.rs":"e96156e2b87a4e9162b918b8f9cae870c5abc9410835651d74ac54f0ff2665e7","src/core/start.rs":"a01d4a91bcd93048977ccafc6af160357297450395bf598351f5a3e6d322e0de","src/core/tables.rs":"d5ae8c92c8707332eda6be6e5649f2f8042a1c6242494b0174cbee5e1971cace","src/core/tags.rs":"26d58904871d92f395eed67d4c25f0914b337d213bab2288011abe3ad31fa12b","src/core/types.rs":"988175ad3a47f4aca29c7fad9d594b54c5a5717fedf7ecd6296fbb45cb058999","src/lib.rs":"aaec7fa68ae0764721d7b4b6d0d935ea60380c6268cbd512480fee2f7a61b755","src/raw.rs":"a6a72cfe8f88ea6476eccee4acf362030ba2d2e5710215bc4f13cde7de6d71ae"},"package":"4eff853c4f09eec94d76af527eddad4e9de13b11d6286a1ef7134bc30135a2b7"}
|
||||
{"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"}
|
||||
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.25.0"
|
||||
version = "0.29.0"
|
||||
authors = ["Nick Fitzgerald <fitzgen@gmail.com>"]
|
||||
description = """
|
||||
A low-level WebAssembly encoder.
|
||||
|
||||
@@ -113,7 +113,7 @@ impl Component {
|
||||
// Magic
|
||||
0x00, 0x61, 0x73, 0x6D,
|
||||
// Version
|
||||
0x0c, 0x00, 0x01, 0x00,
|
||||
0x0d, 0x00, 0x01, 0x00,
|
||||
];
|
||||
|
||||
/// Begin writing a new `Component`.
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
use crate::{encode_section, ComponentSection, ComponentSectionId, Encode};
|
||||
use crate::{encode_section, ComponentSection, ComponentSectionId, ComponentValType, Encode};
|
||||
|
||||
/// Represents options for canonical function definitions.
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
@@ -118,6 +118,32 @@ impl CanonicalFunctionSection {
|
||||
self.num_added += 1;
|
||||
self
|
||||
}
|
||||
|
||||
/// Defines a function which will create an owned handle to the resource
|
||||
/// specified by `ty_index`.
|
||||
pub fn resource_new(&mut self, ty_index: u32) -> &mut Self {
|
||||
self.bytes.push(0x02);
|
||||
ty_index.encode(&mut self.bytes);
|
||||
self.num_added += 1;
|
||||
self
|
||||
}
|
||||
|
||||
/// Defines a function which will drop the specified type of handle.
|
||||
pub fn resource_drop(&mut self, ty: ComponentValType) -> &mut Self {
|
||||
self.bytes.push(0x03);
|
||||
ty.encode(&mut self.bytes);
|
||||
self.num_added += 1;
|
||||
self
|
||||
}
|
||||
|
||||
/// Defines a function which will return the representation of the specified
|
||||
/// resource type.
|
||||
pub fn resource_rep(&mut self, ty_index: u32) -> &mut Self {
|
||||
self.bytes.push(0x04);
|
||||
ty_index.encode(&mut self.bytes);
|
||||
self.num_added += 1;
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl Encode for CanonicalFunctionSection {
|
||||
|
||||
@@ -2,7 +2,10 @@ use super::{
|
||||
COMPONENT_SORT, CORE_MODULE_SORT, CORE_SORT, FUNCTION_SORT, INSTANCE_SORT, TYPE_SORT,
|
||||
VALUE_SORT,
|
||||
};
|
||||
use crate::{encode_section, ComponentSection, ComponentSectionId, ComponentTypeRef, Encode};
|
||||
use crate::{
|
||||
encode_section, AsComponentExternName, ComponentSection, ComponentSectionId, ComponentTypeRef,
|
||||
Encode,
|
||||
};
|
||||
|
||||
/// Represents the kind of an export from a WebAssembly component.
|
||||
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
|
||||
@@ -52,11 +55,12 @@ impl Encode for ComponentExportKind {
|
||||
/// # Example
|
||||
///
|
||||
/// ```rust
|
||||
/// use wasm_encoder::{Component, ComponentExportSection, ComponentExportKind};
|
||||
/// use wasm_encoder::{Component, ComponentExportSection, ComponentExportKind, ComponentExternName};
|
||||
///
|
||||
/// // This exports a function named "foo"
|
||||
/// let mut exports = ComponentExportSection::new();
|
||||
/// exports.export("foo", "", ComponentExportKind::Func, 0, None);
|
||||
/// let name = ComponentExternName::Kebab("foo");
|
||||
/// exports.export(name, ComponentExportKind::Func, 0, None);
|
||||
///
|
||||
/// let mut component = Component::new();
|
||||
/// component.section(&exports);
|
||||
@@ -88,14 +92,12 @@ impl ComponentExportSection {
|
||||
/// Define an export in the export section.
|
||||
pub fn export(
|
||||
&mut self,
|
||||
name: &str,
|
||||
url: &str,
|
||||
name: impl AsComponentExternName,
|
||||
kind: ComponentExportKind,
|
||||
index: u32,
|
||||
ty: Option<ComponentTypeRef>,
|
||||
) -> &mut Self {
|
||||
name.encode(&mut self.bytes);
|
||||
url.encode(&mut self.bytes);
|
||||
name.as_component_extern_name().encode(&mut self.bytes);
|
||||
kind.encode(&mut self.bytes);
|
||||
index.encode(&mut self.bytes);
|
||||
match ty {
|
||||
|
||||
@@ -6,14 +6,20 @@ use crate::{
|
||||
/// Represents the possible type bounds for type references.
|
||||
#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)]
|
||||
pub enum TypeBounds {
|
||||
/// The type is bounded by equality.
|
||||
Eq,
|
||||
/// The type is bounded by equality to the type index specified.
|
||||
Eq(u32),
|
||||
/// This type is a fresh resource type,
|
||||
SubResource,
|
||||
}
|
||||
|
||||
impl Encode for TypeBounds {
|
||||
fn encode(&self, sink: &mut Vec<u8>) {
|
||||
match self {
|
||||
Self::Eq => sink.push(0x00),
|
||||
Self::Eq(i) => {
|
||||
sink.push(0x00);
|
||||
i.encode(sink);
|
||||
}
|
||||
Self::SubResource => sink.push(0x01),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -32,9 +38,7 @@ pub enum ComponentTypeRef {
|
||||
/// The reference is to a value type.
|
||||
Value(ComponentValType),
|
||||
/// The reference is to a bounded type.
|
||||
///
|
||||
/// The index is expected to be a type index.
|
||||
Type(TypeBounds, u32),
|
||||
Type(TypeBounds),
|
||||
/// The reference is to an instance type.
|
||||
///
|
||||
/// The index is expected to be a type index to an instance type.
|
||||
@@ -68,10 +72,7 @@ impl Encode for ComponentTypeRef {
|
||||
idx.encode(sink);
|
||||
}
|
||||
Self::Value(ty) => ty.encode(sink),
|
||||
Self::Type(bounds, idx) => {
|
||||
bounds.encode(sink);
|
||||
idx.encode(sink);
|
||||
}
|
||||
Self::Type(bounds) => bounds.encode(sink),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -81,7 +82,7 @@ impl Encode for ComponentTypeRef {
|
||||
/// # Example
|
||||
///
|
||||
/// ```rust
|
||||
/// use wasm_encoder::{Component, ComponentTypeSection, PrimitiveValType, ComponentImportSection, ComponentTypeRef};
|
||||
/// use wasm_encoder::{Component, ComponentTypeSection, PrimitiveValType, ComponentImportSection, ComponentTypeRef, ComponentExternName};
|
||||
///
|
||||
/// let mut types = ComponentTypeSection::new();
|
||||
///
|
||||
@@ -98,7 +99,8 @@ impl Encode for ComponentTypeRef {
|
||||
///
|
||||
/// // This imports a function named `f` with the type defined above
|
||||
/// let mut imports = ComponentImportSection::new();
|
||||
/// imports.import("f", "", ComponentTypeRef::Func(0));
|
||||
/// let name = ComponentExternName::Kebab("f");
|
||||
/// imports.import(name, ComponentTypeRef::Func(0));
|
||||
///
|
||||
/// let mut component = Component::new();
|
||||
/// component.section(&types);
|
||||
@@ -129,9 +131,8 @@ impl ComponentImportSection {
|
||||
}
|
||||
|
||||
/// Define an import in the component import section.
|
||||
pub fn import(&mut self, name: &str, url: &str, ty: ComponentTypeRef) -> &mut Self {
|
||||
name.encode(&mut self.bytes);
|
||||
url.encode(&mut self.bytes);
|
||||
pub fn import(&mut self, name: impl AsComponentExternName, ty: ComponentTypeRef) -> &mut Self {
|
||||
name.as_component_extern_name().encode(&mut self.bytes);
|
||||
ty.encode(&mut self.bytes);
|
||||
self.num_added += 1;
|
||||
self
|
||||
@@ -149,3 +150,51 @@ impl ComponentSection for ComponentImportSection {
|
||||
ComponentSectionId::Import.into()
|
||||
}
|
||||
}
|
||||
|
||||
/// The different names that can be assigned to component imports
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
pub enum ComponentExternName<'a> {
|
||||
/// This is a "kebab name" along the lines of "a-foo-bar"
|
||||
Kebab(&'a str),
|
||||
/// This is an ID along the lines of "wasi:http/types@2.0"
|
||||
Interface(&'a str),
|
||||
}
|
||||
|
||||
impl Encode for ComponentExternName<'_> {
|
||||
fn encode(&self, sink: &mut Vec<u8>) {
|
||||
match self {
|
||||
ComponentExternName::Kebab(name) => {
|
||||
sink.push(0x00);
|
||||
name.encode(sink);
|
||||
}
|
||||
ComponentExternName::Interface(name) => {
|
||||
sink.push(0x01);
|
||||
name.encode(sink);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Helper trait to convert into a `ComponentExternName` either from that type
|
||||
/// or from a string.
|
||||
pub trait AsComponentExternName {
|
||||
/// Converts this receiver into a `ComponentExternName`.
|
||||
fn as_component_extern_name(&self) -> ComponentExternName<'_>;
|
||||
}
|
||||
|
||||
impl AsComponentExternName for ComponentExternName<'_> {
|
||||
fn as_component_extern_name(&self) -> ComponentExternName<'_> {
|
||||
*self
|
||||
}
|
||||
}
|
||||
|
||||
impl<S: AsRef<str>> AsComponentExternName for S {
|
||||
fn as_component_extern_name(&self) -> ComponentExternName<'_> {
|
||||
let s = self.as_ref();
|
||||
if s.contains("/") {
|
||||
ComponentExternName::Interface(s)
|
||||
} else {
|
||||
ComponentExternName::Kebab(s)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
use super::CORE_INSTANCE_SORT;
|
||||
use crate::{
|
||||
encode_section, ComponentExportKind, ComponentSection, ComponentSectionId, Encode, ExportKind,
|
||||
encode_section, ComponentExportKind, ComponentExternName, ComponentSection, ComponentSectionId,
|
||||
Encode, ExportKind,
|
||||
};
|
||||
|
||||
/// Represents an argument to a module instantiation.
|
||||
@@ -114,10 +115,10 @@ impl ComponentSection for InstanceSection {
|
||||
/// # Example
|
||||
///
|
||||
/// ```rust
|
||||
/// use wasm_encoder::{Component, ComponentInstanceSection, ComponentExportKind};
|
||||
/// use wasm_encoder::{Component, ComponentInstanceSection, ComponentExportKind, ComponentExternName};
|
||||
///
|
||||
/// let mut instances = ComponentInstanceSection::new();
|
||||
/// instances.export_items([("foo", ComponentExportKind::Func, 0)]);
|
||||
/// instances.export_items([(ComponentExternName::Kebab("foo"), ComponentExportKind::Func, 0)]);
|
||||
/// instances.instantiate(1, [("foo", ComponentExportKind::Instance, 0)]);
|
||||
///
|
||||
/// let mut component = Component::new();
|
||||
@@ -170,7 +171,7 @@ impl ComponentInstanceSection {
|
||||
/// Define an instance by exporting items.
|
||||
pub fn export_items<'a, E>(&mut self, exports: E) -> &mut Self
|
||||
where
|
||||
E: IntoIterator<Item = (&'a str, ComponentExportKind, u32)>,
|
||||
E: IntoIterator<Item = (ComponentExternName<'a>, ComponentExportKind, u32)>,
|
||||
E::IntoIter: ExactSizeIterator,
|
||||
{
|
||||
let exports = exports.into_iter();
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
use std::borrow::Cow;
|
||||
|
||||
use super::*;
|
||||
use crate::{encoding_size, CustomSection, Encode, ExportKind, NameMap, SectionId};
|
||||
|
||||
@@ -128,8 +130,8 @@ impl ComponentNameSection {
|
||||
/// View the encoded section as a CustomSection.
|
||||
pub fn as_custom<'a>(&'a self) -> CustomSection<'a> {
|
||||
CustomSection {
|
||||
name: "component-name",
|
||||
data: &self.bytes,
|
||||
name: "component-name".into(),
|
||||
data: Cow::Borrowed(&self.bytes),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
use super::CORE_TYPE_SORT;
|
||||
use crate::{
|
||||
encode_section, Alias, ComponentExportKind, ComponentOuterAliasKind, ComponentSection,
|
||||
ComponentSectionId, ComponentTypeRef, Encode, EntityType, ValType,
|
||||
encode_section, Alias, AsComponentExternName, ComponentExportKind, ComponentOuterAliasKind,
|
||||
ComponentSection, ComponentSectionId, ComponentTypeRef, Encode, EntityType, ValType,
|
||||
};
|
||||
|
||||
/// Represents the type of a core module.
|
||||
@@ -245,10 +245,9 @@ impl ComponentType {
|
||||
}
|
||||
|
||||
/// Defines an import in this component type.
|
||||
pub fn import(&mut self, name: &str, url: &str, ty: ComponentTypeRef) -> &mut Self {
|
||||
pub fn import(&mut self, name: impl AsComponentExternName, ty: ComponentTypeRef) -> &mut Self {
|
||||
self.bytes.push(0x03);
|
||||
name.encode(&mut self.bytes);
|
||||
url.encode(&mut self.bytes);
|
||||
name.as_component_extern_name().encode(&mut self.bytes);
|
||||
ty.encode(&mut self.bytes);
|
||||
self.num_added += 1;
|
||||
match ty {
|
||||
@@ -259,10 +258,9 @@ impl ComponentType {
|
||||
}
|
||||
|
||||
/// Defines an export in this component type.
|
||||
pub fn export(&mut self, name: &str, url: &str, ty: ComponentTypeRef) -> &mut Self {
|
||||
pub fn export(&mut self, name: impl AsComponentExternName, ty: ComponentTypeRef) -> &mut Self {
|
||||
self.bytes.push(0x04);
|
||||
name.encode(&mut self.bytes);
|
||||
url.encode(&mut self.bytes);
|
||||
name.as_component_extern_name().encode(&mut self.bytes);
|
||||
ty.encode(&mut self.bytes);
|
||||
self.num_added += 1;
|
||||
match ty {
|
||||
@@ -324,8 +322,8 @@ impl InstanceType {
|
||||
}
|
||||
|
||||
/// Defines an export in this instance type.
|
||||
pub fn export(&mut self, name: &str, url: &str, ty: ComponentTypeRef) -> &mut Self {
|
||||
self.0.export(name, url, ty);
|
||||
pub fn export(&mut self, name: impl AsComponentExternName, ty: ComponentTypeRef) -> &mut Self {
|
||||
self.0.export(name, ty);
|
||||
self
|
||||
}
|
||||
|
||||
@@ -442,6 +440,19 @@ impl<'a> ComponentTypeEncoder<'a> {
|
||||
pub fn defined_type(self) -> ComponentDefinedTypeEncoder<'a> {
|
||||
ComponentDefinedTypeEncoder(self.0)
|
||||
}
|
||||
|
||||
/// Define a resource type.
|
||||
pub fn resource(self, rep: ValType, dtor: Option<u32>) {
|
||||
self.0.push(0x3f);
|
||||
rep.encode(self.0);
|
||||
match dtor {
|
||||
Some(i) => {
|
||||
self.0.push(0x01);
|
||||
i.encode(self.0);
|
||||
}
|
||||
None => self.0.push(0x00),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Represents a primitive component value type.
|
||||
@@ -639,6 +650,18 @@ impl ComponentDefinedTypeEncoder<'_> {
|
||||
ok.encode(self.0);
|
||||
err.encode(self.0);
|
||||
}
|
||||
|
||||
/// Define a `own` handle type
|
||||
pub fn own(self, idx: u32) {
|
||||
self.0.push(0x69);
|
||||
idx.encode(self.0);
|
||||
}
|
||||
|
||||
/// Define a `borrow` handle type
|
||||
pub fn borrow(self, idx: u32) {
|
||||
self.0.push(0x68);
|
||||
idx.encode(self.0);
|
||||
}
|
||||
}
|
||||
|
||||
/// An encoder for the type section of WebAssembly components.
|
||||
|
||||
2
third_party/rust/wasm-encoder/src/core.rs
vendored
2
third_party/rust/wasm-encoder/src/core.rs
vendored
@@ -1,6 +1,7 @@
|
||||
mod code;
|
||||
mod custom;
|
||||
mod data;
|
||||
mod dump;
|
||||
mod elements;
|
||||
mod exports;
|
||||
mod functions;
|
||||
@@ -18,6 +19,7 @@ mod types;
|
||||
pub use code::*;
|
||||
pub use custom::*;
|
||||
pub use data::*;
|
||||
pub use dump::*;
|
||||
pub use elements::*;
|
||||
pub use exports::*;
|
||||
pub use functions::*;
|
||||
|
||||
23
third_party/rust/wasm-encoder/src/core/code.rs
vendored
23
third_party/rust/wasm-encoder/src/core/code.rs
vendored
@@ -322,9 +322,9 @@ pub enum Instruction<'a> {
|
||||
BrOnNonNull(u32),
|
||||
Return,
|
||||
Call(u32),
|
||||
CallRef(HeapType),
|
||||
CallRef(u32),
|
||||
CallIndirect { ty: u32, table: u32 },
|
||||
ReturnCallRef(HeapType),
|
||||
ReturnCallRef(u32),
|
||||
ReturnCall(u32),
|
||||
ReturnCallIndirect { ty: u32, table: u32 },
|
||||
Throw(u32),
|
||||
@@ -522,6 +522,11 @@ pub enum Instruction<'a> {
|
||||
RefFunc(u32),
|
||||
RefAsNonNull,
|
||||
|
||||
// GC types instructions.
|
||||
I31New,
|
||||
I31GetS,
|
||||
I31GetU,
|
||||
|
||||
// Bulk memory instructions.
|
||||
TableInit { elem_index: u32, table: u32 },
|
||||
ElemDrop(u32),
|
||||
@@ -1315,6 +1320,20 @@ impl Encode for Instruction<'_> {
|
||||
}
|
||||
Instruction::RefAsNonNull => sink.push(0xD3),
|
||||
|
||||
// GC instructions.
|
||||
Instruction::I31New => {
|
||||
sink.push(0xfb);
|
||||
sink.push(0x20)
|
||||
}
|
||||
Instruction::I31GetS => {
|
||||
sink.push(0xfb);
|
||||
sink.push(0x21)
|
||||
}
|
||||
Instruction::I31GetU => {
|
||||
sink.push(0xfb);
|
||||
sink.push(0x22)
|
||||
}
|
||||
|
||||
// Bulk memory instructions.
|
||||
Instruction::TableInit { elem_index, table } => {
|
||||
sink.push(0xfc);
|
||||
|
||||
12
third_party/rust/wasm-encoder/src/core/custom.rs
vendored
12
third_party/rust/wasm-encoder/src/core/custom.rs
vendored
@@ -1,12 +1,14 @@
|
||||
use std::borrow::Cow;
|
||||
|
||||
use crate::{encoding_size, Encode, Section, SectionId};
|
||||
|
||||
/// A custom section holding arbitrary data.
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct CustomSection<'a> {
|
||||
/// The name of this custom section.
|
||||
pub name: &'a str,
|
||||
pub name: Cow<'a, str>,
|
||||
/// This custom section's data.
|
||||
pub data: &'a [u8],
|
||||
pub data: Cow<'a, [u8]>,
|
||||
}
|
||||
|
||||
impl Encode for CustomSection<'_> {
|
||||
@@ -14,7 +16,7 @@ impl Encode for CustomSection<'_> {
|
||||
let encoded_name_len = encoding_size(u32::try_from(self.name.len()).unwrap());
|
||||
(encoded_name_len + self.name.len() + self.data.len()).encode(sink);
|
||||
self.name.encode(sink);
|
||||
sink.extend(self.data);
|
||||
sink.extend(&*self.data);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,8 +33,8 @@ mod tests {
|
||||
#[test]
|
||||
fn test_custom_section() {
|
||||
let custom = CustomSection {
|
||||
name: "test",
|
||||
data: &[11, 22, 33, 44],
|
||||
name: "test".into(),
|
||||
data: Cow::Borrowed(&[11, 22, 33, 44]),
|
||||
};
|
||||
|
||||
let mut encoded = vec![];
|
||||
|
||||
627
third_party/rust/wasm-encoder/src/core/dump.rs
vendored
Normal file
627
third_party/rust/wasm-encoder/src/core/dump.rs
vendored
Normal file
@@ -0,0 +1,627 @@
|
||||
use std::borrow::Cow;
|
||||
|
||||
use crate::{CustomSection, Encode, Section};
|
||||
|
||||
/// The "core" custom section for coredumps, as described in the
|
||||
/// [tool-conventions
|
||||
/// repository](https://github.com/WebAssembly/tool-conventions/blob/main/Coredump.md).
|
||||
///
|
||||
/// There are four sections that comprise a core dump:
|
||||
/// - "core", which contains the name of the core dump
|
||||
/// - "coremodules", a listing of modules
|
||||
/// - "coreinstances", a listing of module instances
|
||||
/// - "corestack", a listing of frames for a specific thread
|
||||
///
|
||||
/// # Example of how these could be constructed and encoded into a module:
|
||||
///
|
||||
/// ```
|
||||
/// use wasm_encoder::{
|
||||
/// CoreDumpInstancesSection, CoreDumpModulesSection, CoreDumpSection, CoreDumpStackSection,
|
||||
/// CoreDumpValue, Module,
|
||||
/// };
|
||||
/// let core = CoreDumpSection::new("MyModule.wasm");
|
||||
///
|
||||
/// let mut modules = CoreDumpModulesSection::new();
|
||||
/// modules.module("my_module");
|
||||
///
|
||||
/// let mut instances = CoreDumpInstancesSection::new();
|
||||
/// let module_idx = 0;
|
||||
/// let memories = vec![1];
|
||||
/// let globals = vec![2];
|
||||
/// instances.instance(module_idx, memories, globals);
|
||||
///
|
||||
/// let mut thread = CoreDumpStackSection::new("main");
|
||||
/// let instance_index = 0;
|
||||
/// let func_index = 42;
|
||||
/// let code_offset = 0x1234;
|
||||
/// let locals = vec![CoreDumpValue::I32(1)];
|
||||
/// let stack = vec![CoreDumpValue::I32(2)];
|
||||
/// thread.frame(instance_index, func_index, code_offset, locals, stack);
|
||||
///
|
||||
/// let mut module = Module::new();
|
||||
/// module.section(&core);
|
||||
/// module.section(&modules);
|
||||
/// module.section(&instances);
|
||||
/// module.section(&thread);
|
||||
/// ```
|
||||
#[derive(Clone, Debug, Default)]
|
||||
pub struct CoreDumpSection {
|
||||
name: String,
|
||||
}
|
||||
|
||||
impl CoreDumpSection {
|
||||
/// Create a new core dump section encoder
|
||||
pub fn new(name: impl Into<String>) -> Self {
|
||||
let name = name.into();
|
||||
CoreDumpSection { name }
|
||||
}
|
||||
|
||||
/// View the encoded section as a CustomSection.
|
||||
fn as_custom<'a>(&'a self) -> CustomSection<'a> {
|
||||
let mut data = vec![0];
|
||||
self.name.encode(&mut data);
|
||||
CustomSection {
|
||||
name: "core".into(),
|
||||
data: Cow::Owned(data),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Encode for CoreDumpSection {
|
||||
fn encode(&self, sink: &mut Vec<u8>) {
|
||||
self.as_custom().encode(sink);
|
||||
}
|
||||
}
|
||||
|
||||
impl Section for CoreDumpSection {
|
||||
fn id(&self) -> u8 {
|
||||
crate::core::SectionId::Custom as u8
|
||||
}
|
||||
}
|
||||
|
||||
/// The "coremodules" custom section for coredumps which lists the names of the
|
||||
/// modules
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```
|
||||
/// use wasm_encoder::{CoreDumpModulesSection, Module};
|
||||
/// let mut modules_section = CoreDumpModulesSection::new();
|
||||
/// modules_section.module("my_module");
|
||||
/// let mut module = Module::new();
|
||||
/// module.section(&modules_section);
|
||||
/// ```
|
||||
#[derive(Debug)]
|
||||
pub struct CoreDumpModulesSection {
|
||||
num_added: u32,
|
||||
bytes: Vec<u8>,
|
||||
}
|
||||
|
||||
impl CoreDumpModulesSection {
|
||||
/// Create a new core dump modules section encoder.
|
||||
pub fn new() -> Self {
|
||||
CoreDumpModulesSection {
|
||||
bytes: vec![],
|
||||
num_added: 0,
|
||||
}
|
||||
}
|
||||
|
||||
/// View the encoded section as a CustomSection.
|
||||
pub fn as_custom(&self) -> CustomSection<'_> {
|
||||
let mut data = vec![];
|
||||
self.num_added.encode(&mut data);
|
||||
data.extend(self.bytes.iter().copied());
|
||||
CustomSection {
|
||||
name: "coremodules".into(),
|
||||
data: Cow::Owned(data),
|
||||
}
|
||||
}
|
||||
|
||||
/// Encode a module name into the section's bytes.
|
||||
pub fn module(&mut self, module_name: impl AsRef<str>) -> &mut Self {
|
||||
self.bytes.push(0x0);
|
||||
module_name.as_ref().encode(&mut self.bytes);
|
||||
self.num_added += 1;
|
||||
self
|
||||
}
|
||||
|
||||
/// The number of modules that are encoded in the section.
|
||||
pub fn len(&self) -> u32 {
|
||||
self.num_added
|
||||
}
|
||||
}
|
||||
|
||||
impl Encode for CoreDumpModulesSection {
|
||||
fn encode(&self, sink: &mut Vec<u8>) {
|
||||
self.as_custom().encode(sink);
|
||||
}
|
||||
}
|
||||
|
||||
impl Section for CoreDumpModulesSection {
|
||||
fn id(&self) -> u8 {
|
||||
crate::core::SectionId::Custom as u8
|
||||
}
|
||||
}
|
||||
|
||||
/// The "coreinstances" section for the core dump
|
||||
#[derive(Debug)]
|
||||
pub struct CoreDumpInstancesSection {
|
||||
num_added: u32,
|
||||
bytes: Vec<u8>,
|
||||
}
|
||||
|
||||
impl CoreDumpInstancesSection {
|
||||
/// Create a new core dump instances section encoder.
|
||||
pub fn new() -> Self {
|
||||
CoreDumpInstancesSection {
|
||||
bytes: vec![],
|
||||
num_added: 0,
|
||||
}
|
||||
}
|
||||
|
||||
/// View the encoded section as a CustomSection.
|
||||
pub fn as_custom(&self) -> CustomSection<'_> {
|
||||
let mut data = vec![];
|
||||
self.num_added.encode(&mut data);
|
||||
data.extend(self.bytes.iter().copied());
|
||||
CustomSection {
|
||||
name: "coreinstances".into(),
|
||||
data: Cow::Owned(data),
|
||||
}
|
||||
}
|
||||
|
||||
/// Encode an instance into the section's bytes.
|
||||
pub fn instance<M, G>(&mut self, module_index: u32, memories: M, globals: G) -> &mut Self
|
||||
where
|
||||
M: IntoIterator<Item = u32>,
|
||||
<M as IntoIterator>::IntoIter: ExactSizeIterator,
|
||||
G: IntoIterator<Item = u32>,
|
||||
<G as IntoIterator>::IntoIter: ExactSizeIterator,
|
||||
{
|
||||
self.bytes.push(0x0);
|
||||
module_index.encode(&mut self.bytes);
|
||||
crate::encode_vec(memories, &mut self.bytes);
|
||||
crate::encode_vec(globals, &mut self.bytes);
|
||||
self.num_added += 1;
|
||||
self
|
||||
}
|
||||
|
||||
/// The number of modules that are encoded in the section.
|
||||
pub fn len(&self) -> u32 {
|
||||
self.num_added
|
||||
}
|
||||
}
|
||||
|
||||
impl Encode for CoreDumpInstancesSection {
|
||||
fn encode(&self, sink: &mut Vec<u8>) {
|
||||
self.as_custom().encode(sink);
|
||||
}
|
||||
}
|
||||
|
||||
impl Section for CoreDumpInstancesSection {
|
||||
fn id(&self) -> u8 {
|
||||
crate::core::SectionId::Custom as u8
|
||||
}
|
||||
}
|
||||
|
||||
/// A "corestack" custom section as described in the [tool-conventions
|
||||
/// repository](https://github.com/WebAssembly/tool-conventions/blob/main/Coredump.md)
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```
|
||||
/// use wasm_encoder::{CoreDumpStackSection, Module, CoreDumpValue};
|
||||
/// let mut thread = CoreDumpStackSection::new("main");
|
||||
///
|
||||
/// let instance_index = 0;
|
||||
/// let func_index = 42;
|
||||
/// let code_offset = 0x1234;
|
||||
/// let locals = vec![CoreDumpValue::I32(1)];
|
||||
/// let stack = vec![CoreDumpValue::I32(2)];
|
||||
/// thread.frame(instance_index, func_index, code_offset, locals, stack);
|
||||
///
|
||||
/// let mut module = Module::new();
|
||||
/// module.section(&thread);
|
||||
/// ```
|
||||
#[derive(Clone, Debug, Default)]
|
||||
pub struct CoreDumpStackSection {
|
||||
frame_bytes: Vec<u8>,
|
||||
count: u32,
|
||||
name: String,
|
||||
}
|
||||
|
||||
impl CoreDumpStackSection {
|
||||
/// Create a new core dump stack section encoder.
|
||||
pub fn new(name: impl Into<String>) -> Self {
|
||||
let name = name.into();
|
||||
CoreDumpStackSection {
|
||||
frame_bytes: Vec::new(),
|
||||
count: 0,
|
||||
name,
|
||||
}
|
||||
}
|
||||
|
||||
/// Add a stack frame to this coredump stack section.
|
||||
pub fn frame<L, S>(
|
||||
&mut self,
|
||||
instanceidx: u32,
|
||||
funcidx: u32,
|
||||
codeoffset: u32,
|
||||
locals: L,
|
||||
stack: S,
|
||||
) -> &mut Self
|
||||
where
|
||||
L: IntoIterator<Item = CoreDumpValue>,
|
||||
<L as IntoIterator>::IntoIter: ExactSizeIterator,
|
||||
S: IntoIterator<Item = CoreDumpValue>,
|
||||
<S as IntoIterator>::IntoIter: ExactSizeIterator,
|
||||
{
|
||||
self.count += 1;
|
||||
self.frame_bytes.push(0);
|
||||
instanceidx.encode(&mut self.frame_bytes);
|
||||
funcidx.encode(&mut self.frame_bytes);
|
||||
codeoffset.encode(&mut self.frame_bytes);
|
||||
crate::encode_vec(locals, &mut self.frame_bytes);
|
||||
crate::encode_vec(stack, &mut self.frame_bytes);
|
||||
self
|
||||
}
|
||||
|
||||
/// View the encoded section as a CustomSection.
|
||||
pub fn as_custom<'a>(&'a self) -> CustomSection<'a> {
|
||||
let mut data = vec![0];
|
||||
self.name.encode(&mut data);
|
||||
self.count.encode(&mut data);
|
||||
data.extend(&self.frame_bytes);
|
||||
CustomSection {
|
||||
name: "corestack".into(),
|
||||
data: Cow::Owned(data),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Encode for CoreDumpStackSection {
|
||||
fn encode(&self, sink: &mut Vec<u8>) {
|
||||
self.as_custom().encode(sink);
|
||||
}
|
||||
}
|
||||
|
||||
impl Section for CoreDumpStackSection {
|
||||
fn id(&self) -> u8 {
|
||||
crate::core::SectionId::Custom as u8
|
||||
}
|
||||
}
|
||||
|
||||
/// Local and stack values are encoded using one byte for the type (similar to
|
||||
/// Wasm's Number Types) followed by bytes representing the actual value
|
||||
/// See the tool-conventions repo for more details.
|
||||
#[derive(Clone, Debug)]
|
||||
pub enum CoreDumpValue {
|
||||
/// a missing value (usually missing because it was optimized out)
|
||||
Missing,
|
||||
/// An i32 value
|
||||
I32(i32),
|
||||
/// An i64 value
|
||||
I64(i64),
|
||||
/// An f32 value
|
||||
F32(f32),
|
||||
/// An f64 value
|
||||
F64(f64),
|
||||
}
|
||||
|
||||
impl Encode for CoreDumpValue {
|
||||
fn encode(&self, sink: &mut Vec<u8>) {
|
||||
match self {
|
||||
CoreDumpValue::Missing => sink.push(0x01),
|
||||
CoreDumpValue::I32(x) => {
|
||||
sink.push(0x7F);
|
||||
x.encode(sink);
|
||||
}
|
||||
CoreDumpValue::I64(x) => {
|
||||
sink.push(0x7E);
|
||||
x.encode(sink);
|
||||
}
|
||||
CoreDumpValue::F32(x) => {
|
||||
sink.push(0x7D);
|
||||
x.encode(sink);
|
||||
}
|
||||
CoreDumpValue::F64(x) => {
|
||||
sink.push(0x7C);
|
||||
x.encode(sink);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::Module;
|
||||
use wasmparser::{BinaryReader, FromReader, Parser, Payload};
|
||||
|
||||
// Create new core dump section and test whether it is properly encoded and
|
||||
// parsed back out by wasmparser
|
||||
#[test]
|
||||
fn test_roundtrip_core() {
|
||||
let core = CoreDumpSection::new("test.wasm");
|
||||
let mut module = Module::new();
|
||||
module.section(&core);
|
||||
|
||||
let wasm_bytes = module.finish();
|
||||
|
||||
let mut parser = Parser::new(0).parse_all(&wasm_bytes);
|
||||
match parser.next() {
|
||||
Some(Ok(Payload::Version { .. })) => {}
|
||||
_ => panic!(""),
|
||||
}
|
||||
|
||||
let payload = parser
|
||||
.next()
|
||||
.expect("parser is not empty")
|
||||
.expect("element is a payload");
|
||||
match payload {
|
||||
Payload::CustomSection(section) => {
|
||||
assert_eq!(section.name(), "core");
|
||||
let core = wasmparser::CoreDumpSection::from_reader(&mut BinaryReader::new(
|
||||
section.data(),
|
||||
))
|
||||
.expect("data is readable into a core dump section");
|
||||
assert_eq!(core.name, "test.wasm");
|
||||
}
|
||||
_ => panic!("unexpected payload"),
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_roundtrip_coremodules() {
|
||||
let mut coremodules = CoreDumpModulesSection::new();
|
||||
coremodules.module("test_module");
|
||||
|
||||
let mut module = crate::Module::new();
|
||||
module.section(&coremodules);
|
||||
|
||||
let wasm_bytes = module.finish();
|
||||
|
||||
let mut parser = Parser::new(0).parse_all(&wasm_bytes);
|
||||
match parser.next() {
|
||||
Some(Ok(Payload::Version { .. })) => {}
|
||||
_ => panic!(""),
|
||||
}
|
||||
|
||||
let payload = parser
|
||||
.next()
|
||||
.expect("parser is not empty")
|
||||
.expect("element is a payload");
|
||||
match payload {
|
||||
Payload::CustomSection(section) => {
|
||||
assert_eq!(section.name(), "coremodules");
|
||||
let modules = wasmparser::CoreDumpModulesSection::from_reader(
|
||||
&mut BinaryReader::new(section.data()),
|
||||
)
|
||||
.expect("data is readable into a core dump modules section");
|
||||
assert_eq!(modules.modules[0], "test_module");
|
||||
}
|
||||
_ => panic!("unexpected payload"),
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_roundtrip_coreinstances() {
|
||||
let mut coreinstances = CoreDumpInstancesSection::new();
|
||||
let module_index = 0;
|
||||
let memories = vec![42];
|
||||
let globals = vec![17];
|
||||
coreinstances.instance(module_index, memories, globals);
|
||||
|
||||
let mut module = Module::new();
|
||||
module.section(&coreinstances);
|
||||
let wasm_bytes = module.finish();
|
||||
|
||||
let mut parser = Parser::new(0).parse_all(&wasm_bytes);
|
||||
match parser.next() {
|
||||
Some(Ok(Payload::Version { .. })) => {}
|
||||
_ => panic!(""),
|
||||
}
|
||||
|
||||
let payload = parser
|
||||
.next()
|
||||
.expect("parser is not empty")
|
||||
.expect("element is a payload");
|
||||
match payload {
|
||||
Payload::CustomSection(section) => {
|
||||
assert_eq!(section.name(), "coreinstances");
|
||||
let coreinstances = wasmparser::CoreDumpInstancesSection::from_reader(
|
||||
&mut BinaryReader::new(section.data()),
|
||||
)
|
||||
.expect("data is readable into a core dump instances section");
|
||||
assert_eq!(coreinstances.instances.len(), 1);
|
||||
let instance = coreinstances
|
||||
.instances
|
||||
.first()
|
||||
.expect("instance is encoded");
|
||||
assert_eq!(instance.module_index, 0);
|
||||
assert_eq!(instance.memories.len(), 1);
|
||||
assert_eq!(instance.globals.len(), 1);
|
||||
}
|
||||
_ => panic!("unexpected payload"),
|
||||
}
|
||||
}
|
||||
|
||||
// Create new corestack section and test whether it is properly encoded and
|
||||
// parsed back out by wasmparser
|
||||
#[test]
|
||||
fn test_roundtrip_corestack() {
|
||||
let mut corestack = CoreDumpStackSection::new("main");
|
||||
corestack.frame(
|
||||
0,
|
||||
12,
|
||||
0,
|
||||
vec![CoreDumpValue::I32(10)],
|
||||
vec![CoreDumpValue::I32(42)],
|
||||
);
|
||||
let mut module = Module::new();
|
||||
module.section(&corestack);
|
||||
let wasm_bytes = module.finish();
|
||||
|
||||
let mut parser = Parser::new(0).parse_all(&wasm_bytes);
|
||||
match parser.next() {
|
||||
Some(Ok(Payload::Version { .. })) => {}
|
||||
_ => panic!(""),
|
||||
}
|
||||
|
||||
let payload = parser
|
||||
.next()
|
||||
.expect("parser is not empty")
|
||||
.expect("element is a payload");
|
||||
match payload {
|
||||
Payload::CustomSection(section) => {
|
||||
assert_eq!(section.name(), "corestack");
|
||||
let corestack = wasmparser::CoreDumpStackSection::from_reader(
|
||||
&mut BinaryReader::new(section.data()),
|
||||
)
|
||||
.expect("data is readable into a core dump stack section");
|
||||
assert_eq!(corestack.name, "main");
|
||||
assert_eq!(corestack.frames.len(), 1);
|
||||
let frame = corestack
|
||||
.frames
|
||||
.first()
|
||||
.expect("frame is encoded in corestack");
|
||||
assert_eq!(frame.instanceidx, 0);
|
||||
assert_eq!(frame.funcidx, 12);
|
||||
assert_eq!(frame.codeoffset, 0);
|
||||
assert_eq!(frame.locals.len(), 1);
|
||||
match frame.locals.first().expect("frame contains a local") {
|
||||
&wasmparser::CoreDumpValue::I32(val) => assert_eq!(val, 10),
|
||||
_ => panic!("unexpected local value"),
|
||||
}
|
||||
assert_eq!(frame.stack.len(), 1);
|
||||
match frame.stack.first().expect("stack contains a value") {
|
||||
&wasmparser::CoreDumpValue::I32(val) => assert_eq!(val, 42),
|
||||
_ => panic!("unexpected stack value"),
|
||||
}
|
||||
}
|
||||
_ => panic!("unexpected payload"),
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_encode_coredump_section() {
|
||||
let core = CoreDumpSection::new("test");
|
||||
|
||||
let mut encoded = vec![];
|
||||
core.encode(&mut encoded);
|
||||
|
||||
#[rustfmt::skip]
|
||||
assert_eq!(encoded, vec![
|
||||
// section length
|
||||
11,
|
||||
// name length
|
||||
4,
|
||||
// section name (core)
|
||||
b'c',b'o',b'r',b'e',
|
||||
// process-info (0, data length, data)
|
||||
0, 4, b't', b'e', b's', b't',
|
||||
]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_encode_coremodules_section() {
|
||||
let mut modules = CoreDumpModulesSection::new();
|
||||
modules.module("mod1");
|
||||
modules.module("mod2");
|
||||
|
||||
let mut encoded = vec![];
|
||||
modules.encode(&mut encoded);
|
||||
|
||||
#[rustfmt::skip]
|
||||
assert_eq!(encoded, vec![
|
||||
// section length
|
||||
25,
|
||||
// name length
|
||||
11,
|
||||
// section name (coremodules)
|
||||
b'c',b'o',b'r',b'e',b'm',b'o',b'd',b'u',b'l',b'e',b's',
|
||||
// module count
|
||||
2,
|
||||
// 0x0, name-length, module name (mod1)
|
||||
0x0, 4, b'm',b'o',b'd',b'1',
|
||||
// 0x0, name-length, module name (mod2)
|
||||
0x0, 4, b'm',b'o',b'd',b'2'
|
||||
]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_encode_coreinstances_section() {
|
||||
let mut instances = CoreDumpInstancesSection::new();
|
||||
instances.instance(0, vec![42], vec![17]);
|
||||
|
||||
let mut encoded = vec![];
|
||||
instances.encode(&mut encoded);
|
||||
|
||||
#[rustfmt::skip]
|
||||
assert_eq!(encoded, vec![
|
||||
// section length
|
||||
21,
|
||||
// name length
|
||||
13,
|
||||
// section name (coreinstances)
|
||||
b'c',b'o',b'r',b'e',b'i',b'n',b's',b't',b'a',b'n',b'c',b'e',b's',
|
||||
// instance count
|
||||
1,
|
||||
// 0x0, module_idx
|
||||
0x0, 0,
|
||||
// memories count, memories
|
||||
1, 42,
|
||||
// globals count, globals
|
||||
1, 17
|
||||
]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_encode_corestack_section() {
|
||||
let mut thread = CoreDumpStackSection::new("main");
|
||||
thread.frame(
|
||||
0,
|
||||
42,
|
||||
51,
|
||||
vec![CoreDumpValue::I32(1)],
|
||||
vec![CoreDumpValue::I32(2)],
|
||||
);
|
||||
|
||||
let mut encoded = vec![];
|
||||
thread.encode(&mut encoded);
|
||||
|
||||
#[rustfmt::skip]
|
||||
assert_eq!(
|
||||
encoded,
|
||||
vec![
|
||||
// section length
|
||||
27,
|
||||
// length of name.
|
||||
9,
|
||||
// section name (corestack)
|
||||
b'c',b'o',b'r',b'e',b's',b't',b'a',b'c',b'k',
|
||||
// 0x0, thread name length
|
||||
0, 4,
|
||||
// thread name (main)
|
||||
b'm',b'a',b'i',b'n',
|
||||
// frame count
|
||||
1,
|
||||
// 0x0, instanceidx, funcidx, codeoffset
|
||||
0, 0, 42, 51,
|
||||
// local count
|
||||
1,
|
||||
// local value type
|
||||
0x7F,
|
||||
// local value
|
||||
1,
|
||||
// stack count
|
||||
1,
|
||||
// stack value type
|
||||
0x7F,
|
||||
// stack value
|
||||
2
|
||||
|
||||
]
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -111,7 +111,7 @@ impl ElementSection {
|
||||
ElementMode::Active {
|
||||
table: None,
|
||||
offset,
|
||||
} => {
|
||||
} if segment.element_type == RefType::FUNCREF => {
|
||||
(/* 0x00 | */expr_bit).encode(&mut self.bytes);
|
||||
offset.encode(&mut self.bytes);
|
||||
}
|
||||
@@ -123,12 +123,9 @@ impl ElementSection {
|
||||
segment.element_type.encode(&mut self.bytes);
|
||||
}
|
||||
}
|
||||
ElementMode::Active {
|
||||
table: Some(i),
|
||||
offset,
|
||||
} => {
|
||||
ElementMode::Active { table, offset } => {
|
||||
(0x02 | expr_bit).encode(&mut self.bytes);
|
||||
i.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
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
use std::borrow::Cow;
|
||||
|
||||
use crate::{encode_section, CustomSection, Encode, Section, SectionId};
|
||||
|
||||
const VERSION: u32 = 2;
|
||||
@@ -72,8 +74,8 @@ impl Default for LinkingSection {
|
||||
impl Encode for LinkingSection {
|
||||
fn encode(&self, sink: &mut Vec<u8>) {
|
||||
CustomSection {
|
||||
name: "linking",
|
||||
data: &self.bytes,
|
||||
name: "linking".into(),
|
||||
data: Cow::Borrowed(&self.bytes),
|
||||
}
|
||||
.encode(sink);
|
||||
}
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
use std::borrow::Cow;
|
||||
|
||||
use crate::{encoding_size, CustomSection, Encode, Section, SectionId};
|
||||
|
||||
/// An encoder for the custom `name` section.
|
||||
@@ -153,8 +155,8 @@ impl NameSection {
|
||||
/// View the encoded section as a CustomSection.
|
||||
pub fn as_custom<'a>(&'a self) -> CustomSection<'a> {
|
||||
CustomSection {
|
||||
name: "name",
|
||||
data: &self.bytes,
|
||||
name: "name".into(),
|
||||
data: Cow::Borrowed(&self.bytes),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
use std::borrow::Cow;
|
||||
|
||||
use crate::{CustomSection, Encode, Section, SectionId};
|
||||
|
||||
/// An encoder for the [producers custom
|
||||
@@ -61,8 +63,8 @@ impl Encode for ProducersSection {
|
||||
data.extend(&self.bytes);
|
||||
|
||||
CustomSection {
|
||||
name: "producers",
|
||||
data: &data,
|
||||
name: "producers".into(),
|
||||
data: Cow::Borrowed(&data),
|
||||
}
|
||||
.encode(sink);
|
||||
}
|
||||
|
||||
65
third_party/rust/wasm-encoder/src/core/types.rs
vendored
65
third_party/rust/wasm-encoder/src/core/types.rs
vendored
@@ -1,5 +1,16 @@
|
||||
use crate::{encode_section, Encode, Section, SectionId};
|
||||
|
||||
/// Array or struct field type.
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Ord, PartialOrd)]
|
||||
pub enum StorageType {
|
||||
/// The `i8` type.
|
||||
I8,
|
||||
/// The `i16` type.
|
||||
I16,
|
||||
/// A value type.
|
||||
Val(ValType),
|
||||
}
|
||||
|
||||
/// The type of a core WebAssembly value.
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Ord, PartialOrd)]
|
||||
pub enum ValType {
|
||||
@@ -30,6 +41,16 @@ impl ValType {
|
||||
pub const EXTERNREF: ValType = ValType::Ref(RefType::EXTERNREF);
|
||||
}
|
||||
|
||||
impl Encode for StorageType {
|
||||
fn encode(&self, sink: &mut Vec<u8>) {
|
||||
match self {
|
||||
StorageType::I8 => sink.push(0x7A),
|
||||
StorageType::I16 => sink.push(0x79),
|
||||
StorageType::Val(vt) => vt.encode(sink),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Encode for ValType {
|
||||
fn encode(&self, sink: &mut Vec<u8>) {
|
||||
match self {
|
||||
@@ -99,12 +120,29 @@ impl From<RefType> for ValType {
|
||||
/// Part of the function references proposal.
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Ord, PartialOrd)]
|
||||
pub enum HeapType {
|
||||
/// A function reference. When nullable, equivalent to `funcref`
|
||||
/// Untyped (any) function.
|
||||
Func,
|
||||
/// An extern reference. When nullable, equivalent to `externref`
|
||||
/// External heap type.
|
||||
Extern,
|
||||
/// A reference to a particular index in a table.
|
||||
TypedFunc(u32),
|
||||
/// The `any` heap type. The common supertype (a.k.a. top) of all internal types.
|
||||
Any,
|
||||
/// The `none` heap type. The common subtype (a.k.a. bottom) of all internal types.
|
||||
None,
|
||||
/// The `noextern` heap type. The common subtype (a.k.a. bottom) of all external types.
|
||||
NoExtern,
|
||||
/// The `nofunc` heap type. The common subtype (a.k.a. bottom) of all function types.
|
||||
NoFunc,
|
||||
/// The `eq` heap type. The common supertype of all referenceable types on which comparison
|
||||
/// (ref.eq) is allowed.
|
||||
Eq,
|
||||
/// The `struct` heap type. The common supertype of all struct types.
|
||||
Struct,
|
||||
/// The `array` heap type. The common supertype of all array types.
|
||||
Array,
|
||||
/// The i31 heap type.
|
||||
I31,
|
||||
/// User defined type at the given index.
|
||||
Indexed(u32),
|
||||
}
|
||||
|
||||
impl Encode for HeapType {
|
||||
@@ -112,9 +150,17 @@ impl Encode for HeapType {
|
||||
match self {
|
||||
HeapType::Func => sink.push(0x70),
|
||||
HeapType::Extern => sink.push(0x6F),
|
||||
HeapType::Any => sink.push(0x6E),
|
||||
HeapType::None => sink.push(0x65),
|
||||
HeapType::NoExtern => sink.push(0x69),
|
||||
HeapType::NoFunc => sink.push(0x68),
|
||||
HeapType::Eq => sink.push(0x6D),
|
||||
HeapType::Struct => sink.push(0x67),
|
||||
HeapType::Array => sink.push(0x66),
|
||||
HeapType::I31 => sink.push(0x6A),
|
||||
// Note that this is encoded as a signed type rather than unsigned
|
||||
// as it's decoded as an s33
|
||||
HeapType::TypedFunc(i) => i64::from(*i).encode(sink),
|
||||
HeapType::Indexed(i) => i64::from(*i).encode(sink),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -176,6 +222,15 @@ impl TypeSection {
|
||||
self.num_added += 1;
|
||||
self
|
||||
}
|
||||
|
||||
/// Define an array type in this type section.
|
||||
pub fn array(&mut self, ty: StorageType, mutable: bool) -> &mut Self {
|
||||
self.bytes.push(0x5e);
|
||||
ty.encode(&mut self.bytes);
|
||||
self.bytes.push(mutable as u8);
|
||||
self.num_added += 1;
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl Encode for TypeSection {
|
||||
|
||||
29
third_party/rust/wasm-encoder/src/lib.rs
vendored
29
third_party/rust/wasm-encoder/src/lib.rs
vendored
@@ -144,6 +144,33 @@ impl Encode for i64 {
|
||||
}
|
||||
}
|
||||
|
||||
impl Encode for f32 {
|
||||
fn encode(&self, sink: &mut Vec<u8>) {
|
||||
let bits = self.to_bits();
|
||||
sink.extend(bits.to_le_bytes())
|
||||
}
|
||||
}
|
||||
|
||||
impl Encode for f64 {
|
||||
fn encode(&self, sink: &mut Vec<u8>) {
|
||||
let bits = self.to_bits();
|
||||
sink.extend(bits.to_le_bytes())
|
||||
}
|
||||
}
|
||||
|
||||
fn encode_vec<T, V>(elements: V, sink: &mut Vec<u8>)
|
||||
where
|
||||
T: Encode,
|
||||
V: IntoIterator<Item = T>,
|
||||
V::IntoIter: ExactSizeIterator,
|
||||
{
|
||||
let elements = elements.into_iter();
|
||||
u32::try_from(elements.len()).unwrap().encode(sink);
|
||||
for x in elements {
|
||||
x.encode(sink);
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> Encode for Option<T>
|
||||
where
|
||||
T: Encode,
|
||||
@@ -183,6 +210,6 @@ mod test {
|
||||
#[test]
|
||||
fn it_encodes_an_empty_component() {
|
||||
let bytes = Component::new().finish();
|
||||
assert_eq!(bytes, [0x00, b'a', b's', b'm', 0x0c, 0x00, 0x01, 0x00]);
|
||||
assert_eq!(bytes, [0x00, b'a', b's', b'm', 0x0d, 0x00, 0x01, 0x00]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1 +1 @@
|
||||
{"files":{"Cargo.toml":"3fab85439f91b5b0dfc20abd90cabf4a9f29ab1c422ab1308851c344302d32b3","LICENSE":"268872b9816f90fd8e85db5a28d33f8150ebb8dd016653fb39ef1f94f2686bc5","README.md":"9202d01e78acf04e38e23e162a91c20ece8968f6172c87bfa6f18bf0b3f27d74","benches/corpus.rs":"2df29556be0799f0cb1f32c8d0ae5ba0c4b9815cf4d59a8b71744d926c0693a0","src/component.rs":"32f93aac210f70fbc3f870c400993f4e7ff780ca6e111453a4dc4545906887e8","src/component/encode.rs":"09eddb96b5b607a87673714208c6d43b247ec4870168661d27d2c3ce92c43afd","src/config.rs":"3d33dea22d53081504e13fea4b5c99898624f26ed03013a831bae0c9759823fc","src/core.rs":"40949add77c2b90e9f3fc0ce6862a7c83ac03d5dd9babde5abee536d6fe074e6","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":"77ed926d64d325a73613f1c307db39c65c428a1eafae114033c73a60da586fd3","tests/component.rs":"54c69ebdda583207f9f0467a600ee0ca87fbee6b365e97ec3deff7b46bd6af06","tests/core.rs":"da9e27e7057a7cd9435666d4bd4d57cec03b0d5d74bad289373db7beb8a2e1a6"},"package":"549cb78be46f43ad6746402871336cb6a989127fb847e93eb6ba0817647485a6"}
|
||||
{"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"}
|
||||
6
third_party/rust/wasm-smith/Cargo.toml
vendored
6
third_party/rust/wasm-smith/Cargo.toml
vendored
@@ -12,7 +12,7 @@
|
||||
[package]
|
||||
edition = "2021"
|
||||
name = "wasm-smith"
|
||||
version = "0.12.5"
|
||||
version = "0.12.10"
|
||||
authors = ["Nick Fitzgerald <fitzgen@gmail.com>"]
|
||||
exclude = ["/benches/corpus"]
|
||||
description = "A WebAssembly test case generator"
|
||||
@@ -50,10 +50,10 @@ features = ["derive"]
|
||||
optional = true
|
||||
|
||||
[dependencies.wasm-encoder]
|
||||
version = "0.25.0"
|
||||
version = "0.29.0"
|
||||
|
||||
[dependencies.wasmparser]
|
||||
version = "0.102.0"
|
||||
version = "0.107.0"
|
||||
|
||||
[dev-dependencies.criterion]
|
||||
version = "0.3.3"
|
||||
|
||||
18
third_party/rust/wasm-smith/src/component.rs
vendored
18
third_party/rust/wasm-smith/src/component.rs
vendored
@@ -13,7 +13,7 @@ use std::{
|
||||
rc::Rc,
|
||||
};
|
||||
use wasm_encoder::{ComponentTypeRef, ComponentValType, PrimitiveValType, TypeBounds, ValType};
|
||||
use wasmparser::types::KebabString;
|
||||
use wasmparser::names::KebabString;
|
||||
|
||||
mod encode;
|
||||
|
||||
@@ -637,12 +637,9 @@ impl ComponentBuilder {
|
||||
&& (for_type_def || scope.types.len() < self.config.max_types())
|
||||
{
|
||||
choices.push(|me, u| {
|
||||
Ok(ComponentTypeRef::Type(
|
||||
TypeBounds::Eq,
|
||||
u.int_in_range(
|
||||
0..=u32::try_from(me.current_type_scope().types.len() - 1).unwrap(),
|
||||
)?,
|
||||
))
|
||||
Ok(ComponentTypeRef::Type(TypeBounds::Eq(u.int_in_range(
|
||||
0..=u32::try_from(me.current_type_scope().types.len() - 1).unwrap(),
|
||||
)?)))
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1115,7 +1112,7 @@ impl ComponentBuilder {
|
||||
if self.current_type_scope().can_ref_type() {
|
||||
choices.push(|me, exports, export_urls, u, _type_fuel| {
|
||||
let ty = me.arbitrary_type_ref(u, false, true)?.unwrap();
|
||||
if let ComponentTypeRef::Type(_, idx) = ty {
|
||||
if let ComponentTypeRef::Type(TypeBounds::Eq(idx)) = ty {
|
||||
let ty = me.current_type_scope().get(idx).clone();
|
||||
me.current_type_scope_mut().push(ty);
|
||||
}
|
||||
@@ -1555,10 +1552,13 @@ impl ComponentBuilder {
|
||||
self.total_values += 1;
|
||||
self.component_mut().values.push(ty);
|
||||
}
|
||||
ComponentTypeRef::Type(TypeBounds::Eq, ty_index) => {
|
||||
ComponentTypeRef::Type(TypeBounds::Eq(ty_index)) => {
|
||||
let ty = self.current_type_scope().get(ty_index).clone();
|
||||
self.current_type_scope_mut().push(ty);
|
||||
}
|
||||
ComponentTypeRef::Type(TypeBounds::SubResource) => {
|
||||
unimplemented!()
|
||||
}
|
||||
ComponentTypeRef::Instance(ty_index) => {
|
||||
let instance_ty = match self.current_type_scope().get(ty_index).as_ref() {
|
||||
Type::Instance(ty) => ty.clone(),
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
use std::borrow::Cow;
|
||||
|
||||
use super::*;
|
||||
use wasm_encoder::{ComponentExportKind, ComponentOuterAliasKind, ExportKind};
|
||||
use wasmparser::types::KebabStr;
|
||||
use wasmparser::names::KebabStr;
|
||||
|
||||
impl Component {
|
||||
/// Encode this Wasm component into bytes.
|
||||
@@ -51,8 +53,8 @@ impl Section {
|
||||
impl CustomSection {
|
||||
fn encode(&self, component: &mut wasm_encoder::Component) {
|
||||
component.section(&wasm_encoder::CustomSection {
|
||||
name: &self.name,
|
||||
data: &self.data,
|
||||
name: (&self.name).into(),
|
||||
data: Cow::Borrowed(&self.data),
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -71,7 +73,7 @@ impl ImportSection {
|
||||
fn encode(&self, component: &mut wasm_encoder::Component) {
|
||||
let mut sec = wasm_encoder::ComponentImportSection::new();
|
||||
for imp in &self.imports {
|
||||
sec.import(&imp.name, imp.url.as_deref().unwrap_or(""), imp.ty);
|
||||
sec.import(wasm_encoder::ComponentExternName::Kebab(&imp.name), imp.ty);
|
||||
}
|
||||
component.section(&sec);
|
||||
}
|
||||
@@ -178,7 +180,10 @@ impl Type {
|
||||
for def in &comp_ty.defs {
|
||||
match def {
|
||||
ComponentTypeDef::Import(imp) => {
|
||||
enc_comp_ty.import(&imp.name, imp.url.as_deref().unwrap_or(""), imp.ty);
|
||||
enc_comp_ty.import(
|
||||
wasm_encoder::ComponentExternName::Kebab(&imp.name),
|
||||
imp.ty,
|
||||
);
|
||||
}
|
||||
ComponentTypeDef::CoreType(ty) => {
|
||||
ty.encode(enc_comp_ty.core_type());
|
||||
@@ -186,8 +191,8 @@ impl Type {
|
||||
ComponentTypeDef::Type(ty) => {
|
||||
ty.encode(enc_comp_ty.ty());
|
||||
}
|
||||
ComponentTypeDef::Export { name, url, ty } => {
|
||||
enc_comp_ty.export(name, url.as_deref().unwrap_or(""), *ty);
|
||||
ComponentTypeDef::Export { name, url: _, ty } => {
|
||||
enc_comp_ty.export(wasm_encoder::ComponentExternName::Kebab(name), *ty);
|
||||
}
|
||||
ComponentTypeDef::Alias(a) => {
|
||||
enc_comp_ty.alias(translate_alias(a));
|
||||
@@ -206,8 +211,8 @@ impl Type {
|
||||
InstanceTypeDecl::Type(ty) => {
|
||||
ty.encode(enc_inst_ty.ty());
|
||||
}
|
||||
InstanceTypeDecl::Export { name, url, ty } => {
|
||||
enc_inst_ty.export(name, url.as_deref().unwrap_or(""), *ty);
|
||||
InstanceTypeDecl::Export { name, url: _, ty } => {
|
||||
enc_inst_ty.export(wasm_encoder::ComponentExternName::Kebab(name), *ty);
|
||||
}
|
||||
InstanceTypeDecl::Alias(a) => {
|
||||
enc_inst_ty.alias(translate_alias(a));
|
||||
|
||||
2
third_party/rust/wasm-smith/src/config.rs
vendored
2
third_party/rust/wasm-smith/src/config.rs
vendored
@@ -578,7 +578,6 @@ impl<'a> Arbitrary<'a> for SwarmConfig {
|
||||
min_uleb_size: u.int_in_range(0..=5)?,
|
||||
bulk_memory_enabled: reference_types_enabled || u.arbitrary()?,
|
||||
reference_types_enabled,
|
||||
tail_call_enabled: u.arbitrary()?,
|
||||
simd_enabled: u.arbitrary()?,
|
||||
multi_value_enabled: u.arbitrary()?,
|
||||
max_aliases: u.int_in_range(0..=MAX_MAXIMUM)?,
|
||||
@@ -628,6 +627,7 @@ impl<'a> Arbitrary<'a> for SwarmConfig {
|
||||
threads_enabled: false,
|
||||
export_everything: false,
|
||||
disallow_traps: false,
|
||||
tail_call_enabled: false,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
21
third_party/rust/wasm-smith/src/core.rs
vendored
21
third_party/rust/wasm-smith/src/core.rs
vendored
@@ -609,6 +609,9 @@ 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.");
|
||||
}
|
||||
};
|
||||
match &new_types[serialized_sig_idx - first_type_index] {
|
||||
Type::Func(f) => Some((serialized_sig_idx as u32, Rc::clone(f))),
|
||||
@@ -1639,11 +1642,19 @@ fn convert_type(parsed_type: wasmparser::ValType) -> ValType {
|
||||
|
||||
fn convert_reftype(ty: wasmparser::RefType) -> RefType {
|
||||
wasm_encoder::RefType {
|
||||
nullable: ty.nullable,
|
||||
heap_type: match ty.heap_type {
|
||||
wasmparser::HeapType::Func => wasm_encoder::HeapType::Func,
|
||||
wasmparser::HeapType::Extern => wasm_encoder::HeapType::Extern,
|
||||
wasmparser::HeapType::TypedFunc(i) => wasm_encoder::HeapType::TypedFunc(i.into()),
|
||||
nullable: ty.is_nullable(),
|
||||
heap_type: match ty.heap_type() {
|
||||
wasmparser::HeapType::Func => HeapType::Func,
|
||||
wasmparser::HeapType::Extern => HeapType::Extern,
|
||||
wasmparser::HeapType::Any => HeapType::Any,
|
||||
wasmparser::HeapType::None => HeapType::None,
|
||||
wasmparser::HeapType::NoExtern => HeapType::NoExtern,
|
||||
wasmparser::HeapType::NoFunc => HeapType::NoFunc,
|
||||
wasmparser::HeapType::Eq => HeapType::Eq,
|
||||
wasmparser::HeapType::Struct => HeapType::Struct,
|
||||
wasmparser::HeapType::Array => HeapType::Array,
|
||||
wasmparser::HeapType::I31 => HeapType::I31,
|
||||
wasmparser::HeapType::Indexed(i) => HeapType::Indexed(i.into()),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
2
third_party/rust/wasm-smith/src/lib.rs
vendored
2
third_party/rust/wasm-smith/src/lib.rs
vendored
@@ -65,7 +65,7 @@ use arbitrary::{Result, Unstructured};
|
||||
pub use component::{Component, ConfiguredComponent};
|
||||
pub use config::{Config, DefaultConfig, SwarmConfig};
|
||||
use std::{collections::HashSet, fmt::Write, str};
|
||||
use wasmparser::types::{KebabStr, KebabString};
|
||||
use wasmparser::names::{KebabStr, KebabString};
|
||||
|
||||
/// Do something an arbitrary number of times.
|
||||
///
|
||||
|
||||
@@ -3,6 +3,7 @@ use rand::{rngs::SmallRng, RngCore, SeedableRng};
|
||||
use wasm_smith::Component;
|
||||
|
||||
#[test]
|
||||
#[ignore] // FIXME(#1000): need to update wasm-smith's support for components
|
||||
fn smoke_test_component() {
|
||||
const NUM_RUNS: usize = 4096;
|
||||
|
||||
|
||||
4
third_party/rust/wasm-smith/tests/core.rs
vendored
4
third_party/rust/wasm-smith/tests/core.rs
vendored
@@ -132,6 +132,9 @@ fn smoke_test_imports_config() {
|
||||
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.")
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if let wasmparser::Payload::ImportSection(rdr) = payload {
|
||||
@@ -302,6 +305,7 @@ fn parser_features_from_config(config: &impl Config) -> WasmFeatures {
|
||||
component_model: false,
|
||||
function_references: false,
|
||||
memory_control: false,
|
||||
gc: false,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1 +1 @@
|
||||
{"files":{"Cargo.lock":"ef76d24da3e4c9b0e0034844c4d3fa21f84ddb56af9f3134222046aaf26a48d3","Cargo.toml":"f1f05638e3da3d7304ccb0a41ef0a9889224bc5dc92352c634a553c6fa27d4bd","LICENSE":"268872b9816f90fd8e85db5a28d33f8150ebb8dd016653fb39ef1f94f2686bc5","README.md":"1c3b4f8db61a673ee2f7dc66118b1008ce8d1a7d0f5197fbe87f1271b23de3bd","benches/benchmark.rs":"b8417fbd86058b76f3ff15426075f9afee25b9f90155bbd9a2d774f4bad0af04","examples/simple.rs":"e9eb076367cc0932e2a32651372defa4a27ef800f47fad28c0ef840ba8ea7e08","src/binary_reader.rs":"1b1f0e1d831a716875ed578380f96b4b60245f0c6a4f43e2407c50fc94e50e6d","src/lib.rs":"d64774abb8d193f6a177130ffca94ce9fd199535fb6177dcb9910c4af7602082","src/limits.rs":"0c4dc6b96b35a320a8cff8269c0b55acd56f1f7b8a093c4885e04b9835441458","src/parser.rs":"b65b995296ed03a5b4d31c6459f2f3430ff685e50fec397c44f91b1364de5aaf","src/readers.rs":"406bf0cf694ed364c9c53cd25eb27a8e3fa97d099994f3e2a640747c49abf74b","src/readers/component.rs":"c259628ca3f09ff904f7e920aeec261b657f7a197c99b520a6a7d3e918b9fb3b","src/readers/component/aliases.rs":"72f3339cb452c1b055bd080281fe4923d132c280da112fcd1182594811b87494","src/readers/component/canonicals.rs":"c36e9bffc2e1ed752586189903eec77ea9897ae265e020096a9b92c467be26d9","src/readers/component/exports.rs":"f2c76e4be5045f1d099fd89dedf20e2f4817f046ea1e64bde7ca8f3ea9b2cdc6","src/readers/component/imports.rs":"725a688f2ab4306dbb421fe92ffff9373e3c88632557e352529f297bb2b96e0e","src/readers/component/instances.rs":"bca614178da3337e8c71a6ec431f12157a8cccc15411a0222bbc0106926a3ad5","src/readers/component/names.rs":"3f5dac9db8668b18cd6721cd780e6aba9b223b404c9d1173d09efe4e6b4d3a8a","src/readers/component/start.rs":"8e1e5d8aa5ece26d42251449cadcce0546c4d995f1641941b8a31ed4bc6ac761","src/readers/component/types.rs":"878fdf8f3d6a1c1387fd92b34838d8e79cee039710366bd5ea6739448d468a7a","src/readers/core.rs":"b1dbe0ffe61af1e6da4104de687009bcaa71fd3137300896159abbcfd903b800","src/readers/core/code.rs":"53f49986febb27f4cb67f4495e7b369fc80e2f70908e1e831750698dd15fe37f","src/readers/core/custom.rs":"f80d3a994e8778a912319834228cbb772c65a4b6b1f25b41fe00d220d388831f","src/readers/core/data.rs":"c1fcda7b548b15be40b3dd1f667d97c30c543867f2dc4734b590846beefe3ae3","src/readers/core/elements.rs":"197d3427fcf0fa8a3eb654e62dfa53159e6bc5cb160e75a06cf394f821bddef5","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":"4b42b7e1c9e22e7e2913d9da2291b491dc2d4fea417503d7ce99ad33c7beb439","src/readers/core/tables.rs":"cbe5b35893bd3929354b4487b344062ce6b540e6a70bde6eddf05a07a68574e9","src/readers/core/tags.rs":"c1dcfeb973195da9708549bcc2df4dd8ff282fe802c15a603bebc8a856f70949","src/readers/core/types.rs":"266a6c37ecdea656c235001b56b15564ad7777c23849a3f6e08ce63272347c7e","src/resources.rs":"b38b564ee425a392a30fb7440b50afa9e91be5ee933e4933b843e18c212a5871","src/validator.rs":"0dc406f1a61cf646719fa2d88675eae4d8c52c23cc3a4a222b6671cd25f84465","src/validator/component.rs":"4ca4d2d3c800e212a68e30577eead6bb69b2e7604f6d774d4f51f2aaa2f87084","src/validator/core.rs":"143f1a531485d411eb459fe608a64ca21f772740cbebe51e9f336e30ce3d1424","src/validator/func.rs":"63b66b7bb274be4115d8a26bce9b73128de0c079bd3318423288fadc1361fdb4","src/validator/operators.rs":"39b3bd04898b02b9dbd1d42c5727c79439593f5ef8fbf3c33fcc789d0b5be91a","src/validator/types.rs":"9ee9fb8a8afa0580c3e71bf9b39bd28c14b2a21f2d9acbb92e7d8ec14615ade2","tests/big-module.rs":"1f9241a4504d0421f6a5c759e3c688c87994fe04668b1d4e8912cedd98f2bd17"},"package":"48134de3d7598219ab9eaf6b91b15d8e50d31da76b8519fe4ecfcec2cf35104b"}
|
||||
{"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"}
|
||||
240
third_party/rust/wasmparser/Cargo.lock
generated
vendored
240
third_party/rust/wasmparser/Cargo.lock
generated
vendored
@@ -4,9 +4,9 @@ version = 3
|
||||
|
||||
[[package]]
|
||||
name = "anyhow"
|
||||
version = "1.0.69"
|
||||
version = "1.0.71"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "224afbd727c3d6e4b90103ece64b8d1b67fbb1973b1046c2281eed3f3803f800"
|
||||
checksum = "9c7d0618f0e0b7e8ff11427422b64564d5fb0be1940354bfe2e0529b18a9d9b8"
|
||||
|
||||
[[package]]
|
||||
name = "atty"
|
||||
@@ -31,23 +31,11 @@ version = "1.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
|
||||
|
||||
[[package]]
|
||||
name = "bstr"
|
||||
version = "0.2.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ba3569f383e8f1598449f1a423e72e99569137b47740b1da11ef19af3d5c3223"
|
||||
dependencies = [
|
||||
"lazy_static",
|
||||
"memchr",
|
||||
"regex-automata",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bumpalo"
|
||||
version = "3.12.0"
|
||||
version = "3.12.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0d261e256854913907f67ed06efbc3338dfe6179796deefc1ff763fc1aee5535"
|
||||
checksum = "3c6ed94e98ecff0c12dd1b04c15ec0d7d9458ca8fe806cea6f12954efe74c63b"
|
||||
|
||||
[[package]]
|
||||
name = "cast"
|
||||
@@ -110,9 +98,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-channel"
|
||||
version = "0.5.6"
|
||||
version = "0.5.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c2dd04ddaf88237dc3b8d8f9a3c1004b506b54b3313403944054d23c0870c521"
|
||||
checksum = "a33c2bf77f2df06183c3aa30d1e96c0695a313d4f9c453cc3762a6db39f99200"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"crossbeam-utils",
|
||||
@@ -120,9 +108,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-deque"
|
||||
version = "0.8.2"
|
||||
version = "0.8.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "715e8152b692bba2d374b53d4875445368fdf21a94751410af607a5ac677d1fc"
|
||||
checksum = "ce6fd6f855243022dcecf8702fef0c297d4338e226845fe067f6341ad9fa0cef"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"crossbeam-epoch",
|
||||
@@ -131,9 +119,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-epoch"
|
||||
version = "0.9.13"
|
||||
version = "0.9.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "01a9af1f4c2ef74bb8aa1f7e19706bc72d03598c8a570bb5de72243c7a9d9d5a"
|
||||
checksum = "46bd5f3f85273295a9d14aedfb86f6aadbff6d8f5295c4a9edb08e819dcf5695"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"cfg-if",
|
||||
@@ -144,22 +132,21 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-utils"
|
||||
version = "0.8.14"
|
||||
version = "0.8.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4fb766fa798726286dbbb842f174001dab8abc7b627a1dd86e0b7222a95d929f"
|
||||
checksum = "3c063cd8cc95f5c377ed0d4b49a4b21f632396ff690e8470c29b3359b346984b"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "csv"
|
||||
version = "1.1.6"
|
||||
version = "1.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "22813a6dc45b335f9bade10bf7271dc477e81113e89eb251a0bc2a8a81c536e1"
|
||||
checksum = "0b015497079b9a9d69c02ad25de6c0a6edef051ea6360a327d0bd05802ef64ad"
|
||||
dependencies = [
|
||||
"bstr",
|
||||
"csv-core",
|
||||
"itoa 0.4.8",
|
||||
"itoa",
|
||||
"ryu",
|
||||
"serde",
|
||||
]
|
||||
@@ -179,15 +166,6 @@ version = "1.8.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7fcaabb2fef8c910e7f4c7ce9f67a1283a1715879a7c230ca9d6d1ae31f16d91"
|
||||
|
||||
[[package]]
|
||||
name = "form_urlencoded"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a9c384f161156f5260c24a097c56119f9be8c798586aecc13afbcbe7b7e26bf8"
|
||||
dependencies = [
|
||||
"percent-encoding",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "half"
|
||||
version = "1.8.2"
|
||||
@@ -218,21 +196,11 @@ dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "idna"
|
||||
version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e14ddfc70884202db2244c223200c204c2bda1bc6e0998d11b5e024d657209e6"
|
||||
dependencies = [
|
||||
"unicode-bidi",
|
||||
"unicode-normalization",
|
||||
]
|
||||
|
||||
[[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",
|
||||
@@ -249,21 +217,15 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "itoa"
|
||||
version = "0.4.8"
|
||||
version = "1.0.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b71991ff56294aa922b450139ee08b3bfc70982c6b2c7562771375cf73542dd4"
|
||||
|
||||
[[package]]
|
||||
name = "itoa"
|
||||
version = "1.0.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fad582f4b9e86b6caa621cabeb0963332d92eea04729ab12892c2533951e6440"
|
||||
checksum = "453ad9f582a441959e5f0d088b02ce04cfe8d51a8eaf077f12ac6d3e94164ca6"
|
||||
|
||||
[[package]]
|
||||
name = "js-sys"
|
||||
version = "0.3.61"
|
||||
version = "0.3.62"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "445dde2150c55e483f3d8416706b97ec8e8237c307e5b7b4b8dd15e6af2a0730"
|
||||
checksum = "68c16e1bfd491478ab155fd8b4896b86f9ede344949b641e61501e07c2b8b4d5"
|
||||
dependencies = [
|
||||
"wasm-bindgen",
|
||||
]
|
||||
@@ -282,9 +244,9 @@ checksum = "884e2677b40cc8c339eaefcb701c32ef1fd2493d71118dc0ca4b6a736c93bd67"
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.139"
|
||||
version = "0.2.144"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "201de327520df007757c1f0adce6e827fe8562fbc28bfd9c15571c66ca1f5f79"
|
||||
checksum = "2b00cc1c228a6782d0f076e7b232802e0c5689d41bb5df366f2a6b6621cfdfe1"
|
||||
|
||||
[[package]]
|
||||
name = "log"
|
||||
@@ -303,9 +265,9 @@ checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d"
|
||||
|
||||
[[package]]
|
||||
name = "memoffset"
|
||||
version = "0.7.1"
|
||||
version = "0.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5de893c32cde5f383baa4c04c5d6dbdd735cfd4a794b0debdb2bb1b421da5ff4"
|
||||
checksum = "d61c719bcfbcf5d62b3a09efa6088de8c54bc0bfcd3ea7ae39fcc186108b8de1"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
]
|
||||
@@ -331,9 +293,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "once_cell"
|
||||
version = "1.17.0"
|
||||
version = "1.17.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6f61fba1741ea2b3d6a1e3178721804bb716a68a6aeba1149b5d52e3d464ea66"
|
||||
checksum = "b7e5500299e16ebb147ae15a00a942af264cf3688f47923b8fc2cd5858f23ad3"
|
||||
|
||||
[[package]]
|
||||
name = "oorandom"
|
||||
@@ -341,12 +303,6 @@ version = "11.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0ab1bc2a289d34bd04a330323ac98a1b4bc82c9d9fcb1e66b63caa84da26b575"
|
||||
|
||||
[[package]]
|
||||
name = "percent-encoding"
|
||||
version = "2.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "478c572c3d73181ff3c2539045f6eb99e5491218eae919370993b890cdbdd98e"
|
||||
|
||||
[[package]]
|
||||
name = "plotters"
|
||||
version = "0.3.4"
|
||||
@@ -377,27 +333,27 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.51"
|
||||
version = "1.0.57"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5d727cae5b39d21da60fa540906919ad737832fe0b1c165da3a34d6548c849d6"
|
||||
checksum = "c4ec6d5fe0b140acb27c9a0444118cf55bfbb4e0b259739429abb4521dd67c16"
|
||||
dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.23"
|
||||
version = "1.0.27"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8856d8364d252a14d474036ea1358d63c9e6965c8e5c1885c18f73d70bff9c7b"
|
||||
checksum = "8f4f29d145265ec1c483c7c654450edde0bfe043d3938d6972630663356d9500"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rayon"
|
||||
version = "1.6.1"
|
||||
version = "1.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6db3a213adf02b3bcfd2d3846bb41cb22857d131789e01df434fb7e7bc0759b7"
|
||||
checksum = "1d2df5196e37bcc87abebc0053e20787d73847bb33134a69841207dd0a47f03b"
|
||||
dependencies = [
|
||||
"either",
|
||||
"rayon-core",
|
||||
@@ -405,9 +361,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "rayon-core"
|
||||
version = "1.10.2"
|
||||
version = "1.11.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "356a0625f1954f730c0201cdab48611198dc6ce21f4acff55089b5a78e6e835b"
|
||||
checksum = "4b8f95bd6966f5c87776639160a66bd8ab9895d9d4ab01ddba9fc60661aebe8d"
|
||||
dependencies = [
|
||||
"crossbeam-channel",
|
||||
"crossbeam-deque",
|
||||
@@ -417,30 +373,24 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "regex"
|
||||
version = "1.7.1"
|
||||
version = "1.8.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "48aaa5748ba571fb95cd2c85c09f629215d3a6ece942baa100950af03a34f733"
|
||||
checksum = "af83e617f331cc6ae2da5443c602dfa5af81e517212d9d611a5b3ba1777b5370"
|
||||
dependencies = [
|
||||
"regex-syntax",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex-automata"
|
||||
version = "0.1.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132"
|
||||
|
||||
[[package]]
|
||||
name = "regex-syntax"
|
||||
version = "0.6.28"
|
||||
version = "0.7.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "456c603be3e8d448b072f410900c09faf164fbce2d480456f50eea6e25f9c848"
|
||||
checksum = "a5996294f19bd3aae0453a862ad728f60e6600695733dd5df01da90c54363a3c"
|
||||
|
||||
[[package]]
|
||||
name = "ryu"
|
||||
version = "1.0.12"
|
||||
version = "1.0.13"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7b4b9743ed687d4b4bcedf9ff5eaa7398495ae14e61cba0a295704edbc7decde"
|
||||
checksum = "f91339c0467de62360649f8d3e185ca8de4224ff281f66000de5eb2a77a79041"
|
||||
|
||||
[[package]]
|
||||
name = "same-file"
|
||||
@@ -458,10 +408,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
|
||||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.152"
|
||||
name = "semver"
|
||||
version = "1.0.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bb7d1f0d3021d347a83e556fc4683dea2ea09d87bccdf88ff5c12545d89d5efb"
|
||||
checksum = "bebd363326d05ec3e2f532ab7660680f3b02130d780c299bca73469d521bc0ed"
|
||||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.163"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2113ab51b87a539ae008b5c6c02dc020ffa39afd2d83cffcb3f4eb2722cebec2"
|
||||
|
||||
[[package]]
|
||||
name = "serde_cbor"
|
||||
@@ -475,9 +431,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "serde_derive"
|
||||
version = "1.0.152"
|
||||
version = "1.0.163"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "af487d118eecd09402d70a5d72551860e788df87b464af30e5ea6a38c75c541e"
|
||||
checksum = "8c805777e3930c8883389c602315a24224bcc738b63905ef87cd1420353ea93e"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
@@ -486,20 +442,20 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "serde_json"
|
||||
version = "1.0.93"
|
||||
version = "1.0.96"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cad406b69c91885b5107daf2c29572f6c8cdb3c66826821e286c533490c0bc76"
|
||||
checksum = "057d394a50403bcac12672b2b18fb387ab6d289d957dab67dd201875391e52f1"
|
||||
dependencies = [
|
||||
"itoa 1.0.5",
|
||||
"itoa",
|
||||
"ryu",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "1.0.107"
|
||||
version = "2.0.16"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1f4064b5b16e03ae50984a5a8ed5d4f8803e6bc1fd170a3cda91a1be4b18e3f5"
|
||||
checksum = "a6f671d4b5ffdb8eadec19c0ae67fe2639df8684bd7bc4b83d986b8db549cf01"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
@@ -525,41 +481,11 @@ dependencies = [
|
||||
"serde_json",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tinyvec"
|
||||
version = "1.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50"
|
||||
dependencies = [
|
||||
"tinyvec_macros",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tinyvec_macros"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-bidi"
|
||||
version = "0.3.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d54675592c1dbefd78cbd98db9bacd89886e1ca50692a0692baefffdeb92dd58"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-ident"
|
||||
version = "1.0.6"
|
||||
version = "1.0.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "84a22b9f218b40614adcb3f4ff08b703773ad44fa9423e4e0d346d5db86e4ebc"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-normalization"
|
||||
version = "0.1.22"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921"
|
||||
dependencies = [
|
||||
"tinyvec",
|
||||
]
|
||||
checksum = "e5464a87b239f13a63a501f2701565754bae92d243d4bb7eb12f6d57d2269bf4"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-width"
|
||||
@@ -567,33 +493,21 @@ version = "0.1.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c0edd1e5b14653f783770bce4a4dabb4a5108a5370a5f5d8cfe8710c361f6c8b"
|
||||
|
||||
[[package]]
|
||||
name = "url"
|
||||
version = "2.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0d68c799ae75762b8c3fe375feb6600ef5602c883c5d21eb51c09f22b83c4643"
|
||||
dependencies = [
|
||||
"form_urlencoded",
|
||||
"idna",
|
||||
"percent-encoding",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "walkdir"
|
||||
version = "2.3.2"
|
||||
version = "2.3.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "808cf2735cd4b6866113f648b791c6adc5714537bc222d9347bb203386ffda56"
|
||||
checksum = "36df944cda56c7d8d8b7496af378e6b16de9284591917d307c9b4d313c44e698"
|
||||
dependencies = [
|
||||
"same-file",
|
||||
"winapi",
|
||||
"winapi-util",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen"
|
||||
version = "0.2.84"
|
||||
version = "0.2.85"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "31f8dcbc21f30d9b8f2ea926ecb58f6b91192c17e9d33594b3df58b2007ca53b"
|
||||
checksum = "5b6cb788c4e39112fbe1822277ef6fb3c55cd86b95cb3d3c4c1c9597e4ac74b4"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"wasm-bindgen-macro",
|
||||
@@ -601,9 +515,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-backend"
|
||||
version = "0.2.84"
|
||||
version = "0.2.85"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "95ce90fd5bcc06af55a641a86428ee4229e44e07033963a2290a8e241607ccb9"
|
||||
checksum = "35e522ed4105a9d626d885b35d62501b30d9666283a5c8be12c14a8bdafe7822"
|
||||
dependencies = [
|
||||
"bumpalo",
|
||||
"log",
|
||||
@@ -616,9 +530,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-macro"
|
||||
version = "0.2.84"
|
||||
version = "0.2.85"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4c21f77c0bedc37fd5dc21f897894a5ca01e7bb159884559461862ae90c0b4c5"
|
||||
checksum = "358a79a0cb89d21db8120cbfb91392335913e4890665b1a7981d9e956903b434"
|
||||
dependencies = [
|
||||
"quote",
|
||||
"wasm-bindgen-macro-support",
|
||||
@@ -626,9 +540,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-macro-support"
|
||||
version = "0.2.84"
|
||||
version = "0.2.85"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2aff81306fcac3c7515ad4e177f521b5c9a15f2b08f4e32d823066102f35a5f6"
|
||||
checksum = "4783ce29f09b9d93134d41297aded3a712b7b979e9c6f28c32cb88c973a94869"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
@@ -639,37 +553,37 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-shared"
|
||||
version = "0.2.84"
|
||||
version = "0.2.85"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0046fef7e28c3804e5e38bfa31ea2a0f73905319b677e57ebe37e49358989b5d"
|
||||
checksum = "a901d592cafaa4d711bc324edfaff879ac700b19c3dfd60058d2b445be2691eb"
|
||||
|
||||
[[package]]
|
||||
name = "wasm-encoder"
|
||||
version = "0.25.0"
|
||||
version = "0.29.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4eff853c4f09eec94d76af527eddad4e9de13b11d6286a1ef7134bc30135a2b7"
|
||||
checksum = "18c41dbd92eaebf3612a39be316540b8377c871cb9bde6b064af962984912881"
|
||||
dependencies = [
|
||||
"leb128",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasmparser"
|
||||
version = "0.102.0"
|
||||
version = "0.107.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"criterion",
|
||||
"indexmap",
|
||||
"once_cell",
|
||||
"rayon",
|
||||
"url",
|
||||
"semver",
|
||||
"wasm-encoder",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "web-sys"
|
||||
version = "0.3.61"
|
||||
version = "0.3.62"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e33b99f4b23ba3eec1a53ac264e35a755f00e966e0065077d6027c0f575b0b97"
|
||||
checksum = "16b5f940c7edfdc6d12126d98c9ef4d1b3d470011c47c76a6581df47ad9ba721"
|
||||
dependencies = [
|
||||
"js-sys",
|
||||
"wasm-bindgen",
|
||||
|
||||
8
third_party/rust/wasmparser/Cargo.toml
vendored
8
third_party/rust/wasmparser/Cargo.toml
vendored
@@ -12,7 +12,7 @@
|
||||
[package]
|
||||
edition = "2021"
|
||||
name = "wasmparser"
|
||||
version = "0.102.0"
|
||||
version = "0.107.0"
|
||||
authors = ["Yury Delendik <ydelendik@mozilla.com>"]
|
||||
exclude = ["benches/*.wasm"]
|
||||
description = """
|
||||
@@ -35,8 +35,8 @@ harness = false
|
||||
[dependencies.indexmap]
|
||||
version = "1.9.1"
|
||||
|
||||
[dependencies.url]
|
||||
version = "2.0.0"
|
||||
[dependencies.semver]
|
||||
version = "1.0.0"
|
||||
|
||||
[dev-dependencies.anyhow]
|
||||
version = "1.0.58"
|
||||
@@ -51,4 +51,4 @@ version = "1.13.0"
|
||||
version = "1.3"
|
||||
|
||||
[dev-dependencies.wasm-encoder]
|
||||
version = "0.25.0"
|
||||
version = "0.29.0"
|
||||
|
||||
@@ -256,6 +256,7 @@ fn define_benchmarks(c: &mut Criterion) {
|
||||
sign_extension: true,
|
||||
function_references: true,
|
||||
memory_control: true,
|
||||
gc: true,
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
26
third_party/rust/wasmparser/src/binary_reader.rs
vendored
26
third_party/rust/wasmparser/src/binary_reader.rs
vendored
@@ -21,7 +21,7 @@ use std::marker;
|
||||
use std::ops::Range;
|
||||
use std::str;
|
||||
|
||||
const WASM_MAGIC_NUMBER: &[u8; 4] = b"\0asm";
|
||||
pub(crate) const WASM_MAGIC_NUMBER: &[u8; 4] = b"\0asm";
|
||||
|
||||
/// A binary reader for WebAssembly modules.
|
||||
#[derive(Debug, Clone)]
|
||||
@@ -92,6 +92,11 @@ impl BinaryReaderError {
|
||||
pub fn offset(&self) -> usize {
|
||||
self.inner.offset
|
||||
}
|
||||
|
||||
pub(crate) fn add_context(&mut self, mut context: String) {
|
||||
context.push_str("\n");
|
||||
self.inner.message.insert_str(0, &context);
|
||||
}
|
||||
}
|
||||
|
||||
/// A binary reader of the WebAssembly structures and types.
|
||||
@@ -977,6 +982,7 @@ impl<'a> BinaryReader<'a> {
|
||||
0xd4 => visitor.visit_br_on_null(self.read_var_u32()?),
|
||||
0xd6 => visitor.visit_br_on_non_null(self.read_var_u32()?),
|
||||
|
||||
0xfb => self.visit_0xfb_operator(pos, visitor)?,
|
||||
0xfc => self.visit_0xfc_operator(pos, visitor)?,
|
||||
0xfd => self.visit_0xfd_operator(pos, visitor)?,
|
||||
0xfe => self.visit_0xfe_operator(pos, visitor)?,
|
||||
@@ -985,6 +991,24 @@ impl<'a> BinaryReader<'a> {
|
||||
})
|
||||
}
|
||||
|
||||
fn visit_0xfb_operator<T>(
|
||||
&mut self,
|
||||
pos: usize,
|
||||
visitor: &mut T,
|
||||
) -> Result<<T as VisitOperator<'a>>::Output>
|
||||
where
|
||||
T: VisitOperator<'a>,
|
||||
{
|
||||
let code = self.read_var_u32()?;
|
||||
Ok(match code {
|
||||
0x20 => visitor.visit_i31_new(),
|
||||
0x21 => visitor.visit_i31_get_s(),
|
||||
0x22 => visitor.visit_i31_get_u(),
|
||||
|
||||
_ => bail!(pos, "unknown 0xfb subopcode: 0x{code:x}"),
|
||||
})
|
||||
}
|
||||
|
||||
fn visit_0xfc_operator<T>(
|
||||
&mut self,
|
||||
pos: usize,
|
||||
|
||||
15
third_party/rust/wasmparser/src/lib.rs
vendored
15
third_party/rust/wasmparser/src/lib.rs
vendored
@@ -49,6 +49,7 @@
|
||||
/// - `@threads`: [Wasm `threads` proposal]
|
||||
/// - `@simd`: [Wasm `simd` proposal]
|
||||
/// - `@relaxed_simd`: [Wasm `relaxed-simd` proposal]
|
||||
/// - `@gc`: [Wasm `gc` proposal]
|
||||
///
|
||||
/// [Wasm `expection-handling` proposal]:
|
||||
/// https://github.com/WebAssembly/exception-handling
|
||||
@@ -77,6 +78,9 @@
|
||||
/// [Wasm `relaxed-simd` proposal]:
|
||||
/// https://github.com/WebAssembly/relaxed-simd
|
||||
///
|
||||
/// [Wasm `gc` proposal]:
|
||||
/// https://github.com/WebAssembly/gc
|
||||
///
|
||||
/// ```
|
||||
/// macro_rules! define_visit_operator {
|
||||
/// // The outer layer of repetition represents how all operators are
|
||||
@@ -306,6 +310,13 @@ macro_rules! for_each_operator {
|
||||
@sign_extension I64Extend16S => visit_i64_extend16_s
|
||||
@sign_extension I64Extend32S => visit_i64_extend32_s
|
||||
|
||||
// 0xFB prefixed operators
|
||||
// Garbage Collection
|
||||
// http://github.com/WebAssembly/gc
|
||||
@gc I31New => visit_i31_new
|
||||
@gc I31GetS => visit_i31_get_s
|
||||
@gc I31GetU => visit_i31_get_u
|
||||
|
||||
// 0xFC operators
|
||||
// Non-trapping Float-to-int Conversions
|
||||
// https://github.com/WebAssembly/nontrapping-float-to-int-conversions
|
||||
@@ -679,8 +690,8 @@ macro_rules! for_each_operator {
|
||||
@relaxed_simd I32x4RelaxedDotI8x16I7x16AddS => visit_i32x4_relaxed_dot_i8x16_i7x16_add_s
|
||||
|
||||
// Typed Function references
|
||||
@function_references CallRef { hty: $crate::HeapType } => visit_call_ref
|
||||
@function_references ReturnCallRef { hty: $crate::HeapType } => visit_return_call_ref
|
||||
@function_references CallRef { type_index: u32 } => visit_call_ref
|
||||
@function_references ReturnCallRef { type_index: u32 } => visit_return_call_ref
|
||||
@function_references RefAsNonNull => visit_ref_as_non_null
|
||||
@function_references BrOnNull { relative_depth: u32 } => visit_br_on_null
|
||||
@function_references BrOnNonNull { relative_depth: u32 } => visit_br_on_non_null
|
||||
|
||||
4
third_party/rust/wasmparser/src/limits.rs
vendored
4
third_party/rust/wasmparser/src/limits.rs
vendored
@@ -46,9 +46,9 @@ pub const MAX_WASM_TUPLE_TYPES: usize = 1000;
|
||||
pub const MAX_WASM_FLAG_NAMES: usize = 1000;
|
||||
pub const MAX_WASM_ENUM_CASES: usize = 1000;
|
||||
pub const MAX_WASM_UNION_TYPES: usize = 1000;
|
||||
pub const MAX_WASM_INSTANTIATION_EXPORTS: usize = 1000;
|
||||
pub const MAX_WASM_INSTANTIATION_EXPORTS: usize = 100_000;
|
||||
pub const MAX_WASM_CANONICAL_OPTIONS: usize = 10;
|
||||
pub const MAX_WASM_INSTANTIATION_ARGS: usize = 1000;
|
||||
pub const MAX_WASM_INSTANTIATION_ARGS: usize = 100_000;
|
||||
pub const MAX_WASM_START_ARGS: usize = 1000;
|
||||
pub const MAX_WASM_TYPE_SIZE: u32 = 1_000_000;
|
||||
pub const MAX_WASM_MODULES: usize = 1_000;
|
||||
|
||||
53
third_party/rust/wasmparser/src/parser.rs
vendored
53
third_party/rust/wasmparser/src/parser.rs
vendored
@@ -1,3 +1,4 @@
|
||||
use crate::binary_reader::WASM_MAGIC_NUMBER;
|
||||
use crate::CoreTypeSectionReader;
|
||||
use crate::{
|
||||
limits::MAX_WASM_MODULE_SIZE, BinaryReader, BinaryReaderError, ComponentCanonicalSectionReader,
|
||||
@@ -18,9 +19,14 @@ pub(crate) const WASM_MODULE_VERSION: u16 = 0x1;
|
||||
// the component model is stabilized this will become 0x1. The changes here are:
|
||||
//
|
||||
// * [????-??-??] 0xa - original version
|
||||
// * [2022-01-05] 0xb - `export` introduces an alias
|
||||
// * [2022-02-06] 0xc - `export` has an optional type ascribed to it
|
||||
pub(crate) const WASM_COMPONENT_VERSION: u16 = 0xc;
|
||||
// * [2023-01-05] 0xb - `export` introduces an alias
|
||||
// * [2023-02-06] 0xc - `export` has an optional type ascribed to it
|
||||
// * [2023-05-10] 0xd - imports/exports drop URLs, new discriminator byte which
|
||||
// allows for `(import (interface "...") ...)` syntax.
|
||||
pub(crate) const WASM_COMPONENT_VERSION: u16 = 0xd;
|
||||
|
||||
const KIND_MODULE: u16 = 0x00;
|
||||
const KIND_COMPONENT: u16 = 0x01;
|
||||
|
||||
/// The supported encoding formats for the parser.
|
||||
#[derive(Debug, Clone, Copy, Eq, PartialEq)]
|
||||
@@ -332,6 +338,42 @@ impl Parser {
|
||||
}
|
||||
}
|
||||
|
||||
/// Tests whether `bytes` looks like a core WebAssembly module.
|
||||
///
|
||||
/// This will inspect the first 8 bytes of `bytes` and return `true` if it
|
||||
/// starts with the standard core WebAssembly header.
|
||||
pub fn is_core_wasm(bytes: &[u8]) -> bool {
|
||||
const HEADER: [u8; 8] = [
|
||||
WASM_MAGIC_NUMBER[0],
|
||||
WASM_MAGIC_NUMBER[1],
|
||||
WASM_MAGIC_NUMBER[2],
|
||||
WASM_MAGIC_NUMBER[3],
|
||||
WASM_MODULE_VERSION.to_le_bytes()[0],
|
||||
WASM_MODULE_VERSION.to_le_bytes()[1],
|
||||
KIND_MODULE.to_le_bytes()[0],
|
||||
KIND_MODULE.to_le_bytes()[1],
|
||||
];
|
||||
bytes.starts_with(&HEADER)
|
||||
}
|
||||
|
||||
/// Tests whether `bytes` looks like a WebAssembly component.
|
||||
///
|
||||
/// This will inspect the first 8 bytes of `bytes` and return `true` if it
|
||||
/// starts with the standard WebAssembly component header.
|
||||
pub fn is_component(bytes: &[u8]) -> bool {
|
||||
const HEADER: [u8; 8] = [
|
||||
WASM_MAGIC_NUMBER[0],
|
||||
WASM_MAGIC_NUMBER[1],
|
||||
WASM_MAGIC_NUMBER[2],
|
||||
WASM_MAGIC_NUMBER[3],
|
||||
WASM_COMPONENT_VERSION.to_le_bytes()[0],
|
||||
WASM_COMPONENT_VERSION.to_le_bytes()[1],
|
||||
KIND_COMPONENT.to_le_bytes()[0],
|
||||
KIND_COMPONENT.to_le_bytes()[1],
|
||||
];
|
||||
bytes.starts_with(&HEADER)
|
||||
}
|
||||
|
||||
/// Attempts to parse a chunk of data.
|
||||
///
|
||||
/// This method will attempt to parse the next incremental portion of a
|
||||
@@ -520,9 +562,6 @@ impl Parser {
|
||||
|
||||
match self.state {
|
||||
State::Header => {
|
||||
const KIND_MODULE: u16 = 0x00;
|
||||
const KIND_COMPONENT: u16 = 0x01;
|
||||
|
||||
let start = reader.original_position();
|
||||
let header_version = reader.read_header_version()?;
|
||||
self.encoding = match (header_version >> 16) as u16 {
|
||||
@@ -1167,7 +1206,7 @@ mod tests {
|
||||
fn parser_after_component_header() -> Parser {
|
||||
let mut p = Parser::default();
|
||||
assert_matches!(
|
||||
p.parse(b"\0asm\x0c\0\x01\0", false),
|
||||
p.parse(b"\0asm\x0d\0\x01\0", false),
|
||||
Ok(Chunk::Parsed {
|
||||
consumed: 8,
|
||||
payload: Payload::Version {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
use crate::limits::MAX_WASM_CANONICAL_OPTIONS;
|
||||
use crate::{BinaryReader, FromReader, Result, SectionLimited};
|
||||
use crate::{BinaryReader, ComponentValType, FromReader, Result, SectionLimited};
|
||||
|
||||
/// Represents options for component functions.
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
@@ -43,6 +43,23 @@ pub enum CanonicalFunction {
|
||||
/// The canonical options for the function.
|
||||
options: Box<[CanonicalOption]>,
|
||||
},
|
||||
/// A function which creates a new owned handle to a resource.
|
||||
ResourceNew {
|
||||
/// The type index of the resource that's being created.
|
||||
resource: u32,
|
||||
},
|
||||
/// 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,
|
||||
},
|
||||
/// A function which returns the underlying i32-based representation of the
|
||||
/// specified resource.
|
||||
ResourceRep {
|
||||
/// The type index of the resource that's being accessed.
|
||||
resource: u32,
|
||||
},
|
||||
}
|
||||
|
||||
/// A reader for the canonical section of a WebAssembly component.
|
||||
@@ -75,6 +92,13 @@ impl<'a> FromReader<'a> for CanonicalFunction {
|
||||
},
|
||||
x => return reader.invalid_leading_byte(x, "canonical function lower"),
|
||||
},
|
||||
0x02 => CanonicalFunction::ResourceNew {
|
||||
resource: reader.read()?,
|
||||
},
|
||||
0x03 => CanonicalFunction::ResourceDrop { ty: reader.read()? },
|
||||
0x04 => CanonicalFunction::ResourceRep {
|
||||
resource: reader.read()?,
|
||||
},
|
||||
x => return reader.invalid_leading_byte(x, "canonical function"),
|
||||
})
|
||||
}
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
use crate::{BinaryReader, ComponentTypeRef, FromReader, Result, SectionLimited};
|
||||
use crate::{
|
||||
BinaryReader, ComponentExternName, ComponentTypeRef, FromReader, Result, SectionLimited,
|
||||
};
|
||||
|
||||
/// Represents the kind of an external items of a WebAssembly component.
|
||||
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
|
||||
@@ -48,15 +50,26 @@ impl ComponentExternalKind {
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/// Returns a simple string description of this kind.
|
||||
pub fn desc(&self) -> &'static str {
|
||||
use ComponentExternalKind::*;
|
||||
match self {
|
||||
Module => "module",
|
||||
Func => "func",
|
||||
Value => "value",
|
||||
Type => "type",
|
||||
Instance => "instance",
|
||||
Component => "component",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Represents an export in a WebAssembly component.
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct ComponentExport<'a> {
|
||||
/// The name of the exported item.
|
||||
pub name: &'a str,
|
||||
/// The optional URL of the exported item.
|
||||
pub url: &'a str,
|
||||
pub name: ComponentExternName<'a>,
|
||||
/// The kind of the export.
|
||||
pub kind: ComponentExternalKind,
|
||||
/// The index of the exported item.
|
||||
@@ -72,7 +85,6 @@ impl<'a> FromReader<'a> for ComponentExport<'a> {
|
||||
fn from_reader(reader: &mut BinaryReader<'a>) -> Result<Self> {
|
||||
Ok(ComponentExport {
|
||||
name: reader.read()?,
|
||||
url: reader.read()?,
|
||||
kind: reader.read()?,
|
||||
index: reader.read()?,
|
||||
ty: match reader.read_u8()? {
|
||||
|
||||
@@ -6,13 +6,16 @@ use crate::{
|
||||
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
|
||||
pub enum TypeBounds {
|
||||
/// The type is bounded by equality.
|
||||
Eq,
|
||||
Eq(u32),
|
||||
/// A fresh resource type,
|
||||
SubResource,
|
||||
}
|
||||
|
||||
impl<'a> FromReader<'a> for TypeBounds {
|
||||
fn from_reader(reader: &mut BinaryReader<'a>) -> Result<Self> {
|
||||
Ok(match reader.read_u8()? {
|
||||
0x00 => TypeBounds::Eq,
|
||||
0x00 => TypeBounds::Eq(reader.read()?),
|
||||
0x01 => TypeBounds::SubResource,
|
||||
x => return reader.invalid_leading_byte(x, "type bound"),
|
||||
})
|
||||
}
|
||||
@@ -34,7 +37,7 @@ pub enum ComponentTypeRef {
|
||||
/// The reference is to a bounded type.
|
||||
///
|
||||
/// The index is expected to be a type index.
|
||||
Type(TypeBounds, u32),
|
||||
Type(TypeBounds),
|
||||
/// The reference is to an instance type.
|
||||
///
|
||||
/// The index is a type index to an instance type.
|
||||
@@ -65,7 +68,7 @@ impl<'a> FromReader<'a> for ComponentTypeRef {
|
||||
ComponentExternalKind::Module => ComponentTypeRef::Module(reader.read()?),
|
||||
ComponentExternalKind::Func => ComponentTypeRef::Func(reader.read()?),
|
||||
ComponentExternalKind::Value => ComponentTypeRef::Value(reader.read()?),
|
||||
ComponentExternalKind::Type => ComponentTypeRef::Type(reader.read()?, reader.read()?),
|
||||
ComponentExternalKind::Type => ComponentTypeRef::Type(reader.read()?),
|
||||
ComponentExternalKind::Instance => ComponentTypeRef::Instance(reader.read()?),
|
||||
ComponentExternalKind::Component => ComponentTypeRef::Component(reader.read()?),
|
||||
})
|
||||
@@ -76,9 +79,7 @@ impl<'a> FromReader<'a> for ComponentTypeRef {
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
pub struct ComponentImport<'a> {
|
||||
/// The name of the imported item.
|
||||
pub name: &'a str,
|
||||
/// The optional URL of the imported item.
|
||||
pub url: &'a str,
|
||||
pub name: ComponentExternName<'a>,
|
||||
/// The type reference for the import.
|
||||
pub ty: ComponentTypeRef,
|
||||
}
|
||||
@@ -87,7 +88,6 @@ impl<'a> FromReader<'a> for ComponentImport<'a> {
|
||||
fn from_reader(reader: &mut BinaryReader<'a>) -> Result<Self> {
|
||||
Ok(ComponentImport {
|
||||
name: reader.read()?,
|
||||
url: reader.read()?,
|
||||
ty: reader.read()?,
|
||||
})
|
||||
}
|
||||
@@ -99,7 +99,7 @@ impl<'a> FromReader<'a> for ComponentImport<'a> {
|
||||
///
|
||||
/// ```
|
||||
/// use wasmparser::ComponentImportSectionReader;
|
||||
/// let data: &[u8] = &[0x01, 0x01, 0x41, 0x00, 0x01, 0x66];
|
||||
/// let data: &[u8] = &[0x01, 0x00, 0x01, 0x41, 0x01, 0x66];
|
||||
/// let reader = ComponentImportSectionReader::new(data, 0).unwrap();
|
||||
/// for import in reader {
|
||||
/// let import = import.expect("import");
|
||||
@@ -107,3 +107,31 @@ impl<'a> FromReader<'a> for ComponentImport<'a> {
|
||||
/// }
|
||||
/// ```
|
||||
pub type ComponentImportSectionReader<'a> = SectionLimited<'a, ComponentImport<'a>>;
|
||||
|
||||
/// Represents the name of a component import.
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
#[allow(missing_docs)]
|
||||
pub enum ComponentExternName<'a> {
|
||||
Kebab(&'a str),
|
||||
Interface(&'a str),
|
||||
}
|
||||
|
||||
impl<'a> ComponentExternName<'a> {
|
||||
/// Returns the underlying string representing this name.
|
||||
pub fn as_str(&self) -> &'a str {
|
||||
match self {
|
||||
ComponentExternName::Kebab(name) => name,
|
||||
ComponentExternName::Interface(name) => name,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> FromReader<'a> for ComponentExternName<'a> {
|
||||
fn from_reader(reader: &mut BinaryReader<'a>) -> Result<Self> {
|
||||
Ok(match reader.read_u8()? {
|
||||
0x00 => ComponentExternName::Kebab(reader.read()?),
|
||||
0x01 => ComponentExternName::Interface(reader.read()?),
|
||||
x => return reader.invalid_leading_byte(x, "import name"),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -141,7 +141,6 @@ impl<'a> FromReader<'a> for ComponentInstance<'a> {
|
||||
.map(|_| {
|
||||
Ok(ComponentExport {
|
||||
name: reader.read()?,
|
||||
url: "",
|
||||
kind: reader.read()?,
|
||||
index: reader.read()?,
|
||||
ty: None,
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
use crate::limits::*;
|
||||
use crate::{
|
||||
BinaryReader, ComponentAlias, ComponentImport, ComponentTypeRef, FromReader, FuncType, Import,
|
||||
Result, SectionLimited, Type, TypeRef,
|
||||
BinaryReader, ComponentAlias, ComponentExternName, ComponentImport, ComponentTypeRef,
|
||||
FromReader, FuncType, Import, Result, SectionLimited, Type, TypeRef, ValType,
|
||||
};
|
||||
use std::fmt;
|
||||
|
||||
/// Represents the kind of an outer core alias in a WebAssembly component.
|
||||
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
|
||||
@@ -201,6 +202,28 @@ impl PrimitiveValType {
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for PrimitiveValType {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
use PrimitiveValType::*;
|
||||
let s = match self {
|
||||
Bool => "bool",
|
||||
S8 => "s8",
|
||||
U8 => "u8",
|
||||
S16 => "s16",
|
||||
U16 => "u16",
|
||||
S32 => "s32",
|
||||
U32 => "u32",
|
||||
S64 => "s64",
|
||||
U64 => "u64",
|
||||
Float32 => "float32",
|
||||
Float64 => "float64",
|
||||
Char => "char",
|
||||
String => "string",
|
||||
};
|
||||
s.fmt(f)
|
||||
}
|
||||
}
|
||||
|
||||
/// Represents a type in a WebAssembly component.
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum ComponentType<'a> {
|
||||
@@ -212,11 +235,27 @@ pub enum ComponentType<'a> {
|
||||
Component(Box<[ComponentTypeDeclaration<'a>]>),
|
||||
/// The type is an instance type.
|
||||
Instance(Box<[InstanceTypeDeclaration<'a>]>),
|
||||
/// The type is a fresh new resource type.
|
||||
Resource {
|
||||
/// The representation of this resource type in core WebAssembly.
|
||||
rep: ValType,
|
||||
/// An optionally-specified destructor to use for when this resource is
|
||||
/// no longer needed.
|
||||
dtor: Option<u32>,
|
||||
},
|
||||
}
|
||||
|
||||
impl<'a> FromReader<'a> for ComponentType<'a> {
|
||||
fn from_reader(reader: &mut BinaryReader<'a>) -> Result<Self> {
|
||||
Ok(match reader.read_u8()? {
|
||||
0x3f => ComponentType::Resource {
|
||||
rep: reader.read()?,
|
||||
dtor: match reader.read_u8()? {
|
||||
0x00 => None,
|
||||
0x01 => Some(reader.read()?),
|
||||
b => return reader.invalid_leading_byte(b, "resource destructor"),
|
||||
},
|
||||
},
|
||||
0x40 => {
|
||||
let params = reader
|
||||
.read_iter(MAX_WASM_FUNCTION_PARAMS, "component function parameters")?
|
||||
@@ -257,9 +296,7 @@ pub enum ComponentTypeDeclaration<'a> {
|
||||
/// The component type declaration is for an export.
|
||||
Export {
|
||||
/// The name of the export.
|
||||
name: &'a str,
|
||||
/// The optional URL of the export.
|
||||
url: &'a str,
|
||||
name: ComponentExternName<'a>,
|
||||
/// The type reference for the export.
|
||||
ty: ComponentTypeRef,
|
||||
},
|
||||
@@ -281,8 +318,8 @@ impl<'a> FromReader<'a> for ComponentTypeDeclaration<'a> {
|
||||
InstanceTypeDeclaration::CoreType(t) => ComponentTypeDeclaration::CoreType(t),
|
||||
InstanceTypeDeclaration::Type(t) => ComponentTypeDeclaration::Type(t),
|
||||
InstanceTypeDeclaration::Alias(a) => ComponentTypeDeclaration::Alias(a),
|
||||
InstanceTypeDeclaration::Export { name, url, ty } => {
|
||||
ComponentTypeDeclaration::Export { name, url, ty }
|
||||
InstanceTypeDeclaration::Export { name, ty } => {
|
||||
ComponentTypeDeclaration::Export { name, ty }
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -300,9 +337,7 @@ pub enum InstanceTypeDeclaration<'a> {
|
||||
/// The instance type declaration is for an export.
|
||||
Export {
|
||||
/// The name of the export.
|
||||
name: &'a str,
|
||||
/// The URL for the export.
|
||||
url: &'a str,
|
||||
name: ComponentExternName<'a>,
|
||||
/// The type reference for the export.
|
||||
ty: ComponentTypeRef,
|
||||
},
|
||||
@@ -316,7 +351,6 @@ impl<'a> FromReader<'a> for InstanceTypeDeclaration<'a> {
|
||||
0x02 => InstanceTypeDeclaration::Alias(reader.read()?),
|
||||
0x04 => InstanceTypeDeclaration::Export {
|
||||
name: reader.read()?,
|
||||
url: reader.read()?,
|
||||
ty: reader.read()?,
|
||||
},
|
||||
x => return reader.invalid_leading_byte(x, "component or instance type declaration"),
|
||||
@@ -447,6 +481,10 @@ pub enum ComponentDefinedType<'a> {
|
||||
/// The type returned for failure.
|
||||
err: Option<ComponentValType>,
|
||||
},
|
||||
/// An owned handle to a resource.
|
||||
Own(u32),
|
||||
/// A borrowed handle to a resource.
|
||||
Borrow(u32),
|
||||
}
|
||||
|
||||
impl<'a> ComponentDefinedType<'a> {
|
||||
@@ -488,6 +526,8 @@ impl<'a> ComponentDefinedType<'a> {
|
||||
ok: reader.read()?,
|
||||
err: reader.read()?,
|
||||
},
|
||||
0x69 => ComponentDefinedType::Own(reader.read()?),
|
||||
0x68 => ComponentDefinedType::Borrow(reader.read()?),
|
||||
x => return reader.invalid_leading_byte(x, "component defined type"),
|
||||
})
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
mod code;
|
||||
mod coredumps;
|
||||
mod custom;
|
||||
mod data;
|
||||
mod elements;
|
||||
@@ -16,6 +17,7 @@ mod tags;
|
||||
mod types;
|
||||
|
||||
pub use self::code::*;
|
||||
pub use self::coredumps::*;
|
||||
pub use self::custom::*;
|
||||
pub use self::data::*;
|
||||
pub use self::elements::*;
|
||||
|
||||
243
third_party/rust/wasmparser/src/readers/core/coredumps.rs
vendored
Normal file
243
third_party/rust/wasmparser/src/readers/core/coredumps.rs
vendored
Normal file
@@ -0,0 +1,243 @@
|
||||
use crate::{BinaryReader, FromReader, Result};
|
||||
|
||||
/// The data portion of a custom section representing a core dump. Per the
|
||||
/// tool-conventions repo, this section just specifies the executable name that
|
||||
/// the core dump came from while the rest of the core dump information is
|
||||
/// contained in a corestack custom section
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use wasmparser::{ BinaryReader, CoreDumpSection, FromReader, Result };
|
||||
/// let data: &[u8] = &[0x00, 0x09, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x77, 0x61,
|
||||
/// 0x73, 0x6d];
|
||||
/// let mut reader = BinaryReader::new(data);
|
||||
/// let core = CoreDumpSection::from_reader(&mut reader).unwrap();
|
||||
/// assert!(core.name == "test.wasm")
|
||||
/// ```
|
||||
pub struct CoreDumpSection<'a> {
|
||||
/// The name of the process that created the core dump
|
||||
pub name: &'a str,
|
||||
}
|
||||
|
||||
impl<'a> FromReader<'a> for CoreDumpSection<'a> {
|
||||
fn from_reader(reader: &mut BinaryReader<'a>) -> Result<Self> {
|
||||
let pos = reader.original_position();
|
||||
if reader.read_u8()? != 0 {
|
||||
bail!(pos, "invalid start byte for core dump name");
|
||||
}
|
||||
let name = reader.read_string()?;
|
||||
Ok(CoreDumpSection { name })
|
||||
}
|
||||
}
|
||||
|
||||
/// The data portion of a "coremodules" custom section. This contains a vec of
|
||||
/// module names that will be referenced by index by other coredump sections.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```
|
||||
/// use wasmparser::{ BinaryReader, CoreDumpModulesSection, FromReader, Result };
|
||||
/// let data: &[u8] = &[0x01, 0x00, 0x04, 0x74, 0x65, 0x73, 0x74];
|
||||
/// let mut reader = BinaryReader::new(data);
|
||||
/// let modules_section = CoreDumpModulesSection::from_reader(&mut reader).unwrap();
|
||||
/// assert!(modules_section.modules[0] == "test")
|
||||
/// ```
|
||||
#[derive(Debug)]
|
||||
pub struct CoreDumpModulesSection<'a> {
|
||||
/// A list of module names, which may be URLs, file paths, or other
|
||||
/// identifiers for the module.
|
||||
pub modules: Vec<&'a str>,
|
||||
}
|
||||
|
||||
impl<'a> FromReader<'a> for CoreDumpModulesSection<'a> {
|
||||
fn from_reader(reader: &mut BinaryReader<'a>) -> Result<Self> {
|
||||
let pos = reader.original_position();
|
||||
let mut modules = vec![];
|
||||
for _ in 0..reader.read_var_u32()? {
|
||||
if reader.read_u8()? != 0 {
|
||||
bail!(pos, "invalid start byte for coremodule");
|
||||
}
|
||||
modules.push(reader.read_string()?);
|
||||
}
|
||||
Ok(CoreDumpModulesSection { modules })
|
||||
}
|
||||
}
|
||||
/// A custom section representing the instances involved in a given coredump
|
||||
pub struct CoreDumpInstancesSection {
|
||||
/// The instances for the coredump
|
||||
pub instances: Vec<CoreDumpInstance>,
|
||||
}
|
||||
|
||||
impl<'a> FromReader<'a> for CoreDumpInstancesSection {
|
||||
fn from_reader(reader: &mut BinaryReader<'a>) -> Result<Self> {
|
||||
let mut instances = vec![];
|
||||
for _ in 0..reader.read_var_u32()? {
|
||||
instances.push(CoreDumpInstance::from_reader(reader)?);
|
||||
}
|
||||
Ok(CoreDumpInstancesSection { instances })
|
||||
}
|
||||
}
|
||||
|
||||
/// A single instance from a coredump instances section
|
||||
pub struct CoreDumpInstance {
|
||||
/// The module that this is an instance of, as an index into a "coremodules"
|
||||
/// section.
|
||||
pub module_index: u32,
|
||||
|
||||
/// Which of the coredump's memories are this instance's memories, via
|
||||
/// indexing into the memory index space.
|
||||
pub memories: Vec<u32>,
|
||||
|
||||
/// Which of the coredump's globals are this instance's globals, via
|
||||
/// indexing into the global index space.
|
||||
pub globals: Vec<u32>,
|
||||
}
|
||||
|
||||
impl<'a> FromReader<'a> for CoreDumpInstance {
|
||||
fn from_reader(reader: &mut BinaryReader<'a>) -> Result<Self> {
|
||||
let pos = reader.original_position();
|
||||
if reader.read_u8()? != 0 {
|
||||
bail!(pos, "invalid start byte for core dump instance");
|
||||
}
|
||||
let module_index = reader.read_var_u32()?;
|
||||
let mut memories = vec![];
|
||||
for _ in 0..reader.read_var_u32()? {
|
||||
memories.push(reader.read_var_u32()?);
|
||||
}
|
||||
let mut globals = vec![];
|
||||
|
||||
for _ in 0..reader.read_var_u32()? {
|
||||
globals.push(reader.read_var_u32()?);
|
||||
}
|
||||
|
||||
Ok(CoreDumpInstance {
|
||||
module_index,
|
||||
memories,
|
||||
globals,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/// The data portion of a custom section representing a core dump stack. The
|
||||
/// structure of this follows the coredump spec in the tool-conventions repo
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// let data: &[u8] = &[0x00, 0x04, 0x6d, 0x61, 0x69, 0x6e, 0x01, 0x00, 0x04,
|
||||
/// 0x2a, 0x33, 0x01, 0x7f, 0x01, 0x01, 0x7f, 0x02];
|
||||
/// use wasmparser::{ BinaryReader, CoreDumpStackSection, FromReader };
|
||||
/// let mut reader = BinaryReader::new(data);
|
||||
/// let corestack = CoreDumpStackSection::from_reader(&mut reader).unwrap();
|
||||
/// assert!(corestack.name == "main");
|
||||
/// assert!(corestack.frames.len() == 1);
|
||||
/// let frame = &corestack.frames[0];
|
||||
/// assert!(frame.instanceidx == 4);
|
||||
/// assert!(frame.funcidx == 42);
|
||||
/// assert!(frame.codeoffset == 51);
|
||||
/// assert!(frame.locals.len() == 1);
|
||||
/// assert!(frame.stack.len() == 1);
|
||||
/// ```
|
||||
pub struct CoreDumpStackSection<'a> {
|
||||
/// The thread name
|
||||
pub name: &'a str,
|
||||
/// The stack frames for the core dump
|
||||
pub frames: Vec<CoreDumpStackFrame>,
|
||||
}
|
||||
|
||||
impl<'a> FromReader<'a> for CoreDumpStackSection<'a> {
|
||||
fn from_reader(reader: &mut BinaryReader<'a>) -> Result<Self> {
|
||||
let pos = reader.original_position();
|
||||
if reader.read_u8()? != 0 {
|
||||
bail!(pos, "invalid start byte for core dump stack name");
|
||||
}
|
||||
let name = reader.read_string()?;
|
||||
let mut frames = vec![];
|
||||
for _ in 0..reader.read_var_u32()? {
|
||||
frames.push(CoreDumpStackFrame::from_reader(reader)?);
|
||||
}
|
||||
Ok(CoreDumpStackSection {
|
||||
name: name,
|
||||
frames: frames,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/// A single stack frame from a core dump
|
||||
#[derive(Debug)]
|
||||
pub struct CoreDumpStackFrame {
|
||||
/// The instance that this stack frame belongs to.
|
||||
pub instanceidx: u32,
|
||||
/// The function index in the module
|
||||
pub funcidx: u32,
|
||||
/// The instruction's offset relative to the function's start
|
||||
pub codeoffset: u32,
|
||||
/// The locals for this stack frame (including function parameters)
|
||||
pub locals: Vec<CoreDumpValue>,
|
||||
/// The values on the stack
|
||||
pub stack: Vec<CoreDumpValue>,
|
||||
}
|
||||
|
||||
impl<'a> FromReader<'a> for CoreDumpStackFrame {
|
||||
fn from_reader(reader: &mut BinaryReader<'a>) -> Result<Self> {
|
||||
let pos = reader.original_position();
|
||||
if reader.read_u8()? != 0 {
|
||||
bail!(pos, "invalid start byte for core dump stack frame");
|
||||
}
|
||||
let instanceidx = reader.read_var_u32()?;
|
||||
let funcidx = reader.read_var_u32()?;
|
||||
let codeoffset = reader.read_var_u32()?;
|
||||
let mut locals = vec![];
|
||||
for _ in 0..reader.read_var_u32()? {
|
||||
locals.push(CoreDumpValue::from_reader(reader)?);
|
||||
}
|
||||
let mut stack = vec![];
|
||||
for _ in 0..reader.read_var_u32()? {
|
||||
stack.push(CoreDumpValue::from_reader(reader)?);
|
||||
}
|
||||
|
||||
Ok(CoreDumpStackFrame {
|
||||
instanceidx,
|
||||
funcidx,
|
||||
codeoffset,
|
||||
locals,
|
||||
stack,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/// Local and stack values are encoded using one byte for the type (similar to
|
||||
/// Wasm's Number Types) followed by bytes representing the actual value
|
||||
/// See the tool-conventions repo for more details.
|
||||
#[derive(Clone, Debug)]
|
||||
pub enum CoreDumpValue {
|
||||
/// A missing value (usually missing because it was optimized out)
|
||||
Missing,
|
||||
/// An i32 value
|
||||
I32(i32),
|
||||
/// An i64 value
|
||||
I64(i64),
|
||||
/// An f32 value
|
||||
F32(f32),
|
||||
/// An f64 value
|
||||
F64(f64),
|
||||
}
|
||||
|
||||
impl<'a> FromReader<'a> for CoreDumpValue {
|
||||
fn from_reader(reader: &mut BinaryReader<'a>) -> Result<Self> {
|
||||
let pos = reader.original_position();
|
||||
match reader.read_u8()? {
|
||||
0x01 => Ok(CoreDumpValue::Missing),
|
||||
0x7F => Ok(CoreDumpValue::I32(reader.read_var_i32()?)),
|
||||
0x7E => Ok(CoreDumpValue::I64(reader.read_var_i64()?)),
|
||||
0x7D => Ok(CoreDumpValue::F32(f32::from_bits(
|
||||
reader.read_f32()?.bits(),
|
||||
))),
|
||||
0x7C => Ok(CoreDumpValue::F64(f64::from_bits(
|
||||
reader.read_f64()?.bits(),
|
||||
))),
|
||||
_ => bail!(pos, "invalid CoreDumpValue type"),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -40,7 +40,7 @@ pub enum ElementKind<'a> {
|
||||
/// The element segment is active.
|
||||
Active {
|
||||
/// The index of the table being initialized.
|
||||
table_index: u32,
|
||||
table_index: Option<u32>,
|
||||
/// The initial expression of the element segment.
|
||||
offset_expr: ConstExpr<'a>,
|
||||
},
|
||||
@@ -91,9 +91,9 @@ impl<'a> FromReader<'a> for Element<'a> {
|
||||
}
|
||||
} else {
|
||||
let table_index = if flags & 0b010 == 0 {
|
||||
0
|
||||
None
|
||||
} else {
|
||||
reader.read_var_u32()?
|
||||
Some(reader.read_var_u32()?)
|
||||
};
|
||||
let offset_expr = reader.read()?;
|
||||
ElementKind::Active {
|
||||
|
||||
@@ -44,7 +44,12 @@ pub struct ProducersField<'a> {
|
||||
|
||||
impl<'a> FromReader<'a> for ProducersField<'a> {
|
||||
fn from_reader(reader: &mut BinaryReader<'a>) -> Result<Self> {
|
||||
let offset = reader.original_position();
|
||||
let name = reader.read_string()?;
|
||||
match name {
|
||||
"language" | "sdk" | "processed-by" => {}
|
||||
_ => bail!(offset, "invalid producers field name: `{name}`"),
|
||||
}
|
||||
let values = reader.skip(|reader| {
|
||||
// FIXME(#188) ideally shouldn't need to skip here
|
||||
for _ in 0..reader.read_var_u32()? {
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
|
||||
use crate::limits::{MAX_WASM_FUNCTION_PARAMS, MAX_WASM_FUNCTION_RETURNS};
|
||||
use crate::{BinaryReader, FromReader, Result, SectionLimited};
|
||||
use std::fmt::Debug;
|
||||
use std::fmt::{self, Debug, Write};
|
||||
|
||||
/// Represents the types of values in a WebAssembly module.
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
|
||||
@@ -30,37 +30,25 @@ pub enum ValType {
|
||||
F64,
|
||||
/// The value type is v128.
|
||||
V128,
|
||||
/// The value type is a reference. Which type of reference is decided by
|
||||
/// RefType. This is a change in syntax from the function references proposal,
|
||||
/// which now provides FuncRef and ExternRef as sugar for the generic ref
|
||||
/// construct.
|
||||
/// The value type is a reference.
|
||||
Ref(RefType),
|
||||
}
|
||||
|
||||
/// A reference type. When the function references feature is disabled, this
|
||||
/// only represents funcref and externref, using the following format:
|
||||
/// RefType { nullable: true, heap_type: Func | Extern })
|
||||
/// Represents storage types introduced in the GC spec for array and struct fields.
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
|
||||
#[repr(packed)]
|
||||
pub struct RefType {
|
||||
/// Whether it's nullable
|
||||
pub nullable: bool,
|
||||
/// The relevant heap type
|
||||
pub heap_type: HeapType,
|
||||
pub enum StorageType {
|
||||
/// The storage type is i8.
|
||||
I8,
|
||||
/// The storage type is i16.
|
||||
I16,
|
||||
/// The storage type is a value type.
|
||||
Val(ValType),
|
||||
}
|
||||
|
||||
impl RefType {
|
||||
/// Alias for the wasm `funcref` type.
|
||||
pub const FUNCREF: RefType = RefType {
|
||||
nullable: true,
|
||||
heap_type: HeapType::Func,
|
||||
};
|
||||
/// Alias for the wasm `externref` type.
|
||||
pub const EXTERNREF: RefType = RefType {
|
||||
nullable: true,
|
||||
heap_type: HeapType::Extern,
|
||||
};
|
||||
}
|
||||
// The size of `ValType` is performance sensitive.
|
||||
const _: () = {
|
||||
assert!(std::mem::size_of::<ValType>() == 4);
|
||||
};
|
||||
|
||||
impl From<RefType> for ValType {
|
||||
fn from(ty: RefType) -> ValType {
|
||||
@@ -68,44 +56,10 @@ impl From<RefType> for ValType {
|
||||
}
|
||||
}
|
||||
|
||||
/// Used as a performance optimization in HeapType. Call `.into()` to get the u32
|
||||
// A u16 forces 2-byte alignment, which forces HeapType to be 4 bytes,
|
||||
// which forces ValType to 5 bytes. This newtype is annotated as unaligned to
|
||||
// store the necessary bits compactly
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
|
||||
#[repr(packed)]
|
||||
pub struct PackedIndex(u16);
|
||||
|
||||
impl TryFrom<u32> for PackedIndex {
|
||||
type Error = ();
|
||||
|
||||
fn try_from(idx: u32) -> Result<PackedIndex, ()> {
|
||||
idx.try_into().map(PackedIndex).map_err(|_| ())
|
||||
}
|
||||
}
|
||||
|
||||
impl From<PackedIndex> for u32 {
|
||||
fn from(x: PackedIndex) -> u32 {
|
||||
x.0 as u32
|
||||
}
|
||||
}
|
||||
|
||||
/// A heap type from function references. When the proposal is disabled, Index
|
||||
/// is an invalid type.
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
|
||||
pub enum HeapType {
|
||||
/// Function type index
|
||||
/// Note: [PackedIndex] may need to be unpacked
|
||||
TypedFunc(PackedIndex),
|
||||
/// From reference types
|
||||
Func,
|
||||
/// From reference types
|
||||
Extern,
|
||||
}
|
||||
|
||||
impl ValType {
|
||||
/// Alias for the wasm `funcref` type.
|
||||
pub const FUNCREF: ValType = ValType::Ref(RefType::FUNCREF);
|
||||
|
||||
/// Alias for the wasm `externref` type.
|
||||
pub const EXTERNREF: ValType = ValType::Ref(RefType::EXTERNREF);
|
||||
|
||||
@@ -116,26 +70,41 @@ impl ValType {
|
||||
pub fn is_reference_type(&self) -> bool {
|
||||
matches!(self, ValType::Ref(_))
|
||||
}
|
||||
/// Whether the type is defaultable according to function references
|
||||
/// spec. This amounts to whether it's a non-nullable ref
|
||||
|
||||
/// Whether the type is defaultable, i.e. it is not a non-nullable reference
|
||||
/// type.
|
||||
pub fn is_defaultable(&self) -> bool {
|
||||
!matches!(
|
||||
self,
|
||||
ValType::Ref(RefType {
|
||||
nullable: false,
|
||||
..
|
||||
})
|
||||
)
|
||||
match *self {
|
||||
Self::I32 | Self::I64 | Self::F32 | Self::F64 | Self::V128 => true,
|
||||
Self::Ref(rt) => rt.is_nullable(),
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn is_valtype_byte(byte: u8) -> bool {
|
||||
match byte {
|
||||
0x7F | 0x7E | 0x7D | 0x7C | 0x7B | 0x70 | 0x6F | 0x6B | 0x6C => true,
|
||||
0x7F | 0x7E | 0x7D | 0x7C | 0x7B | 0x70 | 0x6F | 0x6B | 0x6C | 0x6E | 0x65 | 0x69
|
||||
| 0x68 | 0x6D | 0x67 | 0x66 | 0x6A => true,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> FromReader<'a> for StorageType {
|
||||
fn from_reader(reader: &mut BinaryReader<'a>) -> Result<Self> {
|
||||
match reader.peek()? {
|
||||
0x7A => {
|
||||
reader.position += 1;
|
||||
Ok(StorageType::I8)
|
||||
}
|
||||
0x79 => {
|
||||
reader.position += 1;
|
||||
Ok(StorageType::I16)
|
||||
}
|
||||
_ => Ok(StorageType::Val(reader.read()?)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> FromReader<'a> for ValType {
|
||||
fn from_reader(reader: &mut BinaryReader<'a>) -> Result<Self> {
|
||||
match reader.peek()? {
|
||||
@@ -159,26 +128,473 @@ impl<'a> FromReader<'a> for ValType {
|
||||
reader.position += 1;
|
||||
Ok(ValType::V128)
|
||||
}
|
||||
0x70 | 0x6F | 0x6B | 0x6C => Ok(ValType::Ref(reader.read()?)),
|
||||
0x70 | 0x6F | 0x6B | 0x6C | 0x6E | 0x65 | 0x69 | 0x68 | 0x6D | 0x67 | 0x66 | 0x6A => {
|
||||
Ok(ValType::Ref(reader.read()?))
|
||||
}
|
||||
_ => bail!(reader.original_position(), "invalid value type"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for ValType {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
let s = match self {
|
||||
ValType::I32 => "i32",
|
||||
ValType::I64 => "i64",
|
||||
ValType::F32 => "f32",
|
||||
ValType::F64 => "f64",
|
||||
ValType::V128 => "v128",
|
||||
ValType::Ref(r) => return fmt::Display::fmt(r, f),
|
||||
};
|
||||
f.write_str(s)
|
||||
}
|
||||
}
|
||||
|
||||
/// A reference type.
|
||||
///
|
||||
/// The reference types proposal first introduced `externref` and `funcref`.
|
||||
///
|
||||
/// The function references proposal introduced typed function references.
|
||||
///
|
||||
/// The GC proposal introduces heap types: any, eq, i31, struct, array, nofunc, noextern, none.
|
||||
//
|
||||
// RefType is a bit-packed enum that fits in a `u24` aka `[u8; 3]`.
|
||||
// Note that its content is opaque (and subject to change), but its API is stable.
|
||||
// It has the following internal structure:
|
||||
// ```
|
||||
// [nullable:u1] [indexed==1:u1] [kind:u2] [index:u20]
|
||||
// [nullable:u1] [indexed==0:u1] [type:u4] [(unused):u18]
|
||||
// ```
|
||||
// , where
|
||||
// - `nullable` determines nullability of the ref
|
||||
// - `indexed` determines if the ref is of a dynamically defined type with an index (encoded in a following bit-packing section) or of a known fixed type
|
||||
// - `kind` determines what kind of indexed type the index is pointing to:
|
||||
// ```
|
||||
// 10 = struct
|
||||
// 11 = array
|
||||
// 01 = function
|
||||
// ```
|
||||
// - `index` is the type index
|
||||
// - `type` is an enumeration of known types:
|
||||
// ```
|
||||
// 1111 = any
|
||||
//
|
||||
// 1101 = eq
|
||||
// 1000 = i31
|
||||
// 1001 = struct
|
||||
// 1100 = array
|
||||
//
|
||||
// 0101 = func
|
||||
// 0100 = nofunc
|
||||
//
|
||||
// 0011 = extern
|
||||
// 0010 = noextern
|
||||
//
|
||||
// 0000 = none
|
||||
// ```
|
||||
// - `(unused)` is unused sequence of bits
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Hash)]
|
||||
pub struct RefType([u8; 3]);
|
||||
|
||||
impl Debug for RefType {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
match (self.is_nullable(), self.heap_type()) {
|
||||
(true, HeapType::Any) => write!(f, "anyref"),
|
||||
(false, HeapType::Any) => write!(f, "(ref any)"),
|
||||
(true, HeapType::None) => write!(f, "nullref"),
|
||||
(false, HeapType::None) => write!(f, "(ref none)"),
|
||||
(true, HeapType::NoExtern) => write!(f, "nullexternref"),
|
||||
(false, HeapType::NoExtern) => write!(f, "(ref noextern)"),
|
||||
(true, HeapType::NoFunc) => write!(f, "nullfuncref"),
|
||||
(false, HeapType::NoFunc) => write!(f, "(ref nofunc)"),
|
||||
(true, HeapType::Eq) => write!(f, "eqref"),
|
||||
(false, HeapType::Eq) => write!(f, "(ref eq)"),
|
||||
(true, HeapType::Struct) => write!(f, "structref"),
|
||||
(false, HeapType::Struct) => write!(f, "(ref struct)"),
|
||||
(true, HeapType::Array) => write!(f, "arrayref"),
|
||||
(false, HeapType::Array) => write!(f, "(ref array)"),
|
||||
(true, HeapType::I31) => write!(f, "i31ref"),
|
||||
(false, HeapType::I31) => write!(f, "(ref i31)"),
|
||||
(true, HeapType::Extern) => write!(f, "externref"),
|
||||
(false, HeapType::Extern) => write!(f, "(ref extern)"),
|
||||
(true, HeapType::Func) => write!(f, "funcref"),
|
||||
(false, HeapType::Func) => write!(f, "(ref func)"),
|
||||
(true, HeapType::Indexed(idx)) => write!(f, "(ref null {idx})"),
|
||||
(false, HeapType::Indexed(idx)) => write!(f, "(ref {idx})"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Static assert that we can fit indices up to `MAX_WASM_TYPES` inside `RefType`.
|
||||
const _: () = {
|
||||
const fn can_roundtrip_index(index: u32) -> bool {
|
||||
assert!(RefType::can_represent_type_index(index));
|
||||
let rt = match RefType::indexed_func(true, index) {
|
||||
Some(rt) => rt,
|
||||
None => panic!(),
|
||||
};
|
||||
assert!(rt.is_nullable());
|
||||
let actual_index = match rt.type_index() {
|
||||
Some(i) => i,
|
||||
None => panic!(),
|
||||
};
|
||||
actual_index == index
|
||||
}
|
||||
|
||||
assert!(can_roundtrip_index(crate::limits::MAX_WASM_TYPES as u32));
|
||||
assert!(can_roundtrip_index(0b00000000_00001111_00000000_00000000));
|
||||
assert!(can_roundtrip_index(0b00000000_00000000_11111111_00000000));
|
||||
assert!(can_roundtrip_index(0b00000000_00000000_00000000_11111111));
|
||||
assert!(can_roundtrip_index(0));
|
||||
};
|
||||
|
||||
impl RefType {
|
||||
const NULLABLE_BIT: u32 = 1 << 23; // bit #23
|
||||
const INDEXED_BIT: u32 = 1 << 22; // bit #22
|
||||
|
||||
const TYPE_MASK: u32 = 0b1111 << 18; // 4 bits #21-#18 (if `indexed == 0`)
|
||||
const ANY_TYPE: u32 = 0b1111 << 18;
|
||||
const EQ_TYPE: u32 = 0b1101 << 18;
|
||||
const I31_TYPE: u32 = 0b1000 << 18;
|
||||
const STRUCT_TYPE: u32 = 0b1001 << 18;
|
||||
const ARRAY_TYPE: u32 = 0b1100 << 18;
|
||||
const FUNC_TYPE: u32 = 0b0101 << 18;
|
||||
const NOFUNC_TYPE: u32 = 0b0100 << 18;
|
||||
const EXTERN_TYPE: u32 = 0b0011 << 18;
|
||||
const NOEXTERN_TYPE: u32 = 0b0010 << 18;
|
||||
const NONE_TYPE: u32 = 0b0000 << 18;
|
||||
|
||||
const KIND_MASK: u32 = 0b11 << 20; // 2 bits #21-#20 (if `indexed == 1`)
|
||||
const STRUCT_KIND: u32 = 0b10 << 20;
|
||||
const ARRAY_KIND: u32 = 0b11 << 20;
|
||||
const FUNC_KIND: u32 = 0b01 << 20;
|
||||
|
||||
const INDEX_MASK: u32 = (1 << 20) - 1; // 20 bits #19-#0 (if `indexed == 1`)
|
||||
|
||||
/// A nullable untyped function reference aka `(ref null func)` aka
|
||||
/// `funcref` aka `anyfunc`.
|
||||
pub const FUNCREF: Self = RefType::FUNC.nullable();
|
||||
|
||||
/// A nullable reference to an extern object aka `(ref null extern)` aka
|
||||
/// `externref`.
|
||||
pub const EXTERNREF: Self = RefType::EXTERN.nullable();
|
||||
|
||||
/// A non-nullable untyped function reference aka `(ref func)`.
|
||||
pub const FUNC: Self = RefType::from_u32(Self::FUNC_TYPE);
|
||||
|
||||
/// A non-nullable reference to an extern object aka `(ref extern)`.
|
||||
pub const EXTERN: Self = RefType::from_u32(Self::EXTERN_TYPE);
|
||||
|
||||
/// A non-nullable reference to any object aka `(ref any)`.
|
||||
pub const ANY: Self = RefType::from_u32(Self::ANY_TYPE);
|
||||
|
||||
/// A non-nullable reference to no object aka `(ref none)`.
|
||||
pub const NONE: Self = RefType::from_u32(Self::NONE_TYPE);
|
||||
|
||||
/// A non-nullable reference to a noextern object aka `(ref noextern)`.
|
||||
pub const NOEXTERN: Self = RefType::from_u32(Self::NOEXTERN_TYPE);
|
||||
|
||||
/// A non-nullable reference to a nofunc object aka `(ref nofunc)`.
|
||||
pub const NOFUNC: Self = RefType::from_u32(Self::NOFUNC_TYPE);
|
||||
|
||||
/// A non-nullable reference to an eq object aka `(ref eq)`.
|
||||
pub const EQ: Self = RefType::from_u32(Self::EQ_TYPE);
|
||||
|
||||
/// A non-nullable reference to a struct aka `(ref struct)`.
|
||||
pub const STRUCT: Self = RefType::from_u32(Self::STRUCT_TYPE);
|
||||
|
||||
/// A non-nullable reference to an array aka `(ref array)`.
|
||||
pub const ARRAY: Self = RefType::from_u32(Self::ARRAY_TYPE);
|
||||
|
||||
/// A non-nullable reference to an i31 object aka `(ref i31)`.
|
||||
pub const I31: Self = RefType::from_u32(Self::I31_TYPE);
|
||||
|
||||
const fn can_represent_type_index(index: u32) -> bool {
|
||||
index & Self::INDEX_MASK == index
|
||||
}
|
||||
|
||||
const fn u24_to_u32(bytes: [u8; 3]) -> u32 {
|
||||
let expanded_bytes = [bytes[0], bytes[1], bytes[2], 0];
|
||||
u32::from_le_bytes(expanded_bytes)
|
||||
}
|
||||
|
||||
const fn u32_to_u24(x: u32) -> [u8; 3] {
|
||||
let bytes = x.to_le_bytes();
|
||||
debug_assert!(bytes[3] == 0);
|
||||
[bytes[0], bytes[1], bytes[2]]
|
||||
}
|
||||
|
||||
#[inline]
|
||||
const fn as_u32(&self) -> u32 {
|
||||
Self::u24_to_u32(self.0)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
const fn from_u32(x: u32) -> Self {
|
||||
debug_assert!(x & (0b11111111 << 24) == 0);
|
||||
|
||||
// if not indexed, type must be any/eq/i31/struct/array/func/extern/nofunc/noextern/none
|
||||
debug_assert!(
|
||||
x & Self::INDEXED_BIT != 0
|
||||
|| matches!(
|
||||
x & Self::TYPE_MASK,
|
||||
Self::ANY_TYPE
|
||||
| Self::EQ_TYPE
|
||||
| Self::I31_TYPE
|
||||
| Self::STRUCT_TYPE
|
||||
| Self::ARRAY_TYPE
|
||||
| Self::FUNC_TYPE
|
||||
| Self::NOFUNC_TYPE
|
||||
| Self::EXTERN_TYPE
|
||||
| Self::NOEXTERN_TYPE
|
||||
| Self::NONE_TYPE
|
||||
)
|
||||
);
|
||||
RefType(Self::u32_to_u24(x))
|
||||
}
|
||||
|
||||
/// Create a reference to a typed function with the type at the given index.
|
||||
///
|
||||
/// Returns `None` when the type index is beyond this crate's implementation
|
||||
/// limits and therefore is not representable.
|
||||
pub const fn indexed_func(nullable: bool, index: u32) -> Option<Self> {
|
||||
Self::indexed(nullable, Self::FUNC_KIND, index)
|
||||
}
|
||||
|
||||
/// Create a reference to an array with the type at the given index.
|
||||
///
|
||||
/// Returns `None` when the type index is beyond this crate's implementation
|
||||
/// limits and therefore is not representable.
|
||||
pub const fn indexed_array(nullable: bool, index: u32) -> Option<Self> {
|
||||
Self::indexed(nullable, Self::ARRAY_KIND, index)
|
||||
}
|
||||
|
||||
/// Create a reference to a struct with the type at the given index.
|
||||
///
|
||||
/// Returns `None` when the type index is beyond this crate's implementation
|
||||
/// limits and therefore is not representable.
|
||||
pub const fn indexed_struct(nullable: bool, index: u32) -> Option<Self> {
|
||||
Self::indexed(nullable, Self::STRUCT_KIND, index)
|
||||
}
|
||||
|
||||
/// Create a reference to a user defined type at the given index.
|
||||
///
|
||||
/// Returns `None` when the type index is beyond this crate's implementation
|
||||
/// limits and therefore is not representable, or when the heap type is not
|
||||
/// a typed array, struct or function.
|
||||
const fn indexed(nullable: bool, kind: u32, index: u32) -> Option<Self> {
|
||||
if Self::can_represent_type_index(index) {
|
||||
let nullable32 = Self::NULLABLE_BIT * nullable as u32;
|
||||
Some(RefType::from_u32(
|
||||
nullable32 | Self::INDEXED_BIT | kind | index,
|
||||
))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
/// Create a new `RefType`.
|
||||
///
|
||||
/// Returns `None` when the heap type's type index (if any) is beyond this
|
||||
/// crate's implementation limits and therfore is not representable.
|
||||
pub const fn new(nullable: bool, heap_type: HeapType) -> Option<Self> {
|
||||
let nullable32 = Self::NULLABLE_BIT * nullable as u32;
|
||||
match heap_type {
|
||||
HeapType::Indexed(index) => RefType::indexed(nullable, 0, index), // 0 bc we don't know the kind
|
||||
HeapType::Func => Some(Self::from_u32(nullable32 | Self::FUNC_TYPE)),
|
||||
HeapType::Extern => Some(Self::from_u32(nullable32 | Self::EXTERN_TYPE)),
|
||||
HeapType::Any => Some(Self::from_u32(nullable32 | Self::ANY_TYPE)),
|
||||
HeapType::None => Some(Self::from_u32(nullable32 | Self::NONE_TYPE)),
|
||||
HeapType::NoExtern => Some(Self::from_u32(nullable32 | Self::NOEXTERN_TYPE)),
|
||||
HeapType::NoFunc => Some(Self::from_u32(nullable32 | Self::NOFUNC_TYPE)),
|
||||
HeapType::Eq => Some(Self::from_u32(nullable32 | Self::EQ_TYPE)),
|
||||
HeapType::Struct => Some(Self::from_u32(nullable32 | Self::STRUCT_TYPE)),
|
||||
HeapType::Array => Some(Self::from_u32(nullable32 | Self::ARRAY_TYPE)),
|
||||
HeapType::I31 => Some(Self::from_u32(nullable32 | Self::I31_TYPE)),
|
||||
}
|
||||
}
|
||||
|
||||
/// Is this a reference to a typed function?
|
||||
pub const fn is_typed_func_ref(&self) -> bool {
|
||||
self.is_indexed_type_ref() && self.as_u32() & Self::KIND_MASK == Self::FUNC_KIND
|
||||
}
|
||||
|
||||
/// Is this a reference to an indexed type?
|
||||
pub const fn is_indexed_type_ref(&self) -> bool {
|
||||
self.as_u32() & Self::INDEXED_BIT != 0
|
||||
}
|
||||
|
||||
/// If this is a reference to a typed function, get its type index.
|
||||
pub const fn type_index(&self) -> Option<u32> {
|
||||
if self.is_indexed_type_ref() {
|
||||
Some(self.as_u32() & Self::INDEX_MASK)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
/// Is this an untyped function reference aka `(ref null func)` aka `funcref` aka `anyfunc`?
|
||||
pub const fn is_func_ref(&self) -> bool {
|
||||
!self.is_indexed_type_ref() && self.as_u32() & Self::TYPE_MASK == Self::FUNC_TYPE
|
||||
}
|
||||
|
||||
/// Is this a `(ref null extern)` aka `externref`?
|
||||
pub const fn is_extern_ref(&self) -> bool {
|
||||
!self.is_indexed_type_ref() && self.as_u32() & Self::TYPE_MASK == Self::EXTERN_TYPE
|
||||
}
|
||||
|
||||
/// Is this ref type nullable?
|
||||
pub const fn is_nullable(&self) -> bool {
|
||||
self.as_u32() & Self::NULLABLE_BIT != 0
|
||||
}
|
||||
|
||||
/// Get the non-nullable version of this ref type.
|
||||
pub const fn as_non_null(&self) -> Self {
|
||||
Self::from_u32(self.as_u32() & !Self::NULLABLE_BIT)
|
||||
}
|
||||
|
||||
/// Get the non-nullable version of this ref type.
|
||||
pub const fn nullable(&self) -> Self {
|
||||
Self::from_u32(self.as_u32() | Self::NULLABLE_BIT)
|
||||
}
|
||||
|
||||
/// Get the heap type that this is a reference to.
|
||||
pub fn heap_type(&self) -> HeapType {
|
||||
let s = self.as_u32();
|
||||
if self.is_indexed_type_ref() {
|
||||
HeapType::Indexed(self.type_index().unwrap())
|
||||
} else {
|
||||
match s & Self::TYPE_MASK {
|
||||
Self::FUNC_TYPE => HeapType::Func,
|
||||
Self::EXTERN_TYPE => HeapType::Extern,
|
||||
Self::ANY_TYPE => HeapType::Any,
|
||||
Self::NONE_TYPE => HeapType::None,
|
||||
Self::NOEXTERN_TYPE => HeapType::NoExtern,
|
||||
Self::NOFUNC_TYPE => HeapType::NoFunc,
|
||||
Self::EQ_TYPE => HeapType::Eq,
|
||||
Self::STRUCT_TYPE => HeapType::Struct,
|
||||
Self::ARRAY_TYPE => HeapType::Array,
|
||||
Self::I31_TYPE => HeapType::I31,
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Note that this is similar to `Display for RefType` except that it has
|
||||
// the indexes stubbed out.
|
||||
pub(crate) fn wat(&self) -> &'static str {
|
||||
match (self.is_nullable(), self.heap_type()) {
|
||||
(true, HeapType::Func) => "funcref",
|
||||
(true, HeapType::Extern) => "externref",
|
||||
(true, HeapType::Indexed(_)) => "(ref null $type)",
|
||||
(true, HeapType::Any) => "anyref",
|
||||
(true, HeapType::None) => "nullref",
|
||||
(true, HeapType::NoExtern) => "nullexternref",
|
||||
(true, HeapType::NoFunc) => "nullfuncref",
|
||||
(true, HeapType::Eq) => "eqref",
|
||||
(true, HeapType::Struct) => "structref",
|
||||
(true, HeapType::Array) => "arrayref",
|
||||
(true, HeapType::I31) => "i31ref",
|
||||
(false, HeapType::Func) => "(ref func)",
|
||||
(false, HeapType::Extern) => "(ref extern)",
|
||||
(false, HeapType::Indexed(_)) => "(ref $type)",
|
||||
(false, HeapType::Any) => "(ref any)",
|
||||
(false, HeapType::None) => "(ref none)",
|
||||
(false, HeapType::NoExtern) => "(ref noextern)",
|
||||
(false, HeapType::NoFunc) => "(ref nofunc)",
|
||||
(false, HeapType::Eq) => "(ref eq)",
|
||||
(false, HeapType::Struct) => "(ref struct)",
|
||||
(false, HeapType::Array) => "(ref array)",
|
||||
(false, HeapType::I31) => "(ref i31)",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> FromReader<'a> for RefType {
|
||||
fn from_reader(reader: &mut BinaryReader<'a>) -> Result<Self> {
|
||||
match reader.read()? {
|
||||
0x70 => Ok(RefType::FUNCREF),
|
||||
0x6F => Ok(RefType::EXTERNREF),
|
||||
byte @ (0x6B | 0x6C) => Ok(RefType {
|
||||
nullable: byte == 0x6C,
|
||||
heap_type: reader.read()?,
|
||||
}),
|
||||
0x70 => Ok(RefType::FUNC.nullable()),
|
||||
0x6F => Ok(RefType::EXTERN.nullable()),
|
||||
0x6E => Ok(RefType::ANY.nullable()),
|
||||
0x65 => Ok(RefType::NONE.nullable()),
|
||||
0x69 => Ok(RefType::NOEXTERN.nullable()),
|
||||
0x68 => Ok(RefType::NOFUNC.nullable()),
|
||||
0x6D => Ok(RefType::EQ.nullable()),
|
||||
0x67 => Ok(RefType::STRUCT.nullable()),
|
||||
0x66 => Ok(RefType::ARRAY.nullable()),
|
||||
0x6A => Ok(RefType::I31.nullable()),
|
||||
byte @ (0x6B | 0x6C) => {
|
||||
let nullable = byte == 0x6C;
|
||||
let pos = reader.original_position();
|
||||
RefType::new(nullable, reader.read()?)
|
||||
.ok_or_else(|| crate::BinaryReaderError::new("type index too large", pos))
|
||||
}
|
||||
_ => bail!(reader.original_position(), "malformed reference type"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for RefType {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
// Note that this is similar to `RefType::wat` except that it has the
|
||||
// indexes filled out.
|
||||
let s = match (self.is_nullable(), self.heap_type()) {
|
||||
(true, HeapType::Func) => "funcref",
|
||||
(true, HeapType::Extern) => "externref",
|
||||
(true, HeapType::Indexed(i)) => return write!(f, "(ref null {i})"),
|
||||
(true, HeapType::Any) => "anyref",
|
||||
(true, HeapType::None) => "nullref",
|
||||
(true, HeapType::NoExtern) => "nullexternref",
|
||||
(true, HeapType::NoFunc) => "nullfuncref",
|
||||
(true, HeapType::Eq) => "eqref",
|
||||
(true, HeapType::Struct) => "structref",
|
||||
(true, HeapType::Array) => "arrayref",
|
||||
(true, HeapType::I31) => "i31ref",
|
||||
(false, HeapType::Func) => "(ref func)",
|
||||
(false, HeapType::Extern) => "(ref extern)",
|
||||
(false, HeapType::Indexed(i)) => return write!(f, "(ref {i})"),
|
||||
(false, HeapType::Any) => "(ref any)",
|
||||
(false, HeapType::None) => "(ref none)",
|
||||
(false, HeapType::NoExtern) => "(ref noextern)",
|
||||
(false, HeapType::NoFunc) => "(ref nofunc)",
|
||||
(false, HeapType::Eq) => "(ref eq)",
|
||||
(false, HeapType::Struct) => "(ref struct)",
|
||||
(false, HeapType::Array) => "(ref array)",
|
||||
(false, HeapType::I31) => "(ref i31)",
|
||||
};
|
||||
f.write_str(s)
|
||||
}
|
||||
}
|
||||
|
||||
/// A heap type from function references. When the proposal is disabled, Index
|
||||
/// is an invalid type.
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
|
||||
pub enum HeapType {
|
||||
/// User defined type at the given index.
|
||||
Indexed(u32),
|
||||
/// Untyped (any) function.
|
||||
Func,
|
||||
/// External heap type.
|
||||
Extern,
|
||||
/// The `any` heap type. The common supertype (a.k.a. top) of all internal types.
|
||||
Any,
|
||||
/// The `none` heap type. The common subtype (a.k.a. bottom) of all internal types.
|
||||
None,
|
||||
/// The `noextern` heap type. The common subtype (a.k.a. bottom) of all external types.
|
||||
NoExtern,
|
||||
/// The `nofunc` heap type. The common subtype (a.k.a. bottom) of all function types.
|
||||
NoFunc,
|
||||
/// The `eq` heap type. The common supertype of all referenceable types on which comparison
|
||||
/// (ref.eq) is allowed.
|
||||
Eq,
|
||||
/// The `struct` heap type. The common supertype of all struct types.
|
||||
Struct,
|
||||
/// The `array` heap type. The common supertype of all array types.
|
||||
Array,
|
||||
/// The i31 heap type.
|
||||
I31,
|
||||
}
|
||||
|
||||
impl<'a> FromReader<'a> for HeapType {
|
||||
fn from_reader(reader: &mut BinaryReader<'a>) -> Result<Self> {
|
||||
match reader.peek()? {
|
||||
@@ -190,19 +606,46 @@ impl<'a> FromReader<'a> for HeapType {
|
||||
reader.position += 1;
|
||||
Ok(HeapType::Extern)
|
||||
}
|
||||
0x6E => {
|
||||
reader.position += 1;
|
||||
Ok(HeapType::Any)
|
||||
}
|
||||
0x65 => {
|
||||
reader.position += 1;
|
||||
Ok(HeapType::None)
|
||||
}
|
||||
0x69 => {
|
||||
reader.position += 1;
|
||||
Ok(HeapType::NoExtern)
|
||||
}
|
||||
0x68 => {
|
||||
reader.position += 1;
|
||||
Ok(HeapType::NoFunc)
|
||||
}
|
||||
0x6D => {
|
||||
reader.position += 1;
|
||||
Ok(HeapType::Eq)
|
||||
}
|
||||
0x67 => {
|
||||
reader.position += 1;
|
||||
Ok(HeapType::Struct)
|
||||
}
|
||||
0x66 => {
|
||||
reader.position += 1;
|
||||
Ok(HeapType::Array)
|
||||
}
|
||||
0x6A => {
|
||||
reader.position += 1;
|
||||
Ok(HeapType::I31)
|
||||
}
|
||||
_ => {
|
||||
let idx = match u32::try_from(reader.read_var_s33()?) {
|
||||
Ok(idx) => idx,
|
||||
Err(_) => {
|
||||
bail!(reader.original_position(), "invalid function heap type",);
|
||||
bail!(reader.original_position(), "invalid indexed ref heap type");
|
||||
}
|
||||
};
|
||||
match idx.try_into() {
|
||||
Ok(packed) => Ok(HeapType::TypedFunc(packed)),
|
||||
Err(_) => {
|
||||
bail!(reader.original_position(), "function index too large");
|
||||
}
|
||||
}
|
||||
Ok(HeapType::Indexed(idx))
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -213,6 +656,9 @@ impl<'a> FromReader<'a> for HeapType {
|
||||
pub enum Type {
|
||||
/// The type is for a function.
|
||||
Func(FuncType),
|
||||
/// The type is for an array.
|
||||
Array(ArrayType),
|
||||
// Struct(StructType),
|
||||
}
|
||||
|
||||
/// Represents a type of a function in a WebAssembly module.
|
||||
@@ -224,6 +670,15 @@ pub struct FuncType {
|
||||
len_params: usize,
|
||||
}
|
||||
|
||||
/// Represents a type of an array in a WebAssembly module.
|
||||
#[derive(Debug, Clone, Eq, PartialEq, Hash)]
|
||||
pub struct ArrayType {
|
||||
/// Array element type.
|
||||
pub element_type: StorageType,
|
||||
/// Are elements mutable.
|
||||
pub mutable: bool,
|
||||
}
|
||||
|
||||
impl Debug for FuncType {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
f.debug_struct("FuncType")
|
||||
@@ -273,6 +728,26 @@ impl FuncType {
|
||||
pub fn results(&self) -> &[ValType] {
|
||||
&self.params_results[self.len_params..]
|
||||
}
|
||||
|
||||
pub(crate) fn desc(&self) -> String {
|
||||
let mut s = String::new();
|
||||
s.push_str("[");
|
||||
for (i, param) in self.params().iter().enumerate() {
|
||||
if i > 0 {
|
||||
s.push_str(" ");
|
||||
}
|
||||
write!(s, "{param}").unwrap();
|
||||
}
|
||||
s.push_str("] -> [");
|
||||
for (i, result) in self.results().iter().enumerate() {
|
||||
if i > 0 {
|
||||
s.push_str(" ");
|
||||
}
|
||||
write!(s, "{result}").unwrap();
|
||||
}
|
||||
s.push_str("]");
|
||||
s
|
||||
}
|
||||
}
|
||||
|
||||
/// Represents a table's type.
|
||||
@@ -359,6 +834,7 @@ impl<'a> FromReader<'a> for Type {
|
||||
fn from_reader(reader: &mut BinaryReader<'a>) -> Result<Self> {
|
||||
Ok(match reader.read_u8()? {
|
||||
0x60 => Type::Func(reader.read()?),
|
||||
0x5e => Type::Array(reader.read()?),
|
||||
x => return reader.invalid_leading_byte(x, "type"),
|
||||
})
|
||||
}
|
||||
@@ -378,3 +854,21 @@ impl<'a> FromReader<'a> for FuncType {
|
||||
Ok(FuncType::from_raw_parts(params_results.into(), len_params))
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> FromReader<'a> for ArrayType {
|
||||
fn from_reader(reader: &mut BinaryReader<'a>) -> Result<Self> {
|
||||
let element_type = reader.read()?;
|
||||
let mutable = reader.read_u8()?;
|
||||
Ok(ArrayType {
|
||||
element_type,
|
||||
mutable: match mutable {
|
||||
0 => false,
|
||||
1 => true,
|
||||
_ => bail!(
|
||||
reader.original_position(),
|
||||
"invalid mutability byte for array type"
|
||||
),
|
||||
},
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
13
third_party/rust/wasmparser/src/resources.rs
vendored
13
third_party/rust/wasmparser/src/resources.rs
vendored
@@ -240,11 +240,14 @@ pub trait WasmModuleResources {
|
||||
// Delegate to the generic value type validation which will have the
|
||||
// same validity checks.
|
||||
self.check_value_type(
|
||||
RefType {
|
||||
nullable: true,
|
||||
heap_type,
|
||||
}
|
||||
.into(),
|
||||
RefType::new(true, heap_type)
|
||||
.ok_or_else(|| {
|
||||
BinaryReaderError::new(
|
||||
"heap type index beyond this crate's implementation limits",
|
||||
offset,
|
||||
)
|
||||
})?
|
||||
.into(),
|
||||
features,
|
||||
offset,
|
||||
)
|
||||
|
||||
143
third_party/rust/wasmparser/src/validator.rs
vendored
143
third_party/rust/wasmparser/src/validator.rs
vendored
@@ -48,6 +48,7 @@ fn test_validate() {
|
||||
mod component;
|
||||
mod core;
|
||||
mod func;
|
||||
pub mod names;
|
||||
mod operators;
|
||||
pub mod types;
|
||||
|
||||
@@ -244,6 +245,8 @@ pub struct WasmFeatures {
|
||||
pub function_references: bool,
|
||||
/// The WebAssembly memory control proposal
|
||||
pub memory_control: bool,
|
||||
/// The WebAssembly gc proposal
|
||||
pub gc: bool,
|
||||
}
|
||||
|
||||
impl WasmFeatures {
|
||||
@@ -262,22 +265,50 @@ impl WasmFeatures {
|
||||
}
|
||||
}
|
||||
ValType::Ref(r) => {
|
||||
if self.reference_types {
|
||||
if !self.function_references {
|
||||
match (r.heap_type, r.nullable) {
|
||||
(_, false) => {
|
||||
Err("function references required for non-nullable types")
|
||||
}
|
||||
(HeapType::TypedFunc(_), _) => {
|
||||
Err("function references required for index reference types")
|
||||
}
|
||||
_ => Ok(()),
|
||||
if !self.reference_types {
|
||||
return Err("reference types support is not enabled");
|
||||
}
|
||||
match (r.heap_type(), r.is_nullable()) {
|
||||
// funcref/externref only require `reference-types`
|
||||
(HeapType::Func, true) | (HeapType::Extern, true) => Ok(()),
|
||||
|
||||
// non-nullable func/extern references requires the
|
||||
// `function-references` proposal
|
||||
(HeapType::Func | HeapType::Extern, false) => {
|
||||
if self.function_references {
|
||||
Ok(())
|
||||
} else {
|
||||
Err("function references required for non-nullable types")
|
||||
}
|
||||
}
|
||||
// indexed types require at least the function-references
|
||||
// proposal
|
||||
(HeapType::Indexed(_), _) => {
|
||||
if self.function_references {
|
||||
Ok(())
|
||||
} else {
|
||||
Err("function references required for index reference types")
|
||||
}
|
||||
}
|
||||
|
||||
// types added in the gc proposal
|
||||
(
|
||||
HeapType::Any
|
||||
| HeapType::None
|
||||
| HeapType::Eq
|
||||
| HeapType::Struct
|
||||
| HeapType::Array
|
||||
| HeapType::I31
|
||||
| HeapType::NoExtern
|
||||
| HeapType::NoFunc,
|
||||
_,
|
||||
) => {
|
||||
if self.gc {
|
||||
Ok(())
|
||||
} else {
|
||||
Err("heap types not supported without the gc feature")
|
||||
}
|
||||
} else {
|
||||
Ok(())
|
||||
}
|
||||
} else {
|
||||
Err("reference types support is not enabled")
|
||||
}
|
||||
}
|
||||
ValType::V128 => {
|
||||
@@ -304,6 +335,7 @@ impl Default for WasmFeatures {
|
||||
component_model: false,
|
||||
function_references: false,
|
||||
memory_control: false,
|
||||
gc: false,
|
||||
|
||||
// On-by-default features (phase 4 or greater).
|
||||
mutable_global: true,
|
||||
@@ -540,7 +572,8 @@ impl Validator {
|
||||
);
|
||||
}
|
||||
if num == WASM_COMPONENT_VERSION {
|
||||
self.components.push(ComponentState::default());
|
||||
self.components
|
||||
.push(ComponentState::new(ComponentKind::Component));
|
||||
State::Component
|
||||
} else if num < WASM_COMPONENT_VERSION {
|
||||
bail!(range.start, "unsupported component version: {num:#x}");
|
||||
@@ -1120,6 +1153,15 @@ impl Validator {
|
||||
func_index,
|
||||
options,
|
||||
} => current.lower_function(func_index, options.into_vec(), types, offset),
|
||||
crate::CanonicalFunction::ResourceNew { resource } => {
|
||||
current.resource_new(resource, types, offset)
|
||||
}
|
||||
crate::CanonicalFunction::ResourceDrop { ty } => {
|
||||
current.resource_drop(ty, types, offset)
|
||||
}
|
||||
crate::CanonicalFunction::ResourceRep { resource } => {
|
||||
current.resource_rep(resource, types, offset)
|
||||
}
|
||||
}
|
||||
},
|
||||
)
|
||||
@@ -1135,16 +1177,6 @@ impl Validator {
|
||||
) -> Result<()> {
|
||||
self.state.ensure_component("start", range.start)?;
|
||||
|
||||
// let mut section = section.clone();
|
||||
// let f = section.read()?;
|
||||
|
||||
// if !section.eof() {
|
||||
// return Err(BinaryReaderError::new(
|
||||
// "trailing data at the end of the start section",
|
||||
// section.original_position(),
|
||||
// ));
|
||||
// }
|
||||
|
||||
self.components.last_mut().unwrap().add_start(
|
||||
f.func_index,
|
||||
&f.arguments,
|
||||
@@ -1187,13 +1219,13 @@ impl Validator {
|
||||
|components, _, count, offset| {
|
||||
let current = components.last_mut().unwrap();
|
||||
check_max(
|
||||
current.externs.len(),
|
||||
current.exports.len(),
|
||||
count,
|
||||
MAX_WASM_EXPORTS,
|
||||
"imports and exports",
|
||||
"exports",
|
||||
offset,
|
||||
)?;
|
||||
current.externs.reserve(count as usize);
|
||||
current.exports.reserve(count as usize);
|
||||
Ok(())
|
||||
},
|
||||
|components, types, _, export, offset| {
|
||||
@@ -1201,8 +1233,8 @@ impl Validator {
|
||||
let ty = current.export_to_entity_type(&export, types, offset)?;
|
||||
current.add_export(
|
||||
export.name,
|
||||
export.url,
|
||||
ty,
|
||||
types,
|
||||
offset,
|
||||
false, /* checked above */
|
||||
)
|
||||
@@ -1251,16 +1283,18 @@ impl Validator {
|
||||
|
||||
// Validate that all values were used for the component
|
||||
if let Some(index) = component.values.iter().position(|(_, used)| !*used) {
|
||||
return Err(
|
||||
format_err!(offset,"value index {index} was not used as part of an instantiation, start function, or export"
|
||||
)
|
||||
bail!(
|
||||
offset,
|
||||
"value index {index} was not used as part of an \
|
||||
instantiation, start function, or export"
|
||||
);
|
||||
}
|
||||
|
||||
// If there's a parent component, pop the stack, add it to the parent,
|
||||
// and continue to validate the component
|
||||
let ty = component.finish(&mut self.types, offset)?;
|
||||
if let Some(parent) = self.components.last_mut() {
|
||||
parent.add_component(&mut component, &mut self.types);
|
||||
parent.add_component(ty, &mut self.types)?;
|
||||
self.state = State::Component;
|
||||
}
|
||||
|
||||
@@ -1494,7 +1528,48 @@ mod tests {
|
||||
let a1_id = types.id_from_type_index(1, false).unwrap();
|
||||
let a2_id = types.id_from_type_index(2, false).unwrap();
|
||||
|
||||
// The ids should all be different
|
||||
// The ids should all be the same
|
||||
assert!(t_id == a1_id);
|
||||
assert!(t_id == a2_id);
|
||||
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()
|
||||
));
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_type_id_exports() -> Result<()> {
|
||||
let bytes = wat::parse_str(
|
||||
r#"
|
||||
(component
|
||||
(type $T (list string))
|
||||
(export $A1 "A1" (type $T))
|
||||
(export $A2 "A2" (type $T))
|
||||
)
|
||||
"#,
|
||||
)?;
|
||||
|
||||
let mut validator = Validator::new_with_features(WasmFeatures {
|
||||
component_model: true,
|
||||
..Default::default()
|
||||
});
|
||||
|
||||
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();
|
||||
|
||||
// The ids should all be the same
|
||||
assert!(t_id != a1_id);
|
||||
assert!(t_id != a2_id);
|
||||
assert!(a1_id != a2_id);
|
||||
|
||||
2027
third_party/rust/wasmparser/src/validator/component.rs
vendored
2027
third_party/rust/wasmparser/src/validator/component.rs
vendored
File diff suppressed because it is too large
Load Diff
160
third_party/rust/wasmparser/src/validator/core.rs
vendored
160
third_party/rust/wasmparser/src/validator/core.rs
vendored
@@ -9,8 +9,9 @@ use crate::limits::*;
|
||||
use crate::validator::core::arc::MaybeOwned;
|
||||
use crate::{
|
||||
BinaryReaderError, ConstExpr, Data, DataKind, Element, ElementKind, ExternalKind, FuncType,
|
||||
Global, GlobalType, HeapType, MemoryType, RefType, Result, Table, TableInit, TableType,
|
||||
TagType, TypeRef, ValType, VisitOperator, WasmFeatures, WasmFuncType, WasmModuleResources,
|
||||
Global, GlobalType, HeapType, MemoryType, RefType, Result, StorageType, Table, TableInit,
|
||||
TableType, TagType, TypeRef, ValType, VisitOperator, WasmFeatures, WasmFuncType,
|
||||
WasmModuleResources,
|
||||
};
|
||||
use indexmap::IndexMap;
|
||||
use std::mem;
|
||||
@@ -133,7 +134,7 @@ impl ModuleState {
|
||||
offset: usize,
|
||||
) -> Result<()> {
|
||||
self.module
|
||||
.check_global_type(&global.ty, features, types, offset)?;
|
||||
.check_global_type(&global.ty, features, offset)?;
|
||||
self.check_const_expr(&global.init_expr, global.ty.content_type, features, types)?;
|
||||
self.module.assert_mut().globals.push(global.ty);
|
||||
Ok(())
|
||||
@@ -146,12 +147,11 @@ impl ModuleState {
|
||||
types: &TypeList,
|
||||
offset: usize,
|
||||
) -> Result<()> {
|
||||
self.module
|
||||
.check_table_type(&table.ty, features, types, offset)?;
|
||||
self.module.check_table_type(&table.ty, features, offset)?;
|
||||
|
||||
match &table.init {
|
||||
TableInit::RefNull => {
|
||||
if !table.ty.element_type.nullable {
|
||||
if !table.ty.element_type.is_nullable() {
|
||||
bail!(offset, "type mismatch: non-defaultable element type");
|
||||
}
|
||||
}
|
||||
@@ -200,14 +200,14 @@ impl ModuleState {
|
||||
// don't check it here
|
||||
if e.ty != RefType::FUNCREF {
|
||||
self.module
|
||||
.check_value_type(ValType::Ref(e.ty), features, types, offset)?;
|
||||
.check_value_type(ValType::Ref(e.ty), features, offset)?;
|
||||
}
|
||||
match e.kind {
|
||||
ElementKind::Active {
|
||||
table_index,
|
||||
offset_expr,
|
||||
} => {
|
||||
let table = self.module.table_at(table_index, offset)?;
|
||||
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)
|
||||
@@ -247,7 +247,7 @@ impl ModuleState {
|
||||
match e.items {
|
||||
crate::ElementItems::Functions(reader) => {
|
||||
let count = reader.count();
|
||||
if !e.ty.nullable && count <= 0 {
|
||||
if !e.ty.is_nullable() && count <= 0 {
|
||||
return Err(BinaryReaderError::new(
|
||||
"a non-nullable element must come with an initialization expression",
|
||||
offset,
|
||||
@@ -503,7 +503,7 @@ impl Module {
|
||||
let ty = match ty {
|
||||
crate::Type::Func(t) => {
|
||||
for ty in t.params().iter().chain(t.results()) {
|
||||
self.check_value_type(*ty, features, types, offset)?;
|
||||
self.check_value_type(*ty, features, offset)?;
|
||||
}
|
||||
if t.results().len() > 1 && !features.multi_value {
|
||||
return Err(BinaryReaderError::new(
|
||||
@@ -513,13 +513,28 @@ impl Module {
|
||||
}
|
||||
Type::Func(t)
|
||||
}
|
||||
crate::Type::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) => {
|
||||
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)?;
|
||||
}
|
||||
|
||||
let id = types.push_defined(ty);
|
||||
let id = types.push_ty(ty);
|
||||
self.types.push(id);
|
||||
Ok(())
|
||||
}
|
||||
@@ -639,20 +654,24 @@ impl Module {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn type_at(&self, idx: u32, offset: usize) -> Result<TypeId> {
|
||||
pub fn type_id_at(&self, idx: u32, offset: usize) -> Result<TypeId> {
|
||||
self.types
|
||||
.get(idx as usize)
|
||||
.copied()
|
||||
.ok_or_else(|| format_err!(offset, "unknown type {idx}: type index out of bounds"))
|
||||
}
|
||||
|
||||
fn type_at<'a>(&self, types: &'a TypeList, idx: u32, offset: usize) -> Result<&'a Type> {
|
||||
self.type_id_at(idx, offset).map(|type_id| &types[type_id])
|
||||
}
|
||||
|
||||
fn func_type_at<'a>(
|
||||
&self,
|
||||
type_index: u32,
|
||||
types: &'a TypeList,
|
||||
offset: usize,
|
||||
) -> Result<&'a FuncType> {
|
||||
types[self.type_at(type_index, offset)?]
|
||||
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"))
|
||||
}
|
||||
@@ -670,7 +689,7 @@ impl Module {
|
||||
EntityType::Func(self.types[*type_index as usize])
|
||||
}
|
||||
TypeRef::Table(t) => {
|
||||
self.check_table_type(t, features, types, offset)?;
|
||||
self.check_table_type(t, features, offset)?;
|
||||
EntityType::Table(*t)
|
||||
}
|
||||
TypeRef::Memory(t) => {
|
||||
@@ -682,7 +701,7 @@ impl Module {
|
||||
EntityType::Tag(self.types[t.func_type_idx as usize])
|
||||
}
|
||||
TypeRef::Global(t) => {
|
||||
self.check_global_type(t, features, types, offset)?;
|
||||
self.check_global_type(t, features, offset)?;
|
||||
EntityType::Global(*t)
|
||||
}
|
||||
})
|
||||
@@ -692,13 +711,12 @@ impl Module {
|
||||
&self,
|
||||
ty: &TableType,
|
||||
features: &WasmFeatures,
|
||||
types: &TypeList,
|
||||
offset: usize,
|
||||
) -> Result<()> {
|
||||
// the `funcref` value type is allowed all the way back to the MVP, so
|
||||
// don't check it here
|
||||
if ty.element_type != RefType::FUNCREF {
|
||||
self.check_value_type(ValType::Ref(ty.element_type), features, types, offset)?
|
||||
self.check_value_type(ValType::Ref(ty.element_type), features, offset)?
|
||||
}
|
||||
|
||||
self.check_limits(ty.initial, ty.maximum, offset)?;
|
||||
@@ -780,13 +798,7 @@ impl Module {
|
||||
.collect::<Result<_>>()
|
||||
}
|
||||
|
||||
fn check_value_type(
|
||||
&self,
|
||||
ty: ValType,
|
||||
features: &WasmFeatures,
|
||||
types: &TypeList,
|
||||
offset: usize,
|
||||
) -> Result<()> {
|
||||
fn check_value_type(&self, ty: ValType, features: &WasmFeatures, offset: usize) -> Result<()> {
|
||||
match features.check_value_type(ty) {
|
||||
Ok(()) => Ok(()),
|
||||
Err(e) => Err(BinaryReaderError::new(e, offset)),
|
||||
@@ -795,20 +807,29 @@ impl Module {
|
||||
// We must check it if it's a reference.
|
||||
match ty {
|
||||
ValType::Ref(rt) => {
|
||||
self.check_ref_type(rt, types, offset)?;
|
||||
self.check_ref_type(rt, offset)?;
|
||||
}
|
||||
_ => (),
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn check_ref_type(&self, ty: RefType, types: &TypeList, offset: usize) -> Result<()> {
|
||||
fn check_ref_type(&self, ty: RefType, offset: usize) -> Result<()> {
|
||||
// Check that the heap type is valid
|
||||
match ty.heap_type {
|
||||
HeapType::Func | HeapType::Extern => (),
|
||||
HeapType::TypedFunc(type_index) => {
|
||||
match ty.heap_type() {
|
||||
HeapType::Func
|
||||
| HeapType::Extern
|
||||
| HeapType::Any
|
||||
| HeapType::None
|
||||
| HeapType::NoExtern
|
||||
| HeapType::NoFunc
|
||||
| HeapType::Eq
|
||||
| HeapType::Struct
|
||||
| HeapType::Array
|
||||
| HeapType::I31 => (),
|
||||
HeapType::Indexed(type_index) => {
|
||||
// Just check that the index is valid
|
||||
self.func_type_at(type_index.into(), types, offset)?;
|
||||
self.type_id_at(type_index, offset)?;
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
@@ -817,21 +838,36 @@ impl Module {
|
||||
fn eq_valtypes(&self, ty1: ValType, ty2: ValType, types: &TypeList) -> bool {
|
||||
match (ty1, ty2) {
|
||||
(ValType::Ref(rt1), ValType::Ref(rt2)) => {
|
||||
rt1.nullable == rt2.nullable
|
||||
&& match (rt1.heap_type, rt2.heap_type) {
|
||||
(HeapType::Func, HeapType::Func) => true,
|
||||
(HeapType::Extern, HeapType::Extern) => true,
|
||||
(HeapType::TypedFunc(n1), HeapType::TypedFunc(n2)) => {
|
||||
let n1 = self.func_type_at(n1.into(), types, 0).unwrap();
|
||||
let n2 = self.func_type_at(n2.into(), types, 0).unwrap();
|
||||
self.eq_fns(n1, n2, types)
|
||||
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)
|
||||
}
|
||||
(_, _) => false,
|
||||
(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()
|
||||
@@ -845,6 +881,9 @@ impl Module {
|
||||
.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
|
||||
@@ -852,20 +891,40 @@ impl Module {
|
||||
|
||||
let matches_heap = |ty1: HeapType, ty2: HeapType, types: &TypeList| -> bool {
|
||||
match (ty1, ty2) {
|
||||
(HeapType::TypedFunc(n1), HeapType::TypedFunc(n2)) => {
|
||||
(HeapType::Indexed(n1), HeapType::Indexed(n2)) => {
|
||||
// Check whether the defined types are (structurally) equivalent.
|
||||
let n1 = self.func_type_at(n1.into(), types, 0).unwrap();
|
||||
let n2 = self.func_type_at(n2.into(), types, 0).unwrap();
|
||||
self.eq_fns(n1, n2, types)
|
||||
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,
|
||||
}
|
||||
}
|
||||
(HeapType::TypedFunc(_), HeapType::Func) => true,
|
||||
(_, _) => ty1 == ty2,
|
||||
}
|
||||
};
|
||||
|
||||
let matches_ref = |ty1: RefType, ty2: RefType, types: &TypeList| -> bool {
|
||||
matches_heap(ty1.heap_type, ty2.heap_type, types)
|
||||
&& matches_null(ty1.nullable, ty2.nullable)
|
||||
matches_heap(ty1.heap_type(), ty2.heap_type(), types)
|
||||
&& matches_null(ty1.is_nullable(), ty2.is_nullable())
|
||||
};
|
||||
|
||||
match (ty1, ty2) {
|
||||
@@ -901,10 +960,9 @@ impl Module {
|
||||
&self,
|
||||
ty: &GlobalType,
|
||||
features: &WasmFeatures,
|
||||
types: &TypeList,
|
||||
offset: usize,
|
||||
) -> Result<()> {
|
||||
self.check_value_type(ty.content_type, features, types, offset)
|
||||
self.check_value_type(ty.content_type, features, offset)
|
||||
}
|
||||
|
||||
fn check_limits<T>(&self, initial: T, maximum: Option<T>, offset: usize) -> Result<()>
|
||||
@@ -1092,8 +1150,7 @@ impl WasmModuleResources for OperatorValidatorResources<'_> {
|
||||
}
|
||||
|
||||
fn check_value_type(&self, t: ValType, features: &WasmFeatures, offset: usize) -> Result<()> {
|
||||
self.module
|
||||
.check_value_type(t, features, self.types, offset)
|
||||
self.module.check_value_type(t, features, offset)
|
||||
}
|
||||
|
||||
fn element_type_at(&self, at: u32) -> Option<RefType> {
|
||||
@@ -1161,8 +1218,7 @@ impl WasmModuleResources for ValidatorResources {
|
||||
}
|
||||
|
||||
fn check_value_type(&self, t: ValType, features: &WasmFeatures, offset: usize) -> Result<()> {
|
||||
self.0
|
||||
.check_value_type(t, features, self.0.snapshot.as_ref().unwrap(), offset)
|
||||
self.0.check_value_type(t, features, offset)
|
||||
}
|
||||
|
||||
fn element_type_at(&self, at: u32) -> Option<RefType> {
|
||||
|
||||
606
third_party/rust/wasmparser/src/validator/names.rs
vendored
Normal file
606
third_party/rust/wasmparser/src/validator/names.rs
vendored
Normal file
@@ -0,0 +1,606 @@
|
||||
//! Definitions of name-related helpers and newtypes, primarily for the
|
||||
//! component model.
|
||||
|
||||
use crate::{ComponentExternName, Result};
|
||||
use semver::Version;
|
||||
use std::borrow::Borrow;
|
||||
use std::fmt;
|
||||
use std::hash::{Hash, Hasher};
|
||||
use std::ops::Deref;
|
||||
|
||||
/// Represents a kebab string slice used in validation.
|
||||
///
|
||||
/// This is a wrapper around `str` that ensures the slice is
|
||||
/// a valid kebab case string according to the component model
|
||||
/// specification.
|
||||
///
|
||||
/// It also provides an equality and hashing implementation
|
||||
/// that ignores ASCII case.
|
||||
#[derive(Debug, Eq)]
|
||||
#[repr(transparent)]
|
||||
pub struct KebabStr(str);
|
||||
|
||||
impl KebabStr {
|
||||
/// Creates a new kebab string slice.
|
||||
///
|
||||
/// Returns `None` if the given string is not a valid kebab string.
|
||||
pub fn new<'a>(s: impl AsRef<str> + 'a) -> Option<&'a Self> {
|
||||
let s = Self::new_unchecked(s);
|
||||
if s.is_kebab_case() {
|
||||
Some(s)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn new_unchecked<'a>(s: impl AsRef<str> + 'a) -> &'a Self {
|
||||
// Safety: `KebabStr` is a transparent wrapper around `str`
|
||||
// Therefore transmuting `&str` to `&KebabStr` is safe.
|
||||
unsafe { std::mem::transmute::<_, &Self>(s.as_ref()) }
|
||||
}
|
||||
|
||||
/// Gets the underlying string slice.
|
||||
pub fn as_str(&self) -> &str {
|
||||
&self.0
|
||||
}
|
||||
|
||||
/// Converts the slice to an owned string.
|
||||
pub fn to_kebab_string(&self) -> KebabString {
|
||||
KebabString(self.to_string())
|
||||
}
|
||||
|
||||
fn is_kebab_case(&self) -> bool {
|
||||
let mut lower = false;
|
||||
let mut upper = false;
|
||||
for c in self.chars() {
|
||||
match c {
|
||||
'a'..='z' if !lower && !upper => lower = true,
|
||||
'A'..='Z' if !lower && !upper => upper = true,
|
||||
'a'..='z' if lower => {}
|
||||
'A'..='Z' if upper => {}
|
||||
'0'..='9' if lower || upper => {}
|
||||
'-' if lower || upper => {
|
||||
lower = false;
|
||||
upper = false;
|
||||
}
|
||||
_ => return false,
|
||||
}
|
||||
}
|
||||
|
||||
!self.is_empty() && !self.ends_with('-')
|
||||
}
|
||||
}
|
||||
|
||||
impl Deref for KebabStr {
|
||||
type Target = str;
|
||||
|
||||
fn deref(&self) -> &str {
|
||||
self.as_str()
|
||||
}
|
||||
}
|
||||
|
||||
impl PartialEq for KebabStr {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
if self.len() != other.len() {
|
||||
return false;
|
||||
}
|
||||
|
||||
self.chars()
|
||||
.zip(other.chars())
|
||||
.all(|(a, b)| a.to_ascii_lowercase() == b.to_ascii_lowercase())
|
||||
}
|
||||
}
|
||||
|
||||
impl PartialEq<KebabString> for KebabStr {
|
||||
fn eq(&self, other: &KebabString) -> bool {
|
||||
self.eq(other.as_kebab_str())
|
||||
}
|
||||
}
|
||||
|
||||
impl Hash for KebabStr {
|
||||
fn hash<H: Hasher>(&self, state: &mut H) {
|
||||
self.len().hash(state);
|
||||
|
||||
for b in self.chars() {
|
||||
b.to_ascii_lowercase().hash(state);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for KebabStr {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
(self as &str).fmt(f)
|
||||
}
|
||||
}
|
||||
|
||||
impl ToOwned for KebabStr {
|
||||
type Owned = KebabString;
|
||||
|
||||
fn to_owned(&self) -> Self::Owned {
|
||||
self.to_kebab_string()
|
||||
}
|
||||
}
|
||||
|
||||
/// Represents an owned kebab string for validation.
|
||||
///
|
||||
/// This is a wrapper around `String` that ensures the string is
|
||||
/// a valid kebab case string according to the component model
|
||||
/// specification.
|
||||
///
|
||||
/// It also provides an equality and hashing implementation
|
||||
/// that ignores ASCII case.
|
||||
#[derive(Debug, Clone, Eq)]
|
||||
pub struct KebabString(String);
|
||||
|
||||
impl KebabString {
|
||||
/// Creates a new kebab string.
|
||||
///
|
||||
/// Returns `None` if the given string is not a valid kebab string.
|
||||
pub fn new(s: impl Into<String>) -> Option<Self> {
|
||||
let s = s.into();
|
||||
if KebabStr::new(&s).is_some() {
|
||||
Some(Self(s))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
/// Gets the underlying string.
|
||||
pub fn as_str(&self) -> &str {
|
||||
self.0.as_str()
|
||||
}
|
||||
|
||||
/// Converts the kebab string to a kebab string slice.
|
||||
pub fn as_kebab_str(&self) -> &KebabStr {
|
||||
// Safety: internal string is always valid kebab-case
|
||||
KebabStr::new_unchecked(self.as_str())
|
||||
}
|
||||
}
|
||||
|
||||
impl Deref for KebabString {
|
||||
type Target = KebabStr;
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
self.as_kebab_str()
|
||||
}
|
||||
}
|
||||
|
||||
impl Borrow<KebabStr> for KebabString {
|
||||
fn borrow(&self) -> &KebabStr {
|
||||
self.as_kebab_str()
|
||||
}
|
||||
}
|
||||
|
||||
impl PartialEq for KebabString {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
self.as_kebab_str().eq(other.as_kebab_str())
|
||||
}
|
||||
}
|
||||
|
||||
impl PartialEq<KebabStr> for KebabString {
|
||||
fn eq(&self, other: &KebabStr) -> bool {
|
||||
self.as_kebab_str().eq(other)
|
||||
}
|
||||
}
|
||||
|
||||
impl Hash for KebabString {
|
||||
fn hash<H: Hasher>(&self, state: &mut H) {
|
||||
self.as_kebab_str().hash(state)
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for KebabString {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
self.as_kebab_str().fmt(f)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<KebabString> for String {
|
||||
fn from(s: KebabString) -> String {
|
||||
s.0
|
||||
}
|
||||
}
|
||||
|
||||
/// A "kebab name" in the component model which is backed by `T`, which defaults
|
||||
/// to `String`.
|
||||
///
|
||||
/// This name can be either:
|
||||
///
|
||||
/// * a `KebabStr`: `a-b-c`
|
||||
/// * a method name : `[method]a-b.c-d`
|
||||
/// * a static method name : `[static]a-b.c-d`
|
||||
/// * a constructor: `[constructor]a-b`
|
||||
///
|
||||
/// # Equality and hashing
|
||||
///
|
||||
/// Note that this type the `Method` and `Static` variants are considered equal
|
||||
/// and hash to the same value. This enables disallowing clashes between the two
|
||||
/// where method name overlap cannot happen.
|
||||
#[derive(Clone)]
|
||||
pub struct KebabName {
|
||||
raw: String,
|
||||
parsed: ParsedKebabName,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
enum ParsedKebabName {
|
||||
Normal,
|
||||
Constructor,
|
||||
Method {
|
||||
dot: u32,
|
||||
},
|
||||
Static {
|
||||
dot: u32,
|
||||
},
|
||||
Id {
|
||||
colon: u32,
|
||||
slash: u32,
|
||||
at: Option<u32>,
|
||||
},
|
||||
}
|
||||
|
||||
/// Created via [`KebabName::kind`] and classifies a name.
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum KebabNameKind<'a> {
|
||||
/// `a-b-c`
|
||||
Normal(&'a KebabStr),
|
||||
/// `[constructor]a-b`
|
||||
Constructor(&'a KebabStr),
|
||||
/// `[method]a-b.c-d`
|
||||
#[allow(missing_docs)]
|
||||
Method {
|
||||
resource: &'a KebabStr,
|
||||
name: &'a KebabStr,
|
||||
},
|
||||
/// `[static]a-b.c-d`
|
||||
#[allow(missing_docs)]
|
||||
Static {
|
||||
resource: &'a KebabStr,
|
||||
name: &'a KebabStr,
|
||||
},
|
||||
/// `wasi:http/types@2.0`
|
||||
#[allow(missing_docs)]
|
||||
Id {
|
||||
namespace: &'a KebabStr,
|
||||
package: &'a KebabStr,
|
||||
interface: &'a KebabStr,
|
||||
version: Option<Version>,
|
||||
},
|
||||
}
|
||||
|
||||
const CONSTRUCTOR: &str = "[constructor]";
|
||||
const METHOD: &str = "[method]";
|
||||
const STATIC: &str = "[static]";
|
||||
|
||||
impl KebabName {
|
||||
/// Attempts to parse `name` as a kebab name, returning `None` if it's not
|
||||
/// valid.
|
||||
pub fn new(name: ComponentExternName<'_>, offset: usize) -> Result<KebabName> {
|
||||
let validate_kebab = |s: &str| {
|
||||
if KebabStr::new(s).is_none() {
|
||||
bail!(offset, "`{s}` is not in kebab case")
|
||||
} else {
|
||||
Ok(())
|
||||
}
|
||||
};
|
||||
let find = |s: &str, c: char| match s.find(c) {
|
||||
Some(i) => Ok(i),
|
||||
None => bail!(offset, "failed to find `{c}` character"),
|
||||
};
|
||||
let parsed = match name {
|
||||
ComponentExternName::Kebab(s) => {
|
||||
if let Some(s) = s.strip_prefix(CONSTRUCTOR) {
|
||||
validate_kebab(s)?;
|
||||
ParsedKebabName::Constructor
|
||||
} else if let Some(s) = s.strip_prefix(METHOD) {
|
||||
let dot = find(s, '.')?;
|
||||
validate_kebab(&s[..dot])?;
|
||||
validate_kebab(&s[dot + 1..])?;
|
||||
ParsedKebabName::Method { dot: dot as u32 }
|
||||
} else if let Some(s) = s.strip_prefix(STATIC) {
|
||||
let dot = find(s, '.')?;
|
||||
validate_kebab(&s[..dot])?;
|
||||
validate_kebab(&s[dot + 1..])?;
|
||||
ParsedKebabName::Static { dot: dot as u32 }
|
||||
} else {
|
||||
validate_kebab(s)?;
|
||||
ParsedKebabName::Normal
|
||||
}
|
||||
}
|
||||
ComponentExternName::Interface(s) => {
|
||||
let colon = find(s, ':')?;
|
||||
validate_kebab(&s[..colon])?;
|
||||
let slash = find(s, '/')?;
|
||||
let at = s[slash..].find('@').map(|i| i + slash);
|
||||
validate_kebab(&s[colon + 1..slash])?;
|
||||
validate_kebab(&s[slash + 1..at.unwrap_or(s.len())])?;
|
||||
if let Some(at) = at {
|
||||
let version = &s[at + 1..];
|
||||
if let Err(e) = version.parse::<Version>() {
|
||||
bail!(offset, "failed to parse version: {e}")
|
||||
}
|
||||
}
|
||||
ParsedKebabName::Id {
|
||||
colon: colon as u32,
|
||||
slash: slash as u32,
|
||||
at: at.map(|i| i as u32),
|
||||
}
|
||||
}
|
||||
};
|
||||
Ok(KebabName {
|
||||
raw: name.as_str().to_string(),
|
||||
parsed,
|
||||
})
|
||||
}
|
||||
|
||||
/// Returns the [`KebabNameKind`] corresponding to this name.
|
||||
pub fn kind(&self) -> KebabNameKind<'_> {
|
||||
match self.parsed {
|
||||
ParsedKebabName::Normal => KebabNameKind::Normal(KebabStr::new_unchecked(&self.raw)),
|
||||
ParsedKebabName::Constructor => {
|
||||
let kebab = &self.raw[CONSTRUCTOR.len()..];
|
||||
KebabNameKind::Constructor(KebabStr::new_unchecked(kebab))
|
||||
}
|
||||
ParsedKebabName::Method { dot } => {
|
||||
let dotted = &self.raw[METHOD.len()..];
|
||||
let resource = KebabStr::new_unchecked(&dotted[..dot as usize]);
|
||||
let name = KebabStr::new_unchecked(&dotted[dot as usize + 1..]);
|
||||
KebabNameKind::Method { resource, name }
|
||||
}
|
||||
ParsedKebabName::Static { dot } => {
|
||||
let dotted = &self.raw[METHOD.len()..];
|
||||
let resource = KebabStr::new_unchecked(&dotted[..dot as usize]);
|
||||
let name = KebabStr::new_unchecked(&dotted[dot as usize + 1..]);
|
||||
KebabNameKind::Static { resource, name }
|
||||
}
|
||||
ParsedKebabName::Id { colon, slash, at } => {
|
||||
let colon = colon as usize;
|
||||
let slash = slash as usize;
|
||||
let at = at.map(|i| i as usize);
|
||||
let namespace = KebabStr::new_unchecked(&self.raw[..colon]);
|
||||
let package = KebabStr::new_unchecked(&self.raw[colon + 1..slash]);
|
||||
let interface =
|
||||
KebabStr::new_unchecked(&self.raw[slash + 1..at.unwrap_or(self.raw.len())]);
|
||||
let version = at.map(|i| Version::parse(&self.raw[i + 1..]).unwrap());
|
||||
KebabNameKind::Id {
|
||||
namespace,
|
||||
package,
|
||||
interface,
|
||||
version,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the raw underlying name as a string.
|
||||
pub fn as_str(&self) -> &str {
|
||||
&self.raw
|
||||
}
|
||||
}
|
||||
|
||||
impl From<KebabName> for String {
|
||||
fn from(name: KebabName) -> String {
|
||||
name.raw
|
||||
}
|
||||
}
|
||||
|
||||
impl Hash for KebabName {
|
||||
fn hash<H: Hasher>(&self, hasher: &mut H) {
|
||||
self.kind().hash(hasher)
|
||||
}
|
||||
}
|
||||
|
||||
impl PartialEq for KebabName {
|
||||
fn eq(&self, other: &KebabName) -> bool {
|
||||
self.kind().eq(&other.kind())
|
||||
}
|
||||
}
|
||||
|
||||
impl Eq for KebabName {}
|
||||
|
||||
impl fmt::Display for KebabName {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
self.raw.fmt(f)
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Debug for KebabName {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
self.raw.fmt(f)
|
||||
}
|
||||
}
|
||||
|
||||
impl Hash for KebabNameKind<'_> {
|
||||
fn hash<H: Hasher>(&self, hasher: &mut H) {
|
||||
match self {
|
||||
KebabNameKind::Normal(name) => {
|
||||
hasher.write_u8(0);
|
||||
name.hash(hasher);
|
||||
}
|
||||
KebabNameKind::Constructor(name) => {
|
||||
hasher.write_u8(1);
|
||||
name.hash(hasher);
|
||||
}
|
||||
// for hashing method == static
|
||||
KebabNameKind::Method { resource, name } | KebabNameKind::Static { resource, name } => {
|
||||
hasher.write_u8(2);
|
||||
resource.hash(hasher);
|
||||
name.hash(hasher);
|
||||
}
|
||||
KebabNameKind::Id {
|
||||
namespace,
|
||||
package,
|
||||
interface,
|
||||
version,
|
||||
} => {
|
||||
hasher.write_u8(3);
|
||||
namespace.hash(hasher);
|
||||
package.hash(hasher);
|
||||
interface.hash(hasher);
|
||||
version.hash(hasher);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl PartialEq for KebabNameKind<'_> {
|
||||
fn eq(&self, other: &KebabNameKind<'_>) -> bool {
|
||||
match (self, other) {
|
||||
(KebabNameKind::Normal(a), KebabNameKind::Normal(b)) => a == b,
|
||||
(KebabNameKind::Normal(_), _) => false,
|
||||
(KebabNameKind::Constructor(a), KebabNameKind::Constructor(b)) => a == b,
|
||||
(KebabNameKind::Constructor(_), _) => false,
|
||||
|
||||
// method == static for the purposes of hashing so equate them here
|
||||
// as well.
|
||||
(
|
||||
KebabNameKind::Method {
|
||||
resource: ar,
|
||||
name: an,
|
||||
},
|
||||
KebabNameKind::Method {
|
||||
resource: br,
|
||||
name: bn,
|
||||
},
|
||||
)
|
||||
| (
|
||||
KebabNameKind::Static {
|
||||
resource: ar,
|
||||
name: an,
|
||||
},
|
||||
KebabNameKind::Static {
|
||||
resource: br,
|
||||
name: bn,
|
||||
},
|
||||
)
|
||||
| (
|
||||
KebabNameKind::Method {
|
||||
resource: ar,
|
||||
name: an,
|
||||
},
|
||||
KebabNameKind::Static {
|
||||
resource: br,
|
||||
name: bn,
|
||||
},
|
||||
)
|
||||
| (
|
||||
KebabNameKind::Static {
|
||||
resource: ar,
|
||||
name: an,
|
||||
},
|
||||
KebabNameKind::Method {
|
||||
resource: br,
|
||||
name: bn,
|
||||
},
|
||||
) => ar == br && an == bn,
|
||||
|
||||
(KebabNameKind::Method { .. }, _) => false,
|
||||
(KebabNameKind::Static { .. }, _) => false,
|
||||
|
||||
(
|
||||
KebabNameKind::Id {
|
||||
namespace: an,
|
||||
package: ap,
|
||||
interface: ai,
|
||||
version: av,
|
||||
},
|
||||
KebabNameKind::Id {
|
||||
namespace: bn,
|
||||
package: bp,
|
||||
interface: bi,
|
||||
version: bv,
|
||||
},
|
||||
) => an == bn && ap == bp && ai == bi && av == bv,
|
||||
(KebabNameKind::Id { .. }, _) => false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Eq for KebabNameKind<'_> {}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use std::collections::HashSet;
|
||||
|
||||
fn parse_kebab_name(s: &str) -> Option<KebabName> {
|
||||
KebabName::new(ComponentExternName::Kebab(s), 0).ok()
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn kebab_smoke() {
|
||||
assert!(KebabStr::new("").is_none());
|
||||
assert!(KebabStr::new("a").is_some());
|
||||
assert!(KebabStr::new("aB").is_none());
|
||||
assert!(KebabStr::new("a-B").is_some());
|
||||
assert!(KebabStr::new("a-").is_none());
|
||||
assert!(KebabStr::new("-").is_none());
|
||||
assert!(KebabStr::new("¶").is_none());
|
||||
assert!(KebabStr::new("0").is_none());
|
||||
assert!(KebabStr::new("a0").is_some());
|
||||
assert!(KebabStr::new("a-0").is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn name_smoke() {
|
||||
assert!(parse_kebab_name("a").is_some());
|
||||
assert!(parse_kebab_name("[foo]a").is_none());
|
||||
assert!(parse_kebab_name("[constructor]a").is_some());
|
||||
assert!(parse_kebab_name("[method]a").is_none());
|
||||
assert!(parse_kebab_name("[method]a.b").is_some());
|
||||
assert!(parse_kebab_name("[method]a.b.c").is_none());
|
||||
assert!(parse_kebab_name("[static]a.b").is_some());
|
||||
assert!(parse_kebab_name("[static]a").is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn name_equality() {
|
||||
assert_eq!(parse_kebab_name("a"), parse_kebab_name("a"));
|
||||
assert_ne!(parse_kebab_name("a"), parse_kebab_name("b"));
|
||||
assert_eq!(
|
||||
parse_kebab_name("[constructor]a"),
|
||||
parse_kebab_name("[constructor]a")
|
||||
);
|
||||
assert_ne!(
|
||||
parse_kebab_name("[constructor]a"),
|
||||
parse_kebab_name("[constructor]b")
|
||||
);
|
||||
assert_eq!(
|
||||
parse_kebab_name("[method]a.b"),
|
||||
parse_kebab_name("[method]a.b")
|
||||
);
|
||||
assert_ne!(
|
||||
parse_kebab_name("[method]a.b"),
|
||||
parse_kebab_name("[method]b.b")
|
||||
);
|
||||
assert_eq!(
|
||||
parse_kebab_name("[static]a.b"),
|
||||
parse_kebab_name("[static]a.b")
|
||||
);
|
||||
assert_ne!(
|
||||
parse_kebab_name("[static]a.b"),
|
||||
parse_kebab_name("[static]b.b")
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
parse_kebab_name("[static]a.b"),
|
||||
parse_kebab_name("[method]a.b")
|
||||
);
|
||||
assert_eq!(
|
||||
parse_kebab_name("[method]a.b"),
|
||||
parse_kebab_name("[static]a.b")
|
||||
);
|
||||
|
||||
assert_ne!(
|
||||
parse_kebab_name("[method]b.b"),
|
||||
parse_kebab_name("[static]a.b")
|
||||
);
|
||||
|
||||
let mut s = HashSet::new();
|
||||
assert!(s.insert(parse_kebab_name("a")));
|
||||
assert!(s.insert(parse_kebab_name("[constructor]a")));
|
||||
assert!(s.insert(parse_kebab_name("[method]a.b")));
|
||||
assert!(!s.insert(parse_kebab_name("[static]a.b")));
|
||||
assert!(s.insert(parse_kebab_name("[static]b.b")));
|
||||
}
|
||||
}
|
||||
@@ -173,6 +173,13 @@ impl From<ValType> for MaybeType {
|
||||
}
|
||||
}
|
||||
|
||||
impl From<RefType> for MaybeType {
|
||||
fn from(ty: RefType) -> MaybeType {
|
||||
let ty: ValType = ty.into();
|
||||
ty.into()
|
||||
}
|
||||
}
|
||||
|
||||
impl OperatorValidator {
|
||||
fn new(features: &WasmFeatures, allocs: OperatorValidatorAllocations) -> Self {
|
||||
let OperatorValidatorAllocations {
|
||||
@@ -506,7 +513,7 @@ impl<'resources, R: WasmModuleResources> OperatorValidatorTemp<'_, 'resources, R
|
||||
) => {
|
||||
bail!(
|
||||
self.offset,
|
||||
"type mismatche: expected {}, found heap type",
|
||||
"type mismatch: expected {}, found heap type",
|
||||
ty_to_str(expected)
|
||||
)
|
||||
}
|
||||
@@ -983,24 +990,7 @@ pub fn ty_to_str(ty: ValType) -> &'static str {
|
||||
ValType::F32 => "f32",
|
||||
ValType::F64 => "f64",
|
||||
ValType::V128 => "v128",
|
||||
ValType::FUNCREF => "funcref",
|
||||
ValType::EXTERNREF => "externref",
|
||||
ValType::Ref(RefType {
|
||||
nullable: false,
|
||||
heap_type: HeapType::Func,
|
||||
}) => "(ref func)",
|
||||
ValType::Ref(RefType {
|
||||
nullable: false,
|
||||
heap_type: HeapType::Extern,
|
||||
}) => "(ref extern)",
|
||||
ValType::Ref(RefType {
|
||||
nullable: false,
|
||||
heap_type: HeapType::TypedFunc(_),
|
||||
}) => "(ref $type)",
|
||||
ValType::Ref(RefType {
|
||||
nullable: true,
|
||||
heap_type: HeapType::TypedFunc(_),
|
||||
}) => "(ref null $type)",
|
||||
ValType::Ref(r) => r.wat(),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1051,6 +1041,7 @@ macro_rules! validate_proposal {
|
||||
(desc tail_call) => ("tail calls");
|
||||
(desc function_references) => ("function references");
|
||||
(desc memory_control) => ("memory control");
|
||||
(desc gc) => ("gc");
|
||||
}
|
||||
|
||||
impl<'a, T> VisitOperator<'a> for WasmProposalValidator<'_, '_, T>
|
||||
@@ -1280,16 +1271,15 @@ where
|
||||
self.check_return()?;
|
||||
Ok(())
|
||||
}
|
||||
fn visit_call_ref(&mut self, hty: HeapType) -> Self::Output {
|
||||
fn visit_call_ref(&mut self, type_index: u32) -> Self::Output {
|
||||
let hty = HeapType::Indexed(type_index);
|
||||
self.resources
|
||||
.check_heap_type(hty, &self.features, self.offset)?;
|
||||
// If `None` is popped then that means a "bottom" type was popped which
|
||||
// is always considered equivalent to the `hty` tag.
|
||||
if let Some(rt) = self.pop_ref()? {
|
||||
let expected = RefType {
|
||||
nullable: true,
|
||||
heap_type: hty,
|
||||
};
|
||||
let expected = RefType::indexed_func(true, type_index)
|
||||
.expect("existing heap types should be within our limits");
|
||||
if !self
|
||||
.resources
|
||||
.matches(ValType::Ref(rt), ValType::Ref(expected))
|
||||
@@ -1300,17 +1290,10 @@ where
|
||||
);
|
||||
}
|
||||
}
|
||||
match hty {
|
||||
HeapType::TypedFunc(type_index) => self.check_call_ty(type_index.into())?,
|
||||
_ => bail!(
|
||||
self.offset,
|
||||
"type mismatch: instruction requires function reference type",
|
||||
),
|
||||
}
|
||||
Ok(())
|
||||
self.check_call_ty(type_index)
|
||||
}
|
||||
fn visit_return_call_ref(&mut self, hty: HeapType) -> Self::Output {
|
||||
self.visit_call_ref(hty)?;
|
||||
fn visit_return_call_ref(&mut self, type_index: u32) -> Self::Output {
|
||||
self.visit_call_ref(type_index)?;
|
||||
self.check_return()
|
||||
}
|
||||
fn visit_call_indirect(
|
||||
@@ -2221,19 +2204,15 @@ where
|
||||
fn visit_ref_null(&mut self, heap_type: HeapType) -> Self::Output {
|
||||
self.resources
|
||||
.check_heap_type(heap_type, &self.features, self.offset)?;
|
||||
self.push_operand(ValType::Ref(RefType {
|
||||
nullable: true,
|
||||
heap_type,
|
||||
}))?;
|
||||
self.push_operand(ValType::Ref(
|
||||
RefType::new(true, heap_type).expect("existing heap types should be within our limits"),
|
||||
))?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn visit_ref_as_non_null(&mut self) -> Self::Output {
|
||||
let ty = match self.pop_ref()? {
|
||||
Some(ty) => MaybeType::Type(ValType::Ref(RefType {
|
||||
nullable: false,
|
||||
heap_type: ty.heap_type,
|
||||
})),
|
||||
Some(ty) => MaybeType::Type(ValType::Ref(ty.as_non_null())),
|
||||
None => MaybeType::HeapBot,
|
||||
};
|
||||
self.push_operand(ty)?;
|
||||
@@ -2242,10 +2221,7 @@ where
|
||||
fn visit_br_on_null(&mut self, relative_depth: u32) -> Self::Output {
|
||||
let ty = match self.pop_ref()? {
|
||||
None => MaybeType::HeapBot,
|
||||
Some(ty) => MaybeType::Type(ValType::Ref(RefType {
|
||||
nullable: false,
|
||||
heap_type: ty.heap_type,
|
||||
})),
|
||||
Some(ty) => MaybeType::Type(ValType::Ref(ty.as_non_null())),
|
||||
};
|
||||
let (ft, kind) = self.jump(relative_depth)?;
|
||||
for ty in self.label_types(ft, kind)?.rev() {
|
||||
@@ -2271,10 +2247,7 @@ where
|
||||
// Switch rt0, our popped type, to a non-nullable type and
|
||||
// perform the match because if the branch is taken it's a
|
||||
// non-null value.
|
||||
let ty = RefType {
|
||||
nullable: false,
|
||||
heap_type: rt0.heap_type,
|
||||
};
|
||||
let ty = rt0.as_non_null();
|
||||
if !self.resources.matches(ty.into(), rt1) {
|
||||
bail!(
|
||||
self.offset,
|
||||
@@ -2318,16 +2291,10 @@ where
|
||||
// FIXME(#924) this should not be conditional based on enabled
|
||||
// proposals.
|
||||
if self.features.function_references {
|
||||
let heap_type = HeapType::TypedFunc(match type_index.try_into() {
|
||||
Ok(packed) => packed,
|
||||
Err(_) => {
|
||||
bail!(self.offset, "type index of `ref.func` target too large")
|
||||
}
|
||||
});
|
||||
self.push_operand(ValType::Ref(RefType {
|
||||
nullable: false,
|
||||
heap_type,
|
||||
}))?;
|
||||
self.push_operand(
|
||||
RefType::indexed_func(false, type_index)
|
||||
.expect("our limits on number of types should fit into ref type"),
|
||||
)?;
|
||||
} else {
|
||||
self.push_operand(ValType::FUNCREF)?;
|
||||
}
|
||||
@@ -3368,6 +3335,28 @@ where
|
||||
self.pop_operand(Some(ValType::I32))?;
|
||||
Ok(())
|
||||
}
|
||||
fn visit_i31_new(&mut self) -> Self::Output {
|
||||
self.pop_operand(Some(ValType::I32))?;
|
||||
self.push_operand(ValType::Ref(RefType::I31))
|
||||
}
|
||||
fn visit_i31_get_s(&mut self) -> Self::Output {
|
||||
match self.pop_ref()? {
|
||||
Some(ref_type) => match ref_type.heap_type() {
|
||||
HeapType::I31 => self.push_operand(ValType::I32),
|
||||
_ => bail!(self.offset, "ref heap type mismatch: expected i31"),
|
||||
},
|
||||
_ => bail!(self.offset, "type mismatch: expected (ref null? i31)"),
|
||||
}
|
||||
}
|
||||
fn visit_i31_get_u(&mut self) -> Self::Output {
|
||||
match self.pop_ref()? {
|
||||
Some(ref_type) => match ref_type.heap_type() {
|
||||
HeapType::I31 => self.push_operand(ValType::I32),
|
||||
_ => bail!(self.offset, "ref heap type mismatch: expected i31"),
|
||||
},
|
||||
_ => bail!(self.offset, "type mismatch: expected (ref null? i31)"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
|
||||
2132
third_party/rust/wasmparser/src/validator/types.rs
vendored
2132
third_party/rust/wasmparser/src/validator/types.rs
vendored
File diff suppressed because it is too large
Load Diff
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 = "56.0.0"
|
||||
version = "60.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.25.0"
|
||||
version = "0.29.0"
|
||||
|
||||
[dev-dependencies.anyhow]
|
||||
version = "1.0.58"
|
||||
|
||||
9
third_party/rust/wast/src/component/alias.rs
vendored
9
third_party/rust/wast/src/component/alias.rs
vendored
@@ -4,17 +4,22 @@ use crate::parser::{Parse, Parser, Result};
|
||||
use crate::token::{Id, Index, NameAnnotation, Span};
|
||||
|
||||
/// A inline alias for component exported items.
|
||||
///
|
||||
/// Handles both `core export` and `export` aliases
|
||||
#[derive(Debug)]
|
||||
pub struct InlineExportAlias<'a> {
|
||||
pub struct InlineExportAlias<'a, const CORE: bool> {
|
||||
/// The instance to alias the export from.
|
||||
pub instance: Index<'a>,
|
||||
/// The name of the export to alias.
|
||||
pub name: &'a str,
|
||||
}
|
||||
|
||||
impl<'a> Parse<'a> for InlineExportAlias<'a> {
|
||||
impl<'a, const CORE: bool> Parse<'a> for InlineExportAlias<'a, CORE> {
|
||||
fn parse(parser: Parser<'a>) -> Result<Self> {
|
||||
parser.parse::<kw::alias>()?;
|
||||
if CORE {
|
||||
parser.parse::<kw::core>()?;
|
||||
}
|
||||
parser.parse::<kw::export>()?;
|
||||
let instance = parser.parse()?;
|
||||
let name = parser.parse()?;
|
||||
|
||||
57
third_party/rust/wast/src/component/binary.rs
vendored
57
third_party/rust/wast/src/component/binary.rs
vendored
@@ -90,6 +90,10 @@ fn encode_type(encoder: ComponentTypeEncoder, ty: &TypeDef) {
|
||||
TypeDef::Instance(i) => {
|
||||
encoder.instance(&i.into());
|
||||
}
|
||||
TypeDef::Resource(i) => {
|
||||
let dtor = i.dtor.as_ref().map(|i| i.idx.into());
|
||||
encoder.resource(i.rep.into(), dtor);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -130,6 +134,8 @@ fn encode_defined_type(encoder: ComponentDefinedTypeEncoder, ty: &ComponentDefin
|
||||
e.err.as_deref().map(Into::into),
|
||||
);
|
||||
}
|
||||
ComponentDefinedType::Own(i) => encoder.own((*i).into()),
|
||||
ComponentDefinedType::Borrow(i) => encoder.borrow((*i).into()),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -256,7 +262,7 @@ impl<'a> Encoder<'a> {
|
||||
InstanceKind::BundleOfExports(exports) => {
|
||||
self.instances.export_items(exports.iter().map(|e| {
|
||||
let (kind, index) = (&e.kind).into();
|
||||
(e.name, kind, index)
|
||||
(e.name.into(), kind, index)
|
||||
}));
|
||||
}
|
||||
}
|
||||
@@ -315,6 +321,18 @@ impl<'a> Encoder<'a> {
|
||||
self.funcs
|
||||
.lower(info.func.idx.into(), info.opts.iter().map(Into::into));
|
||||
}
|
||||
CanonicalFuncKind::ResourceNew(info) => {
|
||||
self.core_func_names.push(name);
|
||||
self.funcs.resource_new(info.ty.into());
|
||||
}
|
||||
CanonicalFuncKind::ResourceDrop(info) => {
|
||||
self.core_func_names.push(name);
|
||||
self.funcs.resource_drop((&info.ty).into());
|
||||
}
|
||||
CanonicalFuncKind::ResourceRep(info) => {
|
||||
self.core_func_names.push(name);
|
||||
self.funcs.resource_rep(info.ty.into());
|
||||
}
|
||||
}
|
||||
|
||||
self.flush(Some(self.funcs.id()));
|
||||
@@ -324,8 +342,7 @@ impl<'a> Encoder<'a> {
|
||||
let name = get_name(&import.item.id, &import.item.name);
|
||||
self.names_for_item_kind(&import.item.kind).push(name);
|
||||
self.imports.import(
|
||||
import.name,
|
||||
import.url.unwrap_or(""),
|
||||
wasm_encoder::ComponentExternName::from(import.name),
|
||||
(&import.item.kind).into(),
|
||||
);
|
||||
self.flush(Some(self.imports.id()));
|
||||
@@ -335,8 +352,7 @@ impl<'a> Encoder<'a> {
|
||||
let name = get_name(&export.id, &export.debug_name);
|
||||
let (kind, index) = (&export.kind).into();
|
||||
self.exports.export(
|
||||
export.name,
|
||||
export.url.unwrap_or(""),
|
||||
wasm_encoder::ComponentExternName::from(export.name),
|
||||
kind,
|
||||
index,
|
||||
export.ty.as_ref().map(|ty| (&ty.0.kind).into()),
|
||||
@@ -571,7 +587,7 @@ impl From<core::HeapType<'_>> for wasm_encoder::HeapType {
|
||||
match r {
|
||||
core::HeapType::Func => Self::Func,
|
||||
core::HeapType::Extern => Self::Extern,
|
||||
core::HeapType::Index(Index::Num(i, _)) => Self::TypedFunc(i),
|
||||
core::HeapType::Index(Index::Num(i, _)) => Self::Indexed(i),
|
||||
core::HeapType::Index(_) => panic!("unresolved index"),
|
||||
core::HeapType::Any
|
||||
| core::HeapType::Eq
|
||||
@@ -777,7 +793,10 @@ impl From<&ItemSigKind<'_>> for wasm_encoder::ComponentTypeRef {
|
||||
ItemSigKind::Value(v) => Self::Value((&v.0).into()),
|
||||
ItemSigKind::Func(f) => Self::Func(f.into()),
|
||||
ItemSigKind::Type(TypeBounds::Eq(t)) => {
|
||||
Self::Type(wasm_encoder::TypeBounds::Eq, (*t).into())
|
||||
Self::Type(wasm_encoder::TypeBounds::Eq((*t).into()))
|
||||
}
|
||||
ItemSigKind::Type(TypeBounds::SubResource) => {
|
||||
Self::Type(wasm_encoder::TypeBounds::SubResource)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -799,10 +818,16 @@ impl From<&ComponentType<'_>> for wasm_encoder::ComponentType {
|
||||
encoded.alias((&a.target).into());
|
||||
}
|
||||
ComponentTypeDecl::Import(i) => {
|
||||
encoded.import(i.name, i.url.unwrap_or(""), (&i.item.kind).into());
|
||||
encoded.import(
|
||||
wasm_encoder::ComponentExternName::from(i.name),
|
||||
(&i.item.kind).into(),
|
||||
);
|
||||
}
|
||||
ComponentTypeDecl::Export(e) => {
|
||||
encoded.export(e.name, e.url.unwrap_or(""), (&e.item.kind).into());
|
||||
encoded.export(
|
||||
wasm_encoder::ComponentExternName::from(e.name),
|
||||
(&e.item.kind).into(),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -827,7 +852,10 @@ impl From<&InstanceType<'_>> for wasm_encoder::InstanceType {
|
||||
encoded.alias((&a.target).into());
|
||||
}
|
||||
InstanceTypeDecl::Export(e) => {
|
||||
encoded.export(e.name, e.url.unwrap_or(""), (&e.item.kind).into());
|
||||
encoded.export(
|
||||
wasm_encoder::ComponentExternName::from(e.name),
|
||||
(&e.item.kind).into(),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -970,3 +998,12 @@ impl<'a> From<&AliasTarget<'a>> for wasm_encoder::Alias<'a> {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> From<ComponentExternName<'a>> for wasm_encoder::ComponentExternName<'a> {
|
||||
fn from(name: ComponentExternName<'a>) -> Self {
|
||||
match name {
|
||||
ComponentExternName::Kebab(name) => Self::Kebab(name),
|
||||
ComponentExternName::Interface(name) => Self::Interface(name),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -188,7 +188,7 @@ impl<'a> Parse<'a> for ComponentField<'a> {
|
||||
return Ok(Self::Alias(parser.parse()?));
|
||||
}
|
||||
if parser.peek::<kw::r#type>() {
|
||||
return Ok(Self::Type(parser.parse()?));
|
||||
return Ok(Self::Type(Type::parse_maybe_with_inline_exports(parser)?));
|
||||
}
|
||||
if parser.peek::<kw::import>() {
|
||||
return Ok(Self::Import(parser.parse()?));
|
||||
|
||||
52
third_party/rust/wast/src/component/expand.rs
vendored
52
third_party/rust/wast/src/component/expand.rs
vendored
@@ -136,7 +136,7 @@ impl<'a> Expander<'a> {
|
||||
}
|
||||
|
||||
fn expand_core_module(&mut self, module: &mut CoreModule<'a>) -> Option<ComponentField<'a>> {
|
||||
for (name, url) in module.exports.names.drain(..) {
|
||||
for name in module.exports.names.drain(..) {
|
||||
let id = gensym::fill(module.span, &mut module.id);
|
||||
self.component_fields_to_append
|
||||
.push(ComponentField::Export(ComponentExport {
|
||||
@@ -144,7 +144,6 @@ impl<'a> Expander<'a> {
|
||||
id: None,
|
||||
debug_name: None,
|
||||
name,
|
||||
url,
|
||||
kind: ComponentExportKind::module(module.span, id),
|
||||
ty: None,
|
||||
}));
|
||||
@@ -157,7 +156,6 @@ impl<'a> Expander<'a> {
|
||||
Some(ComponentField::Import(ComponentImport {
|
||||
span: module.span,
|
||||
name: import.name,
|
||||
url: import.url,
|
||||
item: ItemSig {
|
||||
span: module.span,
|
||||
id: module.id,
|
||||
@@ -184,7 +182,7 @@ impl<'a> Expander<'a> {
|
||||
&mut self,
|
||||
component: &mut NestedComponent<'a>,
|
||||
) -> Option<ComponentField<'a>> {
|
||||
for (name, url) in component.exports.names.drain(..) {
|
||||
for name in component.exports.names.drain(..) {
|
||||
let id = gensym::fill(component.span, &mut component.id);
|
||||
self.component_fields_to_append
|
||||
.push(ComponentField::Export(ComponentExport {
|
||||
@@ -192,7 +190,6 @@ impl<'a> Expander<'a> {
|
||||
id: None,
|
||||
debug_name: None,
|
||||
name,
|
||||
url,
|
||||
kind: ComponentExportKind::component(component.span, id),
|
||||
ty: None,
|
||||
}));
|
||||
@@ -207,7 +204,6 @@ impl<'a> Expander<'a> {
|
||||
Some(ComponentField::Import(ComponentImport {
|
||||
span: component.span,
|
||||
name: import.name,
|
||||
url: import.url,
|
||||
item: ItemSig {
|
||||
span: component.span,
|
||||
id: component.id,
|
||||
@@ -220,7 +216,7 @@ impl<'a> Expander<'a> {
|
||||
}
|
||||
|
||||
fn expand_instance(&mut self, instance: &mut Instance<'a>) -> Option<ComponentField<'a>> {
|
||||
for (name, url) in instance.exports.names.drain(..) {
|
||||
for name in instance.exports.names.drain(..) {
|
||||
let id = gensym::fill(instance.span, &mut instance.id);
|
||||
self.component_fields_to_append
|
||||
.push(ComponentField::Export(ComponentExport {
|
||||
@@ -228,7 +224,6 @@ impl<'a> Expander<'a> {
|
||||
id: None,
|
||||
debug_name: None,
|
||||
name,
|
||||
url,
|
||||
kind: ComponentExportKind::instance(instance.span, id),
|
||||
ty: None,
|
||||
}));
|
||||
@@ -239,7 +234,6 @@ impl<'a> Expander<'a> {
|
||||
Some(ComponentField::Import(ComponentImport {
|
||||
span: instance.span,
|
||||
name: import.name,
|
||||
url: import.url,
|
||||
item: ItemSig {
|
||||
span: instance.span,
|
||||
id: instance.id,
|
||||
@@ -263,7 +257,13 @@ impl<'a> Expander<'a> {
|
||||
CanonicalFuncKind::Lift { ty, .. } => {
|
||||
self.expand_component_type_use(ty);
|
||||
}
|
||||
CanonicalFuncKind::Lower(_) => {}
|
||||
CanonicalFuncKind::Lower(_)
|
||||
| CanonicalFuncKind::ResourceNew(_)
|
||||
| CanonicalFuncKind::ResourceRep(_) => {}
|
||||
|
||||
CanonicalFuncKind::ResourceDrop(info) => {
|
||||
self.expand_component_val_ty(&mut info.ty);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -285,11 +285,32 @@ impl<'a> Expander<'a> {
|
||||
name: func.name,
|
||||
kind: CanonicalFuncKind::Lower(mem::take(info)),
|
||||
})),
|
||||
CoreFuncKind::ResourceNew(info) => Some(ComponentField::CanonicalFunc(CanonicalFunc {
|
||||
span: func.span,
|
||||
id: func.id,
|
||||
name: func.name,
|
||||
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,
|
||||
name: func.name,
|
||||
kind: CanonicalFuncKind::ResourceDrop(mem::take(info)),
|
||||
}))
|
||||
}
|
||||
CoreFuncKind::ResourceRep(info) => Some(ComponentField::CanonicalFunc(CanonicalFunc {
|
||||
span: func.span,
|
||||
id: func.id,
|
||||
name: func.name,
|
||||
kind: CanonicalFuncKind::ResourceRep(mem::take(info)),
|
||||
})),
|
||||
}
|
||||
}
|
||||
|
||||
fn expand_func(&mut self, func: &mut Func<'a>) -> Option<ComponentField<'a>> {
|
||||
for (name, url) in func.exports.names.drain(..) {
|
||||
for name in func.exports.names.drain(..) {
|
||||
let id = gensym::fill(func.span, &mut func.id);
|
||||
self.component_fields_to_append
|
||||
.push(ComponentField::Export(ComponentExport {
|
||||
@@ -297,7 +318,6 @@ impl<'a> Expander<'a> {
|
||||
id: None,
|
||||
debug_name: None,
|
||||
name,
|
||||
url,
|
||||
kind: ComponentExportKind::func(func.span, id),
|
||||
ty: None,
|
||||
}));
|
||||
@@ -308,7 +328,6 @@ impl<'a> Expander<'a> {
|
||||
Some(ComponentField::Import(ComponentImport {
|
||||
span: func.span,
|
||||
name: import.name,
|
||||
url: import.url,
|
||||
item: ItemSig {
|
||||
span: func.span,
|
||||
id: func.id,
|
||||
@@ -362,6 +381,7 @@ impl<'a> Expander<'a> {
|
||||
TypeDef::Func(f) => self.expand_func_ty(f),
|
||||
TypeDef::Component(c) => self.expand_component_ty(c),
|
||||
TypeDef::Instance(i) => self.expand_instance_ty(i),
|
||||
TypeDef::Resource(_) => {}
|
||||
}
|
||||
|
||||
let id = gensym::fill(field.span, &mut field.id);
|
||||
@@ -371,15 +391,15 @@ impl<'a> Expander<'a> {
|
||||
TypeDef::Func(t) => t.key().insert(self, index),
|
||||
TypeDef::Component(t) => t.key().insert(self, index),
|
||||
TypeDef::Instance(t) => t.key().insert(self, index),
|
||||
TypeDef::Resource(_) => {}
|
||||
}
|
||||
for (name, url) in field.exports.names.drain(..) {
|
||||
for name in field.exports.names.drain(..) {
|
||||
self.component_fields_to_append
|
||||
.push(ComponentField::Export(ComponentExport {
|
||||
span: field.span,
|
||||
id: None,
|
||||
debug_name: None,
|
||||
name,
|
||||
url,
|
||||
kind: ComponentExportKind::ty(field.span, id),
|
||||
ty: None,
|
||||
}));
|
||||
@@ -459,6 +479,7 @@ impl<'a> Expander<'a> {
|
||||
name: None,
|
||||
def: key.to_def(item.span),
|
||||
parent: None,
|
||||
final_type: None,
|
||||
}));
|
||||
let idx = Index::Id(id);
|
||||
t.index = Some(idx);
|
||||
@@ -552,6 +573,7 @@ impl<'a> Expander<'a> {
|
||||
self.expand_component_val_ty(ty);
|
||||
}
|
||||
}
|
||||
ComponentDefinedType::Own(_) | ComponentDefinedType::Borrow(_) => {}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
40
third_party/rust/wast/src/component/export.rs
vendored
40
third_party/rust/wast/src/component/export.rs
vendored
@@ -1,4 +1,4 @@
|
||||
use super::{ItemRef, ItemSigNoName};
|
||||
use super::{ComponentExternName, ItemRef, ItemSigNoName};
|
||||
use crate::kw;
|
||||
use crate::parser::{Cursor, Parse, Parser, Peek, Result};
|
||||
use crate::token::{Id, Index, NameAnnotation, Span};
|
||||
@@ -13,9 +13,7 @@ pub struct ComponentExport<'a> {
|
||||
/// An optional name for this instance stored in the custom `name` section.
|
||||
pub debug_name: Option<NameAnnotation<'a>>,
|
||||
/// The name of this export from the component.
|
||||
pub name: &'a str,
|
||||
/// The URL of the export.
|
||||
pub url: Option<&'a str>,
|
||||
pub name: ComponentExternName<'a>,
|
||||
/// The kind of export.
|
||||
pub kind: ComponentExportKind<'a>,
|
||||
/// The kind of export.
|
||||
@@ -28,7 +26,6 @@ impl<'a> Parse<'a> for ComponentExport<'a> {
|
||||
let id = parser.parse()?;
|
||||
let debug_name = parser.parse()?;
|
||||
let name = parser.parse()?;
|
||||
let url = parser.parse()?;
|
||||
let kind = parser.parse()?;
|
||||
let ty = if !parser.is_empty() {
|
||||
Some(parser.parens(|p| p.parse())?)
|
||||
@@ -40,7 +37,6 @@ impl<'a> Parse<'a> for ComponentExport<'a> {
|
||||
id,
|
||||
debug_name,
|
||||
name,
|
||||
url,
|
||||
kind,
|
||||
ty,
|
||||
})
|
||||
@@ -177,7 +173,7 @@ impl Peek for ComponentExportKind<'_> {
|
||||
#[derive(Debug, Default)]
|
||||
pub struct InlineExport<'a> {
|
||||
/// The extra names to export an item as, if any.
|
||||
pub names: Vec<(&'a str, Option<&'a str>)>,
|
||||
pub names: Vec<ComponentExternName<'a>>,
|
||||
}
|
||||
|
||||
impl<'a> Parse<'a> for InlineExport<'a> {
|
||||
@@ -186,7 +182,7 @@ impl<'a> Parse<'a> for InlineExport<'a> {
|
||||
while parser.peek::<Self>() {
|
||||
names.push(parser.parens(|p| {
|
||||
p.parse::<kw::export>()?;
|
||||
Ok((p.parse()?, p.parse()?))
|
||||
p.parse()
|
||||
})?);
|
||||
}
|
||||
Ok(InlineExport { names })
|
||||
@@ -203,15 +199,29 @@ impl Peek for InlineExport<'_> {
|
||||
Some(("export", cursor)) => cursor,
|
||||
_ => return false,
|
||||
};
|
||||
// Name
|
||||
let mut cursor = match cursor.string() {
|
||||
Some((_, cursor)) => cursor,
|
||||
|
||||
// (export "foo")
|
||||
if let Some((_, cursor)) = cursor.string() {
|
||||
return cursor.rparen().is_some();
|
||||
}
|
||||
|
||||
// (export (interface "foo"))
|
||||
let cursor = match cursor.lparen() {
|
||||
Some(cursor) => cursor,
|
||||
None => return false,
|
||||
};
|
||||
// Optional URL
|
||||
if let Some((_, c)) = cursor.string() {
|
||||
cursor = c;
|
||||
}
|
||||
let cursor = match cursor.keyword() {
|
||||
Some(("interface", cursor)) => cursor,
|
||||
_ => return false,
|
||||
};
|
||||
let cursor = match cursor.string() {
|
||||
Some((_, cursor)) => cursor,
|
||||
_ => return false,
|
||||
};
|
||||
let cursor = match cursor.rparen() {
|
||||
Some(cursor) => cursor,
|
||||
_ => return false,
|
||||
};
|
||||
cursor.rparen().is_some()
|
||||
}
|
||||
|
||||
|
||||
152
third_party/rust/wast/src/component/func.rs
vendored
152
third_party/rust/wast/src/component/func.rs
vendored
@@ -38,6 +38,7 @@ impl<'a> Parse<'a> for CoreFunc<'a> {
|
||||
|
||||
/// Represents the kind of core functions.
|
||||
#[derive(Debug)]
|
||||
#[allow(missing_docs)]
|
||||
pub enum CoreFuncKind<'a> {
|
||||
/// The core function is defined in terms of lowering a component function.
|
||||
///
|
||||
@@ -46,7 +47,10 @@ pub enum CoreFuncKind<'a> {
|
||||
/// The core function is defined in terms of aliasing a module instance export.
|
||||
///
|
||||
/// The core function is actually a member of the core alias section.
|
||||
Alias(InlineExportAlias<'a>),
|
||||
Alias(InlineExportAlias<'a, true>),
|
||||
ResourceNew(CanonResourceNew<'a>),
|
||||
ResourceDrop(CanonResourceDrop<'a>),
|
||||
ResourceRep(CanonResourceRep<'a>),
|
||||
}
|
||||
|
||||
impl<'a> Parse<'a> for CoreFuncKind<'a> {
|
||||
@@ -55,9 +59,20 @@ impl<'a> Parse<'a> for CoreFuncKind<'a> {
|
||||
let mut l = parser.lookahead1();
|
||||
if l.peek::<kw::canon>() {
|
||||
parser.parse::<kw::canon>()?;
|
||||
Ok(Self::Lower(parser.parse()?))
|
||||
} else if l.peek::<kw::alias>() {
|
||||
Ok(Self::Alias(parser.parse()?))
|
||||
return Ok(Self::Alias(parser.parse()?));
|
||||
} else {
|
||||
return Err(l.error());
|
||||
}
|
||||
let mut l = parser.lookahead1();
|
||||
if l.peek::<kw::lower>() {
|
||||
Ok(CoreFuncKind::Lower(parser.parse()?))
|
||||
} else if l.peek::<kw::resource_new>() {
|
||||
Ok(CoreFuncKind::ResourceNew(parser.parse()?))
|
||||
} else if l.peek::<kw::resource_drop>() {
|
||||
Ok(CoreFuncKind::ResourceDrop(parser.parse()?))
|
||||
} else if l.peek::<kw::resource_rep>() {
|
||||
Ok(CoreFuncKind::ResourceRep(parser.parse()?))
|
||||
} else {
|
||||
Err(l.error())
|
||||
}
|
||||
@@ -128,7 +143,7 @@ pub enum FuncKind<'a> {
|
||||
/// The function is defined in terms of aliasing a component instance export.
|
||||
///
|
||||
/// The function is actually a member of the alias section.
|
||||
Alias(InlineExportAlias<'a>),
|
||||
Alias(InlineExportAlias<'a, false>),
|
||||
}
|
||||
|
||||
impl<'a> Parse<'a> for FuncKind<'a> {
|
||||
@@ -189,29 +204,49 @@ impl<'a> Parse<'a> for CanonicalFunc<'a> {
|
||||
kind: CanonicalFuncKind::Lift { info, ty },
|
||||
})
|
||||
} else if parser.peek::<kw::lower>() {
|
||||
let info = parser.parse()?;
|
||||
let (id, name) = parser.parens(|parser| {
|
||||
parser.parse::<kw::core>()?;
|
||||
parser.parse::<kw::func>()?;
|
||||
let id = parser.parse()?;
|
||||
let name = parser.parse()?;
|
||||
Ok((id, name))
|
||||
})?;
|
||||
|
||||
Ok(Self {
|
||||
span,
|
||||
id,
|
||||
name,
|
||||
kind: CanonicalFuncKind::Lower(info),
|
||||
})
|
||||
Self::parse_core_func(span, parser, CanonicalFuncKind::Lower)
|
||||
} else if parser.peek::<kw::resource_new>() {
|
||||
Self::parse_core_func(span, parser, CanonicalFuncKind::ResourceNew)
|
||||
} else if parser.peek::<kw::resource_drop>() {
|
||||
Self::parse_core_func(span, parser, CanonicalFuncKind::ResourceDrop)
|
||||
} 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`"))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> CanonicalFunc<'a> {
|
||||
fn parse_core_func<T>(
|
||||
span: Span,
|
||||
parser: Parser<'a>,
|
||||
variant: fn(T) -> CanonicalFuncKind<'a>,
|
||||
) -> Result<Self>
|
||||
where
|
||||
T: Parse<'a>,
|
||||
{
|
||||
let info = parser.parse()?;
|
||||
let (id, name) = parser.parens(|parser| {
|
||||
parser.parse::<kw::core>()?;
|
||||
parser.parse::<kw::func>()?;
|
||||
let id = parser.parse()?;
|
||||
let name = parser.parse()?;
|
||||
Ok((id, name))
|
||||
})?;
|
||||
|
||||
Ok(Self {
|
||||
span,
|
||||
id,
|
||||
name,
|
||||
kind: variant(info),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/// Possible ways to define a canonical function in the text format.
|
||||
#[derive(Debug)]
|
||||
#[allow(missing_docs)]
|
||||
pub enum CanonicalFuncKind<'a> {
|
||||
/// A canonical function that is defined in terms of lifting a core function.
|
||||
Lift {
|
||||
@@ -222,6 +257,10 @@ pub enum CanonicalFuncKind<'a> {
|
||||
},
|
||||
/// A canonical function that is defined in terms of lowering a component function.
|
||||
Lower(CanonLower<'a>),
|
||||
|
||||
ResourceNew(CanonResourceNew<'a>),
|
||||
ResourceDrop(CanonResourceDrop<'a>),
|
||||
ResourceRep(CanonResourceRep<'a>),
|
||||
}
|
||||
|
||||
/// Information relating to lifting a core function.
|
||||
@@ -295,6 +334,81 @@ impl Default for CanonLower<'_> {
|
||||
}
|
||||
}
|
||||
|
||||
/// Information relating to the `resource.new` intrinsic.
|
||||
#[derive(Debug)]
|
||||
pub struct CanonResourceNew<'a> {
|
||||
/// The resource type that this intrinsic creates an owned reference to.
|
||||
pub ty: Index<'a>,
|
||||
}
|
||||
|
||||
impl<'a> Parse<'a> for CanonResourceNew<'a> {
|
||||
fn parse(parser: Parser<'a>) -> Result<Self> {
|
||||
parser.parse::<kw::resource_new>()?;
|
||||
|
||||
Ok(Self {
|
||||
ty: parser.parse()?,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for CanonResourceNew<'_> {
|
||||
fn default() -> Self {
|
||||
CanonResourceNew {
|
||||
ty: Index::Num(0, Span::from_offset(0)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// 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>,
|
||||
}
|
||||
|
||||
impl<'a> Parse<'a> for CanonResourceDrop<'a> {
|
||||
fn parse(parser: Parser<'a>) -> Result<Self> {
|
||||
parser.parse::<kw::resource_drop>()?;
|
||||
|
||||
Ok(Self {
|
||||
ty: parser.parse()?,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for CanonResourceDrop<'_> {
|
||||
fn default() -> Self {
|
||||
CanonResourceDrop {
|
||||
ty: ComponentValType::Ref(Index::Num(0, Span::from_offset(0))),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Information relating to the `resource.rep` intrinsic.
|
||||
#[derive(Debug)]
|
||||
pub struct CanonResourceRep<'a> {
|
||||
/// The resource type that this intrinsic is accessing.
|
||||
pub ty: Index<'a>,
|
||||
}
|
||||
|
||||
impl<'a> Parse<'a> for CanonResourceRep<'a> {
|
||||
fn parse(parser: Parser<'a>) -> Result<Self> {
|
||||
parser.parse::<kw::resource_rep>()?;
|
||||
|
||||
Ok(Self {
|
||||
ty: parser.parse()?,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for CanonResourceRep<'_> {
|
||||
fn default() -> Self {
|
||||
CanonResourceRep {
|
||||
ty: Index::Num(0, Span::from_offset(0)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
/// Canonical ABI options.
|
||||
pub enum CanonOpt<'a> {
|
||||
|
||||
85
third_party/rust/wast/src/component/import.rs
vendored
85
third_party/rust/wast/src/component/import.rs
vendored
@@ -1,18 +1,15 @@
|
||||
use crate::component::*;
|
||||
use crate::kw;
|
||||
use crate::parser::{Cursor, Parse, Parser, Peek, Result};
|
||||
use crate::token::Index;
|
||||
use crate::token::{Id, NameAnnotation, Span};
|
||||
use crate::token::{Id, Index, LParen, NameAnnotation, Span};
|
||||
|
||||
/// An `import` statement and entry in a WebAssembly component.
|
||||
#[derive(Debug)]
|
||||
pub struct ComponentImport<'a> {
|
||||
/// Where this `import` was defined
|
||||
pub span: Span,
|
||||
/// The name of the item to import.
|
||||
pub name: &'a str,
|
||||
/// The optional URL of the import.
|
||||
pub url: Option<&'a str>,
|
||||
/// The name of the item being imported.
|
||||
pub name: ComponentExternName<'a>,
|
||||
/// The item that's being imported.
|
||||
pub item: ItemSig<'a>,
|
||||
}
|
||||
@@ -21,14 +18,30 @@ impl<'a> Parse<'a> for ComponentImport<'a> {
|
||||
fn parse(parser: Parser<'a>) -> Result<Self> {
|
||||
let span = parser.parse::<kw::import>()?.0;
|
||||
let name = parser.parse()?;
|
||||
let url = parser.parse()?;
|
||||
let item = parser.parens(|p| p.parse())?;
|
||||
Ok(ComponentImport {
|
||||
span,
|
||||
name,
|
||||
url,
|
||||
item,
|
||||
})
|
||||
Ok(ComponentImport { span, name, item })
|
||||
}
|
||||
}
|
||||
|
||||
/// The different ways an import can be named.
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
pub enum ComponentExternName<'a> {
|
||||
/// This is a kebab-named import where a top-level name is assigned.
|
||||
Kebab(&'a str),
|
||||
/// This is an interface import where the string is an ID.
|
||||
Interface(&'a str),
|
||||
}
|
||||
|
||||
impl<'a> Parse<'a> for ComponentExternName<'a> {
|
||||
fn parse(parser: Parser<'a>) -> Result<Self> {
|
||||
if parser.peek::<LParen>() {
|
||||
Ok(ComponentExternName::Interface(parser.parens(|p| {
|
||||
p.parse::<kw::interface>()?;
|
||||
p.parse()
|
||||
})?))
|
||||
} else {
|
||||
Ok(ComponentExternName::Kebab(parser.parse()?))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -119,13 +132,23 @@ pub enum ItemSigKind<'a> {
|
||||
pub enum TypeBounds<'a> {
|
||||
/// The equality type bounds.
|
||||
Eq(Index<'a>),
|
||||
/// A resource type is imported/exported,
|
||||
SubResource,
|
||||
}
|
||||
|
||||
impl<'a> Parse<'a> for TypeBounds<'a> {
|
||||
fn parse(parser: Parser<'a>) -> Result<Self> {
|
||||
// Currently this is the only supported type bounds.
|
||||
parser.parse::<kw::eq>()?;
|
||||
Ok(Self::Eq(parser.parse()?))
|
||||
let mut l = parser.lookahead1();
|
||||
if l.peek::<kw::eq>() {
|
||||
parser.parse::<kw::eq>()?;
|
||||
Ok(Self::Eq(parser.parse()?))
|
||||
} else if l.peek::<kw::sub>() {
|
||||
parser.parse::<kw::sub>()?;
|
||||
parser.parse::<kw::resource>()?;
|
||||
Ok(Self::SubResource)
|
||||
} else {
|
||||
Err(l.error())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -136,19 +159,14 @@ impl<'a> Parse<'a> for TypeBounds<'a> {
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct InlineImport<'a> {
|
||||
/// The name of the item being imported.
|
||||
pub name: &'a str,
|
||||
/// The optional URL of the item being imported.
|
||||
pub url: Option<&'a str>,
|
||||
pub name: ComponentExternName<'a>,
|
||||
}
|
||||
|
||||
impl<'a> Parse<'a> for InlineImport<'a> {
|
||||
fn parse(parser: Parser<'a>) -> Result<Self> {
|
||||
parser.parens(|p| {
|
||||
p.parse::<kw::import>()?;
|
||||
Ok(InlineImport {
|
||||
name: p.parse()?,
|
||||
url: p.parse()?,
|
||||
})
|
||||
Ok(InlineImport { name: p.parse()? })
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -163,9 +181,28 @@ impl Peek for InlineImport<'_> {
|
||||
Some(("import", cursor)) => cursor,
|
||||
_ => return false,
|
||||
};
|
||||
|
||||
// (import "foo")
|
||||
if let Some((_, cursor)) = cursor.string() {
|
||||
return cursor.rparen().is_some();
|
||||
}
|
||||
|
||||
// (import (interface "foo"))
|
||||
let cursor = match cursor.lparen() {
|
||||
Some(cursor) => cursor,
|
||||
None => return false,
|
||||
};
|
||||
let cursor = match cursor.keyword() {
|
||||
Some(("interface", cursor)) => cursor,
|
||||
_ => return false,
|
||||
};
|
||||
let cursor = match cursor.string() {
|
||||
Some((_, cursor)) => cursor,
|
||||
None => return false,
|
||||
_ => return false,
|
||||
};
|
||||
let cursor = match cursor.rparen() {
|
||||
Some(cursor) => cursor,
|
||||
_ => return false,
|
||||
};
|
||||
cursor.rparen().is_some()
|
||||
}
|
||||
|
||||
39
third_party/rust/wast/src/component/resolve.rs
vendored
39
third_party/rust/wast/src/component/resolve.rs
vendored
@@ -1,5 +1,5 @@
|
||||
use crate::component::*;
|
||||
use crate::core;
|
||||
use crate::core::{self, ValType};
|
||||
use crate::kw;
|
||||
use crate::names::Namespace;
|
||||
use crate::token::Span;
|
||||
@@ -257,6 +257,7 @@ impl<'a> Resolver<'a> {
|
||||
ItemSigKind::Value(t) => self.component_val_type(&mut t.0),
|
||||
ItemSigKind::Type(b) => match b {
|
||||
TypeBounds::Eq(i) => self.resolve_ns(i, Ns::Type),
|
||||
TypeBounds::SubResource => Ok(()),
|
||||
},
|
||||
}
|
||||
}
|
||||
@@ -372,6 +373,9 @@ impl<'a> Resolver<'a> {
|
||||
self.component_item_ref(&mut info.func)?;
|
||||
&mut info.opts
|
||||
}
|
||||
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),
|
||||
};
|
||||
|
||||
for opt in opts {
|
||||
@@ -465,6 +469,9 @@ impl<'a> Resolver<'a> {
|
||||
self.component_val_type(ty)?;
|
||||
}
|
||||
}
|
||||
ComponentDefinedType::Own(t) | ComponentDefinedType::Borrow(t) => {
|
||||
self.resolve_ns(t, Ns::Type)?;
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
@@ -513,6 +520,29 @@ impl<'a> Resolver<'a> {
|
||||
self.instance_type(i)?;
|
||||
self.stack.pop();
|
||||
}
|
||||
TypeDef::Resource(r) => {
|
||||
match &mut r.rep {
|
||||
ValType::I32 | ValType::I64 | ValType::F32 | ValType::F64 | ValType::V128 => {}
|
||||
ValType::Ref(r) => match &mut r.heap {
|
||||
core::HeapType::Func
|
||||
| core::HeapType::Extern
|
||||
| core::HeapType::Any
|
||||
| core::HeapType::Eq
|
||||
| core::HeapType::Array
|
||||
| core::HeapType::I31
|
||||
| core::HeapType::Struct
|
||||
| core::HeapType::None
|
||||
| core::HeapType::NoFunc
|
||||
| core::HeapType::NoExtern => {}
|
||||
core::HeapType::Index(id) => {
|
||||
self.resolve_ns(id, Ns::Type)?;
|
||||
}
|
||||
},
|
||||
}
|
||||
if let Some(dtor) = &mut r.dtor {
|
||||
self.core_item_ref(dtor)?;
|
||||
}
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
@@ -788,7 +818,12 @@ impl<'a> ComponentState<'a> {
|
||||
ComponentField::Type(t) => self.types.register(t.id, "type")?,
|
||||
ComponentField::CanonicalFunc(f) => match &f.kind {
|
||||
CanonicalFuncKind::Lift { .. } => self.funcs.register(f.id, "func")?,
|
||||
CanonicalFuncKind::Lower(_) => self.core_funcs.register(f.id, "core func")?,
|
||||
CanonicalFuncKind::Lower(_)
|
||||
| CanonicalFuncKind::ResourceNew(_)
|
||||
| CanonicalFuncKind::ResourceRep(_)
|
||||
| CanonicalFuncKind::ResourceDrop(_) => {
|
||||
self.core_funcs.register(f.id, "core func")?
|
||||
}
|
||||
},
|
||||
ComponentField::CoreFunc(_) | ComponentField::Func(_) => {
|
||||
unreachable!("should be expanded already")
|
||||
|
||||
78
third_party/rust/wast/src/component/types.rs
vendored
78
third_party/rust/wast/src/component/types.rs
vendored
@@ -138,12 +138,26 @@ pub struct Type<'a> {
|
||||
pub def: TypeDef<'a>,
|
||||
}
|
||||
|
||||
impl<'a> Parse<'a> for Type<'a> {
|
||||
fn parse(parser: Parser<'a>) -> Result<Self> {
|
||||
impl<'a> Type<'a> {
|
||||
/// Parses a `Type` while allowing inline `(export "...")` names to be
|
||||
/// defined.
|
||||
pub fn parse_maybe_with_inline_exports(parser: Parser<'a>) -> Result<Self> {
|
||||
Type::parse(parser, true)
|
||||
}
|
||||
|
||||
fn parse_no_inline_exports(parser: Parser<'a>) -> Result<Self> {
|
||||
Type::parse(parser, false)
|
||||
}
|
||||
|
||||
fn parse(parser: Parser<'a>, allow_inline_exports: bool) -> Result<Self> {
|
||||
let span = parser.parse::<kw::r#type>()?.0;
|
||||
let id = parser.parse()?;
|
||||
let name = parser.parse()?;
|
||||
let exports = parser.parse()?;
|
||||
let exports = if allow_inline_exports {
|
||||
parser.parse()?
|
||||
} else {
|
||||
Default::default()
|
||||
};
|
||||
let def = parser.parse()?;
|
||||
|
||||
Ok(Self {
|
||||
@@ -167,6 +181,8 @@ pub enum TypeDef<'a> {
|
||||
Component(ComponentType<'a>),
|
||||
/// An instance type.
|
||||
Instance(InstanceType<'a>),
|
||||
/// A resource type.
|
||||
Resource(ResourceType<'a>),
|
||||
}
|
||||
|
||||
impl<'a> Parse<'a> for TypeDef<'a> {
|
||||
@@ -183,6 +199,9 @@ impl<'a> Parse<'a> for TypeDef<'a> {
|
||||
} else if l.peek::<kw::instance>() {
|
||||
parser.parse::<kw::instance>()?;
|
||||
Ok(Self::Instance(parser.parse()?))
|
||||
} else if l.peek::<kw::resource>() {
|
||||
parser.parse::<kw::resource>()?;
|
||||
Ok(Self::Resource(parser.parse()?))
|
||||
} else {
|
||||
Ok(Self::Defined(ComponentDefinedType::parse_non_primitive(
|
||||
parser, l,
|
||||
@@ -356,6 +375,8 @@ pub enum ComponentDefinedType<'a> {
|
||||
Union(Union<'a>),
|
||||
Option(OptionType<'a>),
|
||||
Result(ResultType<'a>),
|
||||
Own(Index<'a>),
|
||||
Borrow(Index<'a>),
|
||||
}
|
||||
|
||||
impl<'a> ComponentDefinedType<'a> {
|
||||
@@ -379,6 +400,12 @@ impl<'a> ComponentDefinedType<'a> {
|
||||
Ok(Self::Option(parser.parse()?))
|
||||
} else if l.peek::<kw::result>() {
|
||||
Ok(Self::Result(parser.parse()?))
|
||||
} else if l.peek::<kw::own>() {
|
||||
parser.parse::<kw::own>()?;
|
||||
Ok(Self::Own(parser.parse()?))
|
||||
} else if l.peek::<kw::borrow>() {
|
||||
parser.parse::<kw::borrow>()?;
|
||||
Ok(Self::Borrow(parser.parse()?))
|
||||
} else {
|
||||
Err(l.error())
|
||||
}
|
||||
@@ -409,6 +436,8 @@ impl Peek for ComponentDefinedType<'_> {
|
||||
| Some(("union", _))
|
||||
| Some(("option", _))
|
||||
| Some(("result", _))
|
||||
| Some(("own", _))
|
||||
| Some(("borrow", _))
|
||||
),
|
||||
None => false,
|
||||
}
|
||||
@@ -739,9 +768,7 @@ pub struct ComponentExportType<'a> {
|
||||
/// Where this export was defined.
|
||||
pub span: Span,
|
||||
/// The name of this export.
|
||||
pub name: &'a str,
|
||||
/// The optional URL of this export.
|
||||
pub url: Option<&'a str>,
|
||||
pub name: ComponentExternName<'a>,
|
||||
/// The signature of the item.
|
||||
pub item: ItemSig<'a>,
|
||||
}
|
||||
@@ -752,19 +779,13 @@ impl<'a> Parse<'a> for ComponentExportType<'a> {
|
||||
let id = parser.parse()?;
|
||||
let debug_name = parser.parse()?;
|
||||
let name = parser.parse()?;
|
||||
let url = parser.parse()?;
|
||||
let item = parser.parens(|p| {
|
||||
let mut item = p.parse::<ItemSigNoName<'_>>()?.0;
|
||||
item.id = id;
|
||||
item.name = debug_name;
|
||||
Ok(item)
|
||||
})?;
|
||||
Ok(Self {
|
||||
span,
|
||||
name,
|
||||
url,
|
||||
item,
|
||||
})
|
||||
Ok(Self { span, name, item })
|
||||
}
|
||||
}
|
||||
|
||||
@@ -805,7 +826,7 @@ impl<'a> Parse<'a> for ComponentTypeDecl<'a> {
|
||||
if l.peek::<kw::core>() {
|
||||
Ok(Self::CoreType(parser.parse()?))
|
||||
} else if l.peek::<kw::r#type>() {
|
||||
Ok(Self::Type(parser.parse()?))
|
||||
Ok(Self::Type(Type::parse_no_inline_exports(parser)?))
|
||||
} else if l.peek::<kw::alias>() {
|
||||
Ok(Self::Alias(parser.parse()?))
|
||||
} else if l.peek::<kw::import>() {
|
||||
@@ -863,7 +884,7 @@ impl<'a> Parse<'a> for InstanceTypeDecl<'a> {
|
||||
if l.peek::<kw::core>() {
|
||||
Ok(Self::CoreType(parser.parse()?))
|
||||
} else if l.peek::<kw::r#type>() {
|
||||
Ok(Self::Type(parser.parse()?))
|
||||
Ok(Self::Type(Type::parse_no_inline_exports(parser)?))
|
||||
} else if l.peek::<kw::alias>() {
|
||||
Ok(Self::Alias(parser.parse()?))
|
||||
} else if l.peek::<kw::export>() {
|
||||
@@ -884,6 +905,33 @@ impl<'a> Parse<'a> for Vec<InstanceTypeDecl<'a>> {
|
||||
}
|
||||
}
|
||||
|
||||
/// A type definition for an instance type.
|
||||
#[derive(Debug)]
|
||||
pub struct ResourceType<'a> {
|
||||
/// Representation, in core WebAssembly, of this resource.
|
||||
pub rep: core::ValType<'a>,
|
||||
/// The declarations of the instance type.
|
||||
pub dtor: Option<CoreItemRef<'a, kw::func>>,
|
||||
}
|
||||
|
||||
impl<'a> Parse<'a> for ResourceType<'a> {
|
||||
fn parse(parser: Parser<'a>) -> Result<Self> {
|
||||
let rep = parser.parens(|p| {
|
||||
p.parse::<kw::rep>()?;
|
||||
p.parse()
|
||||
})?;
|
||||
let dtor = if parser.is_empty() {
|
||||
None
|
||||
} else {
|
||||
Some(parser.parens(|p| {
|
||||
p.parse::<kw::dtor>()?;
|
||||
p.parens(|p| p.parse())
|
||||
})?)
|
||||
};
|
||||
Ok(Self { rep, dtor })
|
||||
}
|
||||
}
|
||||
|
||||
/// A value type declaration used for values in import signatures.
|
||||
#[derive(Debug)]
|
||||
pub struct ComponentValTypeUse<'a>(pub ComponentValType<'a>);
|
||||
|
||||
54
third_party/rust/wast/src/core/binary.rs
vendored
54
third_party/rust/wast/src/core/binary.rs
vendored
@@ -108,8 +108,8 @@ impl Encoder<'_> {
|
||||
|
||||
fn custom_sections(&mut self, place: CustomPlace) {
|
||||
for entry in self.customs.iter() {
|
||||
if entry.place == place {
|
||||
self.section(0, &(entry.name, entry));
|
||||
if entry.place() == place {
|
||||
self.section(0, &(entry.name(), entry));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -173,10 +173,25 @@ impl Encode for RecOrType<'_> {
|
||||
|
||||
impl Encode for Type<'_> {
|
||||
fn encode(&self, e: &mut Vec<u8>) {
|
||||
if let Some(parent) = &self.parent {
|
||||
e.push(0x50);
|
||||
(1 as usize).encode(e);
|
||||
parent.encode(e);
|
||||
match (&self.parent, self.final_type) {
|
||||
(Some(parent), Some(true)) => {
|
||||
// Type is final with a supertype
|
||||
e.push(0x4e);
|
||||
e.push(0x01);
|
||||
parent.encode(e);
|
||||
}
|
||||
(Some(parent), Some(false) | None) => {
|
||||
// Type is not final and has a declared supertype
|
||||
e.push(0x50);
|
||||
e.push(0x01);
|
||||
parent.encode(e);
|
||||
}
|
||||
(None, Some(false)) => {
|
||||
// Sub was used without any declared supertype
|
||||
e.push(0x50);
|
||||
e.push(0x00);
|
||||
}
|
||||
(None, _) => {} // No supertype, sub wasn't used
|
||||
}
|
||||
match &self.def {
|
||||
TypeDef::Func(func) => {
|
||||
@@ -1043,6 +1058,15 @@ impl<'a> Encode for SelectTypes<'a> {
|
||||
}
|
||||
|
||||
impl Encode for Custom<'_> {
|
||||
fn encode(&self, e: &mut Vec<u8>) {
|
||||
match self {
|
||||
Custom::Raw(r) => r.encode(e),
|
||||
Custom::Producers(p) => p.encode(e),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Encode for RawCustomSection<'_> {
|
||||
fn encode(&self, e: &mut Vec<u8>) {
|
||||
for list in self.data.iter() {
|
||||
e.extend_from_slice(list);
|
||||
@@ -1050,6 +1074,12 @@ impl Encode for Custom<'_> {
|
||||
}
|
||||
}
|
||||
|
||||
impl Encode for Producers<'_> {
|
||||
fn encode(&self, e: &mut Vec<u8>) {
|
||||
self.fields.encode(e);
|
||||
}
|
||||
}
|
||||
|
||||
impl Encode for Tag<'_> {
|
||||
fn encode(&self, e: &mut Vec<u8>) {
|
||||
self.ty.encode(e);
|
||||
@@ -1161,7 +1191,11 @@ impl Encode for BrOnCast<'_> {
|
||||
fn encode(&self, e: &mut Vec<u8>) {
|
||||
e.push(0xfb);
|
||||
e.push(0x4f);
|
||||
e.push(br_on_cast_flags(false, self.from_type.nullable, self.to_type.nullable));
|
||||
e.push(br_on_cast_flags(
|
||||
false,
|
||||
self.from_type.nullable,
|
||||
self.to_type.nullable,
|
||||
));
|
||||
self.label.encode(e);
|
||||
self.from_type.heap.encode(e);
|
||||
self.to_type.heap.encode(e);
|
||||
@@ -1172,7 +1206,11 @@ impl Encode for BrOnCastFail<'_> {
|
||||
fn encode(&self, e: &mut Vec<u8>) {
|
||||
e.push(0xfb);
|
||||
e.push(0x4f);
|
||||
e.push(br_on_cast_flags(true, self.from_type.nullable, self.to_type.nullable));
|
||||
e.push(br_on_cast_flags(
|
||||
true,
|
||||
self.from_type.nullable,
|
||||
self.to_type.nullable,
|
||||
));
|
||||
self.label.encode(e);
|
||||
self.from_type.heap.encode(e);
|
||||
self.to_type.heap.encode(e);
|
||||
|
||||
91
third_party/rust/wast/src/core/custom.rs
vendored
91
third_party/rust/wast/src/core/custom.rs
vendored
@@ -2,9 +2,46 @@ use crate::parser::{Parse, Parser, Result};
|
||||
use crate::token::{self, Span};
|
||||
use crate::{annotation, kw};
|
||||
|
||||
/// A custom section within a wasm module.
|
||||
#[derive(Debug)]
|
||||
pub enum Custom<'a> {
|
||||
/// A raw custom section with the manual placement and bytes specified.
|
||||
Raw(RawCustomSection<'a>),
|
||||
/// A producers custom section.
|
||||
Producers(Producers<'a>),
|
||||
}
|
||||
|
||||
impl Custom<'_> {
|
||||
/// Where this custom section is placed.
|
||||
pub fn place(&self) -> CustomPlace {
|
||||
match self {
|
||||
Custom::Raw(s) => s.place,
|
||||
Custom::Producers(_) => CustomPlace::AfterLast,
|
||||
}
|
||||
}
|
||||
|
||||
/// The name of this custom section
|
||||
pub fn name(&self) -> &str {
|
||||
match self {
|
||||
Custom::Raw(s) => s.name,
|
||||
Custom::Producers(_) => "producers",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Parse<'a> for Custom<'a> {
|
||||
fn parse(parser: Parser<'a>) -> Result<Self> {
|
||||
if parser.peek::<annotation::producers>() {
|
||||
Ok(Custom::Producers(parser.parse()?))
|
||||
} else {
|
||||
Ok(Custom::Raw(parser.parse()?))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// A wasm custom section within a module.
|
||||
#[derive(Debug)]
|
||||
pub struct Custom<'a> {
|
||||
pub struct RawCustomSection<'a> {
|
||||
/// Where this `@custom` was defined.
|
||||
pub span: Span,
|
||||
|
||||
@@ -49,7 +86,7 @@ pub enum CustomPlaceAnchor {
|
||||
Tag,
|
||||
}
|
||||
|
||||
impl<'a> Parse<'a> for Custom<'a> {
|
||||
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()?;
|
||||
@@ -62,7 +99,7 @@ impl<'a> Parse<'a> for Custom<'a> {
|
||||
while !parser.is_empty() {
|
||||
data.push(parser.parse()?);
|
||||
}
|
||||
Ok(Custom {
|
||||
Ok(RawCustomSection {
|
||||
span,
|
||||
name,
|
||||
place,
|
||||
@@ -149,3 +186,51 @@ impl<'a> Parse<'a> for CustomPlaceAnchor {
|
||||
Err(parser.error("expected a valid section name"))
|
||||
}
|
||||
}
|
||||
|
||||
/// A producers custom section
|
||||
#[allow(missing_docs)]
|
||||
#[derive(Debug)]
|
||||
pub struct Producers<'a> {
|
||||
pub fields: Vec<(&'a str, Vec<(&'a str, &'a str)>)>,
|
||||
}
|
||||
|
||||
impl<'a> Parse<'a> for Producers<'a> {
|
||||
fn parse(parser: Parser<'a>) -> Result<Self> {
|
||||
parser.parse::<annotation::producers>()?.0;
|
||||
let mut languages = Vec::new();
|
||||
let mut sdks = Vec::new();
|
||||
let mut processed_by = Vec::new();
|
||||
while !parser.is_empty() {
|
||||
parser.parens(|parser| {
|
||||
let mut l = parser.lookahead1();
|
||||
let dst = if l.peek::<kw::language>() {
|
||||
parser.parse::<kw::language>()?;
|
||||
&mut languages
|
||||
} else if l.peek::<kw::sdk>() {
|
||||
parser.parse::<kw::sdk>()?;
|
||||
&mut sdks
|
||||
} else if l.peek::<kw::processed_by>() {
|
||||
parser.parse::<kw::processed_by>()?;
|
||||
&mut processed_by
|
||||
} else {
|
||||
return Err(l.error());
|
||||
};
|
||||
|
||||
dst.push((parser.parse()?, parser.parse()?));
|
||||
Ok(())
|
||||
})?;
|
||||
}
|
||||
|
||||
let mut fields = Vec::new();
|
||||
if !languages.is_empty() {
|
||||
fields.push(("language", languages));
|
||||
}
|
||||
if !sdks.is_empty() {
|
||||
fields.push(("sdk", sdks));
|
||||
}
|
||||
if !processed_by.is_empty() {
|
||||
fields.push(("processed-by", processed_by));
|
||||
}
|
||||
Ok(Producers { fields })
|
||||
}
|
||||
}
|
||||
|
||||
4
third_party/rust/wast/src/core/expr.rs
vendored
4
third_party/rust/wast/src/core/expr.rs
vendored
@@ -522,8 +522,8 @@ instructions! {
|
||||
ReturnCallIndirect(CallIndirect<'a>) : [0x13] : "return_call_indirect",
|
||||
|
||||
// function-references proposal
|
||||
CallRef(HeapType<'a>) : [0x14] : "call_ref",
|
||||
ReturnCallRef(HeapType<'a>) : [0x15] : "return_call_ref",
|
||||
CallRef(Index<'a>) : [0x14] : "call_ref",
|
||||
ReturnCallRef(Index<'a>) : [0x15] : "return_call_ref",
|
||||
FuncBind(FuncBindType<'a>) : [0x16] : "func.bind",
|
||||
Let(LetType<'a>) : [0x17] : "let",
|
||||
|
||||
|
||||
5
third_party/rust/wast/src/core/module.rs
vendored
5
third_party/rust/wast/src/core/module.rs
vendored
@@ -110,7 +110,6 @@ 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 span = parser.parse::<kw::module>()?.0;
|
||||
let id = parser.parse()?;
|
||||
let name = parser.parse()?;
|
||||
@@ -155,6 +154,8 @@ 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)?);
|
||||
@@ -202,7 +203,7 @@ impl<'a> Parse<'a> for ModuleField<'a> {
|
||||
if parser.peek::<kw::tag>() {
|
||||
return Ok(ModuleField::Tag(parser.parse()?));
|
||||
}
|
||||
if parser.peek::<annotation::custom>() {
|
||||
if parser.peek::<annotation::custom>() || parser.peek::<annotation::producers>() {
|
||||
return Ok(ModuleField::Custom(parser.parse()?));
|
||||
}
|
||||
Err(parser.error("expected valid module field"))
|
||||
|
||||
@@ -482,6 +482,10 @@ impl<'a, 'b> ExprResolver<'a, 'b> {
|
||||
self.resolver.resolve_type_use(&mut c.ty)?;
|
||||
}
|
||||
|
||||
CallRef(i) | ReturnCallRef(i) => {
|
||||
self.resolver.resolve(i, Ns::Type)?;
|
||||
}
|
||||
|
||||
FuncBind(b) => {
|
||||
self.resolver.resolve_type_use(&mut b.ty)?;
|
||||
}
|
||||
@@ -637,7 +641,7 @@ impl<'a, 'b> ExprResolver<'a, 'b> {
|
||||
self.resolver.elems.resolve(&mut a.segment, "elem")?;
|
||||
}
|
||||
|
||||
RefNull(ty) | CallRef(ty) | ReturnCallRef(ty) => self.resolver.resolve_heaptype(ty)?,
|
||||
RefNull(ty) => self.resolver.resolve_heaptype(ty)?,
|
||||
|
||||
_ => {}
|
||||
}
|
||||
|
||||
@@ -218,6 +218,7 @@ impl<'a> Expander<'a> {
|
||||
name: None,
|
||||
def: key.to_def(span),
|
||||
parent: None,
|
||||
final_type: None,
|
||||
}));
|
||||
let idx = Index::Id(id);
|
||||
key.insert(self, idx);
|
||||
|
||||
18
third_party/rust/wast/src/core/types.rs
vendored
18
third_party/rust/wast/src/core/types.rs
vendored
@@ -724,6 +724,8 @@ pub struct Type<'a> {
|
||||
pub def: TypeDef<'a>,
|
||||
/// The declared parent type of this definition.
|
||||
pub parent: Option<Index<'a>>,
|
||||
/// Whether this type is final or not. By default types are final.
|
||||
pub final_type: Option<bool>,
|
||||
}
|
||||
|
||||
impl<'a> Peek for Type<'a> {
|
||||
@@ -741,19 +743,28 @@ impl<'a> Parse<'a> for Type<'a> {
|
||||
let id = parser.parse()?;
|
||||
let name = parser.parse()?;
|
||||
|
||||
let (parent, def) = 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>() {
|
||||
parser.parse::<kw::r#final>()?;
|
||||
Some(true)
|
||||
} else {
|
||||
Some(false)
|
||||
};
|
||||
|
||||
let parent = if parser.peek::<Index<'a>>() {
|
||||
parser.parse()?
|
||||
} else {
|
||||
None
|
||||
};
|
||||
let def = parser.parens(|parser| parser.parse())?;
|
||||
Ok((parent, def))
|
||||
Ok((parent, def, final_type))
|
||||
})?
|
||||
} else {
|
||||
(None, parser.parens(|parser| parser.parse())?)
|
||||
(None, parser.parens(|parser| parser.parse())?, None)
|
||||
};
|
||||
|
||||
Ok(Type {
|
||||
@@ -762,6 +773,7 @@ impl<'a> Parse<'a> for Type<'a> {
|
||||
name,
|
||||
def,
|
||||
parent,
|
||||
final_type,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
14
third_party/rust/wast/src/lib.rs
vendored
14
third_party/rust/wast/src/lib.rs
vendored
@@ -391,6 +391,7 @@ pub mod kw {
|
||||
custom_keyword!(before);
|
||||
custom_keyword!(binary);
|
||||
custom_keyword!(block);
|
||||
custom_keyword!(borrow);
|
||||
custom_keyword!(catch);
|
||||
custom_keyword!(catch_all);
|
||||
custom_keyword!(code);
|
||||
@@ -399,6 +400,7 @@ pub mod kw {
|
||||
custom_keyword!(declare);
|
||||
custom_keyword!(delegate);
|
||||
custom_keyword!(r#do = "do");
|
||||
custom_keyword!(dtor);
|
||||
custom_keyword!(elem);
|
||||
custom_keyword!(end);
|
||||
custom_keyword!(tag);
|
||||
@@ -430,6 +432,7 @@ pub mod kw {
|
||||
custom_keyword!(import);
|
||||
custom_keyword!(instance);
|
||||
custom_keyword!(instantiate);
|
||||
custom_keyword!(interface);
|
||||
custom_keyword!(invoke);
|
||||
custom_keyword!(item);
|
||||
custom_keyword!(last);
|
||||
@@ -448,6 +451,7 @@ pub mod kw {
|
||||
custom_keyword!(nullref);
|
||||
custom_keyword!(offset);
|
||||
custom_keyword!(outer);
|
||||
custom_keyword!(own);
|
||||
custom_keyword!(param);
|
||||
custom_keyword!(parent);
|
||||
custom_keyword!(passive);
|
||||
@@ -462,10 +466,16 @@ pub mod kw {
|
||||
custom_keyword!(ref_null = "ref.null");
|
||||
custom_keyword!(register);
|
||||
custom_keyword!(rec);
|
||||
custom_keyword!(rep);
|
||||
custom_keyword!(resource);
|
||||
custom_keyword!(resource_new = "resource.new");
|
||||
custom_keyword!(resource_drop = "resource.drop");
|
||||
custom_keyword!(resource_rep = "resource.rep");
|
||||
custom_keyword!(result);
|
||||
custom_keyword!(shared);
|
||||
custom_keyword!(start);
|
||||
custom_keyword!(sub);
|
||||
custom_keyword!(r#final = "final");
|
||||
custom_keyword!(table);
|
||||
custom_keyword!(then);
|
||||
custom_keyword!(r#try = "try");
|
||||
@@ -509,10 +519,14 @@ pub mod kw {
|
||||
custom_keyword!(core);
|
||||
custom_keyword!(true_ = "true");
|
||||
custom_keyword!(false_ = "false");
|
||||
custom_keyword!(language);
|
||||
custom_keyword!(sdk);
|
||||
custom_keyword!(processed_by = "processed-by");
|
||||
}
|
||||
|
||||
/// Common annotations used to parse WebAssembly text files.
|
||||
pub mod annotation {
|
||||
annotation!(custom);
|
||||
annotation!(name);
|
||||
annotation!(producers);
|
||||
}
|
||||
|
||||
7
third_party/rust/wast/tests/parse-fail/bad-core-func-alias.wat
vendored
Normal file
7
third_party/rust/wast/tests/parse-fail/bad-core-func-alias.wat
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
(component
|
||||
(core module $mod (func (export "fun")))
|
||||
(core instance $inst (instantiate $mod))
|
||||
(alias core export $inst "fun" (core func $fun1))
|
||||
(core func $fun2 (alias core export $inst "fun"))
|
||||
(core func $fun3 (alias export $inst "fun"))
|
||||
)
|
||||
5
third_party/rust/wast/tests/parse-fail/bad-core-func-alias.wat.err
vendored
Normal file
5
third_party/rust/wast/tests/parse-fail/bad-core-func-alias.wat.err
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
expected keyword `core`
|
||||
--> tests/parse-fail/bad-core-func-alias.wat:6:27
|
||||
|
|
||||
6 | (core func $fun3 (alias export $inst "fun"))
|
||||
| ^
|
||||
7
third_party/rust/wast/tests/parse-fail/bad-func-alias.wat
vendored
Normal file
7
third_party/rust/wast/tests/parse-fail/bad-func-alias.wat
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
(component
|
||||
(component $comp)
|
||||
(instance $inst (instantiate $comp))
|
||||
(func $alias1 (alias export $inst "fun"))
|
||||
(alias export $inst "fun" (func $alias2))
|
||||
(alias export $inst "fun" (core func $alias3))
|
||||
)
|
||||
5
third_party/rust/wast/tests/parse-fail/bad-func-alias.wat.err
vendored
Normal file
5
third_party/rust/wast/tests/parse-fail/bad-func-alias.wat.err
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
unexpected token, expected `module`
|
||||
--> tests/parse-fail/bad-func-alias.wat:6:37
|
||||
|
|
||||
6 | (alias export $inst "fun" (core func $alias3))
|
||||
| ^
|
||||
Reference in New Issue
Block a user