diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-28 14:29:10 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-28 14:29:10 +0000 |
commit | 2aa4a82499d4becd2284cdb482213d541b8804dd (patch) | |
tree | b80bf8bf13c3766139fbacc530efd0dd9d54394c /third_party/rust/wat | |
parent | Initial commit. (diff) | |
download | firefox-2aa4a82499d4becd2284cdb482213d541b8804dd.tar.xz firefox-2aa4a82499d4becd2284cdb482213d541b8804dd.zip |
Adding upstream version 86.0.1.upstream/86.0.1upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'third_party/rust/wat')
-rw-r--r-- | third_party/rust/wat/.cargo-checksum.json | 1 | ||||
-rw-r--r-- | third_party/rust/wat/Cargo.toml | 25 | ||||
-rw-r--r-- | third_party/rust/wat/README.md | 74 | ||||
-rw-r--r-- | third_party/rust/wat/src/lib.rs | 275 |
4 files changed, 375 insertions, 0 deletions
diff --git a/third_party/rust/wat/.cargo-checksum.json b/third_party/rust/wat/.cargo-checksum.json new file mode 100644 index 0000000000..f9e09232ba --- /dev/null +++ b/third_party/rust/wat/.cargo-checksum.json @@ -0,0 +1 @@ +{"files":{"Cargo.toml":"e0fcbdec6003b6e17e6a7f11e14878af64949b426a3967eb4cc8c5fa9b68dba0","README.md":"6653a386a2210f0f7e36964f15214bc441e2c723c42867dfe90dfcedcd301814","src/lib.rs":"03652351228b7f7a520f4e7f1e689fa34a37b8e5e0fc8367a167cc893cdbc449"},"package":"5e8f7f34773fa6318e8897283abf7941c1f250faae4e1a52f82df09c3bad7cce"}
\ No newline at end of file diff --git a/third_party/rust/wat/Cargo.toml b/third_party/rust/wat/Cargo.toml new file mode 100644 index 0000000000..342aada15d --- /dev/null +++ b/third_party/rust/wat/Cargo.toml @@ -0,0 +1,25 @@ +# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO +# +# When uploading crates to the registry Cargo will automatically +# "normalize" Cargo.toml files for maximal compatibility +# with all versions of Cargo and also rewrite `path` dependencies +# to registry (e.g., crates.io) dependencies +# +# If you believe there's an error in this file please file an +# issue against the rust-lang/cargo repository. If you're +# editing this file be aware that the upstream Cargo.toml +# will likely look very different (and much more reasonable) + +[package] +edition = "2018" +name = "wat" +version = "1.0.33" +authors = ["Alex Crichton <alex@alexcrichton.com>"] +description = "Rust parser for the WebAssembly Text format, WAT\n" +homepage = "https://github.com/bytecodealliance/wasm-tools/tree/main/crates/wat" +documentation = "https://docs.rs/wat" +readme = "README.md" +license = "Apache-2.0 WITH LLVM-exception" +repository = "https://github.com/bytecodealliance/wasm-tools/tree/main/crates/wat" +[dependencies.wast] +version = "32.0.0" diff --git a/third_party/rust/wat/README.md b/third_party/rust/wat/README.md new file mode 100644 index 0000000000..bcbbe9a4ac --- /dev/null +++ b/third_party/rust/wat/README.md @@ -0,0 +1,74 @@ +<div align="center"> + <h1><code>wat</code></h1> + +<strong>A <a href="https://bytecodealliance.org/">Bytecode Alliance</a> project</strong> + + <p> + <strong>A Rust parser for the <a href="https://webassembly.github.io/spec/core/text/index.html">WebAssembly Text Format (WAT)</a>.</strong> + </p> + + <p> + <a href="https://crates.io/crates/wat"><img src="https://img.shields.io/crates/v/wat.svg?style=flat-square" alt="Crates.io version" /></a> + <a href="https://crates.io/crates/wat"><img src="https://img.shields.io/crates/d/wat.svg?style=flat-square" alt="Download" /></a> + <a href="https://docs.rs/wat/"><img src="https://img.shields.io/static/v1?label=docs&message=wat&color=blue&style=flat-square" alt="docs.rs docs" /></a> + <a href="https://docs.rs/wast/"><img src="https://img.shields.io/static/v1?label=docs&message=wast&color=blue&style=flat-square" alt="docs.rs docs" /></a> + </p> +</div> + +## Usage + +Add this to your `Cargo.toml`: + +```toml +[dependencies] +wat = "1.0" +``` + +And then you can parse WAT to binary WebAssembly via: + +```rust +// Parse from a file ... +let binary = wat::parse_file("./foo.wat")?; + +// ... or a string +let wat = r#" + (module + (func $foo) + + (func (export "bar") + call $foo + ) + ) +"#; +let binary = wat::parse_str(wat)?; +``` + +## Low-level parsing + +This repository and project also aims to provide low-level parsing support for +the WAT and WAST formats. Effectively, if you've got an s-expression lookalike +that you'd like to parse, you should be able to parse it! + +The `wat` crate does not support this because it strives to provide strong +API-level stability guarantees, but the `wast` crate has all the +low-level details and is the implementation of the `wast` crate. Be sure to +[check out its `README.md`](../wast/README.md) for more information. + +## Stability and WebAssembly Features + +Consult the [crate documentation](https://docs.rs/wat) for more information, +but the general idea is this crate will not issue a semver-breaking change for +breaking changes in the WAT format, either for MVP features or post-MVP +features. No opt-in is required to use WebAssembly features, so using them may +break if the upstream spec changes. + +# License + +This project is licensed under the Apache 2.0 license with the LLVM exception. +See [LICENSE](../../LICENSE) for more details. + +### Contribution + +Unless you explicitly state otherwise, any contribution intentionally submitted +for inclusion in this project by you, as defined in the Apache-2.0 license, +shall be licensed as above, without any additional terms or conditions. diff --git a/third_party/rust/wat/src/lib.rs b/third_party/rust/wat/src/lib.rs new file mode 100644 index 0000000000..e499e6b9d5 --- /dev/null +++ b/third_party/rust/wat/src/lib.rs @@ -0,0 +1,275 @@ +//! A Rust parser for the [WebAssembly Text format][wat] +//! +//! This crate contains a stable interface to the parser for the [WAT][wat] +//! format of WebAssembly text files. The format parsed by this crate follows +//! the [online specification][wat]. +//! +//! # Examples +//! +//! Parse an in-memory string: +//! +//! ``` +//! # fn foo() -> wat::Result<()> { +//! let wat = r#" +//! (module +//! (func $foo) +//! +//! (func (export "bar") +//! call $foo +//! ) +//! ) +//! "#; +//! +//! let binary = wat::parse_str(wat)?; +//! // ... +//! # Ok(()) +//! # } +//! ``` +//! +//! Parse an on-disk file: +//! +//! ``` +//! # fn foo() -> wat::Result<()> { +//! let binary = wat::parse_file("./foo.wat")?; +//! // ... +//! # Ok(()) +//! # } +//! ``` +//! +//! ## Evolution of the WAT Format +//! +//! WebAssembly, and the WAT format, are an evolving specification. Features are +//! added to WAT, WAT changes, and sometimes WAT breaks. The policy of this +//! crate is that it will always follow the [official specification][wat] for +//! WAT files. +//! +//! Future WebAssembly features will be accepted to this parser **and they will +//! not require a feature gate to opt-in**. All implemented WebAssembly features +//! will be enabled at all times. Using a future WebAssembly feature in the WAT +//! format may cause breakage because while specifications are in development +//! the WAT syntax (and/or binary encoding) will often change. This crate will +//! do its best to keep up with these proposals, but breaking textual changes +//! will be published as non-breaking semver changes to this crate. +//! +//! ## Stability +//! +//! This crate is intended to be a very stable shim over the `wast` crate +//! which is expected to be much more unstable. The `wast` crate contains +//! AST data structures for parsing `*.wat` files and they will evolve was the +//! WAT and WebAssembly specifications evolve over time. +//! +//! This crate is currently at version 1.x.y, and it is intended that it will +//! remain here for quite some time. Breaking changes to the WAT format will be +//! landed as a non-semver-breaking version change in this crate. This crate +//! will always follow the [official specification for WAT][wat]. +//! +//! [wat]: http://webassembly.github.io/spec/core/text/index.html + +#![deny(missing_docs)] + +use std::borrow::Cow; +use std::fmt; +use std::path::Path; +use std::str; +use wast::parser::{self, ParseBuffer}; + +/// Parses a file on disk as a [WebAssembly Text format][wat] file, or a binary +/// WebAssembly file +/// +/// This function will read the bytes on disk and delegate them to the +/// [`parse_bytes`] function. For more information on the behavior of parsing +/// see [`parse_bytes`]. +/// +/// # Errors +/// +/// For information about errors, see the [`parse_bytes`] documentation. +/// +/// # Examples +/// +/// ``` +/// # fn foo() -> wat::Result<()> { +/// let binary = wat::parse_file("./foo.wat")?; +/// // ... +/// # Ok(()) +/// # } +/// ``` +/// +/// [wat]: http://webassembly.github.io/spec/core/text/index.html +pub fn parse_file(file: impl AsRef<Path>) -> Result<Vec<u8>> { + _parse_file(file.as_ref()) +} + +fn _parse_file(file: &Path) -> Result<Vec<u8>> { + let contents = std::fs::read(file).map_err(|err| Error { + kind: Box::new(ErrorKind::Io { + err, + msg: format!("failed to read `{}` to a string", file.display()), + }), + })?; + match parse_bytes(&contents) { + Ok(bytes) => Ok(bytes.into_owned()), + Err(mut e) => { + if let ErrorKind::Wast(e) = &mut *e.kind { + e.set_path(file); + } + Err(e) + } + } +} + +/// Parses in-memory bytes as either the [WebAssembly Text format][wat], or a +/// binary WebAssembly module. +/// +/// This function will attempt to interpret the given bytes as one of two +/// options: +/// +/// * A utf-8 string which is a `*.wat` file to be parsed. +/// * A binary WebAssembly file starting with `b"\0asm"` +/// +/// If the input is a string then it will be parsed as `*.wat`, and then after +/// parsing it will be encoded back into a WebAssembly binary module. If the +/// input is a binary that starts with `b"\0asm"` it will be returned verbatim. +/// Everything that doesn't start with `b"\0asm"` will be parsed as a utf-8 +/// `*.wat` file, returning errors as appropriate. +/// +/// For more information about parsing wat files, see [`parse_str`]. +/// +/// # Errors +/// +/// In addition to all of the errors that can be returned from [`parse_str`], +/// this function will also return an error if the input does not start with +/// `b"\0asm"` and is invalid utf-8. (failed to even try to call [`parse_str`]). +/// +/// # Examples +/// +/// ``` +/// # fn foo() -> wat::Result<()> { +/// // Parsing bytes that are actually `*.wat` files +/// assert_eq!(&*wat::parse_bytes(b"(module)")?, b"\0asm\x01\0\0\0"); +/// assert!(wat::parse_bytes(b"module").is_err()); +/// assert!(wat::parse_bytes(b"binary\0file\0\that\0is\0not\0wat").is_err()); +/// +/// // Pass through binaries that look like real wasm files +/// assert_eq!(&*wat::parse_bytes(b"\0asm\x01\0\0\0")?, b"\0asm\x01\0\0\0"); +/// # Ok(()) +/// # } +/// ``` +/// +/// [wat]: http://webassembly.github.io/spec/core/text/index.html +pub fn parse_bytes(bytes: &[u8]) -> Result<Cow<'_, [u8]>> { + if bytes.starts_with(b"\0asm") { + return Ok(bytes.into()); + } + match str::from_utf8(bytes) { + Ok(s) => _parse_str(s).map(|s| s.into()), + Err(_) => Err(Error { + kind: Box::new(ErrorKind::Custom(format!("input bytes aren't valid utf-8"))), + }), + } +} + +/// Parses an in-memory string as the [WebAssembly Text format][wat], returning +/// the file as a binary WebAssembly file. +/// +/// This function is intended to be a stable convenience function for parsing a +/// wat file into a WebAssembly binary file. This is a high-level operation +/// which does not expose any parsing internals, for that you'll want to use the +/// `wast` crate. +/// +/// # Errors +/// +/// This function can fail for a number of reasons, including (but not limited +/// to): +/// +/// * The `wat` input may fail to lex, such as having invalid tokens or syntax +/// * The `wat` input may fail to parse, such as having incorrect syntactical +/// structure +/// * The `wat` input may contain names that could not be resolved +/// +/// # Examples +/// +/// ``` +/// # fn foo() -> wat::Result<()> { +/// assert_eq!(wat::parse_str("(module)")?, b"\0asm\x01\0\0\0"); +/// assert!(wat::parse_str("module").is_err()); +/// +/// let wat = r#" +/// (module +/// (func $foo) +/// +/// (func (export "bar") +/// call $foo +/// ) +/// ) +/// "#; +/// +/// let binary = wat::parse_str(wat)?; +/// // ... +/// # Ok(()) +/// # } +/// ``` +/// +/// [wat]: http://webassembly.github.io/spec/core/text/index.html +pub fn parse_str(wat: impl AsRef<str>) -> Result<Vec<u8>> { + _parse_str(wat.as_ref()) +} + +fn _parse_str(wat: &str) -> Result<Vec<u8>> { + let buf = ParseBuffer::new(&wat).map_err(|e| Error::cvt(e, wat))?; + let mut ast = parser::parse::<wast::Wat>(&buf).map_err(|e| Error::cvt(e, wat))?; + Ok(ast.module.encode().map_err(|e| Error::cvt(e, wat))?) +} + +/// A convenience type definition for `Result` where the error is [`Error`] +pub type Result<T> = std::result::Result<T, Error>; + +/// Errors from this crate related to parsing WAT files +/// +/// An error can during example phases like: +/// +/// * Lexing can fail if the document is syntactically invalid. +/// * A string may not be utf-8 +/// * The syntactical structure of the wat file may be invalid +/// * The wat file may be semantically invalid such as having name resolution +/// failures +#[derive(Debug)] +pub struct Error { + kind: Box<ErrorKind>, +} + +#[derive(Debug)] +enum ErrorKind { + Wast(wast::Error), + Io { err: std::io::Error, msg: String }, + Custom(String), +} + +impl Error { + fn cvt<E: Into<wast::Error>>(e: E, contents: &str) -> Error { + let mut err = e.into(); + err.set_text(contents); + Error { + kind: Box::new(ErrorKind::Wast(err)), + } + } +} + +impl fmt::Display for Error { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match &*self.kind { + ErrorKind::Wast(err) => err.fmt(f), + ErrorKind::Custom(err) => err.fmt(f), + ErrorKind::Io { msg, .. } => msg.fmt(f), + } + } +} + +impl std::error::Error for Error { + fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { + match &*self.kind { + ErrorKind::Wast(_) => None, + ErrorKind::Custom(_) => None, + ErrorKind::Io { err, .. } => Some(err), + } + } +} |