mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-07 18:04:46 +00:00
Bug 1774829 - wasm: Vendor latest wast crate. r=yury,glandium,supply-chain-reviewers
Differential Revision: https://phabricator.services.mozilla.com/D151738
This commit is contained in:
parent
c7b9bb7b6c
commit
214a1d40fc
28
Cargo.lock
generated
28
Cargo.lock
generated
@ -1598,6 +1598,12 @@ dependencies = [
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "flagset"
|
||||
version = "0.4.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cda653ca797810c02f7ca4b804b40b8b95ae046eb989d356bce17919a8c25499"
|
||||
|
||||
[[package]]
|
||||
name = "flate2"
|
||||
version = "1.0.24"
|
||||
@ -5780,40 +5786,46 @@ version = "0.2.100"
|
||||
|
||||
[[package]]
|
||||
name = "wasm-encoder"
|
||||
version = "0.7.0"
|
||||
version = "0.14.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "49cfbd7c23474849807ecde008c82eb38d303b07ec61d48f45b65f3c8cdd2770"
|
||||
checksum = "f76068e87fe9b837a6bc2ccded66784173eadb828c4168643e9fddf6f9ed2e61"
|
||||
dependencies = [
|
||||
"leb128",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-smith"
|
||||
version = "0.8.0"
|
||||
version = "0.11.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "440458e050ee2731e85af3368ee58e23d4728d597809a88f841a24778876f2b6"
|
||||
checksum = "b73250e61e41d0e467b78559c7d761841005d724384bb0b78d52ff974acf5520"
|
||||
dependencies = [
|
||||
"arbitrary",
|
||||
"flagset",
|
||||
"indexmap",
|
||||
"leb128",
|
||||
"wasm-encoder",
|
||||
"wasmparser",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasmparser"
|
||||
version = "0.78.2"
|
||||
version = "0.87.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "52144d4c78e5cf8b055ceab8e5fa22814ce4315d6002ad32cfd914f37c12fd65"
|
||||
checksum = "5c04e207cd2e8ecb6f9bd28a2cf3119b4c6bfeee6fe3a25cc1daf8041d00a875"
|
||||
dependencies = [
|
||||
"indexmap",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wast"
|
||||
version = "41.0.0"
|
||||
version = "44.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f882898b8b817cc4edc16aa3692fdc087b356edc8cc0c2164f5b5181e31c3870"
|
||||
checksum = "5f474d1b1cb7d92e5360b293f28e8bc9b2d115197a5bbf76bdbfba9161cf9cdc"
|
||||
dependencies = [
|
||||
"leb128",
|
||||
"memchr",
|
||||
"unicode-width",
|
||||
"wasm-encoder",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -5,6 +5,6 @@ authors = ["Christian Holler"]
|
||||
license = "MPL 2.0"
|
||||
|
||||
[dependencies]
|
||||
wasm-smith = "0.8.0"
|
||||
wasm-smith = "0.11.2"
|
||||
arbitrary = { version = "1.0.0", features = ["derive"] }
|
||||
libc = "0.2"
|
||||
|
@ -18,5 +18,5 @@ gluesmith = ['jsrust_shared/gluesmith']
|
||||
jsrust_shared = { path = "./shared" }
|
||||
# Workaround for https://github.com/rust-lang/rust/issues/58393
|
||||
mozglue-static = { path = "../../../mozglue/static/rust" }
|
||||
wast = { version = "41.0.0" }
|
||||
wasmparser = { version = "0.78.2" }
|
||||
wast = { version = "44.0.0" }
|
||||
wasmparser = { version = "0.87.0" }
|
||||
|
@ -93,6 +93,12 @@ criteria = "safe-to-deploy"
|
||||
delta = "0.4.0 -> 0.5.0"
|
||||
notes = "The repository for this crate belongs in the Mozilla org."
|
||||
|
||||
[[audits.flagset]]
|
||||
who = "Ryan Hunt <rhunt@eqrion.net>"
|
||||
criteria = "safe-to-deploy"
|
||||
version = "0.4.3"
|
||||
notes = "Uses no ambient capabilities, vetted the one instance of unsafe."
|
||||
|
||||
[[audits.getrandom]]
|
||||
who = "Mike Hommey <mh+mozilla@glandium.org>"
|
||||
criteria = "safe-to-deploy"
|
||||
@ -268,6 +274,36 @@ criteria = "safe-to-deploy"
|
||||
version = "1.0.2"
|
||||
notes = "Very small crate, just hosts the Void type for easier cross-crate interfacing."
|
||||
|
||||
[[audits.wasm-encoder]]
|
||||
who = "Ryan Hunt <rhunt@eqrion.net>"
|
||||
criteria = "safe-to-deploy"
|
||||
version = "0.7.0"
|
||||
notes = "Maintained by the Bytecode Alliance, with contributions from Mozilla. This has no unsafe code and uses no ambient capabilities."
|
||||
|
||||
[[audits.wasm-encoder]]
|
||||
who = "Ryan Hunt <rhunt@eqrion.net>"
|
||||
criteria = "safe-to-deploy"
|
||||
delta = "0.7.0 -> 0.14.0"
|
||||
notes = "wasm-encoder has no unsafe code and uses no ambient capabilities."
|
||||
|
||||
[[audits.wasm-smith]]
|
||||
who = "Ryan Hunt <rhunt@eqrion.net>"
|
||||
criteria = "safe-to-deploy"
|
||||
version = "0.11.2"
|
||||
notes = "Maintained by the Bytecode Alliance, with contributions from Mozilla. I've vetted the one instance of unsafe code."
|
||||
|
||||
[[audits.wasmparser]]
|
||||
who = "Ryan Hunt <rhunt@eqrion.net>"
|
||||
criteria = "safe-to-deploy"
|
||||
version = "0.87.0"
|
||||
notes = "Maintained by the Bytecode Alliance, with contributions from Mozilla. I've vetted the one instance of unsafe code."
|
||||
|
||||
[[audits.wast]]
|
||||
who = "Ryan Hunt <rhunt@eqrion.net>"
|
||||
criteria = "safe-to-deploy"
|
||||
version = "44.0.0"
|
||||
notes = "Maintained by the Bytecode Alliance, with contributions from Mozilla. wast has no unsafe code and the only ambient capability it uses is to read the full contents of a file that is given to it."
|
||||
|
||||
[[audits.webdriver]]
|
||||
who = "Henrik Skupin <mail@hskupin.info>"
|
||||
criteria = "safe-to-deploy"
|
||||
|
@ -1693,22 +1693,10 @@ criteria = "safe-to-run"
|
||||
version = "0.11.0+wasi-snapshot-preview1"
|
||||
criteria = "safe-to-deploy"
|
||||
|
||||
[[exemptions.wasm-encoder]]
|
||||
version = "0.7.0"
|
||||
criteria = "safe-to-run"
|
||||
|
||||
[[exemptions.wasm-smith]]
|
||||
version = "0.8.0"
|
||||
criteria = "safe-to-run"
|
||||
|
||||
[[exemptions.wasmparser]]
|
||||
version = "0.78.2"
|
||||
criteria = "safe-to-deploy"
|
||||
|
||||
[[exemptions.wast]]
|
||||
version = "41.0.0"
|
||||
criteria = "safe-to-deploy"
|
||||
|
||||
[[exemptions.webrtc-sdp]]
|
||||
version = "0.3.9"
|
||||
criteria = "safe-to-deploy"
|
||||
|
1
third_party/rust/flagset/.cargo-checksum.json
vendored
Normal file
1
third_party/rust/flagset/.cargo-checksum.json
vendored
Normal file
@ -0,0 +1 @@
|
||||
{"files":{"Cargo.toml":"5a87209bc98397121d9b710b6eb05559c5f2ddb7884e82fbfc706026a24fac13","LICENSE":"cfc7749b96f63bd31c3c42b5c471bf756814053e847c10f3eb003417bc523d30","README.md":"391c693969a7cd5e1810d3fc4271f1b69f79ee1a26def1fc9b3f7c5df50920dd","src/lib.rs":"77804ee547d8723e603975d586deaf4fa8a58bf13a8c80d9416eed0298b39462"},"package":"cda653ca797810c02f7ca4b804b40b8b95ae046eb989d356bce17919a8c25499"}
|
34
third_party/rust/flagset/Cargo.toml
vendored
Normal file
34
third_party/rust/flagset/Cargo.toml
vendored
Normal file
@ -0,0 +1,34 @@
|
||||
# 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 are reading this file be aware that the original Cargo.toml
|
||||
# will likely look very different (and much more reasonable).
|
||||
# See Cargo.toml.orig for the original contents.
|
||||
|
||||
[package]
|
||||
edition = "2018"
|
||||
name = "flagset"
|
||||
version = "0.4.3"
|
||||
authors = ["Nathaniel McCallum <nathaniel@profian.com>"]
|
||||
description = "Data types and a macro for generating enumeration-based bit flags"
|
||||
homepage = "https://github.com/enarx/flagset"
|
||||
documentation = "https://docs.rs/flagset"
|
||||
readme = "README.md"
|
||||
keywords = ["flags", "bitflags", "enum", "enumflags"]
|
||||
license = "Apache-2.0"
|
||||
repository = "https://github.com/enarx/flagset"
|
||||
[package.metadata.docs.rs]
|
||||
all-features = true
|
||||
[dependencies.serde]
|
||||
version = "1.0"
|
||||
features = ["serde_derive"]
|
||||
optional = true
|
||||
[dev-dependencies.serde_json]
|
||||
version = "1.0"
|
||||
|
||||
[dev-dependencies.serde_repr]
|
||||
version = "0.1"
|
202
third_party/rust/flagset/LICENSE
vendored
Normal file
202
third_party/rust/flagset/LICENSE
vendored
Normal file
@ -0,0 +1,202 @@
|
||||
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
227
third_party/rust/flagset/README.md
vendored
Normal file
227
third_party/rust/flagset/README.md
vendored
Normal file
@ -0,0 +1,227 @@
|
||||
[![Build Status](https://github.com/enarx/flagset/workflows/test/badge.svg)](https://github.com/enarx/flagset/actions)
|
||||
![Rust Version 1.36+](https://img.shields.io/badge/rustc-v1.36%2B-blue.svg)
|
||||
[![Crate](https://img.shields.io/crates/v/flagset.svg)](https://crates.io/crates/flagset)
|
||||
[![Docs](https://docs.rs/flagset/badge.svg)](https://docs.rs/flagset)
|
||||
![License](https://img.shields.io/crates/l/flagset.svg?style=popout)
|
||||
|
||||
# Welcome to FlagSet!
|
||||
|
||||
FlagSet is a new, ergonomic approach to handling flags that combines the
|
||||
best of existing crates like `bitflags` and `enumflags` without their
|
||||
downsides.
|
||||
|
||||
## Existing Implementations
|
||||
|
||||
The `bitflags` crate has long been part of the Rust ecosystem.
|
||||
Unfortunately, it doesn't feel like natural Rust. The `bitflags` crate
|
||||
uses a wierd struct format to define flags. Flags themselves are just
|
||||
integers constants, so there is little type-safety involved. But it doesn't
|
||||
have any dependencies. It also allows you to define implied flags (otherwise
|
||||
known as overlapping flags).
|
||||
|
||||
The `enumflags` crate tried to improve on `bitflags` by using enumerations
|
||||
to define flags. This was a big improvement to the natural feel of the code.
|
||||
Unfortunately, there are some design flaws. To generate the flags,
|
||||
procedural macros were used. This implied two separate crates plus
|
||||
additional dependencies. Further, `enumflags` specifies the size of the
|
||||
flags using a `repr($size)` attribute. Unfortunately, this attribute
|
||||
cannot resolve type aliases, such as `c_int`. This makes `enumflags` a
|
||||
poor fit for FFI, which is the most important place for a flags library.
|
||||
The `enumflags` crate also disallows overlapping flags and is not
|
||||
maintained.
|
||||
|
||||
FlagSet improves on both of these by adopting the `enumflags` natural feel
|
||||
and the `bitflags` mode of flag generation; as well as additional API usage
|
||||
niceties. FlagSet has no dependencies and is extensively documented and
|
||||
tested. It also tries very hard to prevent you from making mistakes by
|
||||
avoiding external usage of the integer types. FlagSet is also a zero-cost
|
||||
abstraction: all functions are inlineable and should reduce to the core
|
||||
integer operations. FlagSet also does not depend on stdlib, so it can be
|
||||
used in `no_std` libraries and applications.
|
||||
|
||||
## Defining Flags
|
||||
|
||||
Flags are defined using the `flags!` macro:
|
||||
|
||||
```rust
|
||||
use flagset::{FlagSet, flags};
|
||||
use std::os::raw::c_int;
|
||||
|
||||
flags! {
|
||||
enum FlagsA: u8 {
|
||||
Foo,
|
||||
Bar,
|
||||
Baz,
|
||||
}
|
||||
|
||||
enum FlagsB: c_int {
|
||||
Foo,
|
||||
Bar,
|
||||
Baz,
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Notice that a flag definition looks just like a regular enumeration, with
|
||||
the addition of the field-size type. The field-size type is required and
|
||||
can be either a type or a type alias. Both examples are given above.
|
||||
|
||||
Also note that the field-size type specifies the size of the corresponding
|
||||
`FlagSet` type, not size of the enumeration itself. To specify the size of
|
||||
the enumeration, use the `repr($size)` attribute as specified below.
|
||||
|
||||
## Flag Values
|
||||
|
||||
Flags often need values assigned to them. This can be done implicitly,
|
||||
where the value depends on the order of the flags:
|
||||
|
||||
```rust
|
||||
use flagset::{FlagSet, flags};
|
||||
|
||||
flags! {
|
||||
enum Flags: u16 {
|
||||
Foo, // Implicit Value: 0b0001
|
||||
Bar, // Implicit Value: 0b0010
|
||||
Baz, // Implicit Value: 0b0100
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Alternatively, flag values can be defined explicitly, by specifying any
|
||||
`const` expression:
|
||||
|
||||
```rust
|
||||
use flagset::{FlagSet, flags};
|
||||
|
||||
flags! {
|
||||
enum Flags: u16 {
|
||||
Foo = 0x01, // Explicit Value: 0b0001
|
||||
Bar = 2, // Explicit Value: 0b0010
|
||||
Baz = 0b0100, // Explicit Value: 0b0100
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Flags can also overlap or "imply" other flags:
|
||||
|
||||
```rust
|
||||
use flagset::{FlagSet, flags};
|
||||
|
||||
flags! {
|
||||
enum Flags: u16 {
|
||||
Foo = 0b0001,
|
||||
Bar = 0b0010,
|
||||
Baz = 0b0110, // Implies Bar
|
||||
All = (Flags::Foo | Flags::Bar | Flags::Baz).bits(),
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Specifying Attributes
|
||||
|
||||
Attributes can be used on the enumeration itself or any of the values:
|
||||
|
||||
```rust
|
||||
use flagset::{FlagSet, flags};
|
||||
|
||||
flags! {
|
||||
#[derive(PartialOrd, Ord)]
|
||||
enum Flags: u8 {
|
||||
Foo,
|
||||
#[deprecated]
|
||||
Bar,
|
||||
Baz,
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Collections of Flags
|
||||
|
||||
A collection of flags is a `FlagSet<T>`. If you are storing the flags in
|
||||
memory, the raw `FlagSet<T>` type should be used. However, if you want to
|
||||
receive flags as an input to a function, you should use
|
||||
`impl Into<FlagSet<T>>`. This allows for very ergonomic APIs:
|
||||
|
||||
```rust
|
||||
use flagset::{FlagSet, flags};
|
||||
|
||||
flags! {
|
||||
enum Flags: u8 {
|
||||
Foo,
|
||||
Bar,
|
||||
Baz,
|
||||
}
|
||||
}
|
||||
|
||||
struct Container(FlagSet<Flags>);
|
||||
|
||||
impl Container {
|
||||
fn new(flags: impl Into<FlagSet<Flags>>) -> Container {
|
||||
Container(flags.into())
|
||||
}
|
||||
}
|
||||
|
||||
assert_eq!(Container::new(Flags::Foo | Flags::Bar).0.bits(), 0b011);
|
||||
assert_eq!(Container::new(Flags::Foo).0.bits(), 0b001);
|
||||
assert_eq!(Container::new(None).0.bits(), 0b000);
|
||||
```
|
||||
|
||||
## Operations
|
||||
|
||||
Operations can be performed on a `FlagSet<F>` or on individual flags:
|
||||
|
||||
| Operator | Assignment Operator | Meaning |
|
||||
|----------|---------------------|------------------------|
|
||||
| \| | \|= | Union |
|
||||
| & | &= | Intersection |
|
||||
| ^ | ^= | Toggle specified flags |
|
||||
| - | -= | Difference |
|
||||
| % | %= | Symmetric difference |
|
||||
| ! | | Toggle all flags |
|
||||
|
||||
## Optional Serde support
|
||||
|
||||
[Serde] support can be enabled with the 'serde' feature flag. You can then serialize and
|
||||
deserialize `FlagSet<T>` to and from any of the [supported formats]:
|
||||
|
||||
```rust
|
||||
use flagset::{FlagSet, flags};
|
||||
|
||||
flags! {
|
||||
enum Flags: u8 {
|
||||
Foo,
|
||||
Bar,
|
||||
}
|
||||
}
|
||||
|
||||
let flagset = Flags::Foo | Flags::Bar;
|
||||
let json = serde_json::to_string(&flagset).unwrap();
|
||||
let flagset: FlagSet<Flags> = serde_json::from_str(&json).unwrap();
|
||||
assert_eq!(flagset.bits(), 0b011);
|
||||
```
|
||||
|
||||
For serialization and deserialization of flags enum itself, you can use the [`serde_repr`] crate
|
||||
(or implement `serde::ser::Serialize` and `serde:de::Deserialize` manually), combined with the
|
||||
appropriate `repr` attribute:
|
||||
|
||||
```rust
|
||||
use flagset::{FlagSet, flags};
|
||||
use serde_repr::{Serialize_repr, Deserialize_repr};
|
||||
|
||||
flags! {
|
||||
#[repr(u8)]
|
||||
#[derive(Deserialize_repr, Serialize_repr)]
|
||||
enum Flags: u8 {
|
||||
Foo,
|
||||
Bar,
|
||||
}
|
||||
}
|
||||
|
||||
let json = serde_json::to_string(&Flags::Foo).unwrap();
|
||||
let flag: Flags = serde_json::from_str(&json).unwrap();
|
||||
assert_eq!(flag, Flags::Foo);
|
||||
```
|
||||
|
||||
[Serde]: https://serde.rs/
|
||||
[supported formats]: https://serde.rs/#data-formats
|
||||
[`serde_repr`]: https://crates.io/crates/serde_repr
|
1286
third_party/rust/flagset/src/lib.rs
vendored
Normal file
1286
third_party/rust/flagset/src/lib.rs
vendored
Normal file
File diff suppressed because it is too large
Load Diff
@ -1 +1 @@
|
||||
{"files":{"Cargo.toml":"019d126cc0ed433d59618be3141d40e936debbdcbbb4f806905b421937e0fee9","LICENSE":"268872b9816f90fd8e85db5a28d33f8150ebb8dd016653fb39ef1f94f2686bc5","README.md":"8d8b48c8ed202bd18494ed37678a0712688909bc350e5423fc18d70447e31f56","src/aliases.rs":"13dfd1947ad7285c1bab5b2bd14703e0e0a9392519e4a3a709a6d160751dfd80","src/code.rs":"c9cda29e7f11e404e8e11632c5e67ca0a1136f893c58376921396b2d81208c96","src/custom.rs":"0926d7c9b8418c316b2478abced1ddc0cf88f25c68c4c320e90fff237a033dd1","src/data.rs":"e89f9297f0e5cf2b784c59f445d6f2e7901eaaf7897731f4ef6282672fe7ae70","src/elements.rs":"8c68d1e0b176c643ba4d49705043d68ae063dfe7b790bbc2d0d8edf931981c16","src/encoders.rs":"c721ac7ad3080da42ff3e7397007e44471d1e47a8de117fbde7ab799b75d10a6","src/exports.rs":"6a9c9d1a8571e599424045296250296d11bc394e0f237403b2b8d5500aa18207","src/functions.rs":"e433d9199bad8c75609202a4282797e594002e3610d803e5732989f7b5edc2a6","src/globals.rs":"bb033493914c1c321f19fd3c974f174c13f877659ae7aae31a664790d839276a","src/imports.rs":"07442618a93c4ae3c381d71631256c6db14ed5dbb850905b83e75fb018ec6fbc","src/instances.rs":"d790933204e530e1264a289ef2090193d19006d082fbeba37a204b2f811d10df","src/lib.rs":"4c59c4c0de4138db6b55e9e97922c8b667d8c256015c5a7f1614d86d54e709f4","src/linking.rs":"830516e338fbe79dad86eab3476944bb810af57b3d1a3f215d3770327d379d9e","src/memories.rs":"950285bcf52e4dd6647b1efda05280a3c93c966ff0da33695e2da187dbff4a12","src/modules.rs":"9d92969c27f0fd59efa14c7bf9ac7b96c951c379de3f85907b387184dd571f3a","src/start.rs":"a2466aba18cd194dbd17ac9103f63639f8538cba765891f07b410107b752bafd","src/tables.rs":"6102a61c69046f826ca8cd4738120c7988f3b639d667ad453b9e1af9052c513e","src/tags.rs":"a7f1248b8c2e336c5991a95e846ceeb29de98dd4d691a86d8bbfe96773583630","src/types.rs":"9d268a4437922f607f23703b94b0ada05f6266b6c08a362fd4674649b3e68976","tests/linking.rs":"43025bd4a1270a6a925f421ba728e0ad180ac8e5ea6cb80f2fc443153a5c4ec4"},"package":"49cfbd7c23474849807ecde008c82eb38d303b07ec61d48f45b65f3c8cdd2770"}
|
||||
{"files":{"Cargo.toml":"fd2036fa2be078a2a13373cf7644d5deb14c640d1fac4414fab7bc753cc632c6","LICENSE":"268872b9816f90fd8e85db5a28d33f8150ebb8dd016653fb39ef1f94f2686bc5","README.md":"8d8b48c8ed202bd18494ed37678a0712688909bc350e5423fc18d70447e31f56","src/component.rs":"d94ed30e52ba557e45139fd268ef6739bffdc5e1e80192917c29cedc6c337af8","src/component/aliases.rs":"c8a5d2f18d3b0586b8a7736b874ba2e685227e4c4a5c8eb2d06137b8e1fd7686","src/component/canonicals.rs":"8b270caef4e0f1e2b62af5b27560ac370399d11ce411aae6b811dddeaedb7750","src/component/components.rs":"07b8cae3a400e1955cc39d142569910b4fef2136021053d0ddbd6404d810aa52","src/component/exports.rs":"3f297f57a1278940c06219581f2129b7608f965371101af3d6c5e1aaa1c22b4f","src/component/imports.rs":"21b88e462ea1bc21fb72099912cb750eece1cf59b74a56a508176ebb4f1e9a74","src/component/instances.rs":"c86f24e466aeb6889413f32d95e039a90a1e20d2e5a0505339aa81fc086a8c24","src/component/modules.rs":"9e80907e72360fae4d8057b6b0e7a6b58edd7ba6aba6e63ba17346518e169617","src/component/start.rs":"6f69ce2ba65fb9551f98300a0f147268cf41323f219496396e911420b427ee1d","src/component/types.rs":"c8e8dd33ffb3379175ac672151fbae8c49c70c461492f0dc350953b15db04bd8","src/core.rs":"d52f366d84a931a1b994c1cf32da860ad0d7a456f82dfcdef32c6260fdc6999c","src/core/code.rs":"765c72621ab253e4f24ecdad5018bfd4327f6782eb2a78dd4687b7ff2702e333","src/core/custom.rs":"df2d6a8c5a64603822301522e9df4344022226301df846941d95930f1f4d99c4","src/core/data.rs":"8ff5166456dc14e46d08571bbc73cabf6da0b035858c63964358225ee0ec64c2","src/core/elements.rs":"102eef18da5b3b07aaf3cd5122d77d43eef96af0e69abfa5ad0efed16d133a46","src/core/exports.rs":"81a40d30b1ae6d8ae32a2ae20e398ccab9cf6b8ae66c985e6ab7f46e06bf2ed4","src/core/functions.rs":"c18b9872ac0c21048a3ce32e5e44e8e702f97a57fa1b3a07bdd98c7f6c820f09","src/core/globals.rs":"f6cd2849026c0d87e9fca4b4273128565b8d75b949c12654d7ad105f7a912ae7","src/core/imports.rs":"782bbc2e70b379831f85716c0f50c0221d1487c8cba26e8845028b2ae1962c0c","src/core/linking.rs":"5c7d5bce822fad92dc096ceafde878c6d25869004ca26dde1378e78ae37071c9","src/core/memories.rs":"840d15fcd9bd4a668298491c6a91455b145c5c7ff1adf8c769aaf49d6c664d3a","src/core/names.rs":"b12bcb3e0462d52849057467f6b80565cda6021f09c3c0f52c1f83341a5f482d","src/core/start.rs":"a01d4a91bcd93048977ccafc6af160357297450395bf598351f5a3e6d322e0de","src/core/tables.rs":"f87a9761002e93c8e04e646cdf19fb5d012b190a4dbba542e8bfe1cfc606b545","src/core/tags.rs":"26d58904871d92f395eed67d4c25f0914b337d213bab2288011abe3ad31fa12b","src/core/types.rs":"42125c08577c418237982980fd13eb9a21e63b52674c0820c2df2e61b5f454fc","src/lib.rs":"54c0f785fa56eed9dc251ce250d54e9fff452bba0a40519fe58e9f137215101c","src/raw.rs":"a6a72cfe8f88ea6476eccee4acf362030ba2d2e5710215bc4f13cde7de6d71ae"},"package":"f76068e87fe9b837a6bc2ccded66784173eadb828c4168643e9fddf6f9ed2e61"}
|
11
third_party/rust/wasm-encoder/Cargo.toml
vendored
11
third_party/rust/wasm-encoder/Cargo.toml
vendored
@ -10,18 +10,23 @@
|
||||
# See Cargo.toml.orig for the original contents.
|
||||
|
||||
[package]
|
||||
edition = "2018"
|
||||
edition = "2021"
|
||||
name = "wasm-encoder"
|
||||
version = "0.7.0"
|
||||
version = "0.14.0"
|
||||
authors = ["Nick Fitzgerald <fitzgen@gmail.com>"]
|
||||
description = "A low-level WebAssembly encoder.\n"
|
||||
description = """
|
||||
A low-level WebAssembly encoder.
|
||||
"""
|
||||
homepage = "https://github.com/bytecodealliance/wasm-tools/tree/main/crates/wasm-encoder"
|
||||
documentation = "https://docs.rs/wasm-encoder"
|
||||
readme = "README.md"
|
||||
license = "Apache-2.0 WITH LLVM-exception"
|
||||
repository = "https://github.com/bytecodealliance/wasm-tools/tree/main/crates/wasm-encoder"
|
||||
resolver = "2"
|
||||
|
||||
[dependencies.leb128]
|
||||
version = "0.2.4"
|
||||
|
||||
[dev-dependencies.anyhow]
|
||||
version = "1.0.38"
|
||||
|
||||
|
97
third_party/rust/wasm-encoder/src/aliases.rs
vendored
97
third_party/rust/wasm-encoder/src/aliases.rs
vendored
@ -1,97 +0,0 @@
|
||||
use super::*;
|
||||
|
||||
/// An encoder for the alias section.
|
||||
///
|
||||
/// Note that this is part of the [module linking proposal][proposal] and is not
|
||||
/// currently part of stable WebAssembly.
|
||||
///
|
||||
/// [proposal]: https://github.com/webassembly/module-linking
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```
|
||||
/// use wasm_encoder::{Module, AliasSection, ItemKind};
|
||||
///
|
||||
/// let mut aliases = AliasSection::new();
|
||||
/// aliases.outer_type(0, 2);
|
||||
/// aliases.instance_export(0, ItemKind::Function, "foo");
|
||||
///
|
||||
/// let mut module = Module::new();
|
||||
/// module.section(&aliases);
|
||||
///
|
||||
/// let wasm_bytes = module.finish();
|
||||
/// ```
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct AliasSection {
|
||||
bytes: Vec<u8>,
|
||||
num_added: u32,
|
||||
}
|
||||
|
||||
impl AliasSection {
|
||||
/// Construct a new alias section encoder.
|
||||
pub fn new() -> AliasSection {
|
||||
AliasSection {
|
||||
bytes: vec![],
|
||||
num_added: 0,
|
||||
}
|
||||
}
|
||||
|
||||
/// How many aliases have been defined inside this section so far?
|
||||
pub fn len(&self) -> u32 {
|
||||
self.num_added
|
||||
}
|
||||
|
||||
/// Define an alias that references the export of a defined instance.
|
||||
pub fn instance_export(
|
||||
&mut self,
|
||||
instance: u32,
|
||||
kind: crate::ItemKind,
|
||||
name: &str,
|
||||
) -> &mut Self {
|
||||
self.bytes.push(0x00);
|
||||
self.bytes.extend(encoders::u32(instance));
|
||||
self.bytes.push(kind as u8);
|
||||
self.bytes.extend(encoders::str(name));
|
||||
self.num_added += 1;
|
||||
self
|
||||
}
|
||||
|
||||
/// Define an alias that references an outer module's type.
|
||||
pub fn outer_type(&mut self, depth: u32, ty: u32) -> &mut Self {
|
||||
self.bytes.push(0x01);
|
||||
self.bytes.extend(encoders::u32(depth));
|
||||
self.bytes.push(0x07);
|
||||
self.bytes.extend(encoders::u32(ty));
|
||||
self.num_added += 1;
|
||||
self
|
||||
}
|
||||
|
||||
/// Define an alias that references an outer module's module.
|
||||
pub fn outer_module(&mut self, depth: u32, module: u32) -> &mut Self {
|
||||
self.bytes.push(0x01);
|
||||
self.bytes.extend(encoders::u32(depth));
|
||||
self.bytes.push(ItemKind::Module as u8);
|
||||
self.bytes.extend(encoders::u32(module));
|
||||
self.num_added += 1;
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl Section for AliasSection {
|
||||
fn id(&self) -> u8 {
|
||||
SectionId::Alias.into()
|
||||
}
|
||||
|
||||
fn encode<S>(&self, sink: &mut S)
|
||||
where
|
||||
S: Extend<u8>,
|
||||
{
|
||||
let num_added = encoders::u32(self.num_added);
|
||||
let n = num_added.len();
|
||||
sink.extend(
|
||||
encoders::u32(u32::try_from(n + self.bytes.len()).unwrap())
|
||||
.chain(num_added)
|
||||
.chain(self.bytes.iter().copied()),
|
||||
);
|
||||
}
|
||||
}
|
2145
third_party/rust/wasm-encoder/src/code.rs
vendored
2145
third_party/rust/wasm-encoder/src/code.rs
vendored
File diff suppressed because it is too large
Load Diff
137
third_party/rust/wasm-encoder/src/component.rs
vendored
Normal file
137
third_party/rust/wasm-encoder/src/component.rs
vendored
Normal file
@ -0,0 +1,137 @@
|
||||
mod aliases;
|
||||
mod canonicals;
|
||||
mod components;
|
||||
mod exports;
|
||||
mod imports;
|
||||
mod instances;
|
||||
mod modules;
|
||||
mod start;
|
||||
mod types;
|
||||
|
||||
pub use self::aliases::*;
|
||||
pub use self::canonicals::*;
|
||||
pub use self::components::*;
|
||||
pub use self::exports::*;
|
||||
pub use self::imports::*;
|
||||
pub use self::instances::*;
|
||||
pub use self::modules::*;
|
||||
pub use self::start::*;
|
||||
pub use self::types::*;
|
||||
|
||||
use crate::{CustomSection, Encode};
|
||||
|
||||
// Core sorts extended by the component model
|
||||
const CORE_TYPE_SORT: u8 = 0x10;
|
||||
const CORE_MODULE_SORT: u8 = 0x11;
|
||||
const CORE_INSTANCE_SORT: u8 = 0x12;
|
||||
|
||||
const CORE_SORT: u8 = 0x00;
|
||||
const FUNCTION_SORT: u8 = 0x01;
|
||||
const VALUE_SORT: u8 = 0x02;
|
||||
const TYPE_SORT: u8 = 0x03;
|
||||
const COMPONENT_SORT: u8 = 0x04;
|
||||
const INSTANCE_SORT: u8 = 0x05;
|
||||
|
||||
/// A WebAssembly component section.
|
||||
///
|
||||
/// Various builders defined in this crate already implement this trait, but you
|
||||
/// can also implement it yourself for your own custom section builders, or use
|
||||
/// `RawSection` to use a bunch of raw bytes as a section.
|
||||
pub trait ComponentSection: Encode {
|
||||
/// Gets the section identifier for this section.
|
||||
fn id(&self) -> u8;
|
||||
}
|
||||
|
||||
/// Known section identifiers of WebAssembly components.
|
||||
///
|
||||
/// These sections are supported by the component model proposal.
|
||||
#[derive(Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd)]
|
||||
#[repr(u8)]
|
||||
pub enum ComponentSectionId {
|
||||
/// The section is a core custom section.
|
||||
CoreCustom = 0,
|
||||
/// The section is a core module section.
|
||||
CoreModule = 1,
|
||||
/// The section is a core instance section.
|
||||
CoreInstance = 2,
|
||||
/// The section is a core alias section.
|
||||
CoreAlias = 3,
|
||||
/// The section is a core type section.
|
||||
CoreType = 4,
|
||||
/// The section is a component section.
|
||||
Component = 5,
|
||||
/// The section is an instance section.
|
||||
Instance = 6,
|
||||
/// The section is an alias section.
|
||||
Alias = 7,
|
||||
/// The section is a type section.
|
||||
Type = 8,
|
||||
/// The section is a canonical function section.
|
||||
CanonicalFunction = 9,
|
||||
/// The section is a start section.
|
||||
Start = 10,
|
||||
/// The section is an import section.
|
||||
Import = 11,
|
||||
/// The section is an export section.
|
||||
Export = 12,
|
||||
}
|
||||
|
||||
impl From<ComponentSectionId> for u8 {
|
||||
#[inline]
|
||||
fn from(id: ComponentSectionId) -> u8 {
|
||||
id as u8
|
||||
}
|
||||
}
|
||||
|
||||
impl Encode for ComponentSectionId {
|
||||
fn encode(&self, sink: &mut Vec<u8>) {
|
||||
sink.push(*self as u8);
|
||||
}
|
||||
}
|
||||
|
||||
/// Represents a WebAssembly component that is being encoded.
|
||||
///
|
||||
/// Unlike core WebAssembly modules, the sections of a component
|
||||
/// may appear in any order and may be repeated.
|
||||
///
|
||||
/// Components may also added as a section to other components.
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct Component {
|
||||
bytes: Vec<u8>,
|
||||
}
|
||||
|
||||
impl Component {
|
||||
/// Begin writing a new `Component`.
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
bytes: vec![
|
||||
0x00, 0x61, 0x73, 0x6D, // magic (`\0asm`)
|
||||
0x0a, 0x00, 0x01, 0x00, // version
|
||||
],
|
||||
}
|
||||
}
|
||||
|
||||
/// Finish writing this component and extract ownership of the encoded bytes.
|
||||
pub fn finish(self) -> Vec<u8> {
|
||||
self.bytes
|
||||
}
|
||||
|
||||
/// Write a section to this component.
|
||||
pub fn section(&mut self, section: &impl ComponentSection) -> &mut Self {
|
||||
self.bytes.push(section.id());
|
||||
section.encode(&mut self.bytes);
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for Component {
|
||||
fn default() -> Self {
|
||||
Self::new()
|
||||
}
|
||||
}
|
||||
|
||||
impl ComponentSection for CustomSection<'_> {
|
||||
fn id(&self) -> u8 {
|
||||
ComponentSectionId::CoreCustom.into()
|
||||
}
|
||||
}
|
208
third_party/rust/wasm-encoder/src/component/aliases.rs
vendored
Normal file
208
third_party/rust/wasm-encoder/src/component/aliases.rs
vendored
Normal file
@ -0,0 +1,208 @@
|
||||
use super::{COMPONENT_SORT, CORE_MODULE_SORT, CORE_SORT, CORE_TYPE_SORT, TYPE_SORT};
|
||||
use crate::{
|
||||
encode_section, ComponentExportKind, ComponentSection, ComponentSectionId, Encode, ExportKind,
|
||||
};
|
||||
|
||||
/// Represents the kinds of outer core aliasable items in a component.
|
||||
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
|
||||
pub enum CoreOuterAliasKind {
|
||||
/// The alias is to a core type.
|
||||
Type,
|
||||
}
|
||||
|
||||
impl Encode for CoreOuterAliasKind {
|
||||
fn encode(&self, sink: &mut Vec<u8>) {
|
||||
match self {
|
||||
Self::Type => {
|
||||
sink.push(CORE_TYPE_SORT);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// An encoder for the core alias section of WebAssembly components.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```rust
|
||||
/// use wasm_encoder::{Component, AliasSection, ExportKind};
|
||||
///
|
||||
/// let mut aliases = AliasSection::new();
|
||||
/// aliases.instance_export(0, ExportKind::Func, "f");
|
||||
///
|
||||
/// let mut component = Component::new();
|
||||
/// component.section(&aliases);
|
||||
///
|
||||
/// let bytes = component.finish();
|
||||
/// ```
|
||||
#[derive(Clone, Debug, Default)]
|
||||
pub struct AliasSection {
|
||||
bytes: Vec<u8>,
|
||||
num_added: u32,
|
||||
}
|
||||
|
||||
impl AliasSection {
|
||||
/// Create a new core alias section encoder.
|
||||
pub fn new() -> Self {
|
||||
Self::default()
|
||||
}
|
||||
|
||||
/// The number of aliases in the section.
|
||||
pub fn len(&self) -> u32 {
|
||||
self.num_added
|
||||
}
|
||||
|
||||
/// Determines if the section is empty.
|
||||
pub fn is_empty(&self) -> bool {
|
||||
self.num_added == 0
|
||||
}
|
||||
|
||||
/// Define an alias to an instance's export.
|
||||
pub fn instance_export(
|
||||
&mut self,
|
||||
instance_index: u32,
|
||||
kind: ExportKind,
|
||||
name: &str,
|
||||
) -> &mut Self {
|
||||
kind.encode(&mut self.bytes);
|
||||
self.bytes.push(0x00);
|
||||
instance_index.encode(&mut self.bytes);
|
||||
name.encode(&mut self.bytes);
|
||||
self.num_added += 1;
|
||||
self
|
||||
}
|
||||
|
||||
/// Define an alias to an outer core item.
|
||||
///
|
||||
/// The count starts at 0 to indicate the current component, 1 indicates the direct
|
||||
/// parent, 2 the grandparent, etc.
|
||||
pub fn outer(&mut self, count: u32, kind: CoreOuterAliasKind, index: u32) -> &mut Self {
|
||||
kind.encode(&mut self.bytes);
|
||||
self.bytes.push(0x01);
|
||||
count.encode(&mut self.bytes);
|
||||
index.encode(&mut self.bytes);
|
||||
self.num_added += 1;
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl Encode for AliasSection {
|
||||
fn encode(&self, sink: &mut Vec<u8>) {
|
||||
encode_section(sink, self.num_added, &self.bytes);
|
||||
}
|
||||
}
|
||||
|
||||
impl ComponentSection for AliasSection {
|
||||
fn id(&self) -> u8 {
|
||||
ComponentSectionId::CoreAlias.into()
|
||||
}
|
||||
}
|
||||
|
||||
/// Represents the kinds of outer aliasable items in a component.
|
||||
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
|
||||
pub enum ComponentOuterAliasKind {
|
||||
/// The alias is to a core module.
|
||||
CoreModule,
|
||||
/// The alias is to a core type.
|
||||
CoreType,
|
||||
/// The alias is to a type.
|
||||
Type,
|
||||
/// The alias is to a component.
|
||||
Component,
|
||||
}
|
||||
|
||||
impl Encode for ComponentOuterAliasKind {
|
||||
fn encode(&self, sink: &mut Vec<u8>) {
|
||||
match self {
|
||||
Self::CoreModule => {
|
||||
sink.push(CORE_SORT);
|
||||
sink.push(CORE_MODULE_SORT);
|
||||
}
|
||||
Self::CoreType => {
|
||||
sink.push(CORE_SORT);
|
||||
sink.push(CORE_TYPE_SORT);
|
||||
}
|
||||
Self::Type => sink.push(TYPE_SORT),
|
||||
Self::Component => sink.push(COMPONENT_SORT),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// An encoder for the alias section of WebAssembly component.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```rust
|
||||
/// use wasm_encoder::{Component, ComponentAliasSection, ComponentExportKind, ComponentOuterAliasKind};
|
||||
///
|
||||
/// let mut aliases = ComponentAliasSection::new();
|
||||
/// aliases.instance_export(0, ComponentExportKind::Func, "f");
|
||||
/// aliases.outer(0, ComponentOuterAliasKind::Type, 1);
|
||||
///
|
||||
/// let mut component = Component::new();
|
||||
/// component.section(&aliases);
|
||||
///
|
||||
/// let bytes = component.finish();
|
||||
/// ```
|
||||
#[derive(Clone, Debug, Default)]
|
||||
pub struct ComponentAliasSection {
|
||||
bytes: Vec<u8>,
|
||||
num_added: u32,
|
||||
}
|
||||
|
||||
impl ComponentAliasSection {
|
||||
/// Create a new alias section encoder.
|
||||
pub fn new() -> Self {
|
||||
Self::default()
|
||||
}
|
||||
|
||||
/// The number of aliases in the section.
|
||||
pub fn len(&self) -> u32 {
|
||||
self.num_added
|
||||
}
|
||||
|
||||
/// Determines if the section is empty.
|
||||
pub fn is_empty(&self) -> bool {
|
||||
self.num_added == 0
|
||||
}
|
||||
|
||||
/// Define an alias to an instance's export.
|
||||
pub fn instance_export(
|
||||
&mut self,
|
||||
instance_index: u32,
|
||||
kind: ComponentExportKind,
|
||||
name: &str,
|
||||
) -> &mut Self {
|
||||
kind.encode(&mut self.bytes);
|
||||
self.bytes.push(0x00);
|
||||
instance_index.encode(&mut self.bytes);
|
||||
name.encode(&mut self.bytes);
|
||||
self.num_added += 1;
|
||||
self
|
||||
}
|
||||
|
||||
/// Define an alias to an outer component item.
|
||||
///
|
||||
/// The count starts at 0 to indicate the current component, 1 indicates the direct
|
||||
/// parent, 2 the grandparent, etc.
|
||||
pub fn outer(&mut self, count: u32, kind: ComponentOuterAliasKind, index: u32) -> &mut Self {
|
||||
kind.encode(&mut self.bytes);
|
||||
self.bytes.push(0x01);
|
||||
count.encode(&mut self.bytes);
|
||||
index.encode(&mut self.bytes);
|
||||
self.num_added += 1;
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl Encode for ComponentAliasSection {
|
||||
fn encode(&self, sink: &mut Vec<u8>) {
|
||||
encode_section(sink, self.num_added, &self.bytes);
|
||||
}
|
||||
}
|
||||
|
||||
impl ComponentSection for ComponentAliasSection {
|
||||
fn id(&self) -> u8 {
|
||||
ComponentSectionId::Alias.into()
|
||||
}
|
||||
}
|
133
third_party/rust/wasm-encoder/src/component/canonicals.rs
vendored
Normal file
133
third_party/rust/wasm-encoder/src/component/canonicals.rs
vendored
Normal file
@ -0,0 +1,133 @@
|
||||
use crate::{encode_section, ComponentSection, ComponentSectionId, Encode};
|
||||
|
||||
/// Represents options for canonical function definitions.
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub enum CanonicalOption {
|
||||
/// The string types in the function signature are UTF-8 encoded.
|
||||
UTF8,
|
||||
/// The string types in the function signature are UTF-16 encoded.
|
||||
UTF16,
|
||||
/// The string types in the function signature are compact UTF-16 encoded.
|
||||
CompactUTF16,
|
||||
/// The memory to use if the lifting or lowering of a function requires memory access.
|
||||
///
|
||||
/// The value is an index to a core memory.
|
||||
Memory(u32),
|
||||
/// The realloc function to use if the lifting or lowering of a function requires memory
|
||||
/// allocation.
|
||||
///
|
||||
/// The value is an index to a core function of type `(func (param i32 i32 i32 i32) (result i32))`.
|
||||
Realloc(u32),
|
||||
/// The post-return function to use if the lifting of a function requires
|
||||
/// cleanup after the function returns.
|
||||
PostReturn(u32),
|
||||
}
|
||||
|
||||
impl Encode for CanonicalOption {
|
||||
fn encode(&self, sink: &mut Vec<u8>) {
|
||||
match self {
|
||||
Self::UTF8 => sink.push(0x00),
|
||||
Self::UTF16 => sink.push(0x01),
|
||||
Self::CompactUTF16 => sink.push(0x02),
|
||||
Self::Memory(idx) => {
|
||||
sink.push(0x03);
|
||||
idx.encode(sink);
|
||||
}
|
||||
Self::Realloc(idx) => {
|
||||
sink.push(0x04);
|
||||
idx.encode(sink);
|
||||
}
|
||||
Self::PostReturn(idx) => {
|
||||
sink.push(0x05);
|
||||
idx.encode(sink);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// An encoder for the canonical function section of WebAssembly components.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```
|
||||
/// use wasm_encoder::{Component, CanonicalFunctionSection, CanonicalOption};
|
||||
///
|
||||
/// let mut functions = CanonicalFunctionSection::new();
|
||||
/// functions.lift(0, 0, [CanonicalOption::UTF8]);
|
||||
///
|
||||
/// let mut component = Component::new();
|
||||
/// component.section(&functions);
|
||||
///
|
||||
/// let bytes = component.finish();
|
||||
/// ```
|
||||
#[derive(Clone, Debug, Default)]
|
||||
pub struct CanonicalFunctionSection {
|
||||
bytes: Vec<u8>,
|
||||
num_added: u32,
|
||||
}
|
||||
|
||||
impl CanonicalFunctionSection {
|
||||
/// Construct a new component function section encoder.
|
||||
pub fn new() -> Self {
|
||||
Self::default()
|
||||
}
|
||||
|
||||
/// The number of functions in the section.
|
||||
pub fn len(&self) -> u32 {
|
||||
self.num_added
|
||||
}
|
||||
|
||||
/// Determines if the section is empty.
|
||||
pub fn is_empty(&self) -> bool {
|
||||
self.num_added == 0
|
||||
}
|
||||
|
||||
/// Define a function that will lift a core WebAssembly function to the canonical ABI.
|
||||
pub fn lift<O>(&mut self, core_func_index: u32, type_index: u32, options: O) -> &mut Self
|
||||
where
|
||||
O: IntoIterator<Item = CanonicalOption>,
|
||||
O::IntoIter: ExactSizeIterator,
|
||||
{
|
||||
let options = options.into_iter();
|
||||
self.bytes.push(0x00);
|
||||
self.bytes.push(0x00);
|
||||
core_func_index.encode(&mut self.bytes);
|
||||
options.len().encode(&mut self.bytes);
|
||||
for option in options {
|
||||
option.encode(&mut self.bytes);
|
||||
}
|
||||
type_index.encode(&mut self.bytes);
|
||||
self.num_added += 1;
|
||||
self
|
||||
}
|
||||
|
||||
/// Define a function that will lower a canonical ABI function to a core WebAssembly function.
|
||||
pub fn lower<O>(&mut self, func_index: u32, options: O) -> &mut Self
|
||||
where
|
||||
O: IntoIterator<Item = CanonicalOption>,
|
||||
O::IntoIter: ExactSizeIterator,
|
||||
{
|
||||
let options = options.into_iter();
|
||||
self.bytes.push(0x01);
|
||||
self.bytes.push(0x00);
|
||||
func_index.encode(&mut self.bytes);
|
||||
options.len().encode(&mut self.bytes);
|
||||
for option in options {
|
||||
option.encode(&mut self.bytes);
|
||||
}
|
||||
self.num_added += 1;
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl Encode for CanonicalFunctionSection {
|
||||
fn encode(&self, sink: &mut Vec<u8>) {
|
||||
encode_section(sink, self.num_added, &self.bytes);
|
||||
}
|
||||
}
|
||||
|
||||
impl ComponentSection for CanonicalFunctionSection {
|
||||
fn id(&self) -> u8 {
|
||||
ComponentSectionId::CanonicalFunction.into()
|
||||
}
|
||||
}
|
29
third_party/rust/wasm-encoder/src/component/components.rs
vendored
Normal file
29
third_party/rust/wasm-encoder/src/component/components.rs
vendored
Normal file
@ -0,0 +1,29 @@
|
||||
use crate::{Component, ComponentSection, ComponentSectionId, Encode};
|
||||
|
||||
/// An encoder for the component section of WebAssembly components.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```rust
|
||||
/// use wasm_encoder::{Component, NestedComponentSection};
|
||||
///
|
||||
/// let mut nested = Component::new();
|
||||
/// let mut component = Component::new();
|
||||
/// component.section(&NestedComponentSection(&nested));
|
||||
///
|
||||
/// let bytes = component.finish();
|
||||
/// ```
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct NestedComponentSection<'a>(pub &'a Component);
|
||||
|
||||
impl Encode for NestedComponentSection<'_> {
|
||||
fn encode(&self, sink: &mut Vec<u8>) {
|
||||
self.0.bytes.encode(sink);
|
||||
}
|
||||
}
|
||||
|
||||
impl ComponentSection for NestedComponentSection<'_> {
|
||||
fn id(&self) -> u8 {
|
||||
ComponentSectionId::Component.into()
|
||||
}
|
||||
}
|
108
third_party/rust/wasm-encoder/src/component/exports.rs
vendored
Normal file
108
third_party/rust/wasm-encoder/src/component/exports.rs
vendored
Normal file
@ -0,0 +1,108 @@
|
||||
use super::{
|
||||
COMPONENT_SORT, CORE_MODULE_SORT, CORE_SORT, FUNCTION_SORT, INSTANCE_SORT, TYPE_SORT,
|
||||
VALUE_SORT,
|
||||
};
|
||||
use crate::{encode_section, ComponentSection, ComponentSectionId, Encode};
|
||||
|
||||
/// Represents the kind of an export from a WebAssembly component.
|
||||
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
|
||||
pub enum ComponentExportKind {
|
||||
/// The export is a core module.
|
||||
Module,
|
||||
/// The export is a function.
|
||||
Func,
|
||||
/// The export is a value.
|
||||
Value,
|
||||
/// The export is a type.
|
||||
Type,
|
||||
/// The export is an instance.
|
||||
Instance,
|
||||
/// The export is a component.
|
||||
Component,
|
||||
}
|
||||
|
||||
impl Encode for ComponentExportKind {
|
||||
fn encode(&self, sink: &mut Vec<u8>) {
|
||||
match self {
|
||||
Self::Module => {
|
||||
sink.push(CORE_SORT);
|
||||
sink.push(CORE_MODULE_SORT);
|
||||
}
|
||||
Self::Func => {
|
||||
sink.push(FUNCTION_SORT);
|
||||
}
|
||||
Self::Value => {
|
||||
sink.push(VALUE_SORT);
|
||||
}
|
||||
Self::Type => {
|
||||
sink.push(TYPE_SORT);
|
||||
}
|
||||
Self::Instance => {
|
||||
sink.push(INSTANCE_SORT);
|
||||
}
|
||||
Self::Component => {
|
||||
sink.push(COMPONENT_SORT);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// An encoder for the export section of WebAssembly component.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```rust
|
||||
/// use wasm_encoder::{Component, ComponentExportSection, ComponentExportKind};
|
||||
///
|
||||
/// // This exports a function named "foo"
|
||||
/// let mut exports = ComponentExportSection::new();
|
||||
/// exports.export("foo", ComponentExportKind::Func, 0);
|
||||
///
|
||||
/// let mut component = Component::new();
|
||||
/// component.section(&exports);
|
||||
///
|
||||
/// let bytes = component.finish();
|
||||
/// ```
|
||||
#[derive(Clone, Debug, Default)]
|
||||
pub struct ComponentExportSection {
|
||||
bytes: Vec<u8>,
|
||||
num_added: u32,
|
||||
}
|
||||
|
||||
impl ComponentExportSection {
|
||||
/// Create a new component export section encoder.
|
||||
pub fn new() -> Self {
|
||||
Self::default()
|
||||
}
|
||||
|
||||
/// The number of exports in the section.
|
||||
pub fn len(&self) -> u32 {
|
||||
self.num_added
|
||||
}
|
||||
|
||||
/// Determines if the section is empty.
|
||||
pub fn is_empty(&self) -> bool {
|
||||
self.num_added == 0
|
||||
}
|
||||
|
||||
/// Define an export in the export section.
|
||||
pub fn export(&mut self, name: &str, kind: ComponentExportKind, index: u32) -> &mut Self {
|
||||
name.encode(&mut self.bytes);
|
||||
kind.encode(&mut self.bytes);
|
||||
index.encode(&mut self.bytes);
|
||||
self.num_added += 1;
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl Encode for ComponentExportSection {
|
||||
fn encode(&self, sink: &mut Vec<u8>) {
|
||||
encode_section(sink, self.num_added, &self.bytes);
|
||||
}
|
||||
}
|
||||
|
||||
impl ComponentSection for ComponentExportSection {
|
||||
fn id(&self) -> u8 {
|
||||
ComponentSectionId::Export.into()
|
||||
}
|
||||
}
|
148
third_party/rust/wasm-encoder/src/component/imports.rs
vendored
Normal file
148
third_party/rust/wasm-encoder/src/component/imports.rs
vendored
Normal file
@ -0,0 +1,148 @@
|
||||
use crate::{
|
||||
encode_section, ComponentExportKind, ComponentSection, ComponentSectionId, ComponentValType,
|
||||
Encode,
|
||||
};
|
||||
|
||||
/// 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,
|
||||
}
|
||||
|
||||
impl Encode for TypeBounds {
|
||||
fn encode(&self, sink: &mut Vec<u8>) {
|
||||
match self {
|
||||
Self::Eq => sink.push(0x00),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Represents a reference to a type.
|
||||
#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)]
|
||||
pub enum ComponentTypeRef {
|
||||
/// The reference is to a core module type.
|
||||
///
|
||||
/// The index is expected to be core type index to a core module type.
|
||||
Module(u32),
|
||||
/// The reference is to a function type.
|
||||
///
|
||||
/// The index is expected to be a type index to a function type.
|
||||
Func(u32),
|
||||
/// 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),
|
||||
/// The reference is to an instance type.
|
||||
///
|
||||
/// The index is expected to be a type index to an instance type.
|
||||
Instance(u32),
|
||||
/// The reference is to a component type.
|
||||
///
|
||||
/// The index is expected to be a type index to a component type.
|
||||
Component(u32),
|
||||
}
|
||||
|
||||
impl ComponentTypeRef {
|
||||
/// Gets the export kind of the reference.
|
||||
pub fn kind(&self) -> ComponentExportKind {
|
||||
match self {
|
||||
Self::Module(_) => ComponentExportKind::Module,
|
||||
Self::Func(_) => ComponentExportKind::Func,
|
||||
Self::Value(_) => ComponentExportKind::Value,
|
||||
Self::Type(..) => ComponentExportKind::Type,
|
||||
Self::Instance(_) => ComponentExportKind::Instance,
|
||||
Self::Component(_) => ComponentExportKind::Component,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Encode for ComponentTypeRef {
|
||||
fn encode(&self, sink: &mut Vec<u8>) {
|
||||
self.kind().encode(sink);
|
||||
|
||||
match self {
|
||||
Self::Module(idx) | Self::Func(idx) | Self::Instance(idx) | Self::Component(idx) => {
|
||||
idx.encode(sink);
|
||||
}
|
||||
Self::Value(ty) => ty.encode(sink),
|
||||
Self::Type(bounds, idx) => {
|
||||
bounds.encode(sink);
|
||||
idx.encode(sink);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// An encoder for the import section of WebAssembly components.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```rust
|
||||
/// use wasm_encoder::{Component, ComponentTypeSection, PrimitiveValType, ComponentImportSection, ComponentTypeRef};
|
||||
///
|
||||
/// let mut types = ComponentTypeSection::new();
|
||||
///
|
||||
/// // Define a function type of `[string, string] -> string`.
|
||||
/// types.function(
|
||||
/// [
|
||||
/// (Some("a"), PrimitiveValType::String),
|
||||
/// (Some("b"), PrimitiveValType::String)
|
||||
/// ],
|
||||
/// PrimitiveValType::String
|
||||
/// );
|
||||
///
|
||||
/// // This imports a function named `f` with the type defined above
|
||||
/// let mut imports = ComponentImportSection::new();
|
||||
/// imports.import("f", ComponentTypeRef::Func(0));
|
||||
///
|
||||
/// let mut component = Component::new();
|
||||
/// component.section(&types);
|
||||
/// component.section(&imports);
|
||||
///
|
||||
/// let bytes = component.finish();
|
||||
/// ```
|
||||
#[derive(Clone, Debug, Default)]
|
||||
pub struct ComponentImportSection {
|
||||
bytes: Vec<u8>,
|
||||
num_added: u32,
|
||||
}
|
||||
|
||||
impl ComponentImportSection {
|
||||
/// Create a new component import section encoder.
|
||||
pub fn new() -> Self {
|
||||
Self::default()
|
||||
}
|
||||
|
||||
/// The number of imports in the section.
|
||||
pub fn len(&self) -> u32 {
|
||||
self.num_added
|
||||
}
|
||||
|
||||
/// Determines if the section is empty.
|
||||
pub fn is_empty(&self) -> bool {
|
||||
self.num_added == 0
|
||||
}
|
||||
|
||||
/// Define an import in the component import section.
|
||||
pub fn import(&mut self, name: &str, ty: ComponentTypeRef) -> &mut Self {
|
||||
name.encode(&mut self.bytes);
|
||||
ty.encode(&mut self.bytes);
|
||||
self.num_added += 1;
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl Encode for ComponentImportSection {
|
||||
fn encode(&self, sink: &mut Vec<u8>) {
|
||||
encode_section(sink, self.num_added, &self.bytes);
|
||||
}
|
||||
}
|
||||
|
||||
impl ComponentSection for ComponentImportSection {
|
||||
fn id(&self) -> u8 {
|
||||
ComponentSectionId::Import.into()
|
||||
}
|
||||
}
|
196
third_party/rust/wasm-encoder/src/component/instances.rs
vendored
Normal file
196
third_party/rust/wasm-encoder/src/component/instances.rs
vendored
Normal file
@ -0,0 +1,196 @@
|
||||
use super::CORE_INSTANCE_SORT;
|
||||
use crate::{
|
||||
encode_section, ComponentExportKind, ComponentSection, ComponentSectionId, Encode, ExportKind,
|
||||
};
|
||||
|
||||
/// Represents an argument to a module instantiation.
|
||||
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
|
||||
pub enum ModuleArg {
|
||||
/// The argument is an instance.
|
||||
Instance(u32),
|
||||
}
|
||||
|
||||
impl Encode for ModuleArg {
|
||||
fn encode(&self, sink: &mut Vec<u8>) {
|
||||
let (sort, idx) = match self {
|
||||
Self::Instance(idx) => (CORE_INSTANCE_SORT, *idx),
|
||||
};
|
||||
sink.push(sort);
|
||||
idx.encode(sink);
|
||||
}
|
||||
}
|
||||
|
||||
/// An encoder for the core instance section of WebAssembly components.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```rust
|
||||
/// use wasm_encoder::{Component, InstanceSection, ExportKind, ModuleArg};
|
||||
///
|
||||
/// let mut instances = InstanceSection::new();
|
||||
/// instances.export_items([("foo", ExportKind::Func, 0)]);
|
||||
/// instances.instantiate(1, [("foo", ModuleArg::Instance(0))]);
|
||||
///
|
||||
/// let mut component = Component::new();
|
||||
/// component.section(&instances);
|
||||
///
|
||||
/// let bytes = component.finish();
|
||||
/// ```
|
||||
#[derive(Clone, Debug, Default)]
|
||||
pub struct InstanceSection {
|
||||
bytes: Vec<u8>,
|
||||
num_added: u32,
|
||||
}
|
||||
|
||||
impl InstanceSection {
|
||||
/// Create a new core instance section encoder.
|
||||
pub fn new() -> Self {
|
||||
Self::default()
|
||||
}
|
||||
|
||||
/// The number of instances in the section.
|
||||
pub fn len(&self) -> u32 {
|
||||
self.num_added
|
||||
}
|
||||
|
||||
/// Determines if the section is empty.
|
||||
pub fn is_empty(&self) -> bool {
|
||||
self.num_added == 0
|
||||
}
|
||||
|
||||
/// Define an instance by instantiating a core module.
|
||||
pub fn instantiate<'a, A>(&mut self, module_index: u32, args: A) -> &mut Self
|
||||
where
|
||||
A: IntoIterator<Item = (&'a str, ModuleArg)>,
|
||||
A::IntoIter: ExactSizeIterator,
|
||||
{
|
||||
let args = args.into_iter();
|
||||
self.bytes.push(0x00);
|
||||
module_index.encode(&mut self.bytes);
|
||||
args.len().encode(&mut self.bytes);
|
||||
for (name, arg) in args {
|
||||
name.encode(&mut self.bytes);
|
||||
arg.encode(&mut self.bytes);
|
||||
}
|
||||
self.num_added += 1;
|
||||
self
|
||||
}
|
||||
|
||||
/// Define an instance by exporting core WebAssembly items.
|
||||
pub fn export_items<'a, E>(&mut self, exports: E) -> &mut Self
|
||||
where
|
||||
E: IntoIterator<Item = (&'a str, ExportKind, u32)>,
|
||||
E::IntoIter: ExactSizeIterator,
|
||||
{
|
||||
let exports = exports.into_iter();
|
||||
self.bytes.push(0x01);
|
||||
exports.len().encode(&mut self.bytes);
|
||||
for (name, kind, index) in exports {
|
||||
name.encode(&mut self.bytes);
|
||||
kind.encode(&mut self.bytes);
|
||||
index.encode(&mut self.bytes);
|
||||
}
|
||||
self.num_added += 1;
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl Encode for InstanceSection {
|
||||
fn encode(&self, sink: &mut Vec<u8>) {
|
||||
encode_section(sink, self.num_added, &self.bytes);
|
||||
}
|
||||
}
|
||||
|
||||
impl ComponentSection for InstanceSection {
|
||||
fn id(&self) -> u8 {
|
||||
ComponentSectionId::CoreInstance.into()
|
||||
}
|
||||
}
|
||||
|
||||
/// An encoder for the instance section of WebAssembly components.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```rust
|
||||
/// use wasm_encoder::{Component, ComponentInstanceSection, ComponentExportKind};
|
||||
///
|
||||
/// let mut instances = ComponentInstanceSection::new();
|
||||
/// instances.export_items([("foo", ComponentExportKind::Func, 0)]);
|
||||
/// instances.instantiate(1, [("foo", ComponentExportKind::Instance, 0)]);
|
||||
///
|
||||
/// let mut component = Component::new();
|
||||
/// component.section(&instances);
|
||||
///
|
||||
/// let bytes = component.finish();
|
||||
/// ```
|
||||
#[derive(Clone, Debug, Default)]
|
||||
pub struct ComponentInstanceSection {
|
||||
bytes: Vec<u8>,
|
||||
num_added: u32,
|
||||
}
|
||||
|
||||
impl ComponentInstanceSection {
|
||||
/// Create a new instance section encoder.
|
||||
pub fn new() -> Self {
|
||||
Self::default()
|
||||
}
|
||||
|
||||
/// The number of instances in the section.
|
||||
pub fn len(&self) -> u32 {
|
||||
self.num_added
|
||||
}
|
||||
|
||||
/// Determines if the section is empty.
|
||||
pub fn is_empty(&self) -> bool {
|
||||
self.num_added == 0
|
||||
}
|
||||
|
||||
/// Define an instance by instantiating a component.
|
||||
pub fn instantiate<'a, A>(&mut self, component_index: u32, args: A) -> &mut Self
|
||||
where
|
||||
A: IntoIterator<Item = (&'a str, ComponentExportKind, u32)>,
|
||||
A::IntoIter: ExactSizeIterator,
|
||||
{
|
||||
let args = args.into_iter();
|
||||
self.bytes.push(0x00);
|
||||
component_index.encode(&mut self.bytes);
|
||||
args.len().encode(&mut self.bytes);
|
||||
for (name, kind, index) in args {
|
||||
name.encode(&mut self.bytes);
|
||||
kind.encode(&mut self.bytes);
|
||||
index.encode(&mut self.bytes);
|
||||
}
|
||||
self.num_added += 1;
|
||||
self
|
||||
}
|
||||
|
||||
/// 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::IntoIter: ExactSizeIterator,
|
||||
{
|
||||
let exports = exports.into_iter();
|
||||
self.bytes.push(0x01);
|
||||
exports.len().encode(&mut self.bytes);
|
||||
for (name, kind, index) in exports {
|
||||
name.encode(&mut self.bytes);
|
||||
kind.encode(&mut self.bytes);
|
||||
index.encode(&mut self.bytes);
|
||||
}
|
||||
self.num_added += 1;
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl Encode for ComponentInstanceSection {
|
||||
fn encode(&self, sink: &mut Vec<u8>) {
|
||||
encode_section(sink, self.num_added, &self.bytes);
|
||||
}
|
||||
}
|
||||
|
||||
impl ComponentSection for ComponentInstanceSection {
|
||||
fn id(&self) -> u8 {
|
||||
ComponentSectionId::Instance.into()
|
||||
}
|
||||
}
|
29
third_party/rust/wasm-encoder/src/component/modules.rs
vendored
Normal file
29
third_party/rust/wasm-encoder/src/component/modules.rs
vendored
Normal file
@ -0,0 +1,29 @@
|
||||
use crate::{ComponentSection, ComponentSectionId, Encode, Module};
|
||||
|
||||
/// An encoder for the module section of WebAssembly components.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```rust
|
||||
/// use wasm_encoder::{Module, Component, ModuleSection};
|
||||
///
|
||||
/// let mut module = Module::new();
|
||||
/// let mut component = Component::new();
|
||||
/// component.section(&ModuleSection(&module));
|
||||
///
|
||||
/// let bytes = component.finish();
|
||||
/// ```
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct ModuleSection<'a>(pub &'a Module);
|
||||
|
||||
impl Encode for ModuleSection<'_> {
|
||||
fn encode(&self, sink: &mut Vec<u8>) {
|
||||
self.0.bytes.encode(sink);
|
||||
}
|
||||
}
|
||||
|
||||
impl ComponentSection for ModuleSection<'_> {
|
||||
fn id(&self) -> u8 {
|
||||
ComponentSectionId::CoreModule.into()
|
||||
}
|
||||
}
|
46
third_party/rust/wasm-encoder/src/component/start.rs
vendored
Normal file
46
third_party/rust/wasm-encoder/src/component/start.rs
vendored
Normal file
@ -0,0 +1,46 @@
|
||||
use crate::{ComponentSection, ComponentSectionId, Encode};
|
||||
|
||||
/// An encoder for the start section of WebAssembly components.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```
|
||||
/// use wasm_encoder::{Component, ComponentStartSection};
|
||||
///
|
||||
/// let start = ComponentStartSection { function_index: 0, args: [] };
|
||||
///
|
||||
/// let mut component = Component::new();
|
||||
/// component.section(&start);
|
||||
///
|
||||
/// let bytes = component.finish();
|
||||
/// ```
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct ComponentStartSection<A> {
|
||||
/// The index to the start function.
|
||||
pub function_index: u32,
|
||||
/// The arguments to pass to the start function.
|
||||
///
|
||||
/// An argument is an index to a value.
|
||||
pub args: A,
|
||||
}
|
||||
|
||||
impl<A> Encode for ComponentStartSection<A>
|
||||
where
|
||||
A: AsRef<[u32]>,
|
||||
{
|
||||
fn encode(&self, sink: &mut Vec<u8>) {
|
||||
let mut bytes = Vec::new();
|
||||
self.function_index.encode(&mut bytes);
|
||||
self.args.as_ref().encode(&mut bytes);
|
||||
bytes.encode(sink);
|
||||
}
|
||||
}
|
||||
|
||||
impl<A> ComponentSection for ComponentStartSection<A>
|
||||
where
|
||||
A: AsRef<[u32]>,
|
||||
{
|
||||
fn id(&self) -> u8 {
|
||||
ComponentSectionId::Start.into()
|
||||
}
|
||||
}
|
727
third_party/rust/wasm-encoder/src/component/types.rs
vendored
Normal file
727
third_party/rust/wasm-encoder/src/component/types.rs
vendored
Normal file
@ -0,0 +1,727 @@
|
||||
use crate::{
|
||||
encode_section, ComponentOuterAliasKind, ComponentSection, ComponentSectionId,
|
||||
ComponentTypeRef, CoreOuterAliasKind, Encode, EntityType, ValType,
|
||||
};
|
||||
|
||||
/// Represents the type of a core module.
|
||||
#[derive(Debug, Clone, Default)]
|
||||
pub struct ModuleType {
|
||||
bytes: Vec<u8>,
|
||||
num_added: u32,
|
||||
types_added: u32,
|
||||
}
|
||||
|
||||
impl ModuleType {
|
||||
/// Creates a new core module type.
|
||||
pub fn new() -> Self {
|
||||
Self::default()
|
||||
}
|
||||
|
||||
/// Defines an outer core type alias in this module type.
|
||||
pub fn alias_outer_core_type(&mut self, count: u32, index: u32) -> &mut Self {
|
||||
self.bytes.push(0x02);
|
||||
CoreOuterAliasKind::Type.encode(&mut self.bytes);
|
||||
self.bytes.push(0x01);
|
||||
count.encode(&mut self.bytes);
|
||||
index.encode(&mut self.bytes);
|
||||
self.num_added += 1;
|
||||
self.types_added += 1;
|
||||
self
|
||||
}
|
||||
|
||||
/// Defines an import in this module type.
|
||||
pub fn import(&mut self, module: &str, name: &str, ty: EntityType) -> &mut Self {
|
||||
self.bytes.push(0x00);
|
||||
module.encode(&mut self.bytes);
|
||||
name.encode(&mut self.bytes);
|
||||
ty.encode(&mut self.bytes);
|
||||
self.num_added += 1;
|
||||
self
|
||||
}
|
||||
|
||||
/// Define a type in this module type.
|
||||
///
|
||||
/// The returned encoder must be used before adding another definition.
|
||||
#[must_use = "the encoder must be used to encode the type"]
|
||||
pub fn ty(&mut self) -> CoreTypeEncoder {
|
||||
self.bytes.push(0x01);
|
||||
self.num_added += 1;
|
||||
self.types_added += 1;
|
||||
CoreTypeEncoder(&mut self.bytes)
|
||||
}
|
||||
|
||||
/// Defines an export in this module type.
|
||||
pub fn export(&mut self, name: &str, ty: EntityType) -> &mut Self {
|
||||
self.bytes.push(0x03);
|
||||
name.encode(&mut self.bytes);
|
||||
ty.encode(&mut self.bytes);
|
||||
self.num_added += 1;
|
||||
self
|
||||
}
|
||||
|
||||
/// Gets the number of types that have been added to this module type.
|
||||
pub fn type_count(&self) -> u32 {
|
||||
self.types_added
|
||||
}
|
||||
}
|
||||
|
||||
impl Encode for ModuleType {
|
||||
fn encode(&self, sink: &mut Vec<u8>) {
|
||||
sink.push(0x50);
|
||||
self.num_added.encode(sink);
|
||||
sink.extend(&self.bytes);
|
||||
}
|
||||
}
|
||||
|
||||
/// Used to encode core types.
|
||||
#[derive(Debug)]
|
||||
pub struct CoreTypeEncoder<'a>(pub(crate) &'a mut Vec<u8>);
|
||||
|
||||
impl<'a> CoreTypeEncoder<'a> {
|
||||
/// Define a function type.
|
||||
pub fn function<P, R>(self, params: P, results: R)
|
||||
where
|
||||
P: IntoIterator<Item = ValType>,
|
||||
P::IntoIter: ExactSizeIterator,
|
||||
R: IntoIterator<Item = ValType>,
|
||||
R::IntoIter: ExactSizeIterator,
|
||||
{
|
||||
let params = params.into_iter();
|
||||
let results = results.into_iter();
|
||||
|
||||
self.0.push(0x60);
|
||||
params.len().encode(self.0);
|
||||
self.0.extend(params.map(u8::from));
|
||||
results.len().encode(self.0);
|
||||
self.0.extend(results.map(u8::from));
|
||||
}
|
||||
|
||||
/// Define a module type.
|
||||
pub fn module(self, ty: &ModuleType) {
|
||||
ty.encode(self.0);
|
||||
}
|
||||
}
|
||||
|
||||
/// An encoder for the core type section of WebAssembly components.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```rust
|
||||
/// use wasm_encoder::{Component, CoreTypeSection, ModuleType};
|
||||
///
|
||||
/// let mut types = CoreTypeSection::new();
|
||||
///
|
||||
/// types.module(&ModuleType::new());
|
||||
///
|
||||
/// let mut component = Component::new();
|
||||
/// component.section(&types);
|
||||
///
|
||||
/// let bytes = component.finish();
|
||||
/// ```
|
||||
#[derive(Clone, Debug, Default)]
|
||||
pub struct CoreTypeSection {
|
||||
bytes: Vec<u8>,
|
||||
num_added: u32,
|
||||
}
|
||||
|
||||
impl CoreTypeSection {
|
||||
/// Create a new core type section encoder.
|
||||
pub fn new() -> Self {
|
||||
Self::default()
|
||||
}
|
||||
|
||||
/// The number of types in the section.
|
||||
pub fn len(&self) -> u32 {
|
||||
self.num_added
|
||||
}
|
||||
|
||||
/// Determines if the section is empty.
|
||||
pub fn is_empty(&self) -> bool {
|
||||
self.num_added == 0
|
||||
}
|
||||
|
||||
/// Encode a type into this section.
|
||||
///
|
||||
/// The returned encoder must be finished before adding another type.
|
||||
#[must_use = "the encoder must be used to encode the type"]
|
||||
pub fn ty(&mut self) -> CoreTypeEncoder<'_> {
|
||||
self.num_added += 1;
|
||||
CoreTypeEncoder(&mut self.bytes)
|
||||
}
|
||||
|
||||
/// Define a function type in this type section.
|
||||
pub fn function<P, R>(&mut self, params: P, results: R) -> &mut Self
|
||||
where
|
||||
P: IntoIterator<Item = ValType>,
|
||||
P::IntoIter: ExactSizeIterator,
|
||||
R: IntoIterator<Item = ValType>,
|
||||
R::IntoIter: ExactSizeIterator,
|
||||
{
|
||||
self.ty().function(params, results);
|
||||
self
|
||||
}
|
||||
|
||||
/// Define a module type in this type section.
|
||||
///
|
||||
/// Currently this is only used for core type sections in components.
|
||||
pub fn module(&mut self, ty: &ModuleType) -> &mut Self {
|
||||
self.ty().module(ty);
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl Encode for CoreTypeSection {
|
||||
fn encode(&self, sink: &mut Vec<u8>) {
|
||||
encode_section(sink, self.num_added, &self.bytes);
|
||||
}
|
||||
}
|
||||
|
||||
impl ComponentSection for CoreTypeSection {
|
||||
fn id(&self) -> u8 {
|
||||
ComponentSectionId::CoreType.into()
|
||||
}
|
||||
}
|
||||
|
||||
/// Represents a component type.
|
||||
#[derive(Debug, Clone, Default)]
|
||||
pub struct ComponentType {
|
||||
bytes: Vec<u8>,
|
||||
num_added: u32,
|
||||
core_types_added: u32,
|
||||
types_added: u32,
|
||||
}
|
||||
|
||||
impl ComponentType {
|
||||
/// Creates a new component type.
|
||||
pub fn new() -> Self {
|
||||
Self::default()
|
||||
}
|
||||
|
||||
/// Define a core type in this component type.
|
||||
///
|
||||
/// The returned encoder must be used before adding another definition.
|
||||
#[must_use = "the encoder must be used to encode the type"]
|
||||
pub fn core_type(&mut self) -> CoreTypeEncoder {
|
||||
self.bytes.push(0x00);
|
||||
self.num_added += 1;
|
||||
self.core_types_added += 1;
|
||||
CoreTypeEncoder(&mut self.bytes)
|
||||
}
|
||||
|
||||
/// Define a type in this component type.
|
||||
///
|
||||
/// The returned encoder must be used before adding another definition.
|
||||
#[must_use = "the encoder must be used to encode the type"]
|
||||
pub fn ty(&mut self) -> ComponentTypeEncoder {
|
||||
self.bytes.push(0x01);
|
||||
self.num_added += 1;
|
||||
self.types_added += 1;
|
||||
ComponentTypeEncoder(&mut self.bytes)
|
||||
}
|
||||
|
||||
/// Defines an outer core type alias in this component type.
|
||||
pub fn alias_outer_core_type(&mut self, count: u32, index: u32) -> &mut Self {
|
||||
self.bytes.push(0x02);
|
||||
ComponentOuterAliasKind::CoreType.encode(&mut self.bytes);
|
||||
self.bytes.push(0x01);
|
||||
count.encode(&mut self.bytes);
|
||||
index.encode(&mut self.bytes);
|
||||
self.num_added += 1;
|
||||
self.types_added += 1;
|
||||
self
|
||||
}
|
||||
|
||||
/// Defines an outer type alias in this component type.
|
||||
pub fn alias_outer_type(&mut self, count: u32, index: u32) -> &mut Self {
|
||||
self.bytes.push(0x02);
|
||||
ComponentOuterAliasKind::Type.encode(&mut self.bytes);
|
||||
self.bytes.push(0x01);
|
||||
count.encode(&mut self.bytes);
|
||||
index.encode(&mut self.bytes);
|
||||
self.num_added += 1;
|
||||
self.types_added += 1;
|
||||
self
|
||||
}
|
||||
|
||||
/// Defines an import in this component type.
|
||||
pub fn import(&mut self, name: &str, ty: ComponentTypeRef) -> &mut Self {
|
||||
self.bytes.push(0x03);
|
||||
name.encode(&mut self.bytes);
|
||||
ty.encode(&mut self.bytes);
|
||||
self.num_added += 1;
|
||||
self
|
||||
}
|
||||
|
||||
/// Defines an export in this component type.
|
||||
pub fn export(&mut self, name: &str, ty: ComponentTypeRef) -> &mut Self {
|
||||
self.bytes.push(0x04);
|
||||
name.encode(&mut self.bytes);
|
||||
ty.encode(&mut self.bytes);
|
||||
self.num_added += 1;
|
||||
self
|
||||
}
|
||||
|
||||
/// Gets the number of core types that have been added to this component type.
|
||||
pub fn core_type_count(&self) -> u32 {
|
||||
self.core_types_added
|
||||
}
|
||||
|
||||
/// Gets the number of types that have been added or aliased in this component type.
|
||||
pub fn type_count(&self) -> u32 {
|
||||
self.types_added
|
||||
}
|
||||
}
|
||||
|
||||
impl Encode for ComponentType {
|
||||
fn encode(&self, sink: &mut Vec<u8>) {
|
||||
sink.push(0x41);
|
||||
self.num_added.encode(sink);
|
||||
sink.extend(&self.bytes);
|
||||
}
|
||||
}
|
||||
|
||||
/// Represents an instance type.
|
||||
#[derive(Debug, Clone, Default)]
|
||||
pub struct InstanceType {
|
||||
bytes: Vec<u8>,
|
||||
num_added: u32,
|
||||
core_types_added: u32,
|
||||
types_added: u32,
|
||||
}
|
||||
|
||||
impl InstanceType {
|
||||
/// Creates a new instance type.
|
||||
pub fn new() -> Self {
|
||||
Self::default()
|
||||
}
|
||||
|
||||
/// Define a core type in this instance type.
|
||||
///
|
||||
/// The returned encoder must be used before adding another definition.
|
||||
#[must_use = "the encoder must be used to encode the type"]
|
||||
pub fn core_type(&mut self) -> CoreTypeEncoder {
|
||||
self.bytes.push(0x00);
|
||||
self.num_added += 1;
|
||||
self.core_types_added += 1;
|
||||
CoreTypeEncoder(&mut self.bytes)
|
||||
}
|
||||
|
||||
/// Define a type in this instance type.
|
||||
///
|
||||
/// The returned encoder must be used before adding another definition.
|
||||
#[must_use = "the encoder must be used to encode the type"]
|
||||
pub fn ty(&mut self) -> ComponentTypeEncoder {
|
||||
self.bytes.push(0x01);
|
||||
self.num_added += 1;
|
||||
self.types_added += 1;
|
||||
ComponentTypeEncoder(&mut self.bytes)
|
||||
}
|
||||
|
||||
/// Defines an outer core type alias in this component type.
|
||||
pub fn alias_outer_core_type(&mut self, count: u32, index: u32) -> &mut Self {
|
||||
self.bytes.push(0x02);
|
||||
ComponentOuterAliasKind::CoreType.encode(&mut self.bytes);
|
||||
self.bytes.push(0x01);
|
||||
count.encode(&mut self.bytes);
|
||||
index.encode(&mut self.bytes);
|
||||
self.num_added += 1;
|
||||
self.types_added += 1;
|
||||
self
|
||||
}
|
||||
|
||||
/// Defines an alias in this instance type.
|
||||
pub fn alias_outer_type(&mut self, count: u32, index: u32) -> &mut Self {
|
||||
self.bytes.push(0x02);
|
||||
ComponentOuterAliasKind::Type.encode(&mut self.bytes);
|
||||
self.bytes.push(0x01);
|
||||
count.encode(&mut self.bytes);
|
||||
index.encode(&mut self.bytes);
|
||||
self.num_added += 1;
|
||||
self.types_added += 1;
|
||||
self
|
||||
}
|
||||
|
||||
/// Defines an export in this instance type.
|
||||
pub fn export(&mut self, name: &str, ty: ComponentTypeRef) -> &mut Self {
|
||||
self.bytes.push(0x04);
|
||||
name.encode(&mut self.bytes);
|
||||
ty.encode(&mut self.bytes);
|
||||
self.num_added += 1;
|
||||
self
|
||||
}
|
||||
|
||||
/// Gets the number of core types that have been added to this instance type.
|
||||
pub fn core_type_count(&self) -> u32 {
|
||||
self.core_types_added
|
||||
}
|
||||
|
||||
/// Gets the number of types that have been added or aliased in this instance type.
|
||||
pub fn type_count(&self) -> u32 {
|
||||
self.types_added
|
||||
}
|
||||
}
|
||||
|
||||
impl Encode for InstanceType {
|
||||
fn encode(&self, sink: &mut Vec<u8>) {
|
||||
sink.push(0x42);
|
||||
self.num_added.encode(sink);
|
||||
sink.extend(&self.bytes);
|
||||
}
|
||||
}
|
||||
|
||||
/// Used to encode component and instance types.
|
||||
#[derive(Debug)]
|
||||
pub struct ComponentTypeEncoder<'a>(&'a mut Vec<u8>);
|
||||
|
||||
impl<'a> ComponentTypeEncoder<'a> {
|
||||
/// Define a component type.
|
||||
pub fn component(self, ty: &ComponentType) {
|
||||
ty.encode(self.0);
|
||||
}
|
||||
|
||||
/// Define an instance type.
|
||||
pub fn instance(self, ty: &InstanceType) {
|
||||
ty.encode(self.0);
|
||||
}
|
||||
|
||||
/// Define a function type.
|
||||
pub fn function<'b, P, T>(self, params: P, result: impl Into<ComponentValType>)
|
||||
where
|
||||
P: IntoIterator<Item = (Option<&'b str>, T)>,
|
||||
P::IntoIter: ExactSizeIterator,
|
||||
T: Into<ComponentValType>,
|
||||
{
|
||||
let params = params.into_iter();
|
||||
self.0.push(0x40);
|
||||
|
||||
params.len().encode(self.0);
|
||||
for (name, ty) in params {
|
||||
match name {
|
||||
Some(name) => {
|
||||
self.0.push(0x01);
|
||||
name.encode(self.0);
|
||||
}
|
||||
None => self.0.push(0x00),
|
||||
}
|
||||
ty.into().encode(self.0);
|
||||
}
|
||||
|
||||
result.into().encode(self.0);
|
||||
}
|
||||
|
||||
/// Define a defined component type.
|
||||
///
|
||||
/// The returned encoder must be used before adding another type.
|
||||
#[must_use = "the encoder must be used to encode the type"]
|
||||
pub fn defined_type(self) -> ComponentDefinedTypeEncoder<'a> {
|
||||
ComponentDefinedTypeEncoder(self.0)
|
||||
}
|
||||
}
|
||||
|
||||
/// Represents a primitive component value type.
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
||||
pub enum PrimitiveValType {
|
||||
/// The type is the unit type.
|
||||
Unit,
|
||||
/// The type is a boolean.
|
||||
Bool,
|
||||
/// The type is a signed 8-bit integer.
|
||||
S8,
|
||||
/// The type is an unsigned 8-bit integer.
|
||||
U8,
|
||||
/// The type is a signed 16-bit integer.
|
||||
S16,
|
||||
/// The type is an unsigned 16-bit integer.
|
||||
U16,
|
||||
/// The type is a signed 32-bit integer.
|
||||
S32,
|
||||
/// The type is an unsigned 32-bit integer.
|
||||
U32,
|
||||
/// The type is a signed 64-bit integer.
|
||||
S64,
|
||||
/// The type is an unsigned 64-bit integer.
|
||||
U64,
|
||||
/// The type is a 32-bit floating point number.
|
||||
Float32,
|
||||
/// The type is a 64-bit floating point number.
|
||||
Float64,
|
||||
/// The type is a Unicode character.
|
||||
Char,
|
||||
/// The type is a string.
|
||||
String,
|
||||
}
|
||||
|
||||
impl Encode for PrimitiveValType {
|
||||
fn encode(&self, sink: &mut Vec<u8>) {
|
||||
sink.push(match self {
|
||||
Self::Unit => 0x7f,
|
||||
Self::Bool => 0x7e,
|
||||
Self::S8 => 0x7d,
|
||||
Self::U8 => 0x7c,
|
||||
Self::S16 => 0x7b,
|
||||
Self::U16 => 0x7a,
|
||||
Self::S32 => 0x79,
|
||||
Self::U32 => 0x78,
|
||||
Self::S64 => 0x77,
|
||||
Self::U64 => 0x76,
|
||||
Self::Float32 => 0x75,
|
||||
Self::Float64 => 0x74,
|
||||
Self::Char => 0x73,
|
||||
Self::String => 0x72,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/// Represents a component value type.
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
||||
pub enum ComponentValType {
|
||||
/// The value is a primitive type.
|
||||
Primitive(PrimitiveValType),
|
||||
/// The value is to a defined value type.
|
||||
///
|
||||
/// The type index must be to a value type.
|
||||
Type(u32),
|
||||
}
|
||||
|
||||
impl Encode for ComponentValType {
|
||||
fn encode(&self, sink: &mut Vec<u8>) {
|
||||
match self {
|
||||
Self::Primitive(ty) => ty.encode(sink),
|
||||
Self::Type(index) => (*index as i64).encode(sink),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<PrimitiveValType> for ComponentValType {
|
||||
fn from(ty: PrimitiveValType) -> Self {
|
||||
Self::Primitive(ty)
|
||||
}
|
||||
}
|
||||
|
||||
/// Used for encoding component defined types.
|
||||
#[derive(Debug)]
|
||||
pub struct ComponentDefinedTypeEncoder<'a>(&'a mut Vec<u8>);
|
||||
|
||||
impl ComponentDefinedTypeEncoder<'_> {
|
||||
/// Define a primitive value type.
|
||||
pub fn primitive(self, ty: PrimitiveValType) {
|
||||
ty.encode(self.0);
|
||||
}
|
||||
|
||||
/// Define a record type.
|
||||
pub fn record<'a, F, T>(self, fields: F)
|
||||
where
|
||||
F: IntoIterator<Item = (&'a str, T)>,
|
||||
F::IntoIter: ExactSizeIterator,
|
||||
T: Into<ComponentValType>,
|
||||
{
|
||||
let fields = fields.into_iter();
|
||||
self.0.push(0x71);
|
||||
fields.len().encode(self.0);
|
||||
for (name, ty) in fields {
|
||||
name.encode(self.0);
|
||||
ty.into().encode(self.0);
|
||||
}
|
||||
}
|
||||
|
||||
/// Define a variant type.
|
||||
pub fn variant<'a, C, T>(self, cases: C)
|
||||
where
|
||||
C: IntoIterator<Item = (&'a str, T, Option<u32>)>,
|
||||
C::IntoIter: ExactSizeIterator,
|
||||
T: Into<ComponentValType>,
|
||||
{
|
||||
let cases = cases.into_iter();
|
||||
self.0.push(0x70);
|
||||
cases.len().encode(self.0);
|
||||
for (name, ty, refines) in cases {
|
||||
name.encode(self.0);
|
||||
ty.into().encode(self.0);
|
||||
if let Some(default) = refines {
|
||||
self.0.push(0x01);
|
||||
default.encode(self.0);
|
||||
} else {
|
||||
self.0.push(0x00);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Define a list type.
|
||||
pub fn list(self, ty: impl Into<ComponentValType>) {
|
||||
self.0.push(0x6f);
|
||||
ty.into().encode(self.0);
|
||||
}
|
||||
|
||||
/// Define a tuple type.
|
||||
pub fn tuple<I, T>(self, types: I)
|
||||
where
|
||||
I: IntoIterator<Item = T>,
|
||||
I::IntoIter: ExactSizeIterator,
|
||||
T: Into<ComponentValType>,
|
||||
{
|
||||
let types = types.into_iter();
|
||||
self.0.push(0x6E);
|
||||
types.len().encode(self.0);
|
||||
for ty in types {
|
||||
ty.into().encode(self.0);
|
||||
}
|
||||
}
|
||||
|
||||
/// Define a flags type.
|
||||
pub fn flags<'a, I>(self, names: I)
|
||||
where
|
||||
I: IntoIterator<Item = &'a str>,
|
||||
I::IntoIter: ExactSizeIterator,
|
||||
{
|
||||
let names = names.into_iter();
|
||||
self.0.push(0x6D);
|
||||
names.len().encode(self.0);
|
||||
for name in names {
|
||||
name.encode(self.0);
|
||||
}
|
||||
}
|
||||
|
||||
/// Define an enum type.
|
||||
pub fn enum_type<'a, I>(self, tags: I)
|
||||
where
|
||||
I: IntoIterator<Item = &'a str>,
|
||||
I::IntoIter: ExactSizeIterator,
|
||||
{
|
||||
let tags = tags.into_iter();
|
||||
self.0.push(0x6C);
|
||||
tags.len().encode(self.0);
|
||||
for tag in tags {
|
||||
tag.encode(self.0);
|
||||
}
|
||||
}
|
||||
|
||||
/// Define a union type.
|
||||
pub fn union<I, T>(self, types: I)
|
||||
where
|
||||
I: IntoIterator<Item = T>,
|
||||
I::IntoIter: ExactSizeIterator,
|
||||
T: Into<ComponentValType>,
|
||||
{
|
||||
let types = types.into_iter();
|
||||
self.0.push(0x6B);
|
||||
types.len().encode(self.0);
|
||||
for ty in types {
|
||||
ty.into().encode(self.0);
|
||||
}
|
||||
}
|
||||
|
||||
/// Define an option type.
|
||||
pub fn option(self, ty: impl Into<ComponentValType>) {
|
||||
self.0.push(0x6A);
|
||||
ty.into().encode(self.0);
|
||||
}
|
||||
|
||||
/// Define an expected type.
|
||||
pub fn expected(self, ok: impl Into<ComponentValType>, error: impl Into<ComponentValType>) {
|
||||
self.0.push(0x69);
|
||||
ok.into().encode(self.0);
|
||||
error.into().encode(self.0);
|
||||
}
|
||||
}
|
||||
|
||||
/// An encoder for the type section of WebAssembly components.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```rust
|
||||
/// use wasm_encoder::{Component, ComponentTypeSection, PrimitiveValType};
|
||||
///
|
||||
/// let mut types = ComponentTypeSection::new();
|
||||
///
|
||||
/// // Define a function type of `[string, string] -> string`.
|
||||
/// types.function(
|
||||
/// [
|
||||
/// (Some("a"), PrimitiveValType::String),
|
||||
/// (Some("b"), PrimitiveValType::String)
|
||||
/// ],
|
||||
/// PrimitiveValType::String
|
||||
/// );
|
||||
///
|
||||
/// let mut component = Component::new();
|
||||
/// component.section(&types);
|
||||
///
|
||||
/// let bytes = component.finish();
|
||||
/// ```
|
||||
#[derive(Clone, Debug, Default)]
|
||||
pub struct ComponentTypeSection {
|
||||
bytes: Vec<u8>,
|
||||
num_added: u32,
|
||||
}
|
||||
|
||||
impl ComponentTypeSection {
|
||||
/// Create a new component type section encoder.
|
||||
pub fn new() -> Self {
|
||||
Self::default()
|
||||
}
|
||||
|
||||
/// The number of types in the section.
|
||||
pub fn len(&self) -> u32 {
|
||||
self.num_added
|
||||
}
|
||||
|
||||
/// Determines if the section is empty.
|
||||
pub fn is_empty(&self) -> bool {
|
||||
self.num_added == 0
|
||||
}
|
||||
|
||||
/// Encode a type into this section.
|
||||
///
|
||||
/// The returned encoder must be finished before adding another type.
|
||||
#[must_use = "the encoder must be used to encode the type"]
|
||||
pub fn ty(&mut self) -> ComponentTypeEncoder<'_> {
|
||||
self.num_added += 1;
|
||||
ComponentTypeEncoder(&mut self.bytes)
|
||||
}
|
||||
|
||||
/// Define a component type in this type section.
|
||||
pub fn component(&mut self, ty: &ComponentType) -> &mut Self {
|
||||
self.ty().component(ty);
|
||||
self
|
||||
}
|
||||
|
||||
/// Define an instance type in this type section.
|
||||
pub fn instance(&mut self, ty: &InstanceType) -> &mut Self {
|
||||
self.ty().instance(ty);
|
||||
self
|
||||
}
|
||||
|
||||
/// Define a function type in this type section.
|
||||
pub fn function<'a, P, T>(
|
||||
&mut self,
|
||||
params: P,
|
||||
result: impl Into<ComponentValType>,
|
||||
) -> &mut Self
|
||||
where
|
||||
P: IntoIterator<Item = (Option<&'a str>, T)>,
|
||||
P::IntoIter: ExactSizeIterator,
|
||||
T: Into<ComponentValType>,
|
||||
{
|
||||
self.ty().function(params, result);
|
||||
self
|
||||
}
|
||||
|
||||
/// Add a component defined type to this type section.
|
||||
///
|
||||
/// The returned encoder must be used before adding another type.
|
||||
#[must_use = "the encoder must be used to encode the type"]
|
||||
pub fn defined_type(&mut self) -> ComponentDefinedTypeEncoder<'_> {
|
||||
self.ty().defined_type()
|
||||
}
|
||||
}
|
||||
|
||||
impl Encode for ComponentTypeSection {
|
||||
fn encode(&self, sink: &mut Vec<u8>) {
|
||||
encode_section(sink, self.num_added, &self.bytes);
|
||||
}
|
||||
}
|
||||
|
||||
impl ComponentSection for ComponentTypeSection {
|
||||
fn id(&self) -> u8 {
|
||||
ComponentSectionId::Type.into()
|
||||
}
|
||||
}
|
154
third_party/rust/wasm-encoder/src/core.rs
vendored
Normal file
154
third_party/rust/wasm-encoder/src/core.rs
vendored
Normal file
@ -0,0 +1,154 @@
|
||||
mod code;
|
||||
mod custom;
|
||||
mod data;
|
||||
mod elements;
|
||||
mod exports;
|
||||
mod functions;
|
||||
mod globals;
|
||||
mod imports;
|
||||
mod linking;
|
||||
mod memories;
|
||||
mod names;
|
||||
mod start;
|
||||
mod tables;
|
||||
mod tags;
|
||||
mod types;
|
||||
|
||||
pub use code::*;
|
||||
pub use custom::*;
|
||||
pub use data::*;
|
||||
pub use elements::*;
|
||||
pub use exports::*;
|
||||
pub use functions::*;
|
||||
pub use globals::*;
|
||||
pub use imports::*;
|
||||
pub use linking::*;
|
||||
pub use memories::*;
|
||||
pub use names::*;
|
||||
pub use start::*;
|
||||
pub use tables::*;
|
||||
pub use tags::*;
|
||||
pub use types::*;
|
||||
|
||||
use crate::Encode;
|
||||
|
||||
pub(crate) const CORE_FUNCTION_SORT: u8 = 0x00;
|
||||
pub(crate) const CORE_TABLE_SORT: u8 = 0x01;
|
||||
pub(crate) const CORE_MEMORY_SORT: u8 = 0x02;
|
||||
pub(crate) const CORE_GLOBAL_SORT: u8 = 0x03;
|
||||
pub(crate) const CORE_TAG_SORT: u8 = 0x04;
|
||||
|
||||
/// A WebAssembly module section.
|
||||
///
|
||||
/// Various builders defined in this crate already implement this trait, but you
|
||||
/// can also implement it yourself for your own custom section builders, or use
|
||||
/// `RawSection` to use a bunch of raw bytes as a section.
|
||||
pub trait Section: Encode {
|
||||
/// Gets the section identifier for this section.
|
||||
fn id(&self) -> u8;
|
||||
}
|
||||
|
||||
/// Known section identifiers of WebAssembly modules.
|
||||
#[derive(Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd)]
|
||||
#[repr(u8)]
|
||||
pub enum SectionId {
|
||||
/// The custom section.
|
||||
Custom = 0,
|
||||
/// The type section.
|
||||
Type = 1,
|
||||
/// The import section.
|
||||
Import = 2,
|
||||
/// The function section.
|
||||
Function = 3,
|
||||
/// The table section.
|
||||
Table = 4,
|
||||
/// The memory section.
|
||||
Memory = 5,
|
||||
/// The global section.
|
||||
Global = 6,
|
||||
/// The export section.
|
||||
Export = 7,
|
||||
/// The start section.
|
||||
Start = 8,
|
||||
/// The element section.
|
||||
Element = 9,
|
||||
/// The code section.
|
||||
Code = 10,
|
||||
/// The data section.
|
||||
Data = 11,
|
||||
/// The data count section.
|
||||
DataCount = 12,
|
||||
/// The tag section.
|
||||
///
|
||||
/// This section is supported by the exception handling proposal.
|
||||
Tag = 13,
|
||||
}
|
||||
|
||||
impl From<SectionId> for u8 {
|
||||
#[inline]
|
||||
fn from(id: SectionId) -> u8 {
|
||||
id as u8
|
||||
}
|
||||
}
|
||||
|
||||
impl Encode for SectionId {
|
||||
fn encode(&self, sink: &mut Vec<u8>) {
|
||||
sink.push(*self as u8);
|
||||
}
|
||||
}
|
||||
|
||||
/// Represents a WebAssembly component that is being encoded.
|
||||
///
|
||||
/// Sections within a WebAssembly module are encoded in a specific order.
|
||||
///
|
||||
/// Modules may also added as a section to a WebAssembly component.
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct Module {
|
||||
pub(crate) bytes: Vec<u8>,
|
||||
}
|
||||
|
||||
impl Module {
|
||||
/// Begin writing a new `Module`.
|
||||
#[rustfmt::skip]
|
||||
pub fn new() -> Self {
|
||||
Module {
|
||||
bytes: vec![
|
||||
// Magic
|
||||
0x00, 0x61, 0x73, 0x6D,
|
||||
// Version
|
||||
0x01, 0x00, 0x00, 0x00,
|
||||
],
|
||||
}
|
||||
}
|
||||
|
||||
/// Write a section into this module.
|
||||
///
|
||||
/// It is your responsibility to define the sections in the [proper
|
||||
/// order](https://webassembly.github.io/spec/core/binary/modules.html#binary-module),
|
||||
/// and to ensure that each kind of section (other than custom sections) is
|
||||
/// only defined once. While this is a potential footgun, it also allows you
|
||||
/// to use this crate to easily construct test cases for bad Wasm module
|
||||
/// encodings.
|
||||
pub fn section(&mut self, section: &impl Section) -> &mut Self {
|
||||
self.bytes.push(section.id());
|
||||
section.encode(&mut self.bytes);
|
||||
self
|
||||
}
|
||||
|
||||
/// Get the encoded Wasm module as a slice.
|
||||
pub fn as_slice(&self) -> &[u8] {
|
||||
&self.bytes
|
||||
}
|
||||
|
||||
/// Finish writing this Wasm module and extract ownership of the encoded
|
||||
/// bytes.
|
||||
pub fn finish(self) -> Vec<u8> {
|
||||
self.bytes
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for Module {
|
||||
fn default() -> Self {
|
||||
Self::new()
|
||||
}
|
||||
}
|
2335
third_party/rust/wasm-encoder/src/core/code.rs
vendored
Normal file
2335
third_party/rust/wasm-encoder/src/core/code.rs
vendored
Normal file
File diff suppressed because it is too large
Load Diff
@ -1,4 +1,4 @@
|
||||
use super::*;
|
||||
use crate::{encoding_size, Encode, Section, SectionId};
|
||||
|
||||
/// A custom section holding arbitrary data.
|
||||
#[derive(Clone, Debug)]
|
||||
@ -9,25 +9,19 @@ pub struct CustomSection<'a> {
|
||||
pub data: &'a [u8],
|
||||
}
|
||||
|
||||
impl Encode for CustomSection<'_> {
|
||||
fn encode(&self, sink: &mut Vec<u8>) {
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
impl Section for CustomSection<'_> {
|
||||
fn id(&self) -> u8 {
|
||||
SectionId::Custom.into()
|
||||
}
|
||||
|
||||
fn encode<S>(&self, sink: &mut S)
|
||||
where
|
||||
S: Extend<u8>,
|
||||
{
|
||||
let name_len = encoders::u32(u32::try_from(self.name.len()).unwrap());
|
||||
let n = name_len.len();
|
||||
|
||||
sink.extend(
|
||||
encoders::u32(u32::try_from(n + self.name.len() + self.data.len()).unwrap())
|
||||
.chain(name_len)
|
||||
.chain(self.name.as_bytes().iter().copied())
|
||||
.chain(self.data.iter().copied()),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
@ -1,7 +1,9 @@
|
||||
use super::*;
|
||||
use crate::{encode_section, encoding_size, Encode, Instruction, Section, SectionId};
|
||||
|
||||
/// An encoder for the data section.
|
||||
///
|
||||
/// Data sections are only supported for modules.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```
|
||||
@ -15,13 +17,14 @@ use super::*;
|
||||
/// minimum: 1,
|
||||
/// maximum: None,
|
||||
/// memory64: false,
|
||||
/// shared: false,
|
||||
/// });
|
||||
///
|
||||
/// let mut data = DataSection::new();
|
||||
/// let memory_index = 0;
|
||||
/// let offset = Instruction::I32Const(42);
|
||||
/// let segment_data = b"hello";
|
||||
/// data.active(memory_index, offset, segment_data.iter().copied());
|
||||
/// data.active(memory_index, &offset, segment_data.iter().copied());
|
||||
///
|
||||
/// let mut module = Module::new();
|
||||
/// module
|
||||
@ -30,14 +33,14 @@ use super::*;
|
||||
///
|
||||
/// let wasm_bytes = module.finish();
|
||||
/// ```
|
||||
#[derive(Clone, Debug)]
|
||||
#[derive(Clone, Default, Debug)]
|
||||
pub struct DataSection {
|
||||
bytes: Vec<u8>,
|
||||
num_added: u32,
|
||||
}
|
||||
|
||||
/// A segment in the data section.
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct DataSegment<'a, D> {
|
||||
/// This data segment's mode.
|
||||
pub mode: DataSegmentMode<'a>,
|
||||
@ -46,14 +49,14 @@ pub struct DataSegment<'a, D> {
|
||||
}
|
||||
|
||||
/// A data segment's mode.
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
#[derive(Clone, Debug)]
|
||||
pub enum DataSegmentMode<'a> {
|
||||
/// An active data segment.
|
||||
Active {
|
||||
/// The memory this segment applies to.
|
||||
memory_index: u32,
|
||||
/// The offset where this segment's data is initialized at.
|
||||
offset: Instruction<'a>,
|
||||
offset: &'a Instruction<'a>,
|
||||
},
|
||||
/// A passive data segment.
|
||||
///
|
||||
@ -63,19 +66,21 @@ pub enum DataSegmentMode<'a> {
|
||||
|
||||
impl DataSection {
|
||||
/// Create a new data section encoder.
|
||||
pub fn new() -> DataSection {
|
||||
DataSection {
|
||||
bytes: vec![],
|
||||
num_added: 0,
|
||||
}
|
||||
pub fn new() -> Self {
|
||||
Self::default()
|
||||
}
|
||||
|
||||
/// How many segments have been defined inside this section so far?
|
||||
/// The number of data segments in the section.
|
||||
pub fn len(&self) -> u32 {
|
||||
self.num_added
|
||||
}
|
||||
|
||||
/// Define an active data segment.
|
||||
/// Determines if the section is empty.
|
||||
pub fn is_empty(&self) -> bool {
|
||||
self.num_added == 0
|
||||
}
|
||||
|
||||
/// Define a data segment.
|
||||
pub fn segment<D>(&mut self, segment: DataSegment<D>) -> &mut Self
|
||||
where
|
||||
D: IntoIterator<Item = u8>,
|
||||
@ -98,15 +103,14 @@ impl DataSection {
|
||||
offset,
|
||||
} => {
|
||||
self.bytes.push(0x02);
|
||||
self.bytes.extend(encoders::u32(memory_index));
|
||||
memory_index.encode(&mut self.bytes);
|
||||
offset.encode(&mut self.bytes);
|
||||
Instruction::End.encode(&mut self.bytes);
|
||||
}
|
||||
}
|
||||
|
||||
let data = segment.data.into_iter();
|
||||
self.bytes
|
||||
.extend(encoders::u32(u32::try_from(data.len()).unwrap()));
|
||||
data.len().encode(&mut self.bytes);
|
||||
self.bytes.extend(data);
|
||||
|
||||
self.num_added += 1;
|
||||
@ -114,12 +118,7 @@ impl DataSection {
|
||||
}
|
||||
|
||||
/// Define an active data segment.
|
||||
pub fn active<'a, D>(
|
||||
&mut self,
|
||||
memory_index: u32,
|
||||
offset: Instruction<'a>,
|
||||
data: D,
|
||||
) -> &mut Self
|
||||
pub fn active<D>(&mut self, memory_index: u32, offset: &Instruction, data: D) -> &mut Self
|
||||
where
|
||||
D: IntoIterator<Item = u8>,
|
||||
D::IntoIter: ExactSizeIterator,
|
||||
@ -136,7 +135,7 @@ impl DataSection {
|
||||
/// Define a passive data segment.
|
||||
///
|
||||
/// Passive data segments are part of the bulk memory proposal.
|
||||
pub fn passive<'a, D>(&mut self, data: D) -> &mut Self
|
||||
pub fn passive<D>(&mut self, data: D) -> &mut Self
|
||||
where
|
||||
D: IntoIterator<Item = u8>,
|
||||
D::IntoIter: ExactSizeIterator,
|
||||
@ -146,25 +145,25 @@ impl DataSection {
|
||||
data,
|
||||
})
|
||||
}
|
||||
|
||||
/// Copy an already-encoded data segment into this data section.
|
||||
pub fn raw(&mut self, already_encoded_data_segment: &[u8]) -> &mut Self {
|
||||
self.bytes.extend_from_slice(already_encoded_data_segment);
|
||||
self.num_added += 1;
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl Encode for DataSection {
|
||||
fn encode(&self, sink: &mut Vec<u8>) {
|
||||
encode_section(sink, self.num_added, &self.bytes);
|
||||
}
|
||||
}
|
||||
|
||||
impl Section for DataSection {
|
||||
fn id(&self) -> u8 {
|
||||
SectionId::Data.into()
|
||||
}
|
||||
|
||||
fn encode<S>(&self, sink: &mut S)
|
||||
where
|
||||
S: Extend<u8>,
|
||||
{
|
||||
let num_added = encoders::u32(self.num_added);
|
||||
let n = num_added.len();
|
||||
sink.extend(
|
||||
encoders::u32(u32::try_from(n + self.bytes.len()).unwrap())
|
||||
.chain(num_added)
|
||||
.chain(self.bytes.iter().copied()),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/// An encoder for the data count section.
|
||||
@ -174,17 +173,15 @@ pub struct DataCountSection {
|
||||
pub count: u32,
|
||||
}
|
||||
|
||||
impl Encode for DataCountSection {
|
||||
fn encode(&self, sink: &mut Vec<u8>) {
|
||||
encoding_size(self.count).encode(sink);
|
||||
self.count.encode(sink);
|
||||
}
|
||||
}
|
||||
|
||||
impl Section for DataCountSection {
|
||||
fn id(&self) -> u8 {
|
||||
SectionId::DataCount.into()
|
||||
}
|
||||
|
||||
fn encode<S>(&self, sink: &mut S)
|
||||
where
|
||||
S: Extend<u8>,
|
||||
{
|
||||
let count = encoders::u32(self.count);
|
||||
let n = count.len();
|
||||
sink.extend(encoders::u32(u32::try_from(n).unwrap()).chain(count));
|
||||
}
|
||||
}
|
@ -1,7 +1,9 @@
|
||||
use super::*;
|
||||
use crate::{encode_section, Encode, Instruction, Section, SectionId, ValType};
|
||||
|
||||
/// An encoder for the element section.
|
||||
///
|
||||
/// Element sections are only supported for modules.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```
|
||||
@ -24,7 +26,7 @@ use super::*;
|
||||
/// let functions = Elements::Functions(&[
|
||||
/// // Function indices...
|
||||
/// ]);
|
||||
/// elements.active(Some(table_index), offset, element_type, functions);
|
||||
/// elements.active(Some(table_index), &offset, element_type, functions);
|
||||
///
|
||||
/// let mut module = Module::new();
|
||||
/// module
|
||||
@ -33,7 +35,7 @@ use super::*;
|
||||
///
|
||||
/// let wasm_bytes = module.finish();
|
||||
/// ```
|
||||
#[derive(Clone, Debug)]
|
||||
#[derive(Clone, Default, Debug)]
|
||||
pub struct ElementSection {
|
||||
bytes: Vec<u8>,
|
||||
num_added: u32,
|
||||
@ -58,7 +60,7 @@ pub enum Element {
|
||||
}
|
||||
|
||||
/// An element segment's mode.
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
#[derive(Clone, Debug)]
|
||||
pub enum ElementMode<'a> {
|
||||
/// A passive element segment.
|
||||
///
|
||||
@ -72,16 +74,17 @@ pub enum ElementMode<'a> {
|
||||
Active {
|
||||
/// The table index.
|
||||
///
|
||||
/// `None` is implicitly table `0`. Non-`None` tables are part of the
|
||||
/// reference types proposal.
|
||||
/// `Active` element specifying a `None` table forces the MVP encoding and refers to the
|
||||
/// 0th table holding `funcref`s. Non-`None` tables use the encoding introduced with the
|
||||
/// bulk memory proposal and can refer to tables with any valid reference type.
|
||||
table: Option<u32>,
|
||||
/// The offset within the table to place this segment.
|
||||
offset: Instruction<'a>,
|
||||
offset: &'a Instruction<'a>,
|
||||
},
|
||||
}
|
||||
|
||||
/// An element segment in the element section.
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct ElementSegment<'a> {
|
||||
/// The element segment's mode.
|
||||
pub mode: ElementMode<'a>,
|
||||
@ -93,75 +96,73 @@ pub struct ElementSegment<'a> {
|
||||
|
||||
impl ElementSection {
|
||||
/// Create a new element section encoder.
|
||||
pub fn new() -> ElementSection {
|
||||
ElementSection {
|
||||
bytes: vec![],
|
||||
num_added: 0,
|
||||
}
|
||||
pub fn new() -> Self {
|
||||
Self::default()
|
||||
}
|
||||
|
||||
/// How many segments have been defined inside this section so far?
|
||||
/// The number of element segments in the section.
|
||||
pub fn len(&self) -> u32 {
|
||||
self.num_added
|
||||
}
|
||||
|
||||
/// Determines if the section is empty.
|
||||
pub fn is_empty(&self) -> bool {
|
||||
self.num_added == 0
|
||||
}
|
||||
|
||||
/// Define an element segment.
|
||||
pub fn segment<'a>(&mut self, segment: ElementSegment<'a>) -> &mut Self {
|
||||
let expr_bit = match segment.elements {
|
||||
Elements::Expressions(_) => 0b100,
|
||||
Elements::Functions(_) => 0b000,
|
||||
Elements::Expressions(_) => 0b100u32,
|
||||
Elements::Functions(_) => 0b000u32,
|
||||
};
|
||||
match &segment.mode {
|
||||
ElementMode::Active {
|
||||
table: None,
|
||||
offset,
|
||||
} => {
|
||||
self.bytes.extend(encoders::u32(0x00 | expr_bit));
|
||||
(/* 0x00 | */expr_bit).encode(&mut self.bytes);
|
||||
offset.encode(&mut self.bytes);
|
||||
Instruction::End.encode(&mut self.bytes);
|
||||
}
|
||||
ElementMode::Passive => {
|
||||
self.bytes.extend(encoders::u32(0x01 | expr_bit));
|
||||
(0x01 | expr_bit).encode(&mut self.bytes);
|
||||
if expr_bit == 0 {
|
||||
self.bytes.push(0x00); // elemkind == funcref
|
||||
} else {
|
||||
self.bytes.push(segment.element_type.into());
|
||||
segment.element_type.encode(&mut self.bytes);
|
||||
}
|
||||
}
|
||||
ElementMode::Active {
|
||||
table: Some(i),
|
||||
offset,
|
||||
} => {
|
||||
self.bytes.extend(encoders::u32(0x02 | expr_bit));
|
||||
self.bytes.extend(encoders::u32(*i));
|
||||
(0x02 | expr_bit).encode(&mut self.bytes);
|
||||
i.encode(&mut self.bytes);
|
||||
offset.encode(&mut self.bytes);
|
||||
Instruction::End.encode(&mut self.bytes);
|
||||
if expr_bit == 0 {
|
||||
self.bytes.push(0x00); // elemkind == funcref
|
||||
} else {
|
||||
self.bytes.push(segment.element_type.into());
|
||||
segment.element_type.encode(&mut self.bytes);
|
||||
}
|
||||
}
|
||||
ElementMode::Declared => {
|
||||
self.bytes.extend(encoders::u32(0x03 | expr_bit));
|
||||
(0x03 | expr_bit).encode(&mut self.bytes);
|
||||
if expr_bit == 0 {
|
||||
self.bytes.push(0x00); // elemkind == funcref
|
||||
} else {
|
||||
self.bytes.push(segment.element_type.into());
|
||||
segment.element_type.encode(&mut self.bytes);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
match segment.elements {
|
||||
Elements::Functions(fs) => {
|
||||
self.bytes
|
||||
.extend(encoders::u32(u32::try_from(fs.len()).unwrap()));
|
||||
for f in fs {
|
||||
self.bytes.extend(encoders::u32(*f));
|
||||
}
|
||||
fs.encode(&mut self.bytes);
|
||||
}
|
||||
Elements::Expressions(e) => {
|
||||
self.bytes.extend(encoders::u32(e.len() as u32));
|
||||
e.len().encode(&mut self.bytes);
|
||||
for expr in e {
|
||||
match expr {
|
||||
Element::Func(i) => Instruction::RefFunc(*i).encode(&mut self.bytes),
|
||||
@ -179,12 +180,16 @@ impl ElementSection {
|
||||
}
|
||||
|
||||
/// Define an active element segment.
|
||||
pub fn active<'a>(
|
||||
///
|
||||
/// `Active` element specifying a `None` table forces the MVP encoding and refers to the 0th
|
||||
/// table holding `funcref`s. Non-`None` tables use the encoding introduced with the bulk
|
||||
/// memory proposal and can refer to tables with any valid reference type.
|
||||
pub fn active(
|
||||
&mut self,
|
||||
table_index: Option<u32>,
|
||||
offset: Instruction,
|
||||
offset: &Instruction<'_>,
|
||||
element_type: ValType,
|
||||
elements: Elements<'a>,
|
||||
elements: Elements<'_>,
|
||||
) -> &mut Self {
|
||||
self.segment(ElementSegment {
|
||||
mode: ElementMode::Active {
|
||||
@ -217,23 +222,23 @@ impl ElementSection {
|
||||
elements,
|
||||
})
|
||||
}
|
||||
|
||||
/// Copy a raw, already-encoded element segment into this elements section.
|
||||
pub fn raw(&mut self, raw_bytes: &[u8]) -> &mut Self {
|
||||
self.bytes.extend_from_slice(raw_bytes);
|
||||
self.num_added += 1;
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl Encode for ElementSection {
|
||||
fn encode(&self, sink: &mut Vec<u8>) {
|
||||
encode_section(sink, self.num_added, &self.bytes);
|
||||
}
|
||||
}
|
||||
|
||||
impl Section for ElementSection {
|
||||
fn id(&self) -> u8 {
|
||||
SectionId::Element.into()
|
||||
}
|
||||
|
||||
fn encode<S>(&self, sink: &mut S)
|
||||
where
|
||||
S: Extend<u8>,
|
||||
{
|
||||
let num_added = encoders::u32(self.num_added);
|
||||
let n = num_added.len();
|
||||
sink.extend(
|
||||
encoders::u32(u32::try_from(n + self.bytes.len()).unwrap())
|
||||
.chain(num_added)
|
||||
.chain(self.bytes.iter().copied()),
|
||||
);
|
||||
}
|
||||
}
|
90
third_party/rust/wasm-encoder/src/core/exports.rs
vendored
Normal file
90
third_party/rust/wasm-encoder/src/core/exports.rs
vendored
Normal file
@ -0,0 +1,90 @@
|
||||
use super::{
|
||||
CORE_FUNCTION_SORT, CORE_GLOBAL_SORT, CORE_MEMORY_SORT, CORE_TABLE_SORT, CORE_TAG_SORT,
|
||||
};
|
||||
use crate::{encode_section, Encode, Section, SectionId};
|
||||
|
||||
/// Represents the kind of an export from a WebAssembly module.
|
||||
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
|
||||
pub enum ExportKind {
|
||||
/// The export is a function.
|
||||
Func,
|
||||
/// The export is a table.
|
||||
Table,
|
||||
/// The export is a memory.
|
||||
Memory,
|
||||
/// The export is a global.
|
||||
Global,
|
||||
/// The export is a tag.
|
||||
Tag,
|
||||
}
|
||||
|
||||
impl Encode for ExportKind {
|
||||
fn encode(&self, sink: &mut Vec<u8>) {
|
||||
sink.push(match self {
|
||||
Self::Func => CORE_FUNCTION_SORT,
|
||||
Self::Table => CORE_TABLE_SORT,
|
||||
Self::Memory => CORE_MEMORY_SORT,
|
||||
Self::Global => CORE_GLOBAL_SORT,
|
||||
Self::Tag => CORE_TAG_SORT,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/// An encoder for the export section of WebAssembly module.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```rust
|
||||
/// use wasm_encoder::{Module, ExportSection, ExportKind};
|
||||
///
|
||||
/// let mut exports = ExportSection::new();
|
||||
/// exports.export("foo", ExportKind::Func, 0);
|
||||
///
|
||||
/// let mut module = Module::new();
|
||||
/// module.section(&exports);
|
||||
///
|
||||
/// let bytes = module.finish();
|
||||
/// ```
|
||||
#[derive(Clone, Debug, Default)]
|
||||
pub struct ExportSection {
|
||||
bytes: Vec<u8>,
|
||||
num_added: u32,
|
||||
}
|
||||
|
||||
impl ExportSection {
|
||||
/// Create a new export section encoder.
|
||||
pub fn new() -> Self {
|
||||
Self::default()
|
||||
}
|
||||
|
||||
/// The number of exports in the section.
|
||||
pub fn len(&self) -> u32 {
|
||||
self.num_added
|
||||
}
|
||||
|
||||
/// Determines if the section is empty.
|
||||
pub fn is_empty(&self) -> bool {
|
||||
self.num_added == 0
|
||||
}
|
||||
|
||||
/// Define an export in the export section.
|
||||
pub fn export(&mut self, name: &str, kind: ExportKind, index: u32) -> &mut Self {
|
||||
name.encode(&mut self.bytes);
|
||||
kind.encode(&mut self.bytes);
|
||||
index.encode(&mut self.bytes);
|
||||
self.num_added += 1;
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl Encode for ExportSection {
|
||||
fn encode(&self, sink: &mut Vec<u8>) {
|
||||
encode_section(sink, self.num_added, &self.bytes);
|
||||
}
|
||||
}
|
||||
|
||||
impl Section for ExportSection {
|
||||
fn id(&self) -> u8 {
|
||||
SectionId::Export.into()
|
||||
}
|
||||
}
|
@ -1,6 +1,6 @@
|
||||
use super::*;
|
||||
use crate::{encode_section, Encode, Section, SectionId};
|
||||
|
||||
/// An encoder for the function section.
|
||||
/// An encoder for the function section of WebAssembly modules.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
@ -18,51 +18,46 @@ use super::*;
|
||||
/// // code section containing the function body. See the documentation for
|
||||
/// // `CodeSection` for details.
|
||||
///
|
||||
/// let wasm_bytes = module.finish();
|
||||
/// let bytes = module.finish();
|
||||
/// ```
|
||||
#[derive(Clone, Debug)]
|
||||
#[derive(Clone, Debug, Default)]
|
||||
pub struct FunctionSection {
|
||||
bytes: Vec<u8>,
|
||||
num_added: u32,
|
||||
}
|
||||
|
||||
impl FunctionSection {
|
||||
/// Construct a new function section encoder.
|
||||
pub fn new() -> FunctionSection {
|
||||
FunctionSection {
|
||||
bytes: vec![],
|
||||
num_added: 0,
|
||||
}
|
||||
/// Construct a new module function section encoder.
|
||||
pub fn new() -> Self {
|
||||
Self::default()
|
||||
}
|
||||
|
||||
/// How many functions have been defined inside this section so far?
|
||||
/// The number of functions in the section.
|
||||
pub fn len(&self) -> u32 {
|
||||
self.num_added
|
||||
}
|
||||
|
||||
/// Define a function that uses the given type.
|
||||
/// Determines if the section is empty.
|
||||
pub fn is_empty(&self) -> bool {
|
||||
self.num_added == 0
|
||||
}
|
||||
|
||||
/// Define a function in a module's function section.
|
||||
pub fn function(&mut self, type_index: u32) -> &mut Self {
|
||||
self.bytes.extend(encoders::u32(type_index));
|
||||
type_index.encode(&mut self.bytes);
|
||||
self.num_added += 1;
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl Encode for FunctionSection {
|
||||
fn encode(&self, sink: &mut Vec<u8>) {
|
||||
encode_section(sink, self.num_added, &self.bytes);
|
||||
}
|
||||
}
|
||||
|
||||
impl Section for FunctionSection {
|
||||
fn id(&self) -> u8 {
|
||||
SectionId::Function.into()
|
||||
}
|
||||
|
||||
fn encode<S>(&self, sink: &mut S)
|
||||
where
|
||||
S: Extend<u8>,
|
||||
{
|
||||
let num_added = encoders::u32(self.num_added);
|
||||
let n = num_added.len();
|
||||
sink.extend(
|
||||
encoders::u32(u32::try_from(n + self.bytes.len()).unwrap())
|
||||
.chain(num_added)
|
||||
.chain(self.bytes.iter().copied()),
|
||||
);
|
||||
}
|
||||
}
|
@ -1,7 +1,9 @@
|
||||
use super::*;
|
||||
use crate::{encode_section, Encode, Instruction, Section, SectionId, ValType};
|
||||
|
||||
/// An encoder for the global section.
|
||||
///
|
||||
/// Global sections are only supported for modules.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```
|
||||
@ -13,7 +15,7 @@ use super::*;
|
||||
/// val_type: ValType::I32,
|
||||
/// mutable: false,
|
||||
/// },
|
||||
/// Instruction::I32Const(42),
|
||||
/// &Instruction::I32Const(42),
|
||||
/// );
|
||||
///
|
||||
/// let mut module = Module::new();
|
||||
@ -21,7 +23,7 @@ use super::*;
|
||||
///
|
||||
/// let wasm_bytes = module.finish();
|
||||
/// ```
|
||||
#[derive(Clone, Debug)]
|
||||
#[derive(Clone, Default, Debug)]
|
||||
pub struct GlobalSection {
|
||||
bytes: Vec<u8>,
|
||||
num_added: u32,
|
||||
@ -29,49 +31,51 @@ pub struct GlobalSection {
|
||||
|
||||
impl GlobalSection {
|
||||
/// Create a new global section encoder.
|
||||
pub fn new() -> GlobalSection {
|
||||
GlobalSection {
|
||||
bytes: vec![],
|
||||
num_added: 0,
|
||||
}
|
||||
pub fn new() -> Self {
|
||||
Self::default()
|
||||
}
|
||||
|
||||
/// How many globals have been defined inside this section so far?
|
||||
/// The number of globals in the section.
|
||||
pub fn len(&self) -> u32 {
|
||||
self.num_added
|
||||
}
|
||||
|
||||
/// Determines if the section is empty.
|
||||
pub fn is_empty(&self) -> bool {
|
||||
self.num_added == 0
|
||||
}
|
||||
|
||||
/// Define a global.
|
||||
pub fn global(&mut self, global_type: GlobalType, init_expr: Instruction) -> &mut Self {
|
||||
pub fn global(&mut self, global_type: GlobalType, init_expr: &Instruction<'_>) -> &mut Self {
|
||||
global_type.encode(&mut self.bytes);
|
||||
init_expr.encode(&mut self.bytes);
|
||||
Instruction::End.encode(&mut self.bytes);
|
||||
self.num_added += 1;
|
||||
self
|
||||
}
|
||||
|
||||
/// Add a raw byte slice into this code section as a global.
|
||||
pub fn raw(&mut self, data: &[u8]) -> &mut Self {
|
||||
self.bytes.extend(data);
|
||||
self.num_added += 1;
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl Encode for GlobalSection {
|
||||
fn encode(&self, sink: &mut Vec<u8>) {
|
||||
encode_section(sink, self.num_added, &self.bytes);
|
||||
}
|
||||
}
|
||||
|
||||
impl Section for GlobalSection {
|
||||
fn id(&self) -> u8 {
|
||||
SectionId::Global.into()
|
||||
}
|
||||
|
||||
fn encode<S>(&self, sink: &mut S)
|
||||
where
|
||||
S: Extend<u8>,
|
||||
{
|
||||
let num_added = encoders::u32(self.num_added);
|
||||
let n = num_added.len();
|
||||
sink.extend(
|
||||
encoders::u32(u32::try_from(n + self.bytes.len()).unwrap())
|
||||
.chain(num_added)
|
||||
.chain(self.bytes.iter().copied()),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/// A global's type.
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)]
|
||||
pub struct GlobalType {
|
||||
/// This global's value type.
|
||||
pub val_type: ValType,
|
||||
@ -79,9 +83,9 @@ pub struct GlobalType {
|
||||
pub mutable: bool,
|
||||
}
|
||||
|
||||
impl GlobalType {
|
||||
pub(crate) fn encode(&self, bytes: &mut Vec<u8>) {
|
||||
bytes.push(self.val_type.into());
|
||||
bytes.push(self.mutable as u8);
|
||||
impl Encode for GlobalType {
|
||||
fn encode(&self, sink: &mut Vec<u8>) {
|
||||
self.val_type.encode(sink);
|
||||
sink.push(self.mutable as u8);
|
||||
}
|
||||
}
|
142
third_party/rust/wasm-encoder/src/core/imports.rs
vendored
Normal file
142
third_party/rust/wasm-encoder/src/core/imports.rs
vendored
Normal file
@ -0,0 +1,142 @@
|
||||
use crate::{
|
||||
encode_section, Encode, GlobalType, MemoryType, Section, SectionId, TableType, TagType,
|
||||
CORE_FUNCTION_SORT, CORE_GLOBAL_SORT, CORE_MEMORY_SORT, CORE_TABLE_SORT, CORE_TAG_SORT,
|
||||
};
|
||||
|
||||
/// The type of an entity.
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub enum EntityType {
|
||||
/// A function type.
|
||||
///
|
||||
/// The value is an index into the types section.
|
||||
Function(u32),
|
||||
/// A table type.
|
||||
Table(TableType),
|
||||
/// A memory type.
|
||||
Memory(MemoryType),
|
||||
/// A global type.
|
||||
Global(GlobalType),
|
||||
/// A tag type.
|
||||
///
|
||||
/// This variant is used with the exception handling proposal.
|
||||
Tag(TagType),
|
||||
}
|
||||
|
||||
impl Encode for EntityType {
|
||||
fn encode(&self, sink: &mut Vec<u8>) {
|
||||
match self {
|
||||
Self::Function(i) => {
|
||||
sink.push(CORE_FUNCTION_SORT);
|
||||
i.encode(sink);
|
||||
}
|
||||
Self::Table(t) => {
|
||||
sink.push(CORE_TABLE_SORT);
|
||||
t.encode(sink);
|
||||
}
|
||||
Self::Memory(t) => {
|
||||
sink.push(CORE_MEMORY_SORT);
|
||||
t.encode(sink);
|
||||
}
|
||||
Self::Global(t) => {
|
||||
sink.push(CORE_GLOBAL_SORT);
|
||||
t.encode(sink);
|
||||
}
|
||||
Self::Tag(t) => {
|
||||
sink.push(CORE_TAG_SORT);
|
||||
t.encode(sink);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<TableType> for EntityType {
|
||||
fn from(t: TableType) -> Self {
|
||||
Self::Table(t)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<MemoryType> for EntityType {
|
||||
fn from(t: MemoryType) -> Self {
|
||||
Self::Memory(t)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<GlobalType> for EntityType {
|
||||
fn from(t: GlobalType) -> Self {
|
||||
Self::Global(t)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<TagType> for EntityType {
|
||||
fn from(t: TagType) -> Self {
|
||||
Self::Tag(t)
|
||||
}
|
||||
}
|
||||
|
||||
/// An encoder for the import section of WebAssembly modules.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```rust
|
||||
/// use wasm_encoder::{MemoryType, Module, ImportSection};
|
||||
///
|
||||
/// let mut imports = ImportSection::new();
|
||||
/// imports.import(
|
||||
/// "env",
|
||||
/// "memory",
|
||||
/// MemoryType {
|
||||
/// minimum: 1,
|
||||
/// maximum: None,
|
||||
/// memory64: false,
|
||||
/// shared: false,
|
||||
/// }
|
||||
/// );
|
||||
///
|
||||
/// let mut module = Module::new();
|
||||
/// module.section(&imports);
|
||||
///
|
||||
/// let bytes = module.finish();
|
||||
/// ```
|
||||
#[derive(Clone, Debug, Default)]
|
||||
pub struct ImportSection {
|
||||
bytes: Vec<u8>,
|
||||
num_added: u32,
|
||||
}
|
||||
|
||||
impl ImportSection {
|
||||
/// Create a new import section encoder.
|
||||
pub fn new() -> Self {
|
||||
Self::default()
|
||||
}
|
||||
|
||||
/// The number of imports in the section.
|
||||
pub fn len(&self) -> u32 {
|
||||
self.num_added
|
||||
}
|
||||
|
||||
/// Determines if the section is empty.
|
||||
pub fn is_empty(&self) -> bool {
|
||||
self.num_added == 0
|
||||
}
|
||||
|
||||
/// Define an import in the import section.
|
||||
pub fn import(&mut self, module: &str, field: &str, ty: impl Into<EntityType>) -> &mut Self {
|
||||
module.encode(&mut self.bytes);
|
||||
field.encode(&mut self.bytes);
|
||||
ty.into().encode(&mut self.bytes);
|
||||
self.num_added += 1;
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl Encode for ImportSection {
|
||||
fn encode(&self, sink: &mut Vec<u8>) {
|
||||
encode_section(sink, self.num_added, &self.bytes);
|
||||
}
|
||||
}
|
||||
|
||||
impl Section for ImportSection {
|
||||
fn id(&self) -> u8 {
|
||||
SectionId::Import.into()
|
||||
}
|
||||
}
|
@ -1,5 +1,6 @@
|
||||
use super::*;
|
||||
use std::convert::TryInto;
|
||||
use crate::{encode_section, CustomSection, Encode, Section, SectionId};
|
||||
|
||||
const VERSION: u32 = 2;
|
||||
|
||||
/// An encoder for the [linking custom
|
||||
/// section](https://github.com/WebAssembly/tool-conventions/blob/master/Linking.md#linking-metadata-section).
|
||||
@ -44,7 +45,7 @@ pub struct LinkingSection {
|
||||
impl LinkingSection {
|
||||
/// Construct a new encoder for the linking custom section.
|
||||
pub fn new() -> Self {
|
||||
LinkingSection { bytes: vec![] }
|
||||
Self::default()
|
||||
}
|
||||
|
||||
// TODO: `fn segment_info` for the `WASM_SEGMENT_INFO` linking subsection.
|
||||
@ -60,30 +61,28 @@ impl LinkingSection {
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for LinkingSection {
|
||||
fn default() -> Self {
|
||||
let mut bytes = Vec::new();
|
||||
VERSION.encode(&mut bytes);
|
||||
Self { bytes }
|
||||
}
|
||||
}
|
||||
|
||||
impl Encode for LinkingSection {
|
||||
fn encode(&self, sink: &mut Vec<u8>) {
|
||||
CustomSection {
|
||||
name: "linking",
|
||||
data: &self.bytes,
|
||||
}
|
||||
.encode(sink);
|
||||
}
|
||||
}
|
||||
|
||||
impl Section for LinkingSection {
|
||||
fn id(&self) -> u8 {
|
||||
SectionId::Custom.into()
|
||||
}
|
||||
|
||||
fn encode<S>(&self, sink: &mut S)
|
||||
where
|
||||
S: Extend<u8>,
|
||||
{
|
||||
let name_len = encoders::u32(u32::try_from("linking".len()).unwrap());
|
||||
let name_len_len = name_len.len();
|
||||
|
||||
let version = 2;
|
||||
|
||||
sink.extend(
|
||||
encoders::u32(
|
||||
u32::try_from(name_len_len + "linking".len() + 1 + self.bytes.len()).unwrap(),
|
||||
)
|
||||
.chain(name_len)
|
||||
.chain(b"linking".iter().copied())
|
||||
.chain(encoders::u32(version))
|
||||
.chain(self.bytes.iter().copied()),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(unused)]
|
||||
@ -97,7 +96,7 @@ const WASM_SYMBOL_TABLE: u8 = 8;
|
||||
/// A subsection of the [linking custom section][crate::LinkingSection] that
|
||||
/// provides extra information about the symbols present in this Wasm object
|
||||
/// file.
|
||||
#[derive(Clone, Debug)]
|
||||
#[derive(Clone, Debug, Default)]
|
||||
pub struct SymbolTable {
|
||||
bytes: Vec<u8>,
|
||||
num_added: u32,
|
||||
@ -126,16 +125,11 @@ impl SymbolTable {
|
||||
/// The `name` must be omitted if `index` references an imported table and
|
||||
/// the `WASM_SYM_EXPLICIT_NAME` flag is not set.
|
||||
pub fn function(&mut self, flags: u32, index: u32, name: Option<&str>) -> &mut Self {
|
||||
self.bytes.extend(
|
||||
encoders::u32(SYMTAB_FUNCTION)
|
||||
.chain(encoders::u32(flags))
|
||||
.chain(encoders::u32(index)),
|
||||
);
|
||||
SYMTAB_FUNCTION.encode(&mut self.bytes);
|
||||
flags.encode(&mut self.bytes);
|
||||
index.encode(&mut self.bytes);
|
||||
if let Some(name) = name {
|
||||
self.bytes.extend(
|
||||
encoders::u32(name.len().try_into().unwrap())
|
||||
.chain(name.as_bytes().iter().copied()),
|
||||
);
|
||||
name.encode(&mut self.bytes);
|
||||
}
|
||||
self.num_added += 1;
|
||||
self
|
||||
@ -146,16 +140,11 @@ impl SymbolTable {
|
||||
/// The `name` must be omitted if `index` references an imported table and
|
||||
/// the `WASM_SYM_EXPLICIT_NAME` flag is not set.
|
||||
pub fn global(&mut self, flags: u32, index: u32, name: Option<&str>) -> &mut Self {
|
||||
self.bytes.extend(
|
||||
encoders::u32(SYMTAB_GLOBAL)
|
||||
.chain(encoders::u32(flags))
|
||||
.chain(encoders::u32(index)),
|
||||
);
|
||||
SYMTAB_GLOBAL.encode(&mut self.bytes);
|
||||
flags.encode(&mut self.bytes);
|
||||
index.encode(&mut self.bytes);
|
||||
if let Some(name) = name {
|
||||
self.bytes.extend(
|
||||
encoders::u32(name.len().try_into().unwrap())
|
||||
.chain(name.as_bytes().iter().copied()),
|
||||
);
|
||||
name.encode(&mut self.bytes);
|
||||
}
|
||||
self.num_added += 1;
|
||||
self
|
||||
@ -168,16 +157,11 @@ impl SymbolTable {
|
||||
/// The `name` must be omitted if `index` references an imported table and
|
||||
/// the `WASM_SYM_EXPLICIT_NAME` flag is not set.
|
||||
pub fn table(&mut self, flags: u32, index: u32, name: Option<&str>) -> &mut Self {
|
||||
self.bytes.extend(
|
||||
encoders::u32(SYMTAB_TABLE)
|
||||
.chain(encoders::u32(flags))
|
||||
.chain(encoders::u32(index)),
|
||||
);
|
||||
SYMTAB_TABLE.encode(&mut self.bytes);
|
||||
flags.encode(&mut self.bytes);
|
||||
index.encode(&mut self.bytes);
|
||||
if let Some(name) = name {
|
||||
self.bytes.extend(
|
||||
encoders::u32(name.len().try_into().unwrap())
|
||||
.chain(name.as_bytes().iter().copied()),
|
||||
);
|
||||
name.encode(&mut self.bytes);
|
||||
}
|
||||
self.num_added += 1;
|
||||
self
|
||||
@ -190,18 +174,13 @@ impl SymbolTable {
|
||||
name: &str,
|
||||
definition: Option<DataSymbolDefinition>,
|
||||
) -> &mut Self {
|
||||
self.bytes.extend(
|
||||
encoders::u32(SYMTAB_DATA)
|
||||
.chain(encoders::u32(flags))
|
||||
.chain(encoders::u32(name.len().try_into().unwrap()))
|
||||
.chain(name.as_bytes().iter().copied()),
|
||||
);
|
||||
SYMTAB_DATA.encode(&mut self.bytes);
|
||||
flags.encode(&mut self.bytes);
|
||||
name.encode(&mut self.bytes);
|
||||
if let Some(def) = definition {
|
||||
self.bytes.extend(
|
||||
encoders::u32(def.index)
|
||||
.chain(encoders::u32(def.offset))
|
||||
.chain(encoders::u32(def.size)),
|
||||
);
|
||||
def.index.encode(&mut self.bytes);
|
||||
def.offset.encode(&mut self.bytes);
|
||||
def.size.encode(&mut self.bytes);
|
||||
}
|
||||
self.num_added += 1;
|
||||
self
|
||||
@ -209,21 +188,6 @@ impl SymbolTable {
|
||||
|
||||
// TODO: sections
|
||||
|
||||
fn encode(&self, bytes: &mut Vec<u8>) {
|
||||
let num_added = encoders::u32(self.num_added);
|
||||
let num_added_len = num_added.len();
|
||||
let payload_len = num_added_len + self.bytes.len();
|
||||
bytes.extend(
|
||||
std::iter::once(WASM_SYMBOL_TABLE)
|
||||
.chain(encoders::u32(payload_len.try_into().unwrap()))
|
||||
.chain(num_added)
|
||||
.chain(self.bytes.iter().copied()),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/// # Symbol definition flags.
|
||||
impl SymbolTable {
|
||||
/// This is a weak symbol.
|
||||
///
|
||||
/// This flag is mutually exclusive with `WASM_SYM_BINDING_LOCAL`.
|
||||
@ -275,6 +239,13 @@ impl SymbolTable {
|
||||
pub const WASM_SYM_NO_STRIP: u32 = 0x80;
|
||||
}
|
||||
|
||||
impl Encode for SymbolTable {
|
||||
fn encode(&self, sink: &mut Vec<u8>) {
|
||||
sink.push(WASM_SYMBOL_TABLE);
|
||||
encode_section(sink, self.num_added, &self.bytes);
|
||||
}
|
||||
}
|
||||
|
||||
/// The definition of a data symbol within a symbol table.
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct DataSymbolDefinition {
|
@ -1,7 +1,9 @@
|
||||
use super::*;
|
||||
use crate::{encode_section, Encode, Section, SectionId};
|
||||
|
||||
/// An encoder for the memory section.
|
||||
///
|
||||
/// Memory sections are only supported for modules.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```
|
||||
@ -12,6 +14,7 @@ use super::*;
|
||||
/// minimum: 1,
|
||||
/// maximum: None,
|
||||
/// memory64: false,
|
||||
/// shared: false,
|
||||
/// });
|
||||
///
|
||||
/// let mut module = Module::new();
|
||||
@ -19,7 +22,7 @@ use super::*;
|
||||
///
|
||||
/// let wasm_bytes = module.finish();
|
||||
/// ```
|
||||
#[derive(Clone, Debug)]
|
||||
#[derive(Clone, Default, Debug)]
|
||||
pub struct MemorySection {
|
||||
bytes: Vec<u8>,
|
||||
num_added: u32,
|
||||
@ -27,18 +30,20 @@ pub struct MemorySection {
|
||||
|
||||
impl MemorySection {
|
||||
/// Create a new memory section encoder.
|
||||
pub fn new() -> MemorySection {
|
||||
MemorySection {
|
||||
bytes: vec![],
|
||||
num_added: 0,
|
||||
}
|
||||
pub fn new() -> Self {
|
||||
Self::default()
|
||||
}
|
||||
|
||||
/// How many memories have been defined inside this section so far?
|
||||
/// The number of memories in the section.
|
||||
pub fn len(&self) -> u32 {
|
||||
self.num_added
|
||||
}
|
||||
|
||||
/// Determines if the section is empty.
|
||||
pub fn is_empty(&self) -> bool {
|
||||
self.num_added == 0
|
||||
}
|
||||
|
||||
/// Define a memory.
|
||||
pub fn memory(&mut self, memory_type: MemoryType) -> &mut Self {
|
||||
memory_type.encode(&mut self.bytes);
|
||||
@ -47,27 +52,20 @@ impl MemorySection {
|
||||
}
|
||||
}
|
||||
|
||||
impl Encode for MemorySection {
|
||||
fn encode(&self, sink: &mut Vec<u8>) {
|
||||
encode_section(sink, self.num_added, &self.bytes);
|
||||
}
|
||||
}
|
||||
|
||||
impl Section for MemorySection {
|
||||
fn id(&self) -> u8 {
|
||||
SectionId::Memory.into()
|
||||
}
|
||||
|
||||
fn encode<S>(&self, sink: &mut S)
|
||||
where
|
||||
S: Extend<u8>,
|
||||
{
|
||||
let num_added = encoders::u32(self.num_added);
|
||||
let n = num_added.len();
|
||||
sink.extend(
|
||||
encoders::u32(u32::try_from(n + self.bytes.len()).unwrap())
|
||||
.chain(num_added)
|
||||
.chain(self.bytes.iter().copied()),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/// A memory's type.
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
|
||||
pub struct MemoryType {
|
||||
/// Minimum size, in pages, of this memory
|
||||
pub minimum: u64,
|
||||
@ -75,21 +73,27 @@ pub struct MemoryType {
|
||||
pub maximum: Option<u64>,
|
||||
/// Whether or not this is a 64-bit memory.
|
||||
pub memory64: bool,
|
||||
/// Whether or not this memory is shared.
|
||||
pub shared: bool,
|
||||
}
|
||||
|
||||
impl MemoryType {
|
||||
pub(crate) fn encode(&self, bytes: &mut Vec<u8>) {
|
||||
impl Encode for MemoryType {
|
||||
fn encode(&self, sink: &mut Vec<u8>) {
|
||||
let mut flags = 0;
|
||||
if self.maximum.is_some() {
|
||||
flags |= 0b001;
|
||||
}
|
||||
if self.shared {
|
||||
flags |= 0b010;
|
||||
}
|
||||
if self.memory64 {
|
||||
flags |= 0b100;
|
||||
}
|
||||
bytes.push(flags);
|
||||
bytes.extend(encoders::u64(self.minimum));
|
||||
|
||||
sink.push(flags);
|
||||
self.minimum.encode(sink);
|
||||
if let Some(max) = self.maximum {
|
||||
bytes.extend(encoders::u64(max));
|
||||
max.encode(sink);
|
||||
}
|
||||
}
|
||||
}
|
254
third_party/rust/wasm-encoder/src/core/names.rs
vendored
Normal file
254
third_party/rust/wasm-encoder/src/core/names.rs
vendored
Normal file
@ -0,0 +1,254 @@
|
||||
use crate::{encoding_size, CustomSection, Encode, Section, SectionId};
|
||||
|
||||
/// An encoder for the custom `name` section.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```
|
||||
/// use wasm_encoder::{Module, NameSection, NameMap};
|
||||
///
|
||||
/// let mut names = NameSection::new();
|
||||
/// names.module("the module name");
|
||||
///
|
||||
/// let mut function_names = NameMap::new();
|
||||
/// function_names.append(0, "name of function 0");
|
||||
/// function_names.append(1, "a better function");
|
||||
/// function_names.append(3, "the best function");
|
||||
/// names.functions(&function_names);
|
||||
///
|
||||
/// let mut module = Module::new();
|
||||
/// module.section(&names);
|
||||
///
|
||||
/// let wasm_bytes = module.finish();
|
||||
/// ```
|
||||
#[derive(Clone, Debug, Default)]
|
||||
pub struct NameSection {
|
||||
bytes: Vec<u8>,
|
||||
}
|
||||
|
||||
enum Subsection {
|
||||
// Currently specified in the wasm spec's appendix
|
||||
Module = 0,
|
||||
Function = 1,
|
||||
Local = 2,
|
||||
|
||||
// specified as part of the extended name section proposal
|
||||
//
|
||||
// https://github.com/WebAssembly/extended-name-section/blob/main/proposals/extended-name-section/Overview.md
|
||||
Label = 3,
|
||||
Type = 4,
|
||||
Table = 5,
|
||||
Memory = 6,
|
||||
Global = 7,
|
||||
Element = 8,
|
||||
Data = 9,
|
||||
}
|
||||
|
||||
impl NameSection {
|
||||
/// Creates a new blank `name` custom section.
|
||||
pub fn new() -> Self {
|
||||
Self::default()
|
||||
}
|
||||
|
||||
/// Appends a module name subsection to this section.
|
||||
///
|
||||
/// This will indicate that the name of the entire module should be the
|
||||
/// `name` specified. Note that this should be encoded first before other
|
||||
/// subsections.
|
||||
pub fn module(&mut self, name: &str) {
|
||||
let len = encoding_size(u32::try_from(name.len()).unwrap());
|
||||
self.subsection_header(Subsection::Module, len + name.len());
|
||||
name.encode(&mut self.bytes);
|
||||
}
|
||||
|
||||
/// Appends a subsection for the names of all functions in this wasm module.
|
||||
///
|
||||
/// Function names are declared in the `names` map provided where the index
|
||||
/// in the map corresponds to the wasm index of the function. This section
|
||||
/// should come after the module name subsection (if present) and before the
|
||||
/// locals subsection (if present).
|
||||
pub fn functions(&mut self, names: &NameMap) {
|
||||
self.subsection_header(Subsection::Function, names.size());
|
||||
names.encode(&mut self.bytes);
|
||||
}
|
||||
|
||||
/// Appends a subsection for the names of locals within functions in the
|
||||
/// wasm module.
|
||||
///
|
||||
/// This section should come after the function name subsection (if present)
|
||||
/// and before the labels subsection (if present).
|
||||
pub fn locals(&mut self, names: &IndirectNameMap) {
|
||||
self.subsection_header(Subsection::Local, names.size());
|
||||
names.encode(&mut self.bytes);
|
||||
}
|
||||
|
||||
/// Appends a subsection for the names of labels within functions in the
|
||||
/// wasm module.
|
||||
///
|
||||
/// This section should come after the local name subsection (if present)
|
||||
/// and before the type subsection (if present).
|
||||
pub fn labels(&mut self, names: &IndirectNameMap) {
|
||||
self.subsection_header(Subsection::Label, names.size());
|
||||
names.encode(&mut self.bytes);
|
||||
}
|
||||
|
||||
/// Appends a subsection for the names of all types in this wasm module.
|
||||
///
|
||||
/// This section should come after the label name subsection (if present)
|
||||
/// and before the table subsection (if present).
|
||||
pub fn types(&mut self, names: &NameMap) {
|
||||
self.subsection_header(Subsection::Type, names.size());
|
||||
names.encode(&mut self.bytes);
|
||||
}
|
||||
|
||||
/// Appends a subsection for the names of all tables in this wasm module.
|
||||
///
|
||||
/// This section should come after the type name subsection (if present)
|
||||
/// and before the memory subsection (if present).
|
||||
pub fn tables(&mut self, names: &NameMap) {
|
||||
self.subsection_header(Subsection::Table, names.size());
|
||||
names.encode(&mut self.bytes);
|
||||
}
|
||||
|
||||
/// Appends a subsection for the names of all memories in this wasm module.
|
||||
///
|
||||
/// This section should come after the table name subsection (if present)
|
||||
/// and before the global subsection (if present).
|
||||
pub fn memories(&mut self, names: &NameMap) {
|
||||
self.subsection_header(Subsection::Memory, names.size());
|
||||
names.encode(&mut self.bytes);
|
||||
}
|
||||
|
||||
/// Appends a subsection for the names of all globals in this wasm module.
|
||||
///
|
||||
/// This section should come after the memory name subsection (if present)
|
||||
/// and before the element subsection (if present).
|
||||
pub fn globals(&mut self, names: &NameMap) {
|
||||
self.subsection_header(Subsection::Global, names.size());
|
||||
names.encode(&mut self.bytes);
|
||||
}
|
||||
|
||||
/// Appends a subsection for the names of all elements in this wasm module.
|
||||
///
|
||||
/// This section should come after the global name subsection (if present)
|
||||
/// and before the data subsection (if present).
|
||||
pub fn elements(&mut self, names: &NameMap) {
|
||||
self.subsection_header(Subsection::Element, names.size());
|
||||
names.encode(&mut self.bytes);
|
||||
}
|
||||
|
||||
/// Appends a subsection for the names of all data in this wasm module.
|
||||
///
|
||||
/// This section should come after the element name subsection (if present).
|
||||
pub fn data(&mut self, names: &NameMap) {
|
||||
self.subsection_header(Subsection::Data, names.size());
|
||||
names.encode(&mut self.bytes);
|
||||
}
|
||||
|
||||
fn subsection_header(&mut self, id: Subsection, len: usize) {
|
||||
self.bytes.push(id as u8);
|
||||
len.encode(&mut self.bytes);
|
||||
}
|
||||
}
|
||||
|
||||
impl Encode for NameSection {
|
||||
fn encode(&self, sink: &mut Vec<u8>) {
|
||||
CustomSection {
|
||||
name: "name",
|
||||
data: &self.bytes,
|
||||
}
|
||||
.encode(sink);
|
||||
}
|
||||
}
|
||||
|
||||
impl Section for NameSection {
|
||||
fn id(&self) -> u8 {
|
||||
SectionId::Custom.into()
|
||||
}
|
||||
}
|
||||
|
||||
/// A map used to name items in a wasm module, organized by naming each
|
||||
/// individual index.
|
||||
///
|
||||
/// This is used in conjunction with [`NameSection::functions`] and simlar
|
||||
/// methods.
|
||||
#[derive(Clone, Debug, Default)]
|
||||
pub struct NameMap {
|
||||
bytes: Vec<u8>,
|
||||
count: u32,
|
||||
}
|
||||
|
||||
impl NameMap {
|
||||
/// Creates a new empty `NameMap`.
|
||||
pub fn new() -> NameMap {
|
||||
NameMap {
|
||||
bytes: vec![],
|
||||
count: 0,
|
||||
}
|
||||
}
|
||||
|
||||
/// Adds a an entry where the item at `idx` has the `name` specified.
|
||||
///
|
||||
/// Note that indices should be appended in ascending order of the index
|
||||
/// value. Each index may only be named once, but not all indices must be
|
||||
/// named (e.g. `0 foo; 1 bar; 7 qux` is valid but `0 foo; 0 bar` is not).
|
||||
/// Names do not have to be unique (e.g. `0 foo; 1 foo; 2 foo` is valid).
|
||||
pub fn append(&mut self, idx: u32, name: &str) {
|
||||
idx.encode(&mut self.bytes);
|
||||
name.encode(&mut self.bytes);
|
||||
self.count += 1;
|
||||
}
|
||||
|
||||
fn size(&self) -> usize {
|
||||
encoding_size(self.count) + self.bytes.len()
|
||||
}
|
||||
}
|
||||
|
||||
impl Encode for NameMap {
|
||||
fn encode(&self, sink: &mut Vec<u8>) {
|
||||
self.count.encode(sink);
|
||||
sink.extend(&self.bytes);
|
||||
}
|
||||
}
|
||||
|
||||
/// A map used to describe names with two levels of indirection, as opposed to a
|
||||
/// [`NameMap`] which has one level of indirection.
|
||||
///
|
||||
/// This naming map is used with [`NameSection::locals`], for example.
|
||||
#[derive(Clone, Debug, Default)]
|
||||
pub struct IndirectNameMap {
|
||||
bytes: Vec<u8>,
|
||||
count: u32,
|
||||
}
|
||||
|
||||
impl IndirectNameMap {
|
||||
/// Creates a new empty name map.
|
||||
pub fn new() -> IndirectNameMap {
|
||||
IndirectNameMap {
|
||||
bytes: vec![],
|
||||
count: 0,
|
||||
}
|
||||
}
|
||||
|
||||
/// Adds a new entry where the item at `idx` has sub-items named within
|
||||
/// `names` as specified.
|
||||
///
|
||||
/// For example if this is describing local names then `idx` is a function
|
||||
/// index where the indexes within `names` are local indices.
|
||||
pub fn append(&mut self, idx: u32, names: &NameMap) {
|
||||
idx.encode(&mut self.bytes);
|
||||
names.encode(&mut self.bytes);
|
||||
self.count += 1;
|
||||
}
|
||||
|
||||
fn size(&self) -> usize {
|
||||
encoding_size(self.count) + self.bytes.len()
|
||||
}
|
||||
}
|
||||
|
||||
impl Encode for IndirectNameMap {
|
||||
fn encode(&self, sink: &mut Vec<u8>) {
|
||||
self.count.encode(sink);
|
||||
sink.extend(&self.bytes);
|
||||
}
|
||||
}
|
@ -1,6 +1,6 @@
|
||||
use super::*;
|
||||
use crate::{encoding_size, Encode, Section, SectionId};
|
||||
|
||||
/// An encoder for the start section.
|
||||
/// An encoder for the start section of WebAssembly modules.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
@ -25,17 +25,15 @@ pub struct StartSection {
|
||||
pub function_index: u32,
|
||||
}
|
||||
|
||||
impl Encode for StartSection {
|
||||
fn encode(&self, sink: &mut Vec<u8>) {
|
||||
encoding_size(self.function_index).encode(sink);
|
||||
self.function_index.encode(sink);
|
||||
}
|
||||
}
|
||||
|
||||
impl Section for StartSection {
|
||||
fn id(&self) -> u8 {
|
||||
SectionId::Start.into()
|
||||
}
|
||||
|
||||
fn encode<S>(&self, sink: &mut S)
|
||||
where
|
||||
S: Extend<u8>,
|
||||
{
|
||||
let f = encoders::u32(self.function_index);
|
||||
let n = f.len();
|
||||
sink.extend(encoders::u32(n as u32).chain(f));
|
||||
}
|
||||
}
|
@ -1,7 +1,9 @@
|
||||
use super::*;
|
||||
use crate::{encode_section, Encode, Section, SectionId, ValType};
|
||||
|
||||
/// An encoder for the table section.
|
||||
///
|
||||
/// Table sections are only supported for modules.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```
|
||||
@ -19,7 +21,7 @@ use super::*;
|
||||
///
|
||||
/// let wasm_bytes = module.finish();
|
||||
/// ```
|
||||
#[derive(Clone, Debug)]
|
||||
#[derive(Clone, Default, Debug)]
|
||||
pub struct TableSection {
|
||||
bytes: Vec<u8>,
|
||||
num_added: u32,
|
||||
@ -27,18 +29,20 @@ pub struct TableSection {
|
||||
|
||||
impl TableSection {
|
||||
/// Construct a new table section encoder.
|
||||
pub fn new() -> TableSection {
|
||||
TableSection {
|
||||
bytes: vec![],
|
||||
num_added: 0,
|
||||
}
|
||||
pub fn new() -> Self {
|
||||
Self::default()
|
||||
}
|
||||
|
||||
/// How many tables have been defined inside this section so far?
|
||||
/// The number of tables in the section.
|
||||
pub fn len(&self) -> u32 {
|
||||
self.num_added
|
||||
}
|
||||
|
||||
/// Determines if the section is empty.
|
||||
pub fn is_empty(&self) -> bool {
|
||||
self.num_added == 0
|
||||
}
|
||||
|
||||
/// Define a table.
|
||||
pub fn table(&mut self, table_type: TableType) -> &mut Self {
|
||||
table_type.encode(&mut self.bytes);
|
||||
@ -47,27 +51,20 @@ impl TableSection {
|
||||
}
|
||||
}
|
||||
|
||||
impl Encode for TableSection {
|
||||
fn encode(&self, sink: &mut Vec<u8>) {
|
||||
encode_section(sink, self.num_added, &self.bytes);
|
||||
}
|
||||
}
|
||||
|
||||
impl Section for TableSection {
|
||||
fn id(&self) -> u8 {
|
||||
SectionId::Table.into()
|
||||
}
|
||||
|
||||
fn encode<S>(&self, sink: &mut S)
|
||||
where
|
||||
S: Extend<u8>,
|
||||
{
|
||||
let num_added = encoders::u32(self.num_added);
|
||||
let n = num_added.len();
|
||||
sink.extend(
|
||||
encoders::u32(u32::try_from(n + self.bytes.len()).unwrap())
|
||||
.chain(num_added)
|
||||
.chain(self.bytes.iter().copied()),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/// A table's type.
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
|
||||
pub struct TableType {
|
||||
/// The table's element type.
|
||||
pub element_type: ValType,
|
||||
@ -77,17 +74,19 @@ pub struct TableType {
|
||||
pub maximum: Option<u32>,
|
||||
}
|
||||
|
||||
impl TableType {
|
||||
pub(crate) fn encode(&self, bytes: &mut Vec<u8>) {
|
||||
bytes.push(self.element_type.into());
|
||||
impl Encode for TableType {
|
||||
fn encode(&self, sink: &mut Vec<u8>) {
|
||||
let mut flags = 0;
|
||||
if self.maximum.is_some() {
|
||||
flags |= 0b001;
|
||||
}
|
||||
bytes.push(flags);
|
||||
bytes.extend(encoders::u32(self.minimum));
|
||||
|
||||
self.element_type.encode(sink);
|
||||
sink.push(flags);
|
||||
self.minimum.encode(sink);
|
||||
|
||||
if let Some(max) = self.maximum {
|
||||
bytes.extend(encoders::u32(max));
|
||||
max.encode(sink);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,5 +1,4 @@
|
||||
use super::*;
|
||||
use std::convert::TryFrom;
|
||||
use crate::{encode_section, Encode, Section, SectionId};
|
||||
|
||||
/// An encoder for the tag section.
|
||||
///
|
||||
@ -19,7 +18,7 @@ use std::convert::TryFrom;
|
||||
///
|
||||
/// let wasm_bytes = module.finish();
|
||||
/// ```
|
||||
#[derive(Clone, Debug)]
|
||||
#[derive(Clone, Default, Debug)]
|
||||
pub struct TagSection {
|
||||
bytes: Vec<u8>,
|
||||
num_added: u32,
|
||||
@ -27,18 +26,20 @@ pub struct TagSection {
|
||||
|
||||
impl TagSection {
|
||||
/// Create a new tag section encoder.
|
||||
pub fn new() -> TagSection {
|
||||
TagSection {
|
||||
bytes: vec![],
|
||||
num_added: 0,
|
||||
}
|
||||
pub fn new() -> Self {
|
||||
Self::default()
|
||||
}
|
||||
|
||||
/// How many tags have been defined inside this section so far?
|
||||
/// The number of tags in the section.
|
||||
pub fn len(&self) -> u32 {
|
||||
self.num_added
|
||||
}
|
||||
|
||||
/// Determines if the section is empty.
|
||||
pub fn is_empty(&self) -> bool {
|
||||
self.num_added == 0
|
||||
}
|
||||
|
||||
/// Define a tag.
|
||||
pub fn tag(&mut self, tag_type: TagType) -> &mut Self {
|
||||
tag_type.encode(&mut self.bytes);
|
||||
@ -47,34 +48,28 @@ impl TagSection {
|
||||
}
|
||||
}
|
||||
|
||||
impl Encode for TagSection {
|
||||
fn encode(&self, sink: &mut Vec<u8>) {
|
||||
encode_section(sink, self.num_added, &self.bytes);
|
||||
}
|
||||
}
|
||||
|
||||
impl Section for TagSection {
|
||||
fn id(&self) -> u8 {
|
||||
SectionId::Tag.into()
|
||||
}
|
||||
|
||||
fn encode<S>(&self, sink: &mut S)
|
||||
where
|
||||
S: Extend<u8>,
|
||||
{
|
||||
let num_added = encoders::u32(self.num_added);
|
||||
let n = num_added.len();
|
||||
sink.extend(
|
||||
encoders::u32(u32::try_from(n + self.bytes.len()).unwrap())
|
||||
.chain(num_added)
|
||||
.chain(self.bytes.iter().copied()),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(missing_docs)]
|
||||
/// Represents a tag kind.
|
||||
#[repr(u8)]
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
|
||||
pub enum TagKind {
|
||||
/// The tag is an exception type.
|
||||
Exception = 0x0,
|
||||
}
|
||||
|
||||
/// A tag's type.
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
|
||||
pub struct TagType {
|
||||
/// The kind of tag
|
||||
pub kind: TagKind,
|
||||
@ -82,9 +77,9 @@ pub struct TagType {
|
||||
pub func_type_idx: u32,
|
||||
}
|
||||
|
||||
impl TagType {
|
||||
pub(crate) fn encode(&self, bytes: &mut Vec<u8>) {
|
||||
bytes.push(self.kind as u8);
|
||||
bytes.extend(encoders::u32(self.func_type_idx));
|
||||
impl Encode for TagType {
|
||||
fn encode(&self, sink: &mut Vec<u8>) {
|
||||
sink.push(self.kind as u8);
|
||||
self.func_type_idx.encode(sink);
|
||||
}
|
||||
}
|
112
third_party/rust/wasm-encoder/src/core/types.rs
vendored
Normal file
112
third_party/rust/wasm-encoder/src/core/types.rs
vendored
Normal file
@ -0,0 +1,112 @@
|
||||
use crate::{encode_section, Encode, Section, SectionId};
|
||||
|
||||
/// The type of a core WebAssembly value.
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Ord, PartialOrd)]
|
||||
#[repr(u8)]
|
||||
pub enum ValType {
|
||||
/// The `i32` type.
|
||||
I32 = 0x7F,
|
||||
/// The `i64` type.
|
||||
I64 = 0x7E,
|
||||
/// The `f32` type.
|
||||
F32 = 0x7D,
|
||||
/// The `f64` type.
|
||||
F64 = 0x7C,
|
||||
/// The `v128` type.
|
||||
///
|
||||
/// Part of the SIMD proposal.
|
||||
V128 = 0x7B,
|
||||
/// The `funcref` type.
|
||||
///
|
||||
/// Part of the reference types proposal when used anywhere other than a
|
||||
/// table's element type.
|
||||
FuncRef = 0x70,
|
||||
/// The `externref` type.
|
||||
///
|
||||
/// Part of the reference types proposal.
|
||||
ExternRef = 0x6F,
|
||||
}
|
||||
|
||||
impl From<ValType> for u8 {
|
||||
#[inline]
|
||||
fn from(t: ValType) -> u8 {
|
||||
t as u8
|
||||
}
|
||||
}
|
||||
|
||||
impl Encode for ValType {
|
||||
fn encode(&self, sink: &mut Vec<u8>) {
|
||||
sink.push(*self as u8);
|
||||
}
|
||||
}
|
||||
|
||||
/// An encoder for the type section of WebAssembly modules.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```rust
|
||||
/// use wasm_encoder::{Module, TypeSection, ValType};
|
||||
///
|
||||
/// let mut types = TypeSection::new();
|
||||
///
|
||||
/// types.function([ValType::I32, ValType::I32], [ValType::I64]);
|
||||
///
|
||||
/// let mut module = Module::new();
|
||||
/// module.section(&types);
|
||||
///
|
||||
/// let bytes = module.finish();
|
||||
/// ```
|
||||
#[derive(Clone, Debug, Default)]
|
||||
pub struct TypeSection {
|
||||
bytes: Vec<u8>,
|
||||
num_added: u32,
|
||||
}
|
||||
|
||||
impl TypeSection {
|
||||
/// Create a new module type section encoder.
|
||||
pub fn new() -> Self {
|
||||
Self::default()
|
||||
}
|
||||
|
||||
/// The number of types in the section.
|
||||
pub fn len(&self) -> u32 {
|
||||
self.num_added
|
||||
}
|
||||
|
||||
/// Determines if the section is empty.
|
||||
pub fn is_empty(&self) -> bool {
|
||||
self.num_added == 0
|
||||
}
|
||||
|
||||
/// Define a function type in this type section.
|
||||
pub fn function<P, R>(&mut self, params: P, results: R) -> &mut Self
|
||||
where
|
||||
P: IntoIterator<Item = ValType>,
|
||||
P::IntoIter: ExactSizeIterator,
|
||||
R: IntoIterator<Item = ValType>,
|
||||
R::IntoIter: ExactSizeIterator,
|
||||
{
|
||||
let params = params.into_iter();
|
||||
let results = results.into_iter();
|
||||
|
||||
self.bytes.push(0x60);
|
||||
params.len().encode(&mut self.bytes);
|
||||
self.bytes.extend(params.map(u8::from));
|
||||
results.len().encode(&mut self.bytes);
|
||||
self.bytes.extend(results.map(u8::from));
|
||||
self.num_added += 1;
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl Encode for TypeSection {
|
||||
fn encode(&self, sink: &mut Vec<u8>) {
|
||||
encode_section(sink, self.num_added, &self.bytes);
|
||||
}
|
||||
}
|
||||
|
||||
impl Section for TypeSection {
|
||||
fn id(&self) -> u8 {
|
||||
SectionId::Type.into()
|
||||
}
|
||||
}
|
70
third_party/rust/wasm-encoder/src/encoders.rs
vendored
70
third_party/rust/wasm-encoder/src/encoders.rs
vendored
@ -1,70 +0,0 @@
|
||||
//! Low-level encoders.
|
||||
//!
|
||||
//! This module provides low-level encoders that can be used (for example) to
|
||||
//! define your own custom section encodings.
|
||||
|
||||
use std::convert::TryFrom;
|
||||
|
||||
/// Encode a `u32` as a ULEB128.
|
||||
pub fn u32(n: u32) -> impl ExactSizeIterator<Item = u8> {
|
||||
let mut buf = [0; 5];
|
||||
let n = leb128::write::unsigned(&mut &mut buf[..], n.into()).unwrap();
|
||||
<_>::into_iter(buf).take(n)
|
||||
}
|
||||
|
||||
/// Encode a `u64` as a ULEB128.
|
||||
pub fn u64(n: u64) -> impl ExactSizeIterator<Item = u8> {
|
||||
let mut buf = [0; 10];
|
||||
let n = leb128::write::unsigned(&mut &mut buf[..], n.into()).unwrap();
|
||||
<_>::into_iter(buf).take(n)
|
||||
}
|
||||
|
||||
/// Encode an `i32` as a SLEB128.
|
||||
pub fn s32(x: i32) -> impl ExactSizeIterator<Item = u8> {
|
||||
let mut buf = [0; 5];
|
||||
let n = leb128::write::signed(&mut &mut buf[..], x.into()).unwrap();
|
||||
<_>::into_iter(buf).take(n)
|
||||
}
|
||||
|
||||
/// Encode an `i64` that uses at most 33 bits as a SLEB128.
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// Panics if more than 33 bits are used.
|
||||
///
|
||||
/// ```
|
||||
/// wasm_encoder::encoders::s33(1 << 32);
|
||||
/// ```
|
||||
///
|
||||
/// ```should_panic
|
||||
/// wasm_encoder::encoders::s33(1 << 33);
|
||||
/// ```
|
||||
///
|
||||
/// ```
|
||||
/// wasm_encoder::encoders::s33(-1 << 32);
|
||||
/// ```
|
||||
///
|
||||
/// ```should_panic
|
||||
/// wasm_encoder::encoders::s33(-1 << 33);
|
||||
/// ```
|
||||
pub fn s33(x: i64) -> impl ExactSizeIterator<Item = u8> {
|
||||
assert!({
|
||||
let mask = 1 << 33 << 30 >> 30;
|
||||
x != mask && (x & mask == 0) == (x >= 0)
|
||||
});
|
||||
let mut buf = [0; 5];
|
||||
let n = leb128::write::signed(&mut &mut buf[..], x).unwrap();
|
||||
<_>::into_iter(buf).take(n)
|
||||
}
|
||||
|
||||
/// Encode an `i64` as a SLEB128.
|
||||
pub fn s64(x: i64) -> impl ExactSizeIterator<Item = u8> {
|
||||
let mut buf = [0; 10];
|
||||
let n = leb128::write::signed(&mut &mut buf[..], x).unwrap();
|
||||
<_>::into_iter(buf).take(n)
|
||||
}
|
||||
|
||||
/// Encode a length-prefixed UTF-8 string.
|
||||
pub fn str<'a>(s: &'a str) -> impl Iterator<Item = u8> + 'a {
|
||||
u32(u32::try_from(s.len()).unwrap()).chain(s.as_bytes().iter().copied())
|
||||
}
|
154
third_party/rust/wasm-encoder/src/exports.rs
vendored
154
third_party/rust/wasm-encoder/src/exports.rs
vendored
@ -1,154 +0,0 @@
|
||||
use super::*;
|
||||
|
||||
/// An encoder for the export section.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```
|
||||
/// use wasm_encoder::{
|
||||
/// Export, ExportSection, TableSection, TableType, Module, ValType,
|
||||
/// };
|
||||
///
|
||||
/// let mut tables = TableSection::new();
|
||||
/// tables.table(TableType {
|
||||
/// element_type: ValType::FuncRef,
|
||||
/// minimum: 128,
|
||||
/// maximum: None,
|
||||
/// });
|
||||
///
|
||||
/// let mut exports = ExportSection::new();
|
||||
/// exports.export("my-table", Export::Table(0));
|
||||
///
|
||||
/// let mut module = Module::new();
|
||||
/// module
|
||||
/// .section(&tables)
|
||||
/// .section(&exports);
|
||||
///
|
||||
/// let wasm_bytes = module.finish();
|
||||
/// ```
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct ExportSection {
|
||||
bytes: Vec<u8>,
|
||||
num_added: u32,
|
||||
}
|
||||
|
||||
impl ExportSection {
|
||||
/// Create a new export section encoder.
|
||||
pub fn new() -> ExportSection {
|
||||
ExportSection {
|
||||
bytes: vec![],
|
||||
num_added: 0,
|
||||
}
|
||||
}
|
||||
|
||||
/// How many exports have been defined inside this section so far?
|
||||
pub fn len(&self) -> u32 {
|
||||
self.num_added
|
||||
}
|
||||
|
||||
/// Define an export.
|
||||
pub fn export(&mut self, name: &str, export: Export) -> &mut Self {
|
||||
self.bytes.extend(encoders::str(name));
|
||||
export.encode(&mut self.bytes);
|
||||
self.num_added += 1;
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl Section for ExportSection {
|
||||
fn id(&self) -> u8 {
|
||||
SectionId::Export.into()
|
||||
}
|
||||
|
||||
fn encode<S>(&self, sink: &mut S)
|
||||
where
|
||||
S: Extend<u8>,
|
||||
{
|
||||
let num_added = encoders::u32(self.num_added);
|
||||
let n = num_added.len();
|
||||
sink.extend(
|
||||
encoders::u32(u32::try_from(n + self.bytes.len()).unwrap())
|
||||
.chain(num_added)
|
||||
.chain(self.bytes.iter().copied()),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/// A WebAssembly export.
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
pub enum Export {
|
||||
/// An export of the `n`th function.
|
||||
Function(u32),
|
||||
/// An export of the `n`th table.
|
||||
Table(u32),
|
||||
/// An export of the `n`th memory.
|
||||
Memory(u32),
|
||||
/// An export of the `n`th global.
|
||||
Global(u32),
|
||||
/// An export of the `n`th tag.
|
||||
Tag(u32),
|
||||
/// An export of the `n`th instance.
|
||||
///
|
||||
/// Note that this is part of the [module linking proposal][proposal] and is
|
||||
/// not currently part of stable WebAssembly.
|
||||
///
|
||||
/// [proposal]: https://github.com/webassembly/module-linking
|
||||
Instance(u32),
|
||||
/// An export of the `n`th module.
|
||||
///
|
||||
/// Note that this is part of the [module linking proposal][proposal] and is
|
||||
/// not currently part of stable WebAssembly.
|
||||
///
|
||||
/// [proposal]: https://github.com/webassembly/module-linking
|
||||
Module(u32),
|
||||
}
|
||||
|
||||
impl Export {
|
||||
pub(crate) fn encode(&self, bytes: &mut Vec<u8>) {
|
||||
let idx = match *self {
|
||||
Export::Function(x) => {
|
||||
bytes.push(ItemKind::Function as u8);
|
||||
x
|
||||
}
|
||||
Export::Table(x) => {
|
||||
bytes.push(ItemKind::Table as u8);
|
||||
x
|
||||
}
|
||||
Export::Memory(x) => {
|
||||
bytes.push(ItemKind::Memory as u8);
|
||||
x
|
||||
}
|
||||
Export::Global(x) => {
|
||||
bytes.push(ItemKind::Global as u8);
|
||||
x
|
||||
}
|
||||
Export::Tag(x) => {
|
||||
bytes.push(ItemKind::Tag as u8);
|
||||
x
|
||||
}
|
||||
Export::Instance(x) => {
|
||||
bytes.push(ItemKind::Instance as u8);
|
||||
x
|
||||
}
|
||||
Export::Module(x) => {
|
||||
bytes.push(ItemKind::Module as u8);
|
||||
x
|
||||
}
|
||||
};
|
||||
bytes.extend(encoders::u32(idx));
|
||||
}
|
||||
}
|
||||
|
||||
/// Kinds of WebAssembly items
|
||||
#[allow(missing_docs)]
|
||||
#[repr(u8)]
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
pub enum ItemKind {
|
||||
Function = 0x00,
|
||||
Table = 0x01,
|
||||
Memory = 0x02,
|
||||
Global = 0x03,
|
||||
Tag = 0x04,
|
||||
Module = 0x05,
|
||||
Instance = 0x06,
|
||||
}
|
167
third_party/rust/wasm-encoder/src/imports.rs
vendored
167
third_party/rust/wasm-encoder/src/imports.rs
vendored
@ -1,167 +0,0 @@
|
||||
use super::*;
|
||||
use std::convert::TryFrom;
|
||||
|
||||
/// An encoder for the import section.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```
|
||||
/// use wasm_encoder::{Module, ImportSection, MemoryType};
|
||||
///
|
||||
/// let mut imports = ImportSection::new();
|
||||
/// imports.import(
|
||||
/// "env",
|
||||
/// Some("memory"),
|
||||
/// MemoryType {
|
||||
/// minimum: 1,
|
||||
/// maximum: None,
|
||||
/// memory64: false,
|
||||
/// }
|
||||
/// );
|
||||
///
|
||||
/// let mut module = Module::new();
|
||||
/// module.section(&imports);
|
||||
///
|
||||
/// let wasm_bytes = module.finish();
|
||||
/// ```
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct ImportSection {
|
||||
bytes: Vec<u8>,
|
||||
num_added: u32,
|
||||
}
|
||||
|
||||
impl ImportSection {
|
||||
/// Construct a new import section encoder.
|
||||
pub fn new() -> ImportSection {
|
||||
ImportSection {
|
||||
bytes: vec![],
|
||||
num_added: 0,
|
||||
}
|
||||
}
|
||||
|
||||
/// How many imports have been defined inside this section so far?
|
||||
pub fn len(&self) -> u32 {
|
||||
self.num_added
|
||||
}
|
||||
|
||||
/// Define an import.
|
||||
pub fn import(
|
||||
&mut self,
|
||||
module: &str,
|
||||
name: Option<&str>,
|
||||
ty: impl Into<EntityType>,
|
||||
) -> &mut Self {
|
||||
self.bytes.extend(encoders::str(module));
|
||||
match name {
|
||||
Some(name) => self.bytes.extend(encoders::str(name)),
|
||||
None => {
|
||||
self.bytes.push(0x00);
|
||||
self.bytes.push(0xff);
|
||||
}
|
||||
}
|
||||
ty.into().encode(&mut self.bytes);
|
||||
self.num_added += 1;
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl Section for ImportSection {
|
||||
fn id(&self) -> u8 {
|
||||
SectionId::Import.into()
|
||||
}
|
||||
|
||||
fn encode<S>(&self, sink: &mut S)
|
||||
where
|
||||
S: Extend<u8>,
|
||||
{
|
||||
let num_added = encoders::u32(self.num_added);
|
||||
let n = num_added.len();
|
||||
sink.extend(
|
||||
encoders::u32(u32::try_from(n + self.bytes.len()).unwrap())
|
||||
.chain(num_added)
|
||||
.chain(self.bytes.iter().copied()),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/// The type of an entity.
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
pub enum EntityType {
|
||||
/// The `n`th type, which is a function.
|
||||
Function(u32),
|
||||
/// A table type.
|
||||
Table(TableType),
|
||||
/// A memory type.
|
||||
Memory(MemoryType),
|
||||
/// A global type.
|
||||
Global(GlobalType),
|
||||
/// A tag type.
|
||||
Tag(TagType),
|
||||
/// The `n`th type, which is an instance.
|
||||
Instance(u32),
|
||||
/// The `n`th type, which is a module.
|
||||
Module(u32),
|
||||
}
|
||||
|
||||
// NB: no `impl From<u32> for ImportType` because instances and modules also use
|
||||
// `u32` indices in module linking, so we would have to remove that impl when
|
||||
// adding support for module linking anyways.
|
||||
|
||||
impl From<TableType> for EntityType {
|
||||
fn from(t: TableType) -> Self {
|
||||
EntityType::Table(t)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<MemoryType> for EntityType {
|
||||
fn from(m: MemoryType) -> Self {
|
||||
EntityType::Memory(m)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<GlobalType> for EntityType {
|
||||
fn from(g: GlobalType) -> Self {
|
||||
EntityType::Global(g)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<TagType> for EntityType {
|
||||
fn from(t: TagType) -> Self {
|
||||
EntityType::Tag(t)
|
||||
}
|
||||
}
|
||||
|
||||
impl EntityType {
|
||||
pub(crate) fn encode(&self, dst: &mut Vec<u8>) {
|
||||
match self {
|
||||
EntityType::Function(x) => {
|
||||
dst.push(0x00);
|
||||
dst.extend(encoders::u32(*x));
|
||||
}
|
||||
EntityType::Table(ty) => {
|
||||
dst.push(0x01);
|
||||
ty.encode(dst);
|
||||
}
|
||||
EntityType::Memory(ty) => {
|
||||
dst.push(0x02);
|
||||
ty.encode(dst);
|
||||
}
|
||||
EntityType::Global(ty) => {
|
||||
dst.push(0x03);
|
||||
ty.encode(dst);
|
||||
}
|
||||
EntityType::Tag(ty) => {
|
||||
dst.push(0x04);
|
||||
ty.encode(dst);
|
||||
}
|
||||
EntityType::Module(ty) => {
|
||||
dst.push(0x05);
|
||||
dst.extend(encoders::u32(*ty));
|
||||
}
|
||||
EntityType::Instance(ty) => {
|
||||
dst.push(0x06);
|
||||
dst.extend(encoders::u32(*ty));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
86
third_party/rust/wasm-encoder/src/instances.rs
vendored
86
third_party/rust/wasm-encoder/src/instances.rs
vendored
@ -1,86 +0,0 @@
|
||||
use super::*;
|
||||
|
||||
/// An encoder for the instance section.
|
||||
///
|
||||
/// Note that this is part of the [module linking proposal][proposal] and is not
|
||||
/// currently part of stable WebAssembly.
|
||||
///
|
||||
/// [proposal]: https://github.com/webassembly/module-linking
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```
|
||||
/// use wasm_encoder::{Module, InstanceSection, Export};
|
||||
///
|
||||
/// let mut instances = InstanceSection::new();
|
||||
/// instances.instantiate(0, vec![
|
||||
/// ("x", Export::Function(0)),
|
||||
/// ("", Export::Module(2)),
|
||||
/// ("foo", Export::Global(0)),
|
||||
/// ]);
|
||||
///
|
||||
/// let mut module = Module::new();
|
||||
/// module.section(&instances);
|
||||
///
|
||||
/// let wasm_bytes = module.finish();
|
||||
/// ```
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct InstanceSection {
|
||||
bytes: Vec<u8>,
|
||||
num_added: u32,
|
||||
}
|
||||
|
||||
impl InstanceSection {
|
||||
/// Construct a new instance section encoder.
|
||||
pub fn new() -> InstanceSection {
|
||||
InstanceSection {
|
||||
bytes: vec![],
|
||||
num_added: 0,
|
||||
}
|
||||
}
|
||||
|
||||
/// How many instances have been defined inside this section so far?
|
||||
pub fn len(&self) -> u32 {
|
||||
self.num_added
|
||||
}
|
||||
|
||||
/// Define an instantiation of the given module with the given items as
|
||||
/// arguments to the instantiation.
|
||||
pub fn instantiate<'a, I>(&mut self, module: u32, args: I) -> &mut Self
|
||||
where
|
||||
I: IntoIterator<Item = (&'a str, Export)>,
|
||||
I::IntoIter: ExactSizeIterator,
|
||||
{
|
||||
let args = args.into_iter();
|
||||
|
||||
self.bytes.push(0x00);
|
||||
self.bytes.extend(encoders::u32(module));
|
||||
self.bytes
|
||||
.extend(encoders::u32(u32::try_from(args.len()).unwrap()));
|
||||
for (name, export) in args {
|
||||
self.bytes.extend(encoders::str(name));
|
||||
export.encode(&mut self.bytes);
|
||||
}
|
||||
self.num_added += 1;
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl Section for InstanceSection {
|
||||
fn id(&self) -> u8 {
|
||||
SectionId::Instance.into()
|
||||
}
|
||||
|
||||
fn encode<S>(&self, sink: &mut S)
|
||||
where
|
||||
S: Extend<u8>,
|
||||
{
|
||||
let num_added = encoders::u32(self.num_added);
|
||||
let n = num_added.len();
|
||||
sink.extend(
|
||||
encoders::u32(u32::try_from(n + self.bytes.len()).unwrap())
|
||||
.chain(num_added)
|
||||
.chain(self.bytes.iter().copied()),
|
||||
);
|
||||
}
|
||||
}
|
273
third_party/rust/wasm-encoder/src/lib.rs
vendored
273
third_party/rust/wasm-encoder/src/lib.rs
vendored
@ -26,7 +26,7 @@
|
||||
//!
|
||||
//! ```
|
||||
//! use wasm_encoder::{
|
||||
//! CodeSection, Export, ExportSection, Function, FunctionSection, Instruction,
|
||||
//! CodeSection, ExportKind, ExportSection, Function, FunctionSection, Instruction,
|
||||
//! Module, TypeSection, ValType,
|
||||
//! };
|
||||
//!
|
||||
@ -47,17 +47,17 @@
|
||||
//!
|
||||
//! // Encode the export section.
|
||||
//! let mut exports = ExportSection::new();
|
||||
//! exports.export("f", Export::Function(0));
|
||||
//! exports.export("f", ExportKind::Func, 0);
|
||||
//! module.section(&exports);
|
||||
//!
|
||||
//! // Encode the code section.
|
||||
//! let mut codes = CodeSection::new();
|
||||
//! let locals = vec![];
|
||||
//! let mut f = Function::new(locals);
|
||||
//! f.instruction(Instruction::LocalGet(0));
|
||||
//! f.instruction(Instruction::LocalGet(1));
|
||||
//! f.instruction(Instruction::I32Add);
|
||||
//! f.instruction(Instruction::End);
|
||||
//! f.instruction(&Instruction::LocalGet(0));
|
||||
//! f.instruction(&Instruction::LocalGet(1));
|
||||
//! f.instruction(&Instruction::I32Add);
|
||||
//! f.instruction(&Instruction::End);
|
||||
//! codes.function(&f);
|
||||
//! module.section(&codes);
|
||||
//!
|
||||
@ -70,199 +70,104 @@
|
||||
|
||||
#![deny(missing_docs, missing_debug_implementations)]
|
||||
|
||||
mod aliases;
|
||||
mod code;
|
||||
mod custom;
|
||||
mod data;
|
||||
mod elements;
|
||||
mod exports;
|
||||
mod functions;
|
||||
mod globals;
|
||||
mod imports;
|
||||
mod instances;
|
||||
mod linking;
|
||||
mod memories;
|
||||
mod modules;
|
||||
mod start;
|
||||
mod tables;
|
||||
mod tags;
|
||||
mod types;
|
||||
mod component;
|
||||
mod core;
|
||||
mod raw;
|
||||
|
||||
pub use aliases::*;
|
||||
pub use code::*;
|
||||
pub use custom::*;
|
||||
pub use data::*;
|
||||
pub use elements::*;
|
||||
pub use exports::*;
|
||||
pub use functions::*;
|
||||
pub use globals::*;
|
||||
pub use imports::*;
|
||||
pub use instances::*;
|
||||
pub use linking::*;
|
||||
pub use memories::*;
|
||||
pub use modules::*;
|
||||
pub use start::*;
|
||||
pub use tables::*;
|
||||
pub use tags::*;
|
||||
pub use types::*;
|
||||
pub use self::component::*;
|
||||
pub use self::core::*;
|
||||
pub use self::raw::*;
|
||||
|
||||
pub mod encoders;
|
||||
|
||||
use std::convert::TryFrom;
|
||||
|
||||
/// A Wasm module that is being encoded.
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct Module {
|
||||
bytes: Vec<u8>,
|
||||
/// Implemented by types that can be encoded into a byte sink.
|
||||
pub trait Encode {
|
||||
/// Encode the type into the given byte sink.
|
||||
fn encode(&self, sink: &mut Vec<u8>);
|
||||
}
|
||||
|
||||
/// A WebAssembly section.
|
||||
///
|
||||
/// Various builders defined in this crate already implement this trait, but you
|
||||
/// can also implement it yourself for your own custom section builders, or use
|
||||
/// `RawSection` to use a bunch of raw bytes as a section.
|
||||
pub trait Section {
|
||||
/// This section's id.
|
||||
///
|
||||
/// See `SectionId` for known section ids.
|
||||
fn id(&self) -> u8;
|
||||
|
||||
/// Write this section's data and data length prefix into the given sink.
|
||||
fn encode<S>(&self, sink: &mut S)
|
||||
where
|
||||
S: Extend<u8>;
|
||||
}
|
||||
|
||||
/// A section made up of uninterpreted, raw bytes.
|
||||
///
|
||||
/// Allows you to splat any data into a Wasm section.
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
pub struct RawSection<'a> {
|
||||
/// The id for this section.
|
||||
pub id: u8,
|
||||
/// The raw data for this section.
|
||||
pub data: &'a [u8],
|
||||
}
|
||||
|
||||
impl Section for RawSection<'_> {
|
||||
fn id(&self) -> u8 {
|
||||
self.id
|
||||
}
|
||||
|
||||
fn encode<S>(&self, sink: &mut S)
|
||||
where
|
||||
S: Extend<u8>,
|
||||
{
|
||||
sink.extend(
|
||||
encoders::u32(u32::try_from(self.data.len()).unwrap()).chain(self.data.iter().copied()),
|
||||
);
|
||||
impl<T: Encode + ?Sized> Encode for &'_ T {
|
||||
fn encode(&self, sink: &mut Vec<u8>) {
|
||||
T::encode(self, sink)
|
||||
}
|
||||
}
|
||||
|
||||
impl Module {
|
||||
/// Begin writing a new `Module`.
|
||||
#[rustfmt::skip]
|
||||
pub fn new() -> Self {
|
||||
Module {
|
||||
bytes: vec![
|
||||
// Magic
|
||||
0x00, 0x61, 0x73, 0x6D,
|
||||
// Version
|
||||
0x01, 0x00, 0x00, 0x00,
|
||||
],
|
||||
impl<T: Encode> Encode for [T] {
|
||||
fn encode(&self, sink: &mut Vec<u8>) {
|
||||
self.len().encode(sink);
|
||||
for item in self {
|
||||
item.encode(sink);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Write a section into this module.
|
||||
///
|
||||
/// It is your responsibility to define the sections in the [proper
|
||||
/// order](https://webassembly.github.io/spec/core/binary/modules.html#binary-module),
|
||||
/// and to ensure that each kind of section (other than custom sections) is
|
||||
/// only defined once. While this is a potential footgun, it also allows you
|
||||
/// to use this crate to easily construct test cases for bad Wasm module
|
||||
/// encodings.
|
||||
pub fn section(&mut self, section: &impl Section) -> &mut Self {
|
||||
self.bytes.push(section.id());
|
||||
section.encode(&mut self.bytes);
|
||||
self
|
||||
}
|
||||
|
||||
/// Get the encoded Wasm module as a slice.
|
||||
pub fn as_slice(&self) -> &[u8] {
|
||||
&self.bytes
|
||||
}
|
||||
|
||||
/// Finish writing this Wasm module and extract ownership of the encoded
|
||||
/// bytes.
|
||||
pub fn finish(self) -> Vec<u8> {
|
||||
self.bytes
|
||||
impl Encode for [u8] {
|
||||
fn encode(&self, sink: &mut Vec<u8>) {
|
||||
self.len().encode(sink);
|
||||
sink.extend(self);
|
||||
}
|
||||
}
|
||||
|
||||
/// Known section IDs.
|
||||
///
|
||||
/// Useful for implementing the `Section` trait, or for setting
|
||||
/// `RawSection::id`.
|
||||
#[derive(Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd)]
|
||||
#[repr(u8)]
|
||||
#[allow(missing_docs)]
|
||||
pub enum SectionId {
|
||||
Custom = 0,
|
||||
Type = 1,
|
||||
Import = 2,
|
||||
Function = 3,
|
||||
Table = 4,
|
||||
Memory = 5,
|
||||
Global = 6,
|
||||
Export = 7,
|
||||
Start = 8,
|
||||
Element = 9,
|
||||
Code = 10,
|
||||
Data = 11,
|
||||
DataCount = 12,
|
||||
Tag = 13,
|
||||
Module = 14,
|
||||
Instance = 15,
|
||||
Alias = 16,
|
||||
}
|
||||
|
||||
impl From<SectionId> for u8 {
|
||||
#[inline]
|
||||
fn from(id: SectionId) -> u8 {
|
||||
id as u8
|
||||
impl Encode for str {
|
||||
fn encode(&self, sink: &mut Vec<u8>) {
|
||||
self.len().encode(sink);
|
||||
sink.extend_from_slice(self.as_bytes());
|
||||
}
|
||||
}
|
||||
|
||||
/// The type of a value.
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
|
||||
#[repr(u8)]
|
||||
pub enum ValType {
|
||||
/// The `i32` type.
|
||||
I32 = 0x7F,
|
||||
/// The `i64` type.
|
||||
I64 = 0x7E,
|
||||
/// The `f32` type.
|
||||
F32 = 0x7D,
|
||||
/// The `f64` type.
|
||||
F64 = 0x7C,
|
||||
/// The `v128` type.
|
||||
///
|
||||
/// Part of the SIMD proposal.
|
||||
V128 = 0x7B,
|
||||
/// The `funcref` type.
|
||||
///
|
||||
/// Part of the reference types proposal when used anywhere other than a
|
||||
/// table's element type.
|
||||
FuncRef = 0x70,
|
||||
/// The `externref` type.
|
||||
///
|
||||
/// Part of the reference types proposal.
|
||||
ExternRef = 0x6F,
|
||||
}
|
||||
|
||||
impl From<ValType> for u8 {
|
||||
#[inline]
|
||||
fn from(t: ValType) -> u8 {
|
||||
t as u8
|
||||
impl Encode for usize {
|
||||
fn encode(&self, sink: &mut Vec<u8>) {
|
||||
assert!(*self <= u32::max_value() as usize);
|
||||
(*self as u32).encode(sink)
|
||||
}
|
||||
}
|
||||
|
||||
impl Encode for u32 {
|
||||
fn encode(&self, sink: &mut Vec<u8>) {
|
||||
leb128::write::unsigned(sink, (*self).into()).unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
impl Encode for i32 {
|
||||
fn encode(&self, sink: &mut Vec<u8>) {
|
||||
leb128::write::signed(sink, (*self).into()).unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
impl Encode for u64 {
|
||||
fn encode(&self, sink: &mut Vec<u8>) {
|
||||
leb128::write::unsigned(sink, *self).unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
impl Encode for i64 {
|
||||
fn encode(&self, sink: &mut Vec<u8>) {
|
||||
leb128::write::signed(sink, *self).unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
fn encoding_size(n: u32) -> usize {
|
||||
let mut buf = [0u8; 5];
|
||||
leb128::write::unsigned(&mut &mut buf[..], n.into()).unwrap()
|
||||
}
|
||||
|
||||
fn encode_section(sink: &mut Vec<u8>, count: u32, bytes: &[u8]) {
|
||||
(encoding_size(count) + bytes.len()).encode(sink);
|
||||
count.encode(sink);
|
||||
sink.extend(bytes);
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn it_encodes_an_empty_module() {
|
||||
let bytes = Module::new().finish();
|
||||
assert_eq!(bytes, [0x00, b'a', b's', b'm', 0x01, 0x00, 0x00, 0x00]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn it_encodes_an_empty_component() {
|
||||
let bytes = Component::new().finish();
|
||||
assert_eq!(bytes, [0x00, b'a', b's', b'm', 0x0a, 0x00, 0x01, 0x00]);
|
||||
}
|
||||
}
|
||||
|
72
third_party/rust/wasm-encoder/src/modules.rs
vendored
72
third_party/rust/wasm-encoder/src/modules.rs
vendored
@ -1,72 +0,0 @@
|
||||
use super::*;
|
||||
|
||||
/// An encoder for the module section.
|
||||
///
|
||||
/// Note that this is part of the [module linking proposal][proposal] and is
|
||||
/// not currently part of stable WebAssembly.
|
||||
///
|
||||
/// [proposal]: https://github.com/webassembly/module-linking
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```
|
||||
/// use wasm_encoder::{ModuleSection, Module};
|
||||
///
|
||||
/// let mut modules = ModuleSection::new();
|
||||
/// modules.module(&Module::new());
|
||||
/// modules.module(&Module::new());
|
||||
///
|
||||
/// let mut module = Module::new();
|
||||
/// module.section(&modules);
|
||||
///
|
||||
/// let wasm_bytes = module.finish();
|
||||
/// ```
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct ModuleSection {
|
||||
bytes: Vec<u8>,
|
||||
num_added: u32,
|
||||
}
|
||||
|
||||
impl ModuleSection {
|
||||
/// Create a new code section encoder.
|
||||
pub fn new() -> ModuleSection {
|
||||
ModuleSection {
|
||||
bytes: vec![],
|
||||
num_added: 0,
|
||||
}
|
||||
}
|
||||
|
||||
/// How many modules have been defined inside this section so far?
|
||||
pub fn len(&self) -> u32 {
|
||||
self.num_added
|
||||
}
|
||||
|
||||
/// Writes a module into this module code section.
|
||||
pub fn module(&mut self, module: &Module) -> &mut Self {
|
||||
self.bytes.extend(
|
||||
encoders::u32(u32::try_from(module.bytes.len()).unwrap())
|
||||
.chain(module.bytes.iter().copied()),
|
||||
);
|
||||
self.num_added += 1;
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl Section for ModuleSection {
|
||||
fn id(&self) -> u8 {
|
||||
SectionId::Module.into()
|
||||
}
|
||||
|
||||
fn encode<S>(&self, sink: &mut S)
|
||||
where
|
||||
S: Extend<u8>,
|
||||
{
|
||||
let num_added = encoders::u32(self.num_added);
|
||||
let n = num_added.len();
|
||||
sink.extend(
|
||||
encoders::u32(u32::try_from(n + self.bytes.len()).unwrap())
|
||||
.chain(num_added)
|
||||
.chain(self.bytes.iter().copied()),
|
||||
);
|
||||
}
|
||||
}
|
30
third_party/rust/wasm-encoder/src/raw.rs
vendored
Normal file
30
third_party/rust/wasm-encoder/src/raw.rs
vendored
Normal file
@ -0,0 +1,30 @@
|
||||
use crate::{ComponentSection, Encode, Section};
|
||||
|
||||
/// A section made up of uninterpreted, raw bytes.
|
||||
///
|
||||
/// Allows you to splat any data into a module or component.
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
pub struct RawSection<'a> {
|
||||
/// The id for this section.
|
||||
pub id: u8,
|
||||
/// The raw data for this section.
|
||||
pub data: &'a [u8],
|
||||
}
|
||||
|
||||
impl Encode for RawSection<'_> {
|
||||
fn encode(&self, sink: &mut Vec<u8>) {
|
||||
self.data.encode(sink);
|
||||
}
|
||||
}
|
||||
|
||||
impl Section for RawSection<'_> {
|
||||
fn id(&self) -> u8 {
|
||||
self.id
|
||||
}
|
||||
}
|
||||
|
||||
impl ComponentSection for RawSection<'_> {
|
||||
fn id(&self) -> u8 {
|
||||
self.id
|
||||
}
|
||||
}
|
140
third_party/rust/wasm-encoder/src/types.rs
vendored
140
third_party/rust/wasm-encoder/src/types.rs
vendored
@ -1,140 +0,0 @@
|
||||
use super::*;
|
||||
use std::convert::TryFrom;
|
||||
|
||||
/// An encoder for the type section.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```
|
||||
/// use wasm_encoder::{Module, TypeSection, ValType};
|
||||
///
|
||||
/// let mut types = TypeSection::new();
|
||||
/// let params = vec![ValType::I32, ValType::I64];
|
||||
/// let results = vec![ValType::I32];
|
||||
/// types.function(params, results);
|
||||
///
|
||||
/// let mut module = Module::new();
|
||||
/// module.section(&types);
|
||||
///
|
||||
/// let wasm_bytes = module.finish();
|
||||
/// ```
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct TypeSection {
|
||||
bytes: Vec<u8>,
|
||||
num_added: u32,
|
||||
}
|
||||
|
||||
impl TypeSection {
|
||||
/// Create a new type section encoder.
|
||||
pub fn new() -> TypeSection {
|
||||
TypeSection {
|
||||
bytes: vec![],
|
||||
num_added: 0,
|
||||
}
|
||||
}
|
||||
|
||||
/// How many types have been defined inside this section so far?
|
||||
pub fn len(&self) -> u32 {
|
||||
self.num_added
|
||||
}
|
||||
|
||||
/// Define a function type.
|
||||
pub fn function<P, R>(&mut self, params: P, results: R) -> &mut Self
|
||||
where
|
||||
P: IntoIterator<Item = ValType>,
|
||||
P::IntoIter: ExactSizeIterator,
|
||||
R: IntoIterator<Item = ValType>,
|
||||
R::IntoIter: ExactSizeIterator,
|
||||
{
|
||||
let params = params.into_iter();
|
||||
let results = results.into_iter();
|
||||
|
||||
self.bytes.push(0x60);
|
||||
|
||||
self.bytes
|
||||
.extend(encoders::u32(u32::try_from(params.len()).unwrap()));
|
||||
self.bytes.extend(params.map(|ty| u8::from(ty)));
|
||||
|
||||
self.bytes
|
||||
.extend(encoders::u32(u32::try_from(results.len()).unwrap()));
|
||||
self.bytes.extend(results.map(|ty| u8::from(ty)));
|
||||
|
||||
self.num_added += 1;
|
||||
self
|
||||
}
|
||||
|
||||
/// Define a module type.
|
||||
pub fn module<'a, I, E>(&mut self, imports: I, exports: E) -> &mut Self
|
||||
where
|
||||
I: IntoIterator<Item = (&'a str, Option<&'a str>, EntityType)>,
|
||||
I::IntoIter: ExactSizeIterator,
|
||||
E: IntoIterator<Item = (&'a str, EntityType)>,
|
||||
E::IntoIter: ExactSizeIterator,
|
||||
{
|
||||
let exports = exports.into_iter();
|
||||
let imports = imports.into_iter();
|
||||
|
||||
self.bytes.push(0x61);
|
||||
|
||||
self.bytes
|
||||
.extend(encoders::u32(u32::try_from(imports.len()).unwrap()));
|
||||
for (module, name, ty) in imports {
|
||||
self.bytes.extend(encoders::str(module));
|
||||
match name {
|
||||
Some(name) => self.bytes.extend(encoders::str(name)),
|
||||
None => self.bytes.extend(&[0x00, 0xff]),
|
||||
}
|
||||
ty.encode(&mut self.bytes);
|
||||
}
|
||||
|
||||
self.bytes
|
||||
.extend(encoders::u32(u32::try_from(exports.len()).unwrap()));
|
||||
for (name, ty) in exports {
|
||||
self.bytes.extend(encoders::str(name));
|
||||
ty.encode(&mut self.bytes);
|
||||
}
|
||||
|
||||
self.num_added += 1;
|
||||
self
|
||||
}
|
||||
|
||||
/// Define an instance type.
|
||||
pub fn instance<'a, E>(&mut self, exports: E) -> &mut Self
|
||||
where
|
||||
E: IntoIterator<Item = (&'a str, EntityType)>,
|
||||
E::IntoIter: ExactSizeIterator,
|
||||
{
|
||||
let exports = exports.into_iter();
|
||||
|
||||
self.bytes.push(0x62);
|
||||
|
||||
self.bytes
|
||||
.extend(encoders::u32(u32::try_from(exports.len()).unwrap()));
|
||||
for (name, ty) in exports {
|
||||
self.bytes.extend(encoders::str(name));
|
||||
ty.encode(&mut self.bytes);
|
||||
}
|
||||
|
||||
self.num_added += 1;
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl Section for TypeSection {
|
||||
fn id(&self) -> u8 {
|
||||
SectionId::Type.into()
|
||||
}
|
||||
|
||||
fn encode<S>(&self, sink: &mut S)
|
||||
where
|
||||
S: Extend<u8>,
|
||||
{
|
||||
let num_added = encoders::u32(self.num_added);
|
||||
let n = num_added.len();
|
||||
sink.extend(
|
||||
encoders::u32(u32::try_from(n + self.bytes.len()).unwrap())
|
||||
.chain(num_added)
|
||||
.chain(self.bytes.iter().copied()),
|
||||
);
|
||||
}
|
||||
}
|
198
third_party/rust/wasm-encoder/tests/linking.rs
vendored
198
third_party/rust/wasm-encoder/tests/linking.rs
vendored
@ -1,198 +0,0 @@
|
||||
use anyhow::{Context, Result};
|
||||
use std::fs;
|
||||
use std::io::{self, Write};
|
||||
use std::process::{Command, Stdio};
|
||||
use wasm_encoder::*;
|
||||
|
||||
/// Run `wasm-objdump -x -j linking` on the given Wasm bytes.
|
||||
///
|
||||
/// Returns `Ok(Some(stdout))` on success, `Ok(None)` if it looks like this
|
||||
/// system doesn't have WABT installed on it (so that the caller can skip the
|
||||
/// current test), and `Err(e)` on some other kind of failure.
|
||||
fn wabt_linking_section(wasm: &[u8]) -> Result<Option<String>> {
|
||||
let tmp = tempfile::NamedTempFile::new().context("failed to create a named temp file")?;
|
||||
fs::write(tmp.path(), wasm).context("failed to write our wasm module to a temp file")?;
|
||||
|
||||
let child = match Command::new("wasm-objdump")
|
||||
.arg(tmp.path())
|
||||
.arg("-x")
|
||||
.arg("-s")
|
||||
.arg("-j")
|
||||
.arg("linking")
|
||||
.stdin(Stdio::null())
|
||||
.stderr(Stdio::null())
|
||||
.stdout(Stdio::piped())
|
||||
.spawn()
|
||||
{
|
||||
Ok(c) => c,
|
||||
Err(_) => {
|
||||
let stderr = io::stderr();
|
||||
let mut stderr = stderr.lock();
|
||||
let _ = writeln!(
|
||||
&mut stderr,
|
||||
"Warning: failed to spawn `wasm-objdump` command. Assuming WABT tools are not \
|
||||
installed on this system and ignoring this test.",
|
||||
);
|
||||
return Ok(None);
|
||||
}
|
||||
};
|
||||
|
||||
let output = child
|
||||
.wait_with_output()
|
||||
.context("failed to read wasm-objdump's stdout")?;
|
||||
let mut stdout =
|
||||
String::from_utf8(output.stdout).context("wasm-objdump did not emit UTF-8 to stdout")?;
|
||||
eprintln!(
|
||||
"====== full wasm-objdump output ======\n{}\n======================================",
|
||||
stdout
|
||||
);
|
||||
|
||||
// Trim the prefix output before the linking section dump (which includes
|
||||
// the name of the tempfile, so we can't have it in here).
|
||||
let i = stdout.find(" - name: \"linking\"\n").ok_or_else(|| {
|
||||
anyhow::anyhow!("could not find linking section dump in wasm-objdump output")
|
||||
})?;
|
||||
let mut stdout = stdout.split_off(i);
|
||||
|
||||
// Trim the hexdump of the custom section. While this is useful to have in
|
||||
// the `stderr` logging above when debugging tests, we don't want it
|
||||
// repeated in our test assertions.
|
||||
let i = stdout
|
||||
.find("\n\nContents of section Custom:\n")
|
||||
.ok_or_else(|| {
|
||||
anyhow::anyhow!("could not find contents of custom section in wasm-objdump output")
|
||||
})?;
|
||||
let _ = stdout.split_off(i);
|
||||
|
||||
Ok(Some(stdout))
|
||||
}
|
||||
|
||||
fn assert_wabt_linking(linking: &LinkingSection, expected_wabt_dump: &str) -> Result<()> {
|
||||
let mut module = Module::new();
|
||||
module.section(linking);
|
||||
let wasm = module.finish();
|
||||
|
||||
if let Some(actual_wabt_dump) = wabt_linking_section(&wasm)? {
|
||||
assert_eq!(expected_wabt_dump.trim(), actual_wabt_dump.trim());
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn sym_tab_function() -> Result<()> {
|
||||
let mut sym_tab = SymbolTable::new();
|
||||
sym_tab.function(0, 42, Some("func"));
|
||||
|
||||
let mut linking = LinkingSection::new();
|
||||
linking.symbol_table(&sym_tab);
|
||||
|
||||
assert_wabt_linking(
|
||||
&linking,
|
||||
"
|
||||
- name: \"linking\"
|
||||
- symbol table [count=1]
|
||||
- 0: F <func> func=42 [ binding=global vis=default ]
|
||||
",
|
||||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn sym_tab_flags() -> Result<()> {
|
||||
let mut sym_tab = SymbolTable::new();
|
||||
sym_tab.function(
|
||||
SymbolTable::WASM_SYM_BINDING_WEAK | SymbolTable::WASM_SYM_VISIBILITY_HIDDEN,
|
||||
1337,
|
||||
Some("func"),
|
||||
);
|
||||
|
||||
let mut linking = LinkingSection::new();
|
||||
linking.symbol_table(&sym_tab);
|
||||
|
||||
assert_wabt_linking(
|
||||
&linking,
|
||||
"
|
||||
- name: \"linking\"
|
||||
- symbol table [count=1]
|
||||
- 0: F <func> func=1337 [ binding=weak vis=hidden ]
|
||||
",
|
||||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn sym_tab_global() -> Result<()> {
|
||||
let mut sym_tab = SymbolTable::new();
|
||||
sym_tab.global(0, 42, Some("my_global"));
|
||||
|
||||
let mut linking = LinkingSection::new();
|
||||
linking.symbol_table(&sym_tab);
|
||||
|
||||
assert_wabt_linking(
|
||||
&linking,
|
||||
"
|
||||
- name: \"linking\"
|
||||
- symbol table [count=1]
|
||||
- 0: G <my_global> global=42 [ binding=global vis=default ]",
|
||||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn sym_tab_table() -> Result<()> {
|
||||
let mut sym_tab = SymbolTable::new();
|
||||
sym_tab.table(0, 42, Some("my_table"));
|
||||
|
||||
let mut linking = LinkingSection::new();
|
||||
linking.symbol_table(&sym_tab);
|
||||
|
||||
assert_wabt_linking(
|
||||
&linking,
|
||||
"
|
||||
- name: \"linking\"
|
||||
- symbol table [count=1]
|
||||
- 0: T <my_table> table=42 [ binding=global vis=default ]",
|
||||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn sym_tab_data_defined() -> Result<()> {
|
||||
let mut sym_tab = SymbolTable::new();
|
||||
sym_tab.data(
|
||||
0,
|
||||
"my_data",
|
||||
Some(DataSymbolDefinition {
|
||||
index: 42,
|
||||
offset: 1337,
|
||||
size: 1234,
|
||||
}),
|
||||
);
|
||||
|
||||
let mut linking = LinkingSection::new();
|
||||
linking.symbol_table(&sym_tab);
|
||||
|
||||
assert_wabt_linking(
|
||||
&linking,
|
||||
"
|
||||
- name: \"linking\"
|
||||
- symbol table [count=1]
|
||||
- 0: D <my_data> segment=42 offset=1337 size=1234 [ binding=global vis=default ]
|
||||
",
|
||||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn sym_tab_data_undefined() -> Result<()> {
|
||||
let mut sym_tab = SymbolTable::new();
|
||||
sym_tab.data(SymbolTable::WASM_SYM_UNDEFINED, "my_data", None);
|
||||
|
||||
let mut linking = LinkingSection::new();
|
||||
linking.symbol_table(&sym_tab);
|
||||
|
||||
assert_wabt_linking(
|
||||
&linking,
|
||||
"
|
||||
- name: \"linking\"
|
||||
- symbol table [count=1]
|
||||
- 0: D <my_data> [ undefined binding=global vis=default ]
|
||||
",
|
||||
)
|
||||
}
|
@ -1 +1 @@
|
||||
{"files":{"Cargo.toml":"ef414c81e8535129ca20ac5d14a376ae9718ad49f5565e93aea462a32b395fa1","LICENSE":"268872b9816f90fd8e85db5a28d33f8150ebb8dd016653fb39ef1f94f2686bc5","README.md":"9948cd1d106d8632025da5d9fc5b9d43da8f5591b16074fc10b5638840d3cd18","benches/corpus.rs":"2df29556be0799f0cb1f32c8d0ae5ba0c4b9815cf4d59a8b71744d926c0693a0","src/code_builder.rs":"d3ff894119bf379fd2188ab897a8dbec86aa12e09e0ccf1045cf9d9b0fd71fcc","src/config.rs":"c0d9c6406e224bded23dc63ca6201a2d91ef9be2f4912f8b2fca91fc1d9363e0","src/encode.rs":"51cbb1432b9a32b5be9257045c7ee23852f36b3559d7bddb3eb7abbbd88e87e6","src/lib.rs":"c55373dd6f62d157d238032941c19ce14f94b9aba1423559d7d691ba7e187964","src/terminate.rs":"dd23771541c966770823e67e350e22390f777d4bc39c1fdbabf4ed13a3b1c6b4","tests/tests.rs":"6ea31f083d7c01d09310203abb1428d323c077dd024fe45049dff77b20625338"},"package":"440458e050ee2731e85af3368ee58e23d4728d597809a88f841a24778876f2b6"}
|
||||
{"files":{"Cargo.toml":"41e7bfa4b5f89f5c3db096de0799cef34ccbc378bd8bca4e444199be6135b625","LICENSE":"268872b9816f90fd8e85db5a28d33f8150ebb8dd016653fb39ef1f94f2686bc5","README.md":"9948cd1d106d8632025da5d9fc5b9d43da8f5591b16074fc10b5638840d3cd18","benches/corpus.rs":"2df29556be0799f0cb1f32c8d0ae5ba0c4b9815cf4d59a8b71744d926c0693a0","src/component.rs":"18f354f335cf84f49f70e1c8c3ad6b272df9b6c6aa6051112ca30b5fd4f63346","src/component/encode.rs":"4905a5efc695ad6e0aae306907ed033d85804cc9e4dfee04d823df47e64acdd0","src/config.rs":"4f2bddb2c9c5c7c16959cd88590965987a177ed029be9267e9a57a9be49f9fde","src/core.rs":"b961e48e975effa1cb273b998062f31d8672a06bec4a76e5168703bf8c543f3c","src/core/code_builder.rs":"35dc4e5bfa4a204a7354b630f71c215b9ae849bc1826279b4e5d8d6e1d16397b","src/core/encode.rs":"560dae224942d768d325f15d732f0a8336171b52b76e5dc07356b1e5e7528ce5","src/core/terminate.rs":"f3fdc4fdc93300417762f05764c5b68e614737adc7749bf3dd49186a1a42b1e9","src/lib.rs":"5230cdd1bfd6f668ea97282702c07fe0d3232da8e8f5a4d89a9f7053d4836a12","tests/component.rs":"54c69ebdda583207f9f0467a600ee0ca87fbee6b365e97ec3deff7b46bd6af06","tests/core.rs":"c595640db5619db703e0f8f08e0aa7426f8b8a8cf70654cac226c80a876fc3e4"},"package":"b73250e61e41d0e467b78559c7d761841005d724384bb0b78d52ff974acf5520"}
|
39
third_party/rust/wasm-smith/Cargo.toml
vendored
39
third_party/rust/wasm-smith/Cargo.toml
vendored
@ -10,33 +10,52 @@
|
||||
# See Cargo.toml.orig for the original contents.
|
||||
|
||||
[package]
|
||||
edition = "2018"
|
||||
edition = "2021"
|
||||
name = "wasm-smith"
|
||||
version = "0.8.0"
|
||||
version = "0.11.2"
|
||||
authors = ["Nick Fitzgerald <fitzgen@gmail.com>"]
|
||||
exclude = ["/benches/corpus"]
|
||||
description = "A WebAssembly test case generator"
|
||||
documentation = "https://docs.rs/wasm-smith"
|
||||
readme = "./README.md"
|
||||
categories = ["command-line-utilities", "development-tools", "development-tools::testing", "wasm"]
|
||||
categories = [
|
||||
"command-line-utilities",
|
||||
"development-tools",
|
||||
"development-tools::testing",
|
||||
"wasm",
|
||||
]
|
||||
license = "Apache-2.0 WITH LLVM-exception"
|
||||
repository = "https://github.com/bytecodealliance/wasm-tools"
|
||||
repository = "https://github.com/bytecodealliance/wasm-tools/tree/main/crates/wasm-smith"
|
||||
resolver = "2"
|
||||
|
||||
[[bench]]
|
||||
name = "corpus"
|
||||
harness = false
|
||||
|
||||
[dependencies.arbitrary]
|
||||
version = "1.0.0"
|
||||
version = "1.1.0"
|
||||
features = ["derive"]
|
||||
|
||||
[dependencies.flagset]
|
||||
version = "0.4"
|
||||
|
||||
[dependencies.indexmap]
|
||||
version = "1.6"
|
||||
|
||||
[dependencies.leb128]
|
||||
version = "0.2.4"
|
||||
|
||||
[dependencies.serde]
|
||||
version = "1"
|
||||
features = ["derive"]
|
||||
optional = true
|
||||
|
||||
[dependencies.wasm-encoder]
|
||||
version = "0.7.0"
|
||||
version = "0.14.0"
|
||||
|
||||
[dependencies.wasmparser]
|
||||
version = "0.87.0"
|
||||
|
||||
[dev-dependencies.criterion]
|
||||
version = "0.3.3"
|
||||
|
||||
@ -44,5 +63,11 @@ version = "0.3.3"
|
||||
version = "0.4.0"
|
||||
|
||||
[dev-dependencies.rand]
|
||||
version = "0.7.3"
|
||||
version = "0.8.0"
|
||||
features = ["small_rng"]
|
||||
|
||||
[features]
|
||||
_internal_cli = [
|
||||
"serde",
|
||||
"flagset/serde",
|
||||
]
|
||||
|
2187
third_party/rust/wasm-smith/src/component.rs
vendored
Normal file
2187
third_party/rust/wasm-smith/src/component.rs
vendored
Normal file
File diff suppressed because it is too large
Load Diff
301
third_party/rust/wasm-smith/src/component/encode.rs
vendored
Normal file
301
third_party/rust/wasm-smith/src/component/encode.rs
vendored
Normal file
@ -0,0 +1,301 @@
|
||||
use super::*;
|
||||
|
||||
impl Component {
|
||||
/// Encode this Wasm component into bytes.
|
||||
pub fn to_bytes(&self) -> Vec<u8> {
|
||||
self.encoded().finish()
|
||||
}
|
||||
|
||||
fn encoded(&self) -> wasm_encoder::Component {
|
||||
let mut component = wasm_encoder::Component::new();
|
||||
for section in &self.sections {
|
||||
section.encode(&mut component);
|
||||
}
|
||||
component
|
||||
}
|
||||
}
|
||||
|
||||
impl Section {
|
||||
fn encode(&self, component: &mut wasm_encoder::Component) {
|
||||
match self {
|
||||
Self::Custom(sec) => sec.encode(component),
|
||||
Self::CoreModule(module) => {
|
||||
let bytes = module.to_bytes();
|
||||
component.section(&wasm_encoder::RawSection {
|
||||
id: wasm_encoder::ComponentSectionId::CoreModule as u8,
|
||||
data: &bytes,
|
||||
});
|
||||
}
|
||||
Self::CoreInstance(_) => todo!(),
|
||||
Self::CoreAlias(_) => todo!(),
|
||||
Self::CoreType(sec) => sec.encode(component),
|
||||
Self::Component(comp) => {
|
||||
let bytes = comp.to_bytes();
|
||||
component.section(&wasm_encoder::RawSection {
|
||||
id: wasm_encoder::ComponentSectionId::Component as u8,
|
||||
data: &bytes,
|
||||
});
|
||||
}
|
||||
Self::Instance(_) => todo!(),
|
||||
Self::Alias(_) => todo!(),
|
||||
Self::Type(sec) => sec.encode(component),
|
||||
Self::Canonical(sec) => sec.encode(component),
|
||||
Self::Start(_) => todo!(),
|
||||
Self::Import(sec) => sec.encode(component),
|
||||
Self::Export(_) => todo!(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl CustomSection {
|
||||
fn encode(&self, component: &mut wasm_encoder::Component) {
|
||||
component.section(&wasm_encoder::CustomSection {
|
||||
name: &self.name,
|
||||
data: &self.data,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
impl TypeSection {
|
||||
fn encode(&self, component: &mut wasm_encoder::Component) {
|
||||
let mut sec = wasm_encoder::ComponentTypeSection::new();
|
||||
for ty in &self.types {
|
||||
ty.encode(sec.ty());
|
||||
}
|
||||
component.section(&sec);
|
||||
}
|
||||
}
|
||||
|
||||
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.ty);
|
||||
}
|
||||
component.section(&sec);
|
||||
}
|
||||
}
|
||||
|
||||
impl CanonicalSection {
|
||||
fn encode(&self, component: &mut wasm_encoder::Component) {
|
||||
let mut sec = wasm_encoder::CanonicalFunctionSection::new();
|
||||
for func in &self.funcs {
|
||||
match func {
|
||||
Func::CanonLift {
|
||||
func_ty,
|
||||
options,
|
||||
core_func_index,
|
||||
} => {
|
||||
let options = translate_canon_opt(options);
|
||||
sec.lift(*core_func_index, *func_ty, options);
|
||||
}
|
||||
Func::CanonLower {
|
||||
options,
|
||||
func_index,
|
||||
} => {
|
||||
let options = translate_canon_opt(options);
|
||||
sec.lower(*func_index, options);
|
||||
}
|
||||
}
|
||||
}
|
||||
component.section(&sec);
|
||||
}
|
||||
}
|
||||
|
||||
impl CoreTypeSection {
|
||||
fn encode(&self, component: &mut wasm_encoder::Component) {
|
||||
let mut sec = wasm_encoder::CoreTypeSection::new();
|
||||
for ty in &self.types {
|
||||
ty.encode(sec.ty());
|
||||
}
|
||||
component.section(&sec);
|
||||
}
|
||||
}
|
||||
|
||||
impl CoreType {
|
||||
fn encode(&self, enc: wasm_encoder::CoreTypeEncoder<'_>) {
|
||||
match self {
|
||||
Self::Func(ty) => {
|
||||
enc.function(ty.params.iter().copied(), ty.results.iter().copied());
|
||||
}
|
||||
Self::Module(mod_ty) => {
|
||||
let mut enc_mod_ty = wasm_encoder::ModuleType::new();
|
||||
for def in &mod_ty.defs {
|
||||
match def {
|
||||
ModuleTypeDef::TypeDef(crate::core::Type::Func(func_ty)) => {
|
||||
enc_mod_ty.ty().function(
|
||||
func_ty.params.iter().copied(),
|
||||
func_ty.results.iter().copied(),
|
||||
);
|
||||
}
|
||||
ModuleTypeDef::Alias(alias) => match alias {
|
||||
CoreAlias::Outer {
|
||||
count,
|
||||
i,
|
||||
kind: CoreOuterAliasKind::Type(_),
|
||||
} => {
|
||||
enc_mod_ty.alias_outer_core_type(*count, *i);
|
||||
}
|
||||
CoreAlias::InstanceExport { .. } => unreachable!(),
|
||||
},
|
||||
ModuleTypeDef::Import(imp) => {
|
||||
enc_mod_ty.import(
|
||||
&imp.module,
|
||||
&imp.field,
|
||||
crate::core::encode::translate_entity_type(&imp.entity_type),
|
||||
);
|
||||
}
|
||||
ModuleTypeDef::Export(name, ty) => {
|
||||
enc_mod_ty.export(name, crate::core::encode::translate_entity_type(ty));
|
||||
}
|
||||
}
|
||||
}
|
||||
enc.module(&enc_mod_ty);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Type {
|
||||
fn encode(&self, enc: wasm_encoder::ComponentTypeEncoder<'_>) {
|
||||
match self {
|
||||
Self::Defined(ty) => {
|
||||
ty.encode(enc.defined_type());
|
||||
}
|
||||
Self::Func(func_ty) => {
|
||||
enc.function(
|
||||
func_ty.params.iter().map(translate_optional_named_type),
|
||||
func_ty.result,
|
||||
);
|
||||
}
|
||||
Self::Component(comp_ty) => {
|
||||
let mut enc_comp_ty = wasm_encoder::ComponentType::new();
|
||||
for def in &comp_ty.defs {
|
||||
match def {
|
||||
ComponentTypeDef::Import(imp) => {
|
||||
enc_comp_ty.import(&imp.name, imp.ty);
|
||||
}
|
||||
ComponentTypeDef::CoreType(ty) => {
|
||||
ty.encode(enc_comp_ty.core_type());
|
||||
}
|
||||
ComponentTypeDef::Type(ty) => {
|
||||
ty.encode(enc_comp_ty.ty());
|
||||
}
|
||||
ComponentTypeDef::Export { name, ty } => {
|
||||
enc_comp_ty.export(name, *ty);
|
||||
}
|
||||
ComponentTypeDef::Alias(Alias::Outer {
|
||||
count,
|
||||
i,
|
||||
kind: OuterAliasKind::Type(_),
|
||||
}) => {
|
||||
enc_comp_ty.alias_outer_type(*count, *i);
|
||||
}
|
||||
ComponentTypeDef::Alias(Alias::Outer {
|
||||
count,
|
||||
i,
|
||||
kind: OuterAliasKind::CoreType(_),
|
||||
}) => {
|
||||
enc_comp_ty.alias_outer_core_type(*count, *i);
|
||||
}
|
||||
ComponentTypeDef::Alias(_) => unreachable!(),
|
||||
}
|
||||
}
|
||||
enc.component(&enc_comp_ty);
|
||||
}
|
||||
Self::Instance(inst_ty) => {
|
||||
let mut enc_inst_ty = wasm_encoder::InstanceType::new();
|
||||
for def in &inst_ty.defs {
|
||||
match def {
|
||||
InstanceTypeDef::CoreType(ty) => {
|
||||
ty.encode(enc_inst_ty.core_type());
|
||||
}
|
||||
InstanceTypeDef::Type(ty) => {
|
||||
ty.encode(enc_inst_ty.ty());
|
||||
}
|
||||
InstanceTypeDef::Export { name, ty } => {
|
||||
enc_inst_ty.export(name, *ty);
|
||||
}
|
||||
InstanceTypeDef::Alias(Alias::Outer {
|
||||
count,
|
||||
i,
|
||||
kind: OuterAliasKind::Type(_),
|
||||
}) => {
|
||||
enc_inst_ty.alias_outer_type(*count, *i);
|
||||
}
|
||||
InstanceTypeDef::Alias(Alias::Outer {
|
||||
count,
|
||||
i,
|
||||
kind: OuterAliasKind::CoreType(_),
|
||||
}) => {
|
||||
enc_inst_ty.alias_outer_core_type(*count, *i);
|
||||
}
|
||||
InstanceTypeDef::Alias(_) => unreachable!(),
|
||||
}
|
||||
}
|
||||
enc.instance(&enc_inst_ty);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl DefinedType {
|
||||
fn encode(&self, enc: wasm_encoder::ComponentDefinedTypeEncoder<'_>) {
|
||||
match self {
|
||||
Self::Primitive(ty) => enc.primitive(*ty),
|
||||
Self::Record(ty) => {
|
||||
enc.record(ty.fields.iter().map(translate_named_type));
|
||||
}
|
||||
Self::Variant(ty) => {
|
||||
enc.variant(
|
||||
ty.cases
|
||||
.iter()
|
||||
.map(|(ty, refines)| (ty.name.as_str(), ty.ty, *refines)),
|
||||
);
|
||||
}
|
||||
Self::List(ty) => {
|
||||
enc.list(ty.elem_ty);
|
||||
}
|
||||
Self::Tuple(ty) => {
|
||||
enc.tuple(ty.fields.iter().copied());
|
||||
}
|
||||
Self::Flags(ty) => {
|
||||
enc.flags(ty.fields.iter().map(|f| f.as_str()));
|
||||
}
|
||||
Self::Enum(ty) => {
|
||||
enc.enum_type(ty.variants.iter().map(|v| v.as_str()));
|
||||
}
|
||||
Self::Union(ty) => {
|
||||
enc.union(ty.variants.iter().copied());
|
||||
}
|
||||
Self::Option(ty) => {
|
||||
enc.option(ty.inner_ty);
|
||||
}
|
||||
Self::Expected(ty) => {
|
||||
enc.expected(ty.ok_ty, ty.err_ty);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn translate_named_type(ty: &NamedType) -> (&str, ComponentValType) {
|
||||
(&ty.name, ty.ty)
|
||||
}
|
||||
|
||||
fn translate_optional_named_type(ty: &OptionalNamedType) -> (Option<&str>, ComponentValType) {
|
||||
(ty.name.as_deref(), ty.ty)
|
||||
}
|
||||
|
||||
fn translate_canon_opt(options: &[CanonOpt]) -> Vec<wasm_encoder::CanonicalOption> {
|
||||
options
|
||||
.iter()
|
||||
.map(|o| match o {
|
||||
CanonOpt::StringUtf8 => wasm_encoder::CanonicalOption::UTF8,
|
||||
CanonOpt::StringUtf16 => wasm_encoder::CanonicalOption::UTF16,
|
||||
CanonOpt::StringLatin1Utf16 => wasm_encoder::CanonicalOption::CompactUTF16,
|
||||
CanonOpt::Memory(idx) => wasm_encoder::CanonicalOption::Memory(*idx),
|
||||
CanonOpt::Realloc(idx) => wasm_encoder::CanonicalOption::Realloc(*idx),
|
||||
CanonOpt::PostReturn(idx) => wasm_encoder::CanonicalOption::PostReturn(*idx),
|
||||
})
|
||||
.collect()
|
||||
}
|
299
third_party/rust/wasm-smith/src/config.rs
vendored
299
third_party/rust/wasm-smith/src/config.rs
vendored
@ -1,6 +1,8 @@
|
||||
//! Configuring the shape of generated Wasm modules.
|
||||
|
||||
use crate::InstructionKinds;
|
||||
use arbitrary::{Arbitrary, Result, Unstructured};
|
||||
use std::borrow::Cow;
|
||||
|
||||
/// Configuration for a generated module.
|
||||
///
|
||||
@ -58,6 +60,41 @@ pub trait Config: 'static + std::fmt::Debug {
|
||||
100
|
||||
}
|
||||
|
||||
/// The imports that may be used when generating the module.
|
||||
///
|
||||
/// Defaults to `None` which means that any arbitrary import can be generated.
|
||||
///
|
||||
/// To only allow specific imports, override this method to return a WebAssembly module which
|
||||
/// describes the imports allowed.
|
||||
///
|
||||
/// Note that [`Self::min_imports`] is ignored when `available_imports` are enabled.
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// The returned value must be a valid binary encoding of a WebAssembly module. `wasm-smith`
|
||||
/// will panic if the module cannot be parsed.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// An implementation of this method could use the `wat` crate to provide a human-readable and
|
||||
/// maintainable description:
|
||||
///
|
||||
/// ```rust
|
||||
/// Some(wat::parse_str(r#"
|
||||
/// (module
|
||||
/// (import "env" "ping" (func (param i32)))
|
||||
/// (import "env" "pong" (func (result i32)))
|
||||
/// (import "env" "memory" (memory 1))
|
||||
/// (import "env" "table" (table 1))
|
||||
/// (import "env" "tag" (tag (param i32)))
|
||||
/// )
|
||||
/// "#))
|
||||
/// # ;
|
||||
/// ```
|
||||
fn available_imports(&self) -> Option<Cow<'_, [u8]>> {
|
||||
None
|
||||
}
|
||||
|
||||
/// The minimum number of functions to generate. Defaults to 0. This
|
||||
/// includes imported functions.
|
||||
fn min_funcs(&self) -> usize {
|
||||
@ -92,6 +129,12 @@ pub trait Config: 'static + std::fmt::Debug {
|
||||
100
|
||||
}
|
||||
|
||||
/// Export all WebAssembly objects in the module. This overrides
|
||||
/// [`Config::min_exports`] and [`Config::max_exports`]. Defaults to false.
|
||||
fn export_everything(&self) -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
/// The minimum number of element segments to generate. Defaults to 0.
|
||||
fn min_element_segments(&self) -> usize {
|
||||
0
|
||||
@ -180,6 +223,19 @@ pub trait Config: 'static + std::fmt::Debug {
|
||||
false
|
||||
}
|
||||
|
||||
/// The maximum, elements, of any table's initial or maximum size.
|
||||
///
|
||||
/// Defaults to 1 million.
|
||||
fn max_table_elements(&self) -> u32 {
|
||||
1_000_000
|
||||
}
|
||||
|
||||
/// Whether every Wasm table must have a maximum size specified. Defaults
|
||||
/// to `false`.
|
||||
fn table_max_size_required(&self) -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
/// The maximum number of instances to use. Defaults to 10. This includes
|
||||
/// imported instances.
|
||||
///
|
||||
@ -191,11 +247,27 @@ pub trait Config: 'static + std::fmt::Debug {
|
||||
/// The maximum number of modules to use. Defaults to 10. This includes
|
||||
/// imported modules.
|
||||
///
|
||||
/// Note that this is irrelevant unless module linking is enabled.
|
||||
/// Note that this is irrelevant unless component model support is enabled.
|
||||
fn max_modules(&self) -> usize {
|
||||
10
|
||||
}
|
||||
|
||||
/// The maximum number of components to use. Defaults to 10. This includes
|
||||
/// imported components.
|
||||
///
|
||||
/// Note that this is irrelevant unless component model support is enabled.
|
||||
fn max_components(&self) -> usize {
|
||||
10
|
||||
}
|
||||
|
||||
/// The maximum number of values to use. Defaults to 10. This includes
|
||||
/// imported values.
|
||||
///
|
||||
/// Note that this is irrelevant unless value model support is enabled.
|
||||
fn max_values(&self) -> usize {
|
||||
10
|
||||
}
|
||||
|
||||
/// Control the probability of generating memory offsets that are in bounds
|
||||
/// vs. potentially out of bounds.
|
||||
///
|
||||
@ -236,34 +308,64 @@ pub trait Config: 'static + std::fmt::Debug {
|
||||
}
|
||||
|
||||
/// Determines whether the bulk memory proposal is enabled for generating
|
||||
/// insructions. Defaults to `false`.
|
||||
/// instructions.
|
||||
///
|
||||
/// Defaults to `false`.
|
||||
fn bulk_memory_enabled(&self) -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
/// Determines whether the reference types proposal is enabled for
|
||||
/// generating insructions. Defaults to `false`.
|
||||
/// generating instructions.
|
||||
///
|
||||
/// Defaults to `false`.
|
||||
fn reference_types_enabled(&self) -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
/// Determines whether the SIMD proposal is enabled for
|
||||
/// generating insructions. Defaults to `false`.
|
||||
/// generating instructions.
|
||||
///
|
||||
/// Defaults to `false`.
|
||||
fn simd_enabled(&self) -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
/// Determines whether the Relaxed SIMD proposal is enabled for
|
||||
/// generating instructions.
|
||||
///
|
||||
/// Defaults to `false`.
|
||||
fn relaxed_simd_enabled(&self) -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
/// Determines whether the exception-handling proposal is enabled for
|
||||
/// generating insructions. Defaults to `false`.
|
||||
/// generating instructions.
|
||||
///
|
||||
/// Defaults to `false`.
|
||||
fn exceptions_enabled(&self) -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
/// Determines whether the module linking proposal is enabled.
|
||||
/// Determines whether the multi-value results are enabled.
|
||||
///
|
||||
/// Defaults to `false`.
|
||||
fn module_linking_enabled(&self) -> bool {
|
||||
false
|
||||
/// Defaults to `true`.
|
||||
fn multi_value_enabled(&self) -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
/// Determines whether the nontrapping-float-to-int-conversions propsal is enabled.
|
||||
///
|
||||
/// Defaults to `true`.
|
||||
fn saturating_float_to_int_enabled(&self) -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
/// Determines whether the sign-extension-ops propsal is enabled.
|
||||
///
|
||||
/// Defaults to `true`.
|
||||
fn sign_extension_ops_enabled(&self) -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
/// Determines whether a `start` export may be included. Defaults to `true`.
|
||||
@ -313,6 +415,40 @@ pub trait Config: 'static + std::fmt::Debug {
|
||||
fn canonicalize_nans(&self) -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
/// Returns the kinds of instructions allowed in the generated wasm
|
||||
/// programs.
|
||||
///
|
||||
/// The categories of instructions match the categories used by the
|
||||
/// [WebAssembly
|
||||
/// specification](https://webassembly.github.io/spec/core/syntax/instructions.html);
|
||||
/// e.g., numeric, vector, control, memory, etc. Note that modifying this
|
||||
/// setting is separate from the proposal flags; that is, if `simd_enabled()
|
||||
/// == true` but `allowed_instruction()` does not include vector
|
||||
/// instructions, the generated programs will not include these instructions
|
||||
/// but could contain vector types.
|
||||
fn allowed_instructions(&self) -> InstructionKinds {
|
||||
InstructionKinds::all()
|
||||
}
|
||||
|
||||
/// Returns whether we should generate custom sections or not.
|
||||
///
|
||||
/// This is false by default.
|
||||
fn generate_custom_sections(&self) -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
/// Determines whether the threads proposal is enabled.
|
||||
///
|
||||
/// The [threads proposal] involves shared linear memory, new atomic
|
||||
/// instructions, and new `wait` and `notify` instructions.
|
||||
///
|
||||
/// [threads proposal]: https://github.com/WebAssembly/threads/blob/master/proposals/threads/Overview.md
|
||||
///
|
||||
/// Defaults to `false`.
|
||||
fn threads_enabled(&self) -> bool {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
/// The default configuration.
|
||||
@ -336,50 +472,57 @@ impl Config for DefaultConfig {}
|
||||
#[derive(Clone, Debug)]
|
||||
#[allow(missing_docs)]
|
||||
pub struct SwarmConfig {
|
||||
// These fields are configured via `Arbitrary`
|
||||
pub max_types: usize,
|
||||
pub max_imports: usize,
|
||||
pub max_tags: usize,
|
||||
pub max_funcs: usize,
|
||||
pub max_globals: usize,
|
||||
pub max_exports: usize,
|
||||
pub allow_start_export: bool,
|
||||
pub available_imports: Option<Vec<u8>>,
|
||||
pub bulk_memory_enabled: bool,
|
||||
pub canonicalize_nans: bool,
|
||||
pub exceptions_enabled: bool,
|
||||
pub export_everything: bool,
|
||||
pub max_aliases: usize,
|
||||
pub max_components: usize,
|
||||
pub max_data_segments: usize,
|
||||
pub max_element_segments: usize,
|
||||
pub max_elements: usize,
|
||||
pub max_data_segments: usize,
|
||||
pub max_exports: usize,
|
||||
pub max_funcs: usize,
|
||||
pub max_globals: usize,
|
||||
pub max_imports: usize,
|
||||
pub max_instances: usize,
|
||||
pub max_instructions: usize,
|
||||
pub max_memories: usize,
|
||||
pub min_uleb_size: u8,
|
||||
pub max_tables: usize,
|
||||
pub max_memory_pages: u64,
|
||||
pub bulk_memory_enabled: bool,
|
||||
pub reference_types_enabled: bool,
|
||||
pub module_linking_enabled: bool,
|
||||
pub max_aliases: usize,
|
||||
pub max_modules: usize,
|
||||
pub max_nesting_depth: usize,
|
||||
|
||||
// These fields are always set to their default value as specified in the
|
||||
// default trait implementation.
|
||||
pub max_tables: usize,
|
||||
pub max_tags: usize,
|
||||
pub max_type_size: u32,
|
||||
pub max_types: usize,
|
||||
pub max_values: usize,
|
||||
pub memory64_enabled: bool,
|
||||
pub min_types: usize,
|
||||
pub min_imports: usize,
|
||||
pub min_tags: usize,
|
||||
pub min_funcs: usize,
|
||||
pub min_globals: usize,
|
||||
pub min_exports: usize,
|
||||
pub memory_max_size_required: bool,
|
||||
pub memory_offset_choices: (u32, u32, u32),
|
||||
pub min_data_segments: usize,
|
||||
pub min_element_segments: usize,
|
||||
pub min_elements: usize,
|
||||
pub min_exports: usize,
|
||||
pub min_funcs: usize,
|
||||
pub min_globals: usize,
|
||||
pub min_imports: usize,
|
||||
pub min_memories: u32,
|
||||
pub min_tables: u32,
|
||||
pub max_instances: usize,
|
||||
pub max_modules: usize,
|
||||
pub memory_offset_choices: (u32, u32, u32),
|
||||
pub memory_max_size_required: bool,
|
||||
pub min_tags: usize,
|
||||
pub min_types: usize,
|
||||
pub min_uleb_size: u8,
|
||||
pub multi_value_enabled: bool,
|
||||
pub reference_types_enabled: bool,
|
||||
pub relaxed_simd_enabled: bool,
|
||||
pub saturating_float_to_int_enabled: bool,
|
||||
pub sign_extension_enabled: bool,
|
||||
pub simd_enabled: bool,
|
||||
pub exceptions_enabled: bool,
|
||||
pub allow_start_export: bool,
|
||||
pub max_type_size: u32,
|
||||
pub canonicalize_nans: bool,
|
||||
pub threads_enabled: bool,
|
||||
pub allowed_instructions: InstructionKinds,
|
||||
pub max_table_elements: u32,
|
||||
pub table_max_size_required: bool,
|
||||
}
|
||||
|
||||
impl<'a> Arbitrary<'a> for SwarmConfig {
|
||||
@ -404,10 +547,26 @@ impl<'a> Arbitrary<'a> for SwarmConfig {
|
||||
max_tables,
|
||||
max_memory_pages: u.arbitrary()?,
|
||||
min_uleb_size: u.int_in_range(0..=5)?,
|
||||
bulk_memory_enabled: u.arbitrary()?,
|
||||
bulk_memory_enabled: reference_types_enabled || u.arbitrary()?,
|
||||
reference_types_enabled,
|
||||
simd_enabled: u.arbitrary()?,
|
||||
multi_value_enabled: u.arbitrary()?,
|
||||
max_aliases: u.int_in_range(0..=MAX_MAXIMUM)?,
|
||||
max_nesting_depth: u.int_in_range(0..=10)?,
|
||||
saturating_float_to_int_enabled: u.arbitrary()?,
|
||||
sign_extension_enabled: u.arbitrary()?,
|
||||
allowed_instructions: {
|
||||
use flagset::Flags;
|
||||
let mut allowed = Vec::new();
|
||||
for kind in crate::core::InstructionKind::LIST {
|
||||
if u.arbitrary()? {
|
||||
allowed.push(*kind);
|
||||
}
|
||||
}
|
||||
InstructionKinds::new(&allowed)
|
||||
},
|
||||
table_max_size_required: u.arbitrary()?,
|
||||
max_table_elements: u.int_in_range(0..=1_000_000)?,
|
||||
|
||||
// These fields, unlike the ones above, are less useful to set.
|
||||
// They either make weird inputs or are for features not widely
|
||||
@ -426,14 +585,18 @@ impl<'a> Arbitrary<'a> for SwarmConfig {
|
||||
memory_max_size_required: false,
|
||||
max_instances: 0,
|
||||
max_modules: 0,
|
||||
max_components: 0,
|
||||
max_values: 0,
|
||||
memory_offset_choices: (75, 24, 1),
|
||||
allow_start_export: true,
|
||||
simd_enabled: false,
|
||||
relaxed_simd_enabled: false,
|
||||
exceptions_enabled: false,
|
||||
memory64_enabled: false,
|
||||
max_type_size: 1000,
|
||||
module_linking_enabled: false,
|
||||
canonicalize_nans: false,
|
||||
available_imports: None,
|
||||
threads_enabled: false,
|
||||
export_everything: false,
|
||||
})
|
||||
}
|
||||
}
|
||||
@ -455,6 +618,12 @@ impl Config for SwarmConfig {
|
||||
self.max_imports
|
||||
}
|
||||
|
||||
fn available_imports(&self) -> Option<Cow<'_, [u8]>> {
|
||||
self.available_imports
|
||||
.as_ref()
|
||||
.map(|is| Cow::Borrowed(&is[..]))
|
||||
}
|
||||
|
||||
fn min_funcs(&self) -> usize {
|
||||
self.min_funcs
|
||||
}
|
||||
@ -479,6 +648,10 @@ impl Config for SwarmConfig {
|
||||
self.max_exports
|
||||
}
|
||||
|
||||
fn export_everything(&self) -> bool {
|
||||
self.export_everything
|
||||
}
|
||||
|
||||
fn min_element_segments(&self) -> usize {
|
||||
self.min_element_segments
|
||||
}
|
||||
@ -559,18 +732,30 @@ impl Config for SwarmConfig {
|
||||
self.reference_types_enabled
|
||||
}
|
||||
|
||||
fn module_linking_enabled(&self) -> bool {
|
||||
self.module_linking_enabled
|
||||
}
|
||||
|
||||
fn simd_enabled(&self) -> bool {
|
||||
self.simd_enabled
|
||||
}
|
||||
|
||||
fn relaxed_simd_enabled(&self) -> bool {
|
||||
self.relaxed_simd_enabled
|
||||
}
|
||||
|
||||
fn exceptions_enabled(&self) -> bool {
|
||||
self.exceptions_enabled
|
||||
}
|
||||
|
||||
fn multi_value_enabled(&self) -> bool {
|
||||
self.multi_value_enabled
|
||||
}
|
||||
|
||||
fn saturating_float_to_int_enabled(&self) -> bool {
|
||||
self.saturating_float_to_int_enabled
|
||||
}
|
||||
|
||||
fn sign_extension_ops_enabled(&self) -> bool {
|
||||
self.sign_extension_enabled
|
||||
}
|
||||
|
||||
fn allow_start_export(&self) -> bool {
|
||||
self.allow_start_export
|
||||
}
|
||||
@ -583,6 +768,10 @@ impl Config for SwarmConfig {
|
||||
self.max_nesting_depth
|
||||
}
|
||||
|
||||
fn max_type_size(&self) -> u32 {
|
||||
self.max_type_size
|
||||
}
|
||||
|
||||
fn memory64_enabled(&self) -> bool {
|
||||
self.memory64_enabled
|
||||
}
|
||||
@ -590,4 +779,20 @@ impl Config for SwarmConfig {
|
||||
fn canonicalize_nans(&self) -> bool {
|
||||
self.canonicalize_nans
|
||||
}
|
||||
|
||||
fn threads_enabled(&self) -> bool {
|
||||
self.threads_enabled
|
||||
}
|
||||
|
||||
fn allowed_instructions(&self) -> InstructionKinds {
|
||||
self.allowed_instructions
|
||||
}
|
||||
|
||||
fn max_table_elements(&self) -> u32 {
|
||||
self.max_table_elements
|
||||
}
|
||||
|
||||
fn table_max_size_required(&self) -> bool {
|
||||
self.table_max_size_required
|
||||
}
|
||||
}
|
||||
|
1651
third_party/rust/wasm-smith/src/core.rs
vendored
Normal file
1651
third_party/rust/wasm-smith/src/core.rs
vendored
Normal file
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
243
third_party/rust/wasm-smith/src/core/encode.rs
vendored
Normal file
243
third_party/rust/wasm-smith/src/core/encode.rs
vendored
Normal file
@ -0,0 +1,243 @@
|
||||
use super::*;
|
||||
use std::convert::TryFrom;
|
||||
|
||||
impl Module {
|
||||
/// Encode this Wasm module into bytes.
|
||||
pub fn to_bytes(&self) -> Vec<u8> {
|
||||
self.encoded().finish()
|
||||
}
|
||||
|
||||
fn encoded(&self) -> wasm_encoder::Module {
|
||||
let mut module = wasm_encoder::Module::new();
|
||||
|
||||
self.encode_types(&mut module);
|
||||
self.encode_imports(&mut module);
|
||||
self.encode_funcs(&mut module);
|
||||
self.encode_tables(&mut module);
|
||||
self.encode_memories(&mut module);
|
||||
self.encode_tags(&mut module);
|
||||
self.encode_globals(&mut module);
|
||||
self.encode_exports(&mut module);
|
||||
self.encode_start(&mut module);
|
||||
self.encode_elems(&mut module);
|
||||
self.encode_data_count(&mut module);
|
||||
self.encode_code(&mut module);
|
||||
self.encode_data(&mut module);
|
||||
|
||||
module
|
||||
}
|
||||
|
||||
fn encode_types(&self, module: &mut wasm_encoder::Module) {
|
||||
if !self.should_encode_types {
|
||||
return;
|
||||
}
|
||||
|
||||
let mut section = wasm_encoder::TypeSection::new();
|
||||
for ty in &self.types {
|
||||
match ty {
|
||||
Type::Func(ty) => {
|
||||
section.function(ty.params.iter().cloned(), ty.results.iter().cloned());
|
||||
}
|
||||
}
|
||||
}
|
||||
module.section(§ion);
|
||||
}
|
||||
|
||||
fn encode_imports(&self, module: &mut wasm_encoder::Module) {
|
||||
if !self.should_encode_imports {
|
||||
return;
|
||||
}
|
||||
|
||||
let mut section = wasm_encoder::ImportSection::new();
|
||||
for im in &self.imports {
|
||||
section.import(
|
||||
&im.module,
|
||||
&im.field,
|
||||
translate_entity_type(&im.entity_type),
|
||||
);
|
||||
}
|
||||
module.section(§ion);
|
||||
}
|
||||
|
||||
fn encode_tags(&self, module: &mut wasm_encoder::Module) {
|
||||
if self.num_defined_tags == 0 {
|
||||
return;
|
||||
}
|
||||
let mut tags = wasm_encoder::TagSection::new();
|
||||
for tag in self.tags[self.tags.len() - self.num_defined_tags..].iter() {
|
||||
tags.tag(wasm_encoder::TagType {
|
||||
kind: wasm_encoder::TagKind::Exception,
|
||||
func_type_idx: tag.func_type_idx,
|
||||
});
|
||||
}
|
||||
module.section(&tags);
|
||||
}
|
||||
|
||||
fn encode_funcs(&self, module: &mut wasm_encoder::Module) {
|
||||
if self.num_defined_funcs == 0 {
|
||||
return;
|
||||
}
|
||||
let mut funcs = wasm_encoder::FunctionSection::new();
|
||||
for (ty, _) in self.funcs[self.funcs.len() - self.num_defined_funcs..].iter() {
|
||||
funcs.function(*ty);
|
||||
}
|
||||
module.section(&funcs);
|
||||
}
|
||||
|
||||
fn encode_tables(&self, module: &mut wasm_encoder::Module) {
|
||||
if self.num_defined_tables == 0 {
|
||||
return;
|
||||
}
|
||||
let mut tables = wasm_encoder::TableSection::new();
|
||||
for t in self.tables[self.tables.len() - self.num_defined_tables..].iter() {
|
||||
tables.table(*t);
|
||||
}
|
||||
module.section(&tables);
|
||||
}
|
||||
|
||||
fn encode_memories(&self, module: &mut wasm_encoder::Module) {
|
||||
if self.num_defined_memories == 0 {
|
||||
return;
|
||||
}
|
||||
let mut mems = wasm_encoder::MemorySection::new();
|
||||
for m in self.memories[self.memories.len() - self.num_defined_memories..].iter() {
|
||||
mems.memory(*m);
|
||||
}
|
||||
module.section(&mems);
|
||||
}
|
||||
|
||||
fn encode_globals(&self, module: &mut wasm_encoder::Module) {
|
||||
if self.globals.is_empty() {
|
||||
return;
|
||||
}
|
||||
let mut globals = wasm_encoder::GlobalSection::new();
|
||||
for (idx, expr) in &self.defined_globals {
|
||||
let ty = &self.globals[*idx as usize];
|
||||
globals.global(*ty, expr);
|
||||
}
|
||||
module.section(&globals);
|
||||
}
|
||||
|
||||
fn encode_exports(&self, module: &mut wasm_encoder::Module) {
|
||||
if self.exports.is_empty() {
|
||||
return;
|
||||
}
|
||||
let mut exports = wasm_encoder::ExportSection::new();
|
||||
for (name, kind, idx) in &self.exports {
|
||||
exports.export(name, *kind, *idx);
|
||||
}
|
||||
module.section(&exports);
|
||||
}
|
||||
|
||||
fn encode_start(&self, module: &mut wasm_encoder::Module) {
|
||||
if let Some(f) = self.start {
|
||||
module.section(&wasm_encoder::StartSection { function_index: f });
|
||||
}
|
||||
}
|
||||
|
||||
fn encode_elems(&self, module: &mut wasm_encoder::Module) {
|
||||
if self.elems.is_empty() {
|
||||
return;
|
||||
}
|
||||
let mut elems = wasm_encoder::ElementSection::new();
|
||||
let mut exps = vec![];
|
||||
for el in &self.elems {
|
||||
let elements = match &el.items {
|
||||
Elements::Expressions(es) => {
|
||||
exps.clear();
|
||||
exps.extend(es.iter().map(|e| match e {
|
||||
Some(i) => wasm_encoder::Element::Func(*i),
|
||||
None => wasm_encoder::Element::Null,
|
||||
}));
|
||||
wasm_encoder::Elements::Expressions(&exps)
|
||||
}
|
||||
Elements::Functions(fs) => wasm_encoder::Elements::Functions(fs),
|
||||
};
|
||||
match &el.kind {
|
||||
ElementKind::Active { table, offset } => {
|
||||
elems.active(*table, offset, el.ty, elements);
|
||||
}
|
||||
ElementKind::Passive => {
|
||||
elems.passive(el.ty, elements);
|
||||
}
|
||||
ElementKind::Declared => {
|
||||
elems.declared(el.ty, elements);
|
||||
}
|
||||
}
|
||||
}
|
||||
module.section(&elems);
|
||||
}
|
||||
|
||||
fn encode_data_count(&self, module: &mut wasm_encoder::Module) {
|
||||
// Without bulk memory there's no need for a data count section,
|
||||
if !self.config.bulk_memory_enabled() {
|
||||
return;
|
||||
}
|
||||
// ... and also if there's no data no need for a data count section.
|
||||
if self.data.is_empty() {
|
||||
return;
|
||||
}
|
||||
module.section(&wasm_encoder::DataCountSection {
|
||||
count: u32::try_from(self.data.len()).unwrap(),
|
||||
});
|
||||
}
|
||||
|
||||
fn encode_code(&self, module: &mut wasm_encoder::Module) {
|
||||
if self.code.is_empty() {
|
||||
return;
|
||||
}
|
||||
let mut code = wasm_encoder::CodeSection::new();
|
||||
for c in &self.code {
|
||||
// Skip the run-length encoding because it is a little
|
||||
// annoying to compute; use a length of one for every local.
|
||||
let mut func = wasm_encoder::Function::new(c.locals.iter().map(|l| (1, *l)));
|
||||
match &c.instructions {
|
||||
Instructions::Generated(instrs) => {
|
||||
for instr in instrs {
|
||||
func.instruction(instr);
|
||||
}
|
||||
func.instruction(&wasm_encoder::Instruction::End);
|
||||
}
|
||||
Instructions::Arbitrary(body) => {
|
||||
func.raw(body.iter().copied());
|
||||
}
|
||||
}
|
||||
code.function(&func);
|
||||
}
|
||||
module.section(&code);
|
||||
}
|
||||
|
||||
fn encode_data(&self, module: &mut wasm_encoder::Module) {
|
||||
if self.data.is_empty() {
|
||||
return;
|
||||
}
|
||||
let mut data = wasm_encoder::DataSection::new();
|
||||
for seg in &self.data {
|
||||
match &seg.kind {
|
||||
DataSegmentKind::Active {
|
||||
memory_index,
|
||||
offset,
|
||||
} => {
|
||||
data.active(*memory_index, offset, seg.init.iter().copied());
|
||||
}
|
||||
DataSegmentKind::Passive => {
|
||||
data.passive(seg.init.iter().copied());
|
||||
}
|
||||
}
|
||||
}
|
||||
module.section(&data);
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn translate_entity_type(ty: &EntityType) -> wasm_encoder::EntityType {
|
||||
match ty {
|
||||
EntityType::Tag(t) => wasm_encoder::EntityType::Tag(wasm_encoder::TagType {
|
||||
kind: wasm_encoder::TagKind::Exception,
|
||||
func_type_idx: t.func_type_idx,
|
||||
}),
|
||||
EntityType::Func(f, _) => wasm_encoder::EntityType::Function(*f),
|
||||
EntityType::Table(ty) => (*ty).into(),
|
||||
EntityType::Memory(m) => (*m).into(),
|
||||
EntityType::Global(g) => (*g).into(),
|
||||
}
|
||||
}
|
@ -1,5 +1,6 @@
|
||||
use super::*;
|
||||
use std::mem;
|
||||
use wasm_encoder::BlockType;
|
||||
|
||||
impl Module {
|
||||
/// Ensure that all of this Wasm module's functions will terminate when
|
907
third_party/rust/wasm-smith/src/encode.rs
vendored
907
third_party/rust/wasm-smith/src/encode.rs
vendored
@ -1,907 +0,0 @@
|
||||
use super::*;
|
||||
use std::convert::TryFrom;
|
||||
|
||||
impl Module {
|
||||
/// Encode this Wasm module into bytes.
|
||||
pub fn to_bytes(&self) -> Vec<u8> {
|
||||
self.encoded().finish()
|
||||
}
|
||||
|
||||
fn encoded(&self) -> wasm_encoder::Module {
|
||||
let mut module = wasm_encoder::Module::new();
|
||||
|
||||
self.encode_initializers(&mut module);
|
||||
self.encode_funcs(&mut module);
|
||||
self.encode_tables(&mut module);
|
||||
self.encode_memories(&mut module);
|
||||
self.encode_tags(&mut module);
|
||||
self.encode_globals(&mut module);
|
||||
self.encode_exports(&mut module);
|
||||
self.encode_start(&mut module);
|
||||
self.encode_elems(&mut module);
|
||||
self.encode_data_count(&mut module);
|
||||
self.encode_code(&mut module);
|
||||
self.encode_data(&mut module);
|
||||
|
||||
module
|
||||
}
|
||||
|
||||
fn encode_initializers(&self, module: &mut wasm_encoder::Module) {
|
||||
for init in self.initial_sections.iter() {
|
||||
match init {
|
||||
InitialSection::Type(types) => self.encode_types(module, types),
|
||||
InitialSection::Import(imports) => self.encode_imports(module, imports),
|
||||
InitialSection::Alias(aliases) => self.encode_aliases(module, aliases),
|
||||
InitialSection::Instance(list) => self.encode_instances(module, list),
|
||||
InitialSection::Module(list) => self.encode_modules(module, list),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn encode_types(&self, module: &mut wasm_encoder::Module, types: &[Type]) {
|
||||
let mut section = wasm_encoder::TypeSection::new();
|
||||
for ty in types {
|
||||
match ty {
|
||||
Type::Func(ty) => {
|
||||
section.function(
|
||||
ty.params.iter().map(|t| translate_val_type(*t)),
|
||||
ty.results.iter().map(|t| translate_val_type(*t)),
|
||||
);
|
||||
}
|
||||
Type::Module(ty) => {
|
||||
section.module(
|
||||
ty.imports.iter().map(|(module, name, ty)| {
|
||||
(module.as_str(), name.as_deref(), translate_entity_type(ty))
|
||||
}),
|
||||
ty.exports
|
||||
.exports
|
||||
.iter()
|
||||
.map(|(name, ty)| (name.as_str(), translate_entity_type(ty))),
|
||||
);
|
||||
}
|
||||
Type::Instance(ty) => {
|
||||
section.instance(
|
||||
ty.exports
|
||||
.iter()
|
||||
.map(|(name, ty)| (name.as_str(), translate_entity_type(ty))),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
module.section(§ion);
|
||||
}
|
||||
|
||||
fn encode_imports(
|
||||
&self,
|
||||
module: &mut wasm_encoder::Module,
|
||||
imports: &[(String, Option<String>, EntityType)],
|
||||
) {
|
||||
let mut section = wasm_encoder::ImportSection::new();
|
||||
for (module, name, ty) in imports {
|
||||
section.import(module, name.as_deref(), translate_entity_type(ty));
|
||||
}
|
||||
module.section(§ion);
|
||||
}
|
||||
|
||||
fn encode_aliases(&self, module: &mut wasm_encoder::Module, imports: &[Alias]) {
|
||||
let mut section = wasm_encoder::AliasSection::new();
|
||||
for alias in imports {
|
||||
match alias {
|
||||
Alias::InstanceExport {
|
||||
instance,
|
||||
kind,
|
||||
name,
|
||||
} => {
|
||||
section.instance_export(*instance, translate_item_kind(kind), name);
|
||||
}
|
||||
Alias::OuterType { depth, index } => {
|
||||
section.outer_type(*depth, *index);
|
||||
}
|
||||
Alias::OuterModule { depth, index } => {
|
||||
section.outer_module(*depth, *index);
|
||||
}
|
||||
}
|
||||
}
|
||||
module.section(§ion);
|
||||
}
|
||||
|
||||
fn encode_instances(&self, module: &mut wasm_encoder::Module, list: &[Instance]) {
|
||||
let mut section = wasm_encoder::InstanceSection::new();
|
||||
for instance in list {
|
||||
section.instantiate(
|
||||
instance.module,
|
||||
instance
|
||||
.args
|
||||
.iter()
|
||||
.map(|(name, export)| (name.as_str(), translate_export(export))),
|
||||
);
|
||||
}
|
||||
module.section(§ion);
|
||||
}
|
||||
|
||||
fn encode_modules(&self, module: &mut wasm_encoder::Module, list: &[Self]) {
|
||||
let mut section = wasm_encoder::ModuleSection::new();
|
||||
for module in list {
|
||||
let encoded = module.encoded();
|
||||
section.module(&encoded);
|
||||
}
|
||||
module.section(§ion);
|
||||
}
|
||||
|
||||
fn encode_tags(&self, module: &mut wasm_encoder::Module) {
|
||||
if self.num_defined_tags == 0 {
|
||||
return;
|
||||
}
|
||||
let mut tags = wasm_encoder::TagSection::new();
|
||||
for tag in self.tags[self.tags.len() - self.num_defined_tags..].iter() {
|
||||
tags.tag(wasm_encoder::TagType {
|
||||
kind: wasm_encoder::TagKind::Exception,
|
||||
func_type_idx: tag.func_type_idx,
|
||||
});
|
||||
}
|
||||
module.section(&tags);
|
||||
}
|
||||
|
||||
fn encode_funcs(&self, module: &mut wasm_encoder::Module) {
|
||||
if self.num_defined_funcs == 0 {
|
||||
return;
|
||||
}
|
||||
let mut funcs = wasm_encoder::FunctionSection::new();
|
||||
for (ty, _) in self.funcs[self.funcs.len() - self.num_defined_funcs..].iter() {
|
||||
funcs.function(ty.unwrap());
|
||||
}
|
||||
module.section(&funcs);
|
||||
}
|
||||
|
||||
fn encode_tables(&self, module: &mut wasm_encoder::Module) {
|
||||
if self.num_defined_tables == 0 {
|
||||
return;
|
||||
}
|
||||
let mut tables = wasm_encoder::TableSection::new();
|
||||
for t in self.tables[self.tables.len() - self.num_defined_tables..].iter() {
|
||||
tables.table(translate_table_type(t));
|
||||
}
|
||||
module.section(&tables);
|
||||
}
|
||||
|
||||
fn encode_memories(&self, module: &mut wasm_encoder::Module) {
|
||||
if self.num_defined_memories == 0 {
|
||||
return;
|
||||
}
|
||||
let mut mems = wasm_encoder::MemorySection::new();
|
||||
for m in self.memories[self.memories.len() - self.num_defined_memories..].iter() {
|
||||
mems.memory(translate_memory_type(m));
|
||||
}
|
||||
module.section(&mems);
|
||||
}
|
||||
|
||||
fn encode_globals(&self, module: &mut wasm_encoder::Module) {
|
||||
if self.globals.is_empty() {
|
||||
return;
|
||||
}
|
||||
let mut globals = wasm_encoder::GlobalSection::new();
|
||||
for (idx, expr) in &self.defined_globals {
|
||||
let ty = &self.globals[*idx as usize];
|
||||
globals.global(translate_global_type(ty), translate_instruction(expr));
|
||||
}
|
||||
module.section(&globals);
|
||||
}
|
||||
|
||||
fn encode_exports(&self, module: &mut wasm_encoder::Module) {
|
||||
if self.exports.is_empty() {
|
||||
return;
|
||||
}
|
||||
let mut exports = wasm_encoder::ExportSection::new();
|
||||
for (name, export) in &self.exports {
|
||||
exports.export(name, translate_export(export));
|
||||
}
|
||||
module.section(&exports);
|
||||
}
|
||||
|
||||
fn encode_start(&self, module: &mut wasm_encoder::Module) {
|
||||
if let Some(f) = self.start {
|
||||
module.section(&wasm_encoder::StartSection { function_index: f });
|
||||
}
|
||||
}
|
||||
|
||||
fn encode_elems(&self, module: &mut wasm_encoder::Module) {
|
||||
if self.elems.is_empty() {
|
||||
return;
|
||||
}
|
||||
let mut elems = wasm_encoder::ElementSection::new();
|
||||
let mut exps = vec![];
|
||||
for el in &self.elems {
|
||||
let elem_ty = translate_val_type(el.ty);
|
||||
let elements = match &el.items {
|
||||
Elements::Expressions(es) => {
|
||||
exps.clear();
|
||||
exps.extend(es.iter().map(|e| match e {
|
||||
Some(i) => wasm_encoder::Element::Func(*i),
|
||||
None => wasm_encoder::Element::Null,
|
||||
}));
|
||||
wasm_encoder::Elements::Expressions(&exps)
|
||||
}
|
||||
Elements::Functions(fs) => wasm_encoder::Elements::Functions(fs),
|
||||
};
|
||||
match &el.kind {
|
||||
ElementKind::Active { table, offset } => {
|
||||
elems.active(*table, translate_instruction(offset), elem_ty, elements);
|
||||
}
|
||||
ElementKind::Passive => {
|
||||
elems.passive(elem_ty, elements);
|
||||
}
|
||||
ElementKind::Declared => {
|
||||
elems.declared(elem_ty, elements);
|
||||
}
|
||||
}
|
||||
}
|
||||
module.section(&elems);
|
||||
}
|
||||
|
||||
fn encode_data_count(&self, module: &mut wasm_encoder::Module) {
|
||||
// Without bulk memory there's no need for a data count section,
|
||||
if !self.config.bulk_memory_enabled() {
|
||||
return;
|
||||
}
|
||||
// ... and also if there's no data no need for a data count section.
|
||||
if self.data.is_empty() {
|
||||
return;
|
||||
}
|
||||
module.section(&wasm_encoder::DataCountSection {
|
||||
count: u32::try_from(self.data.len()).unwrap(),
|
||||
});
|
||||
}
|
||||
|
||||
fn encode_code(&self, module: &mut wasm_encoder::Module) {
|
||||
if self.code.is_empty() {
|
||||
return;
|
||||
}
|
||||
let mut code = wasm_encoder::CodeSection::new();
|
||||
for c in &self.code {
|
||||
// Skip the run-length encoding because it is a little
|
||||
// annoying to compute; use a length of one for every local.
|
||||
let mut func =
|
||||
wasm_encoder::Function::new(c.locals.iter().map(|l| (1, translate_val_type(*l))));
|
||||
match &c.instructions {
|
||||
Instructions::Generated(instrs) => {
|
||||
for instr in instrs {
|
||||
func.instruction(translate_instruction(instr));
|
||||
}
|
||||
func.instruction(wasm_encoder::Instruction::End);
|
||||
}
|
||||
Instructions::Arbitrary(body) => {
|
||||
func.raw(body.iter().copied());
|
||||
}
|
||||
}
|
||||
code.function(&func);
|
||||
}
|
||||
module.section(&code);
|
||||
}
|
||||
|
||||
fn encode_data(&self, module: &mut wasm_encoder::Module) {
|
||||
if self.data.is_empty() {
|
||||
return;
|
||||
}
|
||||
let mut data = wasm_encoder::DataSection::new();
|
||||
for seg in &self.data {
|
||||
match &seg.kind {
|
||||
DataSegmentKind::Active {
|
||||
memory_index,
|
||||
offset,
|
||||
} => {
|
||||
data.active(
|
||||
*memory_index,
|
||||
translate_instruction(offset),
|
||||
seg.init.iter().copied(),
|
||||
);
|
||||
}
|
||||
DataSegmentKind::Passive => {
|
||||
data.passive(seg.init.iter().copied());
|
||||
}
|
||||
}
|
||||
}
|
||||
module.section(&data);
|
||||
}
|
||||
}
|
||||
|
||||
fn translate_val_type(ty: ValType) -> wasm_encoder::ValType {
|
||||
match ty {
|
||||
ValType::I32 => wasm_encoder::ValType::I32,
|
||||
ValType::I64 => wasm_encoder::ValType::I64,
|
||||
ValType::F32 => wasm_encoder::ValType::F32,
|
||||
ValType::F64 => wasm_encoder::ValType::F64,
|
||||
ValType::V128 => wasm_encoder::ValType::V128,
|
||||
ValType::FuncRef => wasm_encoder::ValType::FuncRef,
|
||||
ValType::ExternRef => wasm_encoder::ValType::ExternRef,
|
||||
}
|
||||
}
|
||||
|
||||
fn translate_entity_type(ty: &EntityType) -> wasm_encoder::EntityType {
|
||||
match ty {
|
||||
EntityType::Tag(t) => wasm_encoder::EntityType::Tag(wasm_encoder::TagType {
|
||||
kind: wasm_encoder::TagKind::Exception,
|
||||
func_type_idx: t.func_type_idx,
|
||||
}),
|
||||
EntityType::Func(f, _) => wasm_encoder::EntityType::Function(*f),
|
||||
EntityType::Instance(i, _) => wasm_encoder::EntityType::Instance(*i),
|
||||
EntityType::Module(i, _) => wasm_encoder::EntityType::Module(*i),
|
||||
EntityType::Table(ty) => translate_table_type(ty).into(),
|
||||
EntityType::Memory(m) => translate_memory_type(m).into(),
|
||||
EntityType::Global(g) => translate_global_type(g).into(),
|
||||
}
|
||||
}
|
||||
|
||||
fn translate_table_type(ty: &TableType) -> wasm_encoder::TableType {
|
||||
wasm_encoder::TableType {
|
||||
element_type: translate_val_type(ty.elem_ty),
|
||||
minimum: ty.minimum,
|
||||
maximum: ty.maximum,
|
||||
}
|
||||
}
|
||||
|
||||
fn translate_memory_type(ty: &MemoryType) -> wasm_encoder::MemoryType {
|
||||
wasm_encoder::MemoryType {
|
||||
minimum: ty.minimum,
|
||||
maximum: ty.maximum,
|
||||
memory64: ty.memory64,
|
||||
}
|
||||
}
|
||||
|
||||
fn translate_global_type(ty: &GlobalType) -> wasm_encoder::GlobalType {
|
||||
wasm_encoder::GlobalType {
|
||||
val_type: translate_val_type(ty.val_type),
|
||||
mutable: ty.mutable,
|
||||
}
|
||||
}
|
||||
|
||||
fn translate_block_type(ty: BlockType) -> wasm_encoder::BlockType {
|
||||
match ty {
|
||||
BlockType::Empty => wasm_encoder::BlockType::Empty,
|
||||
BlockType::Result(ty) => wasm_encoder::BlockType::Result(translate_val_type(ty)),
|
||||
BlockType::FuncType(f) => wasm_encoder::BlockType::FunctionType(f),
|
||||
}
|
||||
}
|
||||
|
||||
fn translate_mem_arg(m: MemArg) -> wasm_encoder::MemArg {
|
||||
wasm_encoder::MemArg {
|
||||
offset: m.offset,
|
||||
align: m.align,
|
||||
memory_index: m.memory_index,
|
||||
}
|
||||
}
|
||||
|
||||
fn translate_item_kind(kind: &ItemKind) -> wasm_encoder::ItemKind {
|
||||
match kind {
|
||||
ItemKind::Tag => wasm_encoder::ItemKind::Tag,
|
||||
ItemKind::Func => wasm_encoder::ItemKind::Function,
|
||||
ItemKind::Table => wasm_encoder::ItemKind::Table,
|
||||
ItemKind::Memory => wasm_encoder::ItemKind::Memory,
|
||||
ItemKind::Global => wasm_encoder::ItemKind::Global,
|
||||
ItemKind::Instance => wasm_encoder::ItemKind::Instance,
|
||||
ItemKind::Module => wasm_encoder::ItemKind::Module,
|
||||
}
|
||||
}
|
||||
|
||||
fn translate_export(export: &Export) -> wasm_encoder::Export {
|
||||
match export {
|
||||
Export::Tag(idx) => wasm_encoder::Export::Tag(*idx),
|
||||
Export::Func(idx) => wasm_encoder::Export::Function(*idx),
|
||||
Export::Table(idx) => wasm_encoder::Export::Table(*idx),
|
||||
Export::Memory(idx) => wasm_encoder::Export::Memory(*idx),
|
||||
Export::Global(idx) => wasm_encoder::Export::Global(*idx),
|
||||
Export::Instance(idx) => wasm_encoder::Export::Instance(*idx),
|
||||
Export::Module(idx) => wasm_encoder::Export::Module(*idx),
|
||||
}
|
||||
}
|
||||
|
||||
fn translate_instruction(inst: &Instruction) -> wasm_encoder::Instruction {
|
||||
use Instruction::*;
|
||||
match *inst {
|
||||
// Control instructions.
|
||||
Unreachable => wasm_encoder::Instruction::Unreachable,
|
||||
Nop => wasm_encoder::Instruction::Nop,
|
||||
Block(bt) => wasm_encoder::Instruction::Block(translate_block_type(bt)),
|
||||
Loop(bt) => wasm_encoder::Instruction::Loop(translate_block_type(bt)),
|
||||
If(bt) => wasm_encoder::Instruction::If(translate_block_type(bt)),
|
||||
Else => wasm_encoder::Instruction::Else,
|
||||
Try(bt) => wasm_encoder::Instruction::Try(translate_block_type(bt)),
|
||||
Delegate(l) => wasm_encoder::Instruction::Delegate(l),
|
||||
Catch(t) => wasm_encoder::Instruction::Catch(t),
|
||||
CatchAll => wasm_encoder::Instruction::CatchAll,
|
||||
End => wasm_encoder::Instruction::End,
|
||||
Br(x) => wasm_encoder::Instruction::Br(x),
|
||||
BrIf(x) => wasm_encoder::Instruction::BrIf(x),
|
||||
BrTable(ref ls, l) => wasm_encoder::Instruction::BrTable(ls, l),
|
||||
Return => wasm_encoder::Instruction::Return,
|
||||
Call(x) => wasm_encoder::Instruction::Call(x),
|
||||
CallIndirect { ty, table } => wasm_encoder::Instruction::CallIndirect { ty, table },
|
||||
Throw(t) => wasm_encoder::Instruction::Throw(t),
|
||||
Rethrow(l) => wasm_encoder::Instruction::Rethrow(l),
|
||||
|
||||
// Parametric instructions.
|
||||
Drop => wasm_encoder::Instruction::Drop,
|
||||
Select => wasm_encoder::Instruction::Select,
|
||||
|
||||
// Variable instructions.
|
||||
LocalGet(x) => wasm_encoder::Instruction::LocalGet(x),
|
||||
LocalSet(x) => wasm_encoder::Instruction::LocalSet(x),
|
||||
LocalTee(x) => wasm_encoder::Instruction::LocalTee(x),
|
||||
GlobalGet(x) => wasm_encoder::Instruction::GlobalGet(x),
|
||||
GlobalSet(x) => wasm_encoder::Instruction::GlobalSet(x),
|
||||
|
||||
// Memory instructions.
|
||||
I32Load(m) => wasm_encoder::Instruction::I32Load(translate_mem_arg(m)),
|
||||
I64Load(m) => wasm_encoder::Instruction::I64Load(translate_mem_arg(m)),
|
||||
F32Load(m) => wasm_encoder::Instruction::F32Load(translate_mem_arg(m)),
|
||||
F64Load(m) => wasm_encoder::Instruction::F64Load(translate_mem_arg(m)),
|
||||
I32Load8_S(m) => wasm_encoder::Instruction::I32Load8_S(translate_mem_arg(m)),
|
||||
I32Load8_U(m) => wasm_encoder::Instruction::I32Load8_U(translate_mem_arg(m)),
|
||||
I32Load16_S(m) => wasm_encoder::Instruction::I32Load16_S(translate_mem_arg(m)),
|
||||
I32Load16_U(m) => wasm_encoder::Instruction::I32Load16_U(translate_mem_arg(m)),
|
||||
I64Load8_S(m) => wasm_encoder::Instruction::I64Load8_S(translate_mem_arg(m)),
|
||||
I64Load8_U(m) => wasm_encoder::Instruction::I64Load8_U(translate_mem_arg(m)),
|
||||
I64Load16_S(m) => wasm_encoder::Instruction::I64Load16_S(translate_mem_arg(m)),
|
||||
I64Load16_U(m) => wasm_encoder::Instruction::I64Load16_U(translate_mem_arg(m)),
|
||||
I64Load32_S(m) => wasm_encoder::Instruction::I64Load32_S(translate_mem_arg(m)),
|
||||
I64Load32_U(m) => wasm_encoder::Instruction::I64Load32_U(translate_mem_arg(m)),
|
||||
I32Store(m) => wasm_encoder::Instruction::I32Store(translate_mem_arg(m)),
|
||||
I64Store(m) => wasm_encoder::Instruction::I64Store(translate_mem_arg(m)),
|
||||
F32Store(m) => wasm_encoder::Instruction::F32Store(translate_mem_arg(m)),
|
||||
F64Store(m) => wasm_encoder::Instruction::F64Store(translate_mem_arg(m)),
|
||||
I32Store8(m) => wasm_encoder::Instruction::I32Store8(translate_mem_arg(m)),
|
||||
I32Store16(m) => wasm_encoder::Instruction::I32Store16(translate_mem_arg(m)),
|
||||
I64Store8(m) => wasm_encoder::Instruction::I64Store8(translate_mem_arg(m)),
|
||||
I64Store16(m) => wasm_encoder::Instruction::I64Store16(translate_mem_arg(m)),
|
||||
I64Store32(m) => wasm_encoder::Instruction::I64Store32(translate_mem_arg(m)),
|
||||
MemorySize(x) => wasm_encoder::Instruction::MemorySize(x),
|
||||
MemoryGrow(x) => wasm_encoder::Instruction::MemoryGrow(x),
|
||||
MemoryInit { mem, data } => wasm_encoder::Instruction::MemoryInit { mem, data },
|
||||
DataDrop(x) => wasm_encoder::Instruction::DataDrop(x),
|
||||
MemoryCopy { src, dst } => wasm_encoder::Instruction::MemoryCopy { src, dst },
|
||||
MemoryFill(x) => wasm_encoder::Instruction::MemoryFill(x),
|
||||
|
||||
// Numeric instructions.
|
||||
I32Const(x) => wasm_encoder::Instruction::I32Const(x),
|
||||
I64Const(x) => wasm_encoder::Instruction::I64Const(x),
|
||||
F32Const(x) => wasm_encoder::Instruction::F32Const(x),
|
||||
F64Const(x) => wasm_encoder::Instruction::F64Const(x),
|
||||
I32Eqz => wasm_encoder::Instruction::I32Eqz,
|
||||
I32Eq => wasm_encoder::Instruction::I32Eq,
|
||||
I32Neq => wasm_encoder::Instruction::I32Neq,
|
||||
I32LtS => wasm_encoder::Instruction::I32LtS,
|
||||
I32LtU => wasm_encoder::Instruction::I32LtU,
|
||||
I32GtS => wasm_encoder::Instruction::I32GtS,
|
||||
I32GtU => wasm_encoder::Instruction::I32GtU,
|
||||
I32LeS => wasm_encoder::Instruction::I32LeS,
|
||||
I32LeU => wasm_encoder::Instruction::I32LeU,
|
||||
I32GeS => wasm_encoder::Instruction::I32GeS,
|
||||
I32GeU => wasm_encoder::Instruction::I32GeU,
|
||||
I64Eqz => wasm_encoder::Instruction::I64Eqz,
|
||||
I64Eq => wasm_encoder::Instruction::I64Eq,
|
||||
I64Neq => wasm_encoder::Instruction::I64Neq,
|
||||
I64LtS => wasm_encoder::Instruction::I64LtS,
|
||||
I64LtU => wasm_encoder::Instruction::I64LtU,
|
||||
I64GtS => wasm_encoder::Instruction::I64GtS,
|
||||
I64GtU => wasm_encoder::Instruction::I64GtU,
|
||||
I64LeS => wasm_encoder::Instruction::I64LeS,
|
||||
I64LeU => wasm_encoder::Instruction::I64LeU,
|
||||
I64GeS => wasm_encoder::Instruction::I64GeS,
|
||||
I64GeU => wasm_encoder::Instruction::I64GeU,
|
||||
F32Eq => wasm_encoder::Instruction::F32Eq,
|
||||
F32Neq => wasm_encoder::Instruction::F32Neq,
|
||||
F32Lt => wasm_encoder::Instruction::F32Lt,
|
||||
F32Gt => wasm_encoder::Instruction::F32Gt,
|
||||
F32Le => wasm_encoder::Instruction::F32Le,
|
||||
F32Ge => wasm_encoder::Instruction::F32Ge,
|
||||
F64Eq => wasm_encoder::Instruction::F64Eq,
|
||||
F64Neq => wasm_encoder::Instruction::F64Neq,
|
||||
F64Lt => wasm_encoder::Instruction::F64Lt,
|
||||
F64Gt => wasm_encoder::Instruction::F64Gt,
|
||||
F64Le => wasm_encoder::Instruction::F64Le,
|
||||
F64Ge => wasm_encoder::Instruction::F64Ge,
|
||||
I32Clz => wasm_encoder::Instruction::I32Clz,
|
||||
I32Ctz => wasm_encoder::Instruction::I32Ctz,
|
||||
I32Popcnt => wasm_encoder::Instruction::I32Popcnt,
|
||||
I32Add => wasm_encoder::Instruction::I32Add,
|
||||
I32Sub => wasm_encoder::Instruction::I32Sub,
|
||||
I32Mul => wasm_encoder::Instruction::I32Mul,
|
||||
I32DivS => wasm_encoder::Instruction::I32DivS,
|
||||
I32DivU => wasm_encoder::Instruction::I32DivU,
|
||||
I32RemS => wasm_encoder::Instruction::I32RemS,
|
||||
I32RemU => wasm_encoder::Instruction::I32RemU,
|
||||
I32And => wasm_encoder::Instruction::I32And,
|
||||
I32Or => wasm_encoder::Instruction::I32Or,
|
||||
I32Xor => wasm_encoder::Instruction::I32Xor,
|
||||
I32Shl => wasm_encoder::Instruction::I32Shl,
|
||||
I32ShrS => wasm_encoder::Instruction::I32ShrS,
|
||||
I32ShrU => wasm_encoder::Instruction::I32ShrU,
|
||||
I32Rotl => wasm_encoder::Instruction::I32Rotl,
|
||||
I32Rotr => wasm_encoder::Instruction::I32Rotr,
|
||||
I64Clz => wasm_encoder::Instruction::I64Clz,
|
||||
I64Ctz => wasm_encoder::Instruction::I64Ctz,
|
||||
I64Popcnt => wasm_encoder::Instruction::I64Popcnt,
|
||||
I64Add => wasm_encoder::Instruction::I64Add,
|
||||
I64Sub => wasm_encoder::Instruction::I64Sub,
|
||||
I64Mul => wasm_encoder::Instruction::I64Mul,
|
||||
I64DivS => wasm_encoder::Instruction::I64DivS,
|
||||
I64DivU => wasm_encoder::Instruction::I64DivU,
|
||||
I64RemS => wasm_encoder::Instruction::I64RemS,
|
||||
I64RemU => wasm_encoder::Instruction::I64RemU,
|
||||
I64And => wasm_encoder::Instruction::I64And,
|
||||
I64Or => wasm_encoder::Instruction::I64Or,
|
||||
I64Xor => wasm_encoder::Instruction::I64Xor,
|
||||
I64Shl => wasm_encoder::Instruction::I64Shl,
|
||||
I64ShrS => wasm_encoder::Instruction::I64ShrS,
|
||||
I64ShrU => wasm_encoder::Instruction::I64ShrU,
|
||||
I64Rotl => wasm_encoder::Instruction::I64Rotl,
|
||||
I64Rotr => wasm_encoder::Instruction::I64Rotr,
|
||||
F32Abs => wasm_encoder::Instruction::F32Abs,
|
||||
F32Neg => wasm_encoder::Instruction::F32Neg,
|
||||
F32Ceil => wasm_encoder::Instruction::F32Ceil,
|
||||
F32Floor => wasm_encoder::Instruction::F32Floor,
|
||||
F32Trunc => wasm_encoder::Instruction::F32Trunc,
|
||||
F32Nearest => wasm_encoder::Instruction::F32Nearest,
|
||||
F32Sqrt => wasm_encoder::Instruction::F32Sqrt,
|
||||
F32Add => wasm_encoder::Instruction::F32Add,
|
||||
F32Sub => wasm_encoder::Instruction::F32Sub,
|
||||
F32Mul => wasm_encoder::Instruction::F32Mul,
|
||||
F32Div => wasm_encoder::Instruction::F32Div,
|
||||
F32Min => wasm_encoder::Instruction::F32Min,
|
||||
F32Max => wasm_encoder::Instruction::F32Max,
|
||||
F32Copysign => wasm_encoder::Instruction::F32Copysign,
|
||||
F64Abs => wasm_encoder::Instruction::F64Abs,
|
||||
F64Neg => wasm_encoder::Instruction::F64Neg,
|
||||
F64Ceil => wasm_encoder::Instruction::F64Ceil,
|
||||
F64Floor => wasm_encoder::Instruction::F64Floor,
|
||||
F64Trunc => wasm_encoder::Instruction::F64Trunc,
|
||||
F64Nearest => wasm_encoder::Instruction::F64Nearest,
|
||||
F64Sqrt => wasm_encoder::Instruction::F64Sqrt,
|
||||
F64Add => wasm_encoder::Instruction::F64Add,
|
||||
F64Sub => wasm_encoder::Instruction::F64Sub,
|
||||
F64Mul => wasm_encoder::Instruction::F64Mul,
|
||||
F64Div => wasm_encoder::Instruction::F64Div,
|
||||
F64Min => wasm_encoder::Instruction::F64Min,
|
||||
F64Max => wasm_encoder::Instruction::F64Max,
|
||||
F64Copysign => wasm_encoder::Instruction::F64Copysign,
|
||||
I32WrapI64 => wasm_encoder::Instruction::I32WrapI64,
|
||||
I32TruncF32S => wasm_encoder::Instruction::I32TruncF32S,
|
||||
I32TruncF32U => wasm_encoder::Instruction::I32TruncF32U,
|
||||
I32TruncF64S => wasm_encoder::Instruction::I32TruncF64S,
|
||||
I32TruncF64U => wasm_encoder::Instruction::I32TruncF64U,
|
||||
I64ExtendI32S => wasm_encoder::Instruction::I64ExtendI32S,
|
||||
I64ExtendI32U => wasm_encoder::Instruction::I64ExtendI32U,
|
||||
I64TruncF32S => wasm_encoder::Instruction::I64TruncF32S,
|
||||
I64TruncF32U => wasm_encoder::Instruction::I64TruncF32U,
|
||||
I64TruncF64S => wasm_encoder::Instruction::I64TruncF64S,
|
||||
I64TruncF64U => wasm_encoder::Instruction::I64TruncF64U,
|
||||
F32ConvertI32S => wasm_encoder::Instruction::F32ConvertI32S,
|
||||
F32ConvertI32U => wasm_encoder::Instruction::F32ConvertI32U,
|
||||
F32ConvertI64S => wasm_encoder::Instruction::F32ConvertI64S,
|
||||
F32ConvertI64U => wasm_encoder::Instruction::F32ConvertI64U,
|
||||
F32DemoteF64 => wasm_encoder::Instruction::F32DemoteF64,
|
||||
F64ConvertI32S => wasm_encoder::Instruction::F64ConvertI32S,
|
||||
F64ConvertI32U => wasm_encoder::Instruction::F64ConvertI32U,
|
||||
F64ConvertI64S => wasm_encoder::Instruction::F64ConvertI64S,
|
||||
F64ConvertI64U => wasm_encoder::Instruction::F64ConvertI64U,
|
||||
F64PromoteF32 => wasm_encoder::Instruction::F64PromoteF32,
|
||||
I32ReinterpretF32 => wasm_encoder::Instruction::I32ReinterpretF32,
|
||||
I64ReinterpretF64 => wasm_encoder::Instruction::I64ReinterpretF64,
|
||||
F32ReinterpretI32 => wasm_encoder::Instruction::F32ReinterpretI32,
|
||||
F64ReinterpretI64 => wasm_encoder::Instruction::F64ReinterpretI64,
|
||||
I32Extend8S => wasm_encoder::Instruction::I32Extend8S,
|
||||
I32Extend16S => wasm_encoder::Instruction::I32Extend16S,
|
||||
I64Extend8S => wasm_encoder::Instruction::I64Extend8S,
|
||||
I64Extend16S => wasm_encoder::Instruction::I64Extend16S,
|
||||
I64Extend32S => wasm_encoder::Instruction::I64Extend32S,
|
||||
I32TruncSatF32S => wasm_encoder::Instruction::I32TruncSatF32S,
|
||||
I32TruncSatF32U => wasm_encoder::Instruction::I32TruncSatF32U,
|
||||
I32TruncSatF64S => wasm_encoder::Instruction::I32TruncSatF64S,
|
||||
I32TruncSatF64U => wasm_encoder::Instruction::I32TruncSatF64U,
|
||||
I64TruncSatF32S => wasm_encoder::Instruction::I64TruncSatF32S,
|
||||
I64TruncSatF32U => wasm_encoder::Instruction::I64TruncSatF32U,
|
||||
I64TruncSatF64S => wasm_encoder::Instruction::I64TruncSatF64S,
|
||||
I64TruncSatF64U => wasm_encoder::Instruction::I64TruncSatF64U,
|
||||
TypedSelect(ty) => wasm_encoder::Instruction::TypedSelect(translate_val_type(ty)),
|
||||
RefNull(ty) => wasm_encoder::Instruction::RefNull(translate_val_type(ty)),
|
||||
RefIsNull => wasm_encoder::Instruction::RefIsNull,
|
||||
RefFunc(x) => wasm_encoder::Instruction::RefFunc(x),
|
||||
TableInit { segment, table } => wasm_encoder::Instruction::TableInit { segment, table },
|
||||
ElemDrop { segment } => wasm_encoder::Instruction::ElemDrop { segment },
|
||||
TableFill { table } => wasm_encoder::Instruction::TableFill { table },
|
||||
TableSet { table } => wasm_encoder::Instruction::TableSet { table },
|
||||
TableGet { table } => wasm_encoder::Instruction::TableGet { table },
|
||||
TableGrow { table } => wasm_encoder::Instruction::TableGrow { table },
|
||||
TableSize { table } => wasm_encoder::Instruction::TableSize { table },
|
||||
TableCopy { src, dst } => wasm_encoder::Instruction::TableCopy { src, dst },
|
||||
|
||||
// SIMD instructions.
|
||||
V128Load { memarg } => wasm_encoder::Instruction::V128Load {
|
||||
memarg: translate_mem_arg(memarg),
|
||||
},
|
||||
V128Load8x8S { memarg } => wasm_encoder::Instruction::V128Load8x8S {
|
||||
memarg: translate_mem_arg(memarg),
|
||||
},
|
||||
V128Load8x8U { memarg } => wasm_encoder::Instruction::V128Load8x8U {
|
||||
memarg: translate_mem_arg(memarg),
|
||||
},
|
||||
V128Load16x4S { memarg } => wasm_encoder::Instruction::V128Load16x4S {
|
||||
memarg: translate_mem_arg(memarg),
|
||||
},
|
||||
V128Load16x4U { memarg } => wasm_encoder::Instruction::V128Load16x4U {
|
||||
memarg: translate_mem_arg(memarg),
|
||||
},
|
||||
V128Load32x2S { memarg } => wasm_encoder::Instruction::V128Load32x2S {
|
||||
memarg: translate_mem_arg(memarg),
|
||||
},
|
||||
V128Load32x2U { memarg } => wasm_encoder::Instruction::V128Load32x2U {
|
||||
memarg: translate_mem_arg(memarg),
|
||||
},
|
||||
V128Load8Splat { memarg } => wasm_encoder::Instruction::V128Load8Splat {
|
||||
memarg: translate_mem_arg(memarg),
|
||||
},
|
||||
V128Load16Splat { memarg } => wasm_encoder::Instruction::V128Load16Splat {
|
||||
memarg: translate_mem_arg(memarg),
|
||||
},
|
||||
V128Load32Splat { memarg } => wasm_encoder::Instruction::V128Load32Splat {
|
||||
memarg: translate_mem_arg(memarg),
|
||||
},
|
||||
V128Load64Splat { memarg } => wasm_encoder::Instruction::V128Load64Splat {
|
||||
memarg: translate_mem_arg(memarg),
|
||||
},
|
||||
V128Load32Zero { memarg } => wasm_encoder::Instruction::V128Load32Zero {
|
||||
memarg: translate_mem_arg(memarg),
|
||||
},
|
||||
V128Load64Zero { memarg } => wasm_encoder::Instruction::V128Load64Zero {
|
||||
memarg: translate_mem_arg(memarg),
|
||||
},
|
||||
V128Store { memarg } => wasm_encoder::Instruction::V128Store {
|
||||
memarg: translate_mem_arg(memarg),
|
||||
},
|
||||
V128Load8Lane { memarg, lane } => wasm_encoder::Instruction::V128Load8Lane {
|
||||
memarg: translate_mem_arg(memarg),
|
||||
lane,
|
||||
},
|
||||
V128Load16Lane { memarg, lane } => wasm_encoder::Instruction::V128Load16Lane {
|
||||
memarg: translate_mem_arg(memarg),
|
||||
lane,
|
||||
},
|
||||
V128Load32Lane { memarg, lane } => wasm_encoder::Instruction::V128Load32Lane {
|
||||
memarg: translate_mem_arg(memarg),
|
||||
lane,
|
||||
},
|
||||
V128Load64Lane { memarg, lane } => wasm_encoder::Instruction::V128Load64Lane {
|
||||
memarg: translate_mem_arg(memarg),
|
||||
lane,
|
||||
},
|
||||
V128Store8Lane { memarg, lane } => wasm_encoder::Instruction::V128Store8Lane {
|
||||
memarg: translate_mem_arg(memarg),
|
||||
lane,
|
||||
},
|
||||
V128Store16Lane { memarg, lane } => wasm_encoder::Instruction::V128Store16Lane {
|
||||
memarg: translate_mem_arg(memarg),
|
||||
lane,
|
||||
},
|
||||
V128Store32Lane { memarg, lane } => wasm_encoder::Instruction::V128Store32Lane {
|
||||
memarg: translate_mem_arg(memarg),
|
||||
lane,
|
||||
},
|
||||
V128Store64Lane { memarg, lane } => wasm_encoder::Instruction::V128Store64Lane {
|
||||
memarg: translate_mem_arg(memarg),
|
||||
lane,
|
||||
},
|
||||
V128Const(c) => wasm_encoder::Instruction::V128Const(c),
|
||||
I8x16Shuffle { lanes } => wasm_encoder::Instruction::I8x16Shuffle { lanes },
|
||||
I8x16ExtractLaneS { lane } => wasm_encoder::Instruction::I8x16ExtractLaneS { lane },
|
||||
I8x16ExtractLaneU { lane } => wasm_encoder::Instruction::I8x16ExtractLaneU { lane },
|
||||
I8x16ReplaceLane { lane } => wasm_encoder::Instruction::I8x16ReplaceLane { lane },
|
||||
I16x8ExtractLaneS { lane } => wasm_encoder::Instruction::I16x8ExtractLaneS { lane },
|
||||
I16x8ExtractLaneU { lane } => wasm_encoder::Instruction::I16x8ExtractLaneU { lane },
|
||||
I16x8ReplaceLane { lane } => wasm_encoder::Instruction::I16x8ReplaceLane { lane },
|
||||
I32x4ExtractLane { lane } => wasm_encoder::Instruction::I32x4ExtractLane { lane },
|
||||
I32x4ReplaceLane { lane } => wasm_encoder::Instruction::I32x4ReplaceLane { lane },
|
||||
I64x2ExtractLane { lane } => wasm_encoder::Instruction::I64x2ExtractLane { lane },
|
||||
I64x2ReplaceLane { lane } => wasm_encoder::Instruction::I64x2ReplaceLane { lane },
|
||||
F32x4ExtractLane { lane } => wasm_encoder::Instruction::F32x4ExtractLane { lane },
|
||||
F32x4ReplaceLane { lane } => wasm_encoder::Instruction::F32x4ReplaceLane { lane },
|
||||
F64x2ExtractLane { lane } => wasm_encoder::Instruction::F64x2ExtractLane { lane },
|
||||
F64x2ReplaceLane { lane } => wasm_encoder::Instruction::F64x2ReplaceLane { lane },
|
||||
I8x16Swizzle => wasm_encoder::Instruction::I8x16Swizzle,
|
||||
I8x16Splat => wasm_encoder::Instruction::I8x16Splat,
|
||||
I16x8Splat => wasm_encoder::Instruction::I16x8Splat,
|
||||
I32x4Splat => wasm_encoder::Instruction::I32x4Splat,
|
||||
I64x2Splat => wasm_encoder::Instruction::I64x2Splat,
|
||||
F32x4Splat => wasm_encoder::Instruction::F32x4Splat,
|
||||
F64x2Splat => wasm_encoder::Instruction::F64x2Splat,
|
||||
I8x16Eq => wasm_encoder::Instruction::I8x16Eq,
|
||||
I8x16Ne => wasm_encoder::Instruction::I8x16Ne,
|
||||
I8x16LtS => wasm_encoder::Instruction::I8x16LtS,
|
||||
I8x16LtU => wasm_encoder::Instruction::I8x16LtU,
|
||||
I8x16GtS => wasm_encoder::Instruction::I8x16GtS,
|
||||
I8x16GtU => wasm_encoder::Instruction::I8x16GtU,
|
||||
I8x16LeS => wasm_encoder::Instruction::I8x16LeS,
|
||||
I8x16LeU => wasm_encoder::Instruction::I8x16LeU,
|
||||
I8x16GeS => wasm_encoder::Instruction::I8x16GeS,
|
||||
I8x16GeU => wasm_encoder::Instruction::I8x16GeU,
|
||||
I16x8Eq => wasm_encoder::Instruction::I16x8Eq,
|
||||
I16x8Ne => wasm_encoder::Instruction::I16x8Ne,
|
||||
I16x8LtS => wasm_encoder::Instruction::I16x8LtS,
|
||||
I16x8LtU => wasm_encoder::Instruction::I16x8LtU,
|
||||
I16x8GtS => wasm_encoder::Instruction::I16x8GtS,
|
||||
I16x8GtU => wasm_encoder::Instruction::I16x8GtU,
|
||||
I16x8LeS => wasm_encoder::Instruction::I16x8LeS,
|
||||
I16x8LeU => wasm_encoder::Instruction::I16x8LeU,
|
||||
I16x8GeS => wasm_encoder::Instruction::I16x8GeS,
|
||||
I16x8GeU => wasm_encoder::Instruction::I16x8GeU,
|
||||
I32x4Eq => wasm_encoder::Instruction::I32x4Eq,
|
||||
I32x4Ne => wasm_encoder::Instruction::I32x4Ne,
|
||||
I32x4LtS => wasm_encoder::Instruction::I32x4LtS,
|
||||
I32x4LtU => wasm_encoder::Instruction::I32x4LtU,
|
||||
I32x4GtS => wasm_encoder::Instruction::I32x4GtS,
|
||||
I32x4GtU => wasm_encoder::Instruction::I32x4GtU,
|
||||
I32x4LeS => wasm_encoder::Instruction::I32x4LeS,
|
||||
I32x4LeU => wasm_encoder::Instruction::I32x4LeU,
|
||||
I32x4GeS => wasm_encoder::Instruction::I32x4GeS,
|
||||
I32x4GeU => wasm_encoder::Instruction::I32x4GeU,
|
||||
I64x2Eq => wasm_encoder::Instruction::I64x2Eq,
|
||||
I64x2Ne => wasm_encoder::Instruction::I64x2Ne,
|
||||
I64x2LtS => wasm_encoder::Instruction::I64x2LtS,
|
||||
I64x2GtS => wasm_encoder::Instruction::I64x2GtS,
|
||||
I64x2LeS => wasm_encoder::Instruction::I64x2LeS,
|
||||
I64x2GeS => wasm_encoder::Instruction::I64x2GeS,
|
||||
F32x4Eq => wasm_encoder::Instruction::F32x4Eq,
|
||||
F32x4Ne => wasm_encoder::Instruction::F32x4Ne,
|
||||
F32x4Lt => wasm_encoder::Instruction::F32x4Lt,
|
||||
F32x4Gt => wasm_encoder::Instruction::F32x4Gt,
|
||||
F32x4Le => wasm_encoder::Instruction::F32x4Le,
|
||||
F32x4Ge => wasm_encoder::Instruction::F32x4Ge,
|
||||
F64x2Eq => wasm_encoder::Instruction::F64x2Eq,
|
||||
F64x2Ne => wasm_encoder::Instruction::F64x2Ne,
|
||||
F64x2Lt => wasm_encoder::Instruction::F64x2Lt,
|
||||
F64x2Gt => wasm_encoder::Instruction::F64x2Gt,
|
||||
F64x2Le => wasm_encoder::Instruction::F64x2Le,
|
||||
F64x2Ge => wasm_encoder::Instruction::F64x2Ge,
|
||||
V128Not => wasm_encoder::Instruction::V128Not,
|
||||
V128And => wasm_encoder::Instruction::V128And,
|
||||
V128AndNot => wasm_encoder::Instruction::V128AndNot,
|
||||
V128Or => wasm_encoder::Instruction::V128Or,
|
||||
V128Xor => wasm_encoder::Instruction::V128Xor,
|
||||
V128Bitselect => wasm_encoder::Instruction::V128Bitselect,
|
||||
V128AnyTrue => wasm_encoder::Instruction::V128AnyTrue,
|
||||
I8x16Abs => wasm_encoder::Instruction::I8x16Abs,
|
||||
I8x16Neg => wasm_encoder::Instruction::I8x16Neg,
|
||||
I8x16Popcnt => wasm_encoder::Instruction::I8x16Popcnt,
|
||||
I8x16AllTrue => wasm_encoder::Instruction::I8x16AllTrue,
|
||||
I8x16Bitmask => wasm_encoder::Instruction::I8x16Bitmask,
|
||||
I8x16NarrowI16x8S => wasm_encoder::Instruction::I8x16NarrowI16x8S,
|
||||
I8x16NarrowI16x8U => wasm_encoder::Instruction::I8x16NarrowI16x8U,
|
||||
I8x16Shl => wasm_encoder::Instruction::I8x16Shl,
|
||||
I8x16ShrS => wasm_encoder::Instruction::I8x16ShrS,
|
||||
I8x16ShrU => wasm_encoder::Instruction::I8x16ShrU,
|
||||
I8x16Add => wasm_encoder::Instruction::I8x16Add,
|
||||
I8x16AddSatS => wasm_encoder::Instruction::I8x16AddSatS,
|
||||
I8x16AddSatU => wasm_encoder::Instruction::I8x16AddSatU,
|
||||
I8x16Sub => wasm_encoder::Instruction::I8x16Sub,
|
||||
I8x16SubSatS => wasm_encoder::Instruction::I8x16SubSatS,
|
||||
I8x16SubSatU => wasm_encoder::Instruction::I8x16SubSatU,
|
||||
I8x16MinS => wasm_encoder::Instruction::I8x16MinS,
|
||||
I8x16MinU => wasm_encoder::Instruction::I8x16MinU,
|
||||
I8x16MaxS => wasm_encoder::Instruction::I8x16MaxS,
|
||||
I8x16MaxU => wasm_encoder::Instruction::I8x16MaxU,
|
||||
I8x16RoundingAverageU => wasm_encoder::Instruction::I8x16RoundingAverageU,
|
||||
I16x8ExtAddPairwiseI8x16S => wasm_encoder::Instruction::I16x8ExtAddPairwiseI8x16S,
|
||||
I16x8ExtAddPairwiseI8x16U => wasm_encoder::Instruction::I16x8ExtAddPairwiseI8x16U,
|
||||
I16x8Abs => wasm_encoder::Instruction::I16x8Abs,
|
||||
I16x8Neg => wasm_encoder::Instruction::I16x8Neg,
|
||||
I16x8Q15MulrSatS => wasm_encoder::Instruction::I16x8Q15MulrSatS,
|
||||
I16x8AllTrue => wasm_encoder::Instruction::I16x8AllTrue,
|
||||
I16x8Bitmask => wasm_encoder::Instruction::I16x8Bitmask,
|
||||
I16x8NarrowI32x4S => wasm_encoder::Instruction::I16x8NarrowI32x4S,
|
||||
I16x8NarrowI32x4U => wasm_encoder::Instruction::I16x8NarrowI32x4U,
|
||||
I16x8ExtendLowI8x16S => wasm_encoder::Instruction::I16x8ExtendLowI8x16S,
|
||||
I16x8ExtendHighI8x16S => wasm_encoder::Instruction::I16x8ExtendHighI8x16S,
|
||||
I16x8ExtendLowI8x16U => wasm_encoder::Instruction::I16x8ExtendLowI8x16U,
|
||||
I16x8ExtendHighI8x16U => wasm_encoder::Instruction::I16x8ExtendHighI8x16U,
|
||||
I16x8Shl => wasm_encoder::Instruction::I16x8Shl,
|
||||
I16x8ShrS => wasm_encoder::Instruction::I16x8ShrS,
|
||||
I16x8ShrU => wasm_encoder::Instruction::I16x8ShrU,
|
||||
I16x8Add => wasm_encoder::Instruction::I16x8Add,
|
||||
I16x8AddSatS => wasm_encoder::Instruction::I16x8AddSatS,
|
||||
I16x8AddSatU => wasm_encoder::Instruction::I16x8AddSatU,
|
||||
I16x8Sub => wasm_encoder::Instruction::I16x8Sub,
|
||||
I16x8SubSatS => wasm_encoder::Instruction::I16x8SubSatS,
|
||||
I16x8SubSatU => wasm_encoder::Instruction::I16x8SubSatU,
|
||||
I16x8Mul => wasm_encoder::Instruction::I16x8Mul,
|
||||
I16x8MinS => wasm_encoder::Instruction::I16x8MinS,
|
||||
I16x8MinU => wasm_encoder::Instruction::I16x8MinU,
|
||||
I16x8MaxS => wasm_encoder::Instruction::I16x8MaxS,
|
||||
I16x8MaxU => wasm_encoder::Instruction::I16x8MaxU,
|
||||
I16x8RoundingAverageU => wasm_encoder::Instruction::I16x8RoundingAverageU,
|
||||
I16x8ExtMulLowI8x16S => wasm_encoder::Instruction::I16x8ExtMulLowI8x16S,
|
||||
I16x8ExtMulHighI8x16S => wasm_encoder::Instruction::I16x8ExtMulHighI8x16S,
|
||||
I16x8ExtMulLowI8x16U => wasm_encoder::Instruction::I16x8ExtMulLowI8x16U,
|
||||
I16x8ExtMulHighI8x16U => wasm_encoder::Instruction::I16x8ExtMulHighI8x16U,
|
||||
I32x4ExtAddPairwiseI16x8S => wasm_encoder::Instruction::I32x4ExtAddPairwiseI16x8S,
|
||||
I32x4ExtAddPairwiseI16x8U => wasm_encoder::Instruction::I32x4ExtAddPairwiseI16x8U,
|
||||
I32x4Abs => wasm_encoder::Instruction::I32x4Abs,
|
||||
I32x4Neg => wasm_encoder::Instruction::I32x4Neg,
|
||||
I32x4AllTrue => wasm_encoder::Instruction::I32x4AllTrue,
|
||||
I32x4Bitmask => wasm_encoder::Instruction::I32x4Bitmask,
|
||||
I32x4ExtendLowI16x8S => wasm_encoder::Instruction::I32x4ExtendLowI16x8S,
|
||||
I32x4ExtendHighI16x8S => wasm_encoder::Instruction::I32x4ExtendHighI16x8S,
|
||||
I32x4ExtendLowI16x8U => wasm_encoder::Instruction::I32x4ExtendLowI16x8U,
|
||||
I32x4ExtendHighI16x8U => wasm_encoder::Instruction::I32x4ExtendHighI16x8U,
|
||||
I32x4Shl => wasm_encoder::Instruction::I32x4Shl,
|
||||
I32x4ShrS => wasm_encoder::Instruction::I32x4ShrS,
|
||||
I32x4ShrU => wasm_encoder::Instruction::I32x4ShrU,
|
||||
I32x4Add => wasm_encoder::Instruction::I32x4Add,
|
||||
I32x4Sub => wasm_encoder::Instruction::I32x4Sub,
|
||||
I32x4Mul => wasm_encoder::Instruction::I32x4Mul,
|
||||
I32x4MinS => wasm_encoder::Instruction::I32x4MinS,
|
||||
I32x4MinU => wasm_encoder::Instruction::I32x4MinU,
|
||||
I32x4MaxS => wasm_encoder::Instruction::I32x4MaxS,
|
||||
I32x4MaxU => wasm_encoder::Instruction::I32x4MaxU,
|
||||
I32x4DotI16x8S => wasm_encoder::Instruction::I32x4DotI16x8S,
|
||||
I32x4ExtMulLowI16x8S => wasm_encoder::Instruction::I32x4ExtMulLowI16x8S,
|
||||
I32x4ExtMulHighI16x8S => wasm_encoder::Instruction::I32x4ExtMulHighI16x8S,
|
||||
I32x4ExtMulLowI16x8U => wasm_encoder::Instruction::I32x4ExtMulLowI16x8U,
|
||||
I32x4ExtMulHighI16x8U => wasm_encoder::Instruction::I32x4ExtMulHighI16x8U,
|
||||
I64x2Abs => wasm_encoder::Instruction::I64x2Abs,
|
||||
I64x2Neg => wasm_encoder::Instruction::I64x2Neg,
|
||||
I64x2AllTrue => wasm_encoder::Instruction::I64x2AllTrue,
|
||||
I64x2Bitmask => wasm_encoder::Instruction::I64x2Bitmask,
|
||||
I64x2ExtendLowI32x4S => wasm_encoder::Instruction::I64x2ExtendLowI32x4S,
|
||||
I64x2ExtendHighI32x4S => wasm_encoder::Instruction::I64x2ExtendHighI32x4S,
|
||||
I64x2ExtendLowI32x4U => wasm_encoder::Instruction::I64x2ExtendLowI32x4U,
|
||||
I64x2ExtendHighI32x4U => wasm_encoder::Instruction::I64x2ExtendHighI32x4U,
|
||||
I64x2Shl => wasm_encoder::Instruction::I64x2Shl,
|
||||
I64x2ShrS => wasm_encoder::Instruction::I64x2ShrS,
|
||||
I64x2ShrU => wasm_encoder::Instruction::I64x2ShrU,
|
||||
I64x2Add => wasm_encoder::Instruction::I64x2Add,
|
||||
I64x2Sub => wasm_encoder::Instruction::I64x2Sub,
|
||||
I64x2Mul => wasm_encoder::Instruction::I64x2Mul,
|
||||
I64x2ExtMulLowI32x4S => wasm_encoder::Instruction::I64x2ExtMulLowI32x4S,
|
||||
I64x2ExtMulHighI32x4S => wasm_encoder::Instruction::I64x2ExtMulHighI32x4S,
|
||||
I64x2ExtMulLowI32x4U => wasm_encoder::Instruction::I64x2ExtMulLowI32x4U,
|
||||
I64x2ExtMulHighI32x4U => wasm_encoder::Instruction::I64x2ExtMulHighI32x4U,
|
||||
F32x4Ceil => wasm_encoder::Instruction::F32x4Ceil,
|
||||
F32x4Floor => wasm_encoder::Instruction::F32x4Floor,
|
||||
F32x4Trunc => wasm_encoder::Instruction::F32x4Trunc,
|
||||
F32x4Nearest => wasm_encoder::Instruction::F32x4Nearest,
|
||||
F32x4Abs => wasm_encoder::Instruction::F32x4Abs,
|
||||
F32x4Neg => wasm_encoder::Instruction::F32x4Neg,
|
||||
F32x4Sqrt => wasm_encoder::Instruction::F32x4Sqrt,
|
||||
F32x4Add => wasm_encoder::Instruction::F32x4Add,
|
||||
F32x4Sub => wasm_encoder::Instruction::F32x4Sub,
|
||||
F32x4Mul => wasm_encoder::Instruction::F32x4Mul,
|
||||
F32x4Div => wasm_encoder::Instruction::F32x4Div,
|
||||
F32x4Min => wasm_encoder::Instruction::F32x4Min,
|
||||
F32x4Max => wasm_encoder::Instruction::F32x4Max,
|
||||
F32x4PMin => wasm_encoder::Instruction::F32x4PMin,
|
||||
F32x4PMax => wasm_encoder::Instruction::F32x4PMax,
|
||||
F64x2Ceil => wasm_encoder::Instruction::F64x2Ceil,
|
||||
F64x2Floor => wasm_encoder::Instruction::F64x2Floor,
|
||||
F64x2Trunc => wasm_encoder::Instruction::F64x2Trunc,
|
||||
F64x2Nearest => wasm_encoder::Instruction::F64x2Nearest,
|
||||
F64x2Abs => wasm_encoder::Instruction::F64x2Abs,
|
||||
F64x2Neg => wasm_encoder::Instruction::F64x2Neg,
|
||||
F64x2Sqrt => wasm_encoder::Instruction::F64x2Sqrt,
|
||||
F64x2Add => wasm_encoder::Instruction::F64x2Add,
|
||||
F64x2Sub => wasm_encoder::Instruction::F64x2Sub,
|
||||
F64x2Mul => wasm_encoder::Instruction::F64x2Mul,
|
||||
F64x2Div => wasm_encoder::Instruction::F64x2Div,
|
||||
F64x2Min => wasm_encoder::Instruction::F64x2Min,
|
||||
F64x2Max => wasm_encoder::Instruction::F64x2Max,
|
||||
F64x2PMin => wasm_encoder::Instruction::F64x2PMin,
|
||||
F64x2PMax => wasm_encoder::Instruction::F64x2PMax,
|
||||
I32x4TruncSatF32x4S => wasm_encoder::Instruction::I32x4TruncSatF32x4S,
|
||||
I32x4TruncSatF32x4U => wasm_encoder::Instruction::I32x4TruncSatF32x4U,
|
||||
F32x4ConvertI32x4S => wasm_encoder::Instruction::F32x4ConvertI32x4S,
|
||||
F32x4ConvertI32x4U => wasm_encoder::Instruction::F32x4ConvertI32x4U,
|
||||
I32x4TruncSatF64x2SZero => wasm_encoder::Instruction::I32x4TruncSatF64x2SZero,
|
||||
I32x4TruncSatF64x2UZero => wasm_encoder::Instruction::I32x4TruncSatF64x2UZero,
|
||||
F64x2ConvertLowI32x4S => wasm_encoder::Instruction::F64x2ConvertLowI32x4S,
|
||||
F64x2ConvertLowI32x4U => wasm_encoder::Instruction::F64x2ConvertLowI32x4U,
|
||||
F32x4DemoteF64x2Zero => wasm_encoder::Instruction::F32x4DemoteF64x2Zero,
|
||||
F64x2PromoteLowF32x4 => wasm_encoder::Instruction::F64x2PromoteLowF32x4,
|
||||
}
|
||||
}
|
2898
third_party/rust/wasm-smith/src/lib.rs
vendored
2898
third_party/rust/wasm-smith/src/lib.rs
vendored
File diff suppressed because it is too large
Load Diff
42
third_party/rust/wasm-smith/tests/component.rs
vendored
Normal file
42
third_party/rust/wasm-smith/tests/component.rs
vendored
Normal file
@ -0,0 +1,42 @@
|
||||
use arbitrary::{Arbitrary, Unstructured};
|
||||
use rand::{rngs::SmallRng, RngCore, SeedableRng};
|
||||
use wasm_smith::Component;
|
||||
|
||||
#[test]
|
||||
fn smoke_test_component() {
|
||||
const NUM_RUNS: usize = 4096;
|
||||
|
||||
let mut rng = SmallRng::seed_from_u64(0);
|
||||
let mut buf = vec![0; 1024];
|
||||
let mut ok_count = 0;
|
||||
|
||||
for _ in 0..NUM_RUNS {
|
||||
rng.fill_bytes(&mut buf);
|
||||
let u = Unstructured::new(&buf);
|
||||
if let Ok(component) = Component::arbitrary_take_rest(u) {
|
||||
ok_count += 1;
|
||||
let component = component.to_bytes();
|
||||
|
||||
let mut validator =
|
||||
wasmparser::Validator::new_with_features(wasmparser::WasmFeatures {
|
||||
component_model: true,
|
||||
..Default::default()
|
||||
});
|
||||
if let Err(e) = validator.validate_all(&component) {
|
||||
std::fs::write("component.wasm", &component).unwrap();
|
||||
panic!(
|
||||
"generated component should be valid; failing binary written \
|
||||
to `component.wasm`. Error: {}",
|
||||
e
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
println!(
|
||||
"Generated {} / {} ({:.02}%) arbitrary components okay",
|
||||
ok_count,
|
||||
NUM_RUNS,
|
||||
ok_count as f64 / NUM_RUNS as f64 * 100.0
|
||||
);
|
||||
}
|
297
third_party/rust/wasm-smith/tests/core.rs
vendored
Normal file
297
third_party/rust/wasm-smith/tests/core.rs
vendored
Normal file
@ -0,0 +1,297 @@
|
||||
use arbitrary::{Arbitrary, Unstructured};
|
||||
use rand::{rngs::SmallRng, RngCore, SeedableRng};
|
||||
use std::collections::HashMap;
|
||||
use wasm_smith::{Config, ConfiguredModule, Module, SwarmConfig};
|
||||
use wasmparser::{Parser, TypeRef, ValType, Validator, WasmFeatures};
|
||||
|
||||
#[test]
|
||||
fn smoke_test_module() {
|
||||
let mut rng = SmallRng::seed_from_u64(0);
|
||||
let mut buf = vec![0; 2048];
|
||||
for _ in 0..1024 {
|
||||
rng.fill_bytes(&mut buf);
|
||||
let u = Unstructured::new(&buf);
|
||||
if let Ok(module) = Module::arbitrary_take_rest(u) {
|
||||
let wasm_bytes = module.to_bytes();
|
||||
|
||||
let mut validator = Validator::new_with_features(wasm_features());
|
||||
validate(&mut validator, &wasm_bytes);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn smoke_test_ensure_termination() {
|
||||
let mut rng = SmallRng::seed_from_u64(0);
|
||||
let mut buf = vec![0; 2048];
|
||||
for _ in 0..1024 {
|
||||
rng.fill_bytes(&mut buf);
|
||||
let u = Unstructured::new(&buf);
|
||||
if let Ok(mut module) = Module::arbitrary_take_rest(u) {
|
||||
module.ensure_termination(10);
|
||||
let wasm_bytes = module.to_bytes();
|
||||
|
||||
let mut validator = Validator::new_with_features(wasm_features());
|
||||
validate(&mut validator, &wasm_bytes);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn smoke_test_swarm_config() {
|
||||
let mut rng = SmallRng::seed_from_u64(0);
|
||||
let mut buf = vec![0; 2048];
|
||||
for _ in 0..1024 {
|
||||
rng.fill_bytes(&mut buf);
|
||||
let u = Unstructured::new(&buf);
|
||||
if let Ok(module) = ConfiguredModule::<SwarmConfig>::arbitrary_take_rest(u) {
|
||||
let module = module.module;
|
||||
let wasm_bytes = module.to_bytes();
|
||||
|
||||
let mut validator = Validator::new_with_features(wasm_features());
|
||||
validate(&mut validator, &wasm_bytes);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn multi_value_disabled() {
|
||||
let mut rng = SmallRng::seed_from_u64(42);
|
||||
let mut buf = vec![0; 2048];
|
||||
for _ in 0..10 {
|
||||
rng.fill_bytes(&mut buf);
|
||||
let mut u = Unstructured::new(&buf);
|
||||
let mut cfg = SwarmConfig::arbitrary(&mut u).unwrap();
|
||||
cfg.multi_value_enabled = false;
|
||||
if let Ok(module) = Module::new(cfg, &mut u) {
|
||||
let wasm_bytes = module.to_bytes();
|
||||
let mut features = wasm_features();
|
||||
features.multi_value = false;
|
||||
let mut validator = Validator::new_with_features(features);
|
||||
validate(&mut validator, &wasm_bytes);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn smoke_can_smith_valid_webassembly_one_point_oh() {
|
||||
let mut rng = SmallRng::seed_from_u64(42);
|
||||
let mut buf = vec![0; 10240];
|
||||
for _ in 0..100 {
|
||||
rng.fill_bytes(&mut buf);
|
||||
let mut u = Unstructured::new(&buf);
|
||||
let mut cfg = SwarmConfig::arbitrary(&mut u).unwrap();
|
||||
cfg.sign_extension_enabled = false;
|
||||
cfg.saturating_float_to_int_enabled = false;
|
||||
cfg.reference_types_enabled = false;
|
||||
cfg.multi_value_enabled = false;
|
||||
cfg.bulk_memory_enabled = false;
|
||||
cfg.simd_enabled = false;
|
||||
cfg.relaxed_simd_enabled = false;
|
||||
cfg.exceptions_enabled = false;
|
||||
cfg.memory64_enabled = false;
|
||||
cfg.max_memories = 1;
|
||||
cfg.max_tables = 1;
|
||||
let features = parser_features_from_config(&cfg);
|
||||
if let Ok(module) = Module::new(cfg, &mut u) {
|
||||
let wasm_bytes = module.to_bytes();
|
||||
// This table should set to `true` only features specified in wasm-core-1 spec.
|
||||
let mut validator = Validator::new_with_features(features);
|
||||
validate(&mut validator, &wasm_bytes);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn smoke_test_imports_config() {
|
||||
let mut n_partial = 0;
|
||||
let mut global_imports_seen = HashMap::<_, bool>::new();
|
||||
let mut rng = SmallRng::seed_from_u64(11);
|
||||
let mut buf = vec![0; 512];
|
||||
for _ in 0..1024 {
|
||||
rng.fill_bytes(&mut buf);
|
||||
|
||||
let mut u = Unstructured::new(&buf);
|
||||
let (config, available) = import_config(&mut u);
|
||||
let features = parser_features_from_config(&config);
|
||||
|
||||
if let Ok(module) = Module::new(config, &mut u) {
|
||||
let wasm_bytes = module.to_bytes();
|
||||
let mut validator = Validator::new_with_features(features);
|
||||
validate(&mut validator, &wasm_bytes);
|
||||
let mut imports_seen = available
|
||||
.iter()
|
||||
.map(|(m, f, t)| ((*m, *f), (false, t)))
|
||||
.collect::<HashMap<_, _>>();
|
||||
let mut sig_types = Vec::new();
|
||||
|
||||
for payload in Parser::new(0).parse_all(&wasm_bytes) {
|
||||
let payload = payload.unwrap();
|
||||
if let wasmparser::Payload::TypeSection(mut rdr) = payload {
|
||||
// Gather the signature types to later check function types against.
|
||||
while let Ok(ty) = rdr.read() {
|
||||
match ty {
|
||||
wasmparser::Type::Func(ft) => sig_types.push(ft),
|
||||
}
|
||||
}
|
||||
} else if let wasmparser::Payload::ImportSection(mut rdr) = payload {
|
||||
// Read out imports, checking that they all are within the list of expected
|
||||
// imports (i.e. we don't generate arbitrary ones), and that we handle the
|
||||
// logic correctly (i.e. signature types are as expected)
|
||||
while let Ok(import) = rdr.read() {
|
||||
use AvailableImportKind as I;
|
||||
let entry = imports_seen.get_mut(&(import.module, import.name));
|
||||
match (entry, &import.ty) {
|
||||
(Some((true, _)), _) => panic!("duplicate import of {:?}", import),
|
||||
(Some((seen, I::Memory)), TypeRef::Memory(_)) => *seen = true,
|
||||
(Some((seen, I::Global(t))), TypeRef::Global(gt))
|
||||
if *t == gt.content_type =>
|
||||
{
|
||||
*seen = true
|
||||
}
|
||||
(Some((seen, I::Table(t))), TypeRef::Table(tt))
|
||||
if *t == tt.element_type =>
|
||||
{
|
||||
*seen = true
|
||||
}
|
||||
(Some((seen, I::Func(p, r))), TypeRef::Func(sig_idx))
|
||||
if &sig_types[*sig_idx as usize].params[..] == *p
|
||||
&& &sig_types[*sig_idx as usize].returns[..] == *r =>
|
||||
{
|
||||
*seen = true
|
||||
}
|
||||
(
|
||||
Some((seen, I::Tag(p))),
|
||||
TypeRef::Tag(wasmparser::TagType { func_type_idx, .. }),
|
||||
) if &sig_types[*func_type_idx as usize].params[..] == *p
|
||||
&& sig_types[*func_type_idx as usize].returns.is_empty() =>
|
||||
{
|
||||
*seen = true
|
||||
}
|
||||
(Some((_, expected)), _) => panic!(
|
||||
"import {:?} type mismatch, expected: {:?}",
|
||||
import, expected
|
||||
),
|
||||
(None, _) => panic!("import of an unknown entity: {:?}", import),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Verify that we have seen both instances with partial imports (i.e. we don't always
|
||||
// just copy over all the imports from the example module) and also that we eventually
|
||||
// observe all of the imports being used (i.e. selection is reasonably random)
|
||||
for (m, f, _) in &available[..] {
|
||||
let seen = imports_seen[&(*m, *f)];
|
||||
let global_seen = global_imports_seen
|
||||
.entry((m.to_string(), f.to_string()))
|
||||
.or_default();
|
||||
*global_seen |= seen.0;
|
||||
}
|
||||
if !imports_seen.values().all(|v| v.0) {
|
||||
n_partial += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
assert!(global_imports_seen.values().all(|v| *v));
|
||||
assert!(n_partial > 0);
|
||||
}
|
||||
|
||||
fn wasm_features() -> WasmFeatures {
|
||||
WasmFeatures {
|
||||
multi_memory: true,
|
||||
relaxed_simd: true,
|
||||
memory64: true,
|
||||
exceptions: true,
|
||||
..WasmFeatures::default()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
enum AvailableImportKind {
|
||||
Func(&'static [ValType], &'static [ValType]),
|
||||
Tag(&'static [ValType]),
|
||||
Global(ValType),
|
||||
Table(ValType),
|
||||
Memory,
|
||||
}
|
||||
|
||||
fn import_config(
|
||||
u: &mut Unstructured,
|
||||
) -> (
|
||||
SwarmConfig,
|
||||
Vec<(&'static str, &'static str, AvailableImportKind)>,
|
||||
) {
|
||||
let mut config = SwarmConfig::arbitrary(u).expect("arbitrary swarm");
|
||||
config.exceptions_enabled = u.arbitrary().expect("exceptions enabled for swarm");
|
||||
let available = {
|
||||
use {AvailableImportKind::*, ValType::*};
|
||||
vec![
|
||||
("env", "pi", Func(&[I32], &[])),
|
||||
("env", "pi2", Func(&[I32], &[])),
|
||||
("env", "pipi2", Func(&[I32, I32], &[])),
|
||||
("env", "po", Func(&[], &[I32])),
|
||||
("env", "pipo", Func(&[I32], &[I32])),
|
||||
("env", "popo", Func(&[], &[I32, I32])),
|
||||
("env", "mem", Memory),
|
||||
("env", "tbl", Table(FuncRef)),
|
||||
("vars", "g", Global(I64)),
|
||||
("tags", "tag1", Tag(&[I32])),
|
||||
]
|
||||
};
|
||||
config.available_imports = Some(
|
||||
wat::parse_str(
|
||||
r#"
|
||||
(module
|
||||
(import "env" "pi" (func (param i32)))
|
||||
(import "env" "pi2" (func (param i32)))
|
||||
(import "env" "pipi2" (func (param i32 i32)))
|
||||
(import "env" "po" (func (result i32)))
|
||||
(import "env" "pipo" (func (param i32) (result i32)))
|
||||
(import "env" "popo" (func (result i32 i32)))
|
||||
(import "env" "mem" (memory 1 16))
|
||||
(import "env" "tbl" (table 1 16 funcref))
|
||||
(import "vars" "g" (global i64))
|
||||
(import "tags" "tag1" (tag (param i32)))
|
||||
)
|
||||
"#,
|
||||
)
|
||||
.unwrap()
|
||||
.into(),
|
||||
);
|
||||
(config, available)
|
||||
}
|
||||
|
||||
fn parser_features_from_config(config: &impl Config) -> WasmFeatures {
|
||||
WasmFeatures {
|
||||
mutable_global: true,
|
||||
saturating_float_to_int: config.saturating_float_to_int_enabled(),
|
||||
sign_extension: config.sign_extension_ops_enabled(),
|
||||
reference_types: config.reference_types_enabled(),
|
||||
multi_value: config.multi_value_enabled(),
|
||||
bulk_memory: config.bulk_memory_enabled(),
|
||||
simd: config.simd_enabled(),
|
||||
relaxed_simd: config.relaxed_simd_enabled(),
|
||||
multi_memory: config.max_memories() > 1,
|
||||
exceptions: config.exceptions_enabled(),
|
||||
memory64: config.memory64_enabled(),
|
||||
|
||||
threads: false,
|
||||
tail_call: false,
|
||||
deterministic_only: false,
|
||||
extended_const: false,
|
||||
component_model: false,
|
||||
}
|
||||
}
|
||||
|
||||
fn validate(validator: &mut Validator, bytes: &[u8]) {
|
||||
let err = match validator.validate_all(bytes) {
|
||||
Ok(_) => return,
|
||||
Err(e) => e,
|
||||
};
|
||||
drop(std::fs::write("test.wasm", &bytes));
|
||||
if let Ok(text) = wasmprinter::print_bytes(bytes) {
|
||||
drop(std::fs::write("test.wat", &text));
|
||||
}
|
||||
panic!("wasm failed to validate {:?}", err);
|
||||
}
|
84
third_party/rust/wasm-smith/tests/tests.rs
vendored
84
third_party/rust/wasm-smith/tests/tests.rs
vendored
@ -1,84 +0,0 @@
|
||||
use arbitrary::{Arbitrary, Unstructured};
|
||||
use rand::{rngs::SmallRng, RngCore, SeedableRng};
|
||||
use wasm_smith::{ConfiguredModule, Module, SwarmConfig};
|
||||
use wasmparser::{Validator, WasmFeatures};
|
||||
|
||||
fn wasm_features() -> WasmFeatures {
|
||||
WasmFeatures {
|
||||
multi_value: true,
|
||||
multi_memory: true,
|
||||
bulk_memory: true,
|
||||
reference_types: true,
|
||||
simd: true,
|
||||
memory64: true,
|
||||
exceptions: true,
|
||||
..WasmFeatures::default()
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn smoke_test_module() {
|
||||
let mut rng = SmallRng::seed_from_u64(0);
|
||||
let mut buf = vec![0; 1024];
|
||||
for _ in 0..1024 {
|
||||
rng.fill_bytes(&mut buf);
|
||||
let u = Unstructured::new(&buf);
|
||||
if let Ok(module) = Module::arbitrary_take_rest(u) {
|
||||
let wasm_bytes = module.to_bytes();
|
||||
|
||||
let mut validator = Validator::new();
|
||||
validator.wasm_features(wasm_features());
|
||||
validate(&mut validator, &wasm_bytes);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn smoke_test_ensure_termination() {
|
||||
let mut rng = SmallRng::seed_from_u64(0);
|
||||
let mut buf = vec![0; 1024];
|
||||
for _ in 0..1024 {
|
||||
rng.fill_bytes(&mut buf);
|
||||
let u = Unstructured::new(&buf);
|
||||
if let Ok(mut module) = Module::arbitrary_take_rest(u) {
|
||||
module.ensure_termination(10);
|
||||
let wasm_bytes = module.to_bytes();
|
||||
|
||||
let mut validator = Validator::new();
|
||||
validator.wasm_features(wasm_features());
|
||||
validate(&mut validator, &wasm_bytes);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn smoke_test_swarm_config() {
|
||||
let mut rng = SmallRng::seed_from_u64(0);
|
||||
let mut buf = vec![0; 1024];
|
||||
for _ in 0..1024 {
|
||||
rng.fill_bytes(&mut buf);
|
||||
let u = Unstructured::new(&buf);
|
||||
if let Ok(module) = ConfiguredModule::<SwarmConfig>::arbitrary_take_rest(u) {
|
||||
let module = module.module;
|
||||
let wasm_bytes = module.to_bytes();
|
||||
|
||||
let mut validator = Validator::new();
|
||||
let mut features = wasm_features();
|
||||
features.module_linking = module.config().module_linking_enabled();
|
||||
validator.wasm_features(features);
|
||||
validate(&mut validator, &wasm_bytes);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn validate(validator: &mut Validator, bytes: &[u8]) {
|
||||
let err = match validator.validate_all(bytes) {
|
||||
Ok(()) => return,
|
||||
Err(e) => e,
|
||||
};
|
||||
drop(std::fs::write("test.wasm", &bytes));
|
||||
if let Ok(text) = wasmprinter::print_bytes(bytes) {
|
||||
drop(std::fs::write("test.wat", &text));
|
||||
}
|
||||
panic!("wasm failed to validate {:?}", err);
|
||||
}
|
@ -1 +1 @@
|
||||
{"files":{"Cargo.lock":"b05bfb3f2377689cbeadee916519217a4a8bcca36b644458fb0d0975d39451c5","Cargo.toml":"451b39c33f593385348d4be4c29c40c13cf318d690e583e86127227ff1caa62e","LICENSE":"268872b9816f90fd8e85db5a28d33f8150ebb8dd016653fb39ef1f94f2686bc5","README.md":"1c3b4f8db61a673ee2f7dc66118b1008ce8d1a7d0f5197fbe87f1271b23de3bd","benches/benchmark.rs":"e416b75903112d91fa303e2a9cabe16dd14fa83c0f1dcf6872fd4e304ffc7772","compare-with-main.sh":"6feeddbc1d4446c8ee98057dd4befb72d2c1784373819936165e9de280545f76","examples/simple.rs":"606072a46c5c80df29da3ecd98a989feb1289243550033cd3c3e1df6045ce8ce","src/binary_reader.rs":"c79620b270db7dd7d96eeb7edc3ed5653122a4d91e87a8af093c122659c42e20","src/lib.rs":"372776c7339cc879ba2a1109e4692d09441dd6832955ed48aed1806b135b72a4","src/limits.rs":"f66a16a5a479d38d5109b2e7504b72a85bb2e0ea6f5a6b6b76f9533cf5595f46","src/module_resources.rs":"372784b2d889c72df6eea6ac2a5a285ecaec43d9216a263143453860f336dbeb","src/operators_validator.rs":"bd537a3bd065a310d5aa91b4a3565ad968651116822f9e023403c1d1659f639e","src/parser.rs":"ec1f3b40322126c6ea38d3dea484a5f754978dfdfd8f8db62c4bb1ff9cfaa4e3","src/primitives.rs":"1f9372200d04a1f84ef089c87168adb08b90640d6bbe84c0ea15dc6561f7c3ef","src/readers/alias_section.rs":"0837521da591555307d6008606308b36b517ce4cb4ea95f9d4bcf608c5fc1b44","src/readers/code_section.rs":"d7d8be8f8bf158dac6ba7ee1d6583ea386e440f728a1f6ce1aa2e91352f884f4","src/readers/data_section.rs":"be92b58b09823574b83fbdb9b9fd32ff57fa054c842b5c24861672caf4726061","src/readers/element_section.rs":"f168a3cb02439aeaa81621525e2747d3bc4743fac2237dcdf8658b67e010ca08","src/readers/event_section.rs":"3848772ed4e0ca7886d92bf02102f71141af41cb660eba5c0107db2423aeb8d0","src/readers/export_section.rs":"3fe296f1789e789009a79115052194a1352d947f2a8830945d6b7d9983bb8579","src/readers/function_section.rs":"5467d7a375c22a4cc225819212e616f275ef01516f185b346eae2ffbb5c53cb3","src/readers/global_section.rs":"359450911ac662503f90288798baec2415df6d3b80990a7b75794683df7894b8","src/readers/import_section.rs":"80906451f78c64d31a76772d97c96d18d208eeabaaaf82372b0567a8991795c1","src/readers/init_expr.rs":"7020c80013dad4518a5f969c3ab4d624b46d778f03e632871cf343964f63441c","src/readers/instance_section.rs":"178663548499468c1911ac1d25aaab8f02bce48e57b06fd207fe0cce7d3c2fd7","src/readers/linking_section.rs":"db3091a48827a5b035e2f79f40f7ed9a7ea10acd4db6ab2bbd01e17a65a4265e","src/readers/memory_section.rs":"67d8457d3167b39fc9ae2c04f3c3e28bc10be97bbdaccd681675fb8d3eba2bd3","src/readers/mod.rs":"fb788013f1cb28419f44dd9ab111c09b76ef060e053ed5d72e6b05663fd02ec9","src/readers/module_code_section.rs":"8c7be8afdfde8e5feffc0d13a8319eb7de459077369a863cee984aa91957f361","src/readers/module_section.rs":"75b9564a135aac154e7f31fba8023438f7a7babb8a426ec0d8b1d894c64ac960","src/readers/name_section.rs":"d5a448a6bd3a20e06f4a4816a2248b2305add19905eb9ccd045104ff45561759","src/readers/operators.rs":"3800f0321a776ddc5e8fb030828e4f2a65ebafa4b7f0808774384559ddfe49ea","src/readers/producers_section.rs":"77f93449e4bdcd61e4c79e47a685742f49cd5dac837ba002bce14120f14c9470","src/readers/reloc_section.rs":"e48e6acaa5145d6fbe1d74eb406ee59c43235faa47fbf0b07288504e60573a5e","src/readers/section_reader.rs":"e99763ce9c48994fd1e92f011a449936c4206a5c91d50fa580d003b6cc824ec5","src/readers/table_section.rs":"5d94185f68c4c7526a8836a2ebdb5b20fe754af58b68d2d0eb8fea62b7e6fe71","src/readers/type_section.rs":"87a54d238bf900aac0d0508e5c644d71b1e591df99367587feb68146a25a5a61","src/validator.rs":"802b64ce8110d0c241b6011786820be496b835c91deb4bc4557ac46670a1f4e5","src/validator/func.rs":"077d50113587d7ef066acfc23611c89e24776f9d3d4e5c4d980cb54ec84acf56"},"package":"52144d4c78e5cf8b055ceab8e5fa22814ce4315d6002ad32cfd914f37c12fd65"}
|
||||
{"files":{"Cargo.lock":"46bc00e7077b7968ca066ebe6d60a327b886cdf5e8d4c5d081f905e52802c0d3","Cargo.toml":"a7143b24f92d2e797e3491a04c37e59367cba6932a584379dbfcb85b03e8680f","LICENSE":"268872b9816f90fd8e85db5a28d33f8150ebb8dd016653fb39ef1f94f2686bc5","README.md":"1c3b4f8db61a673ee2f7dc66118b1008ce8d1a7d0f5197fbe87f1271b23de3bd","benches/benchmark.rs":"b4292376262051e0a7b21d0e4c31c9244ea83bc2870c5c88417693bd9d22dceb","compare-with-main.sh":"6feeddbc1d4446c8ee98057dd4befb72d2c1784373819936165e9de280545f76","examples/simple.rs":"e9eb076367cc0932e2a32651372defa4a27ef800f47fad28c0ef840ba8ea7e08","src/binary_reader.rs":"18e4a1a3dd77de2e9b377bff44b0807bcd955da662ae92eb5626b76a44c8536d","src/lib.rs":"513e383504bb1c6453419ca64de08aac62d9b211b1e5cd0e02dc88f9c760ec01","src/limits.rs":"cdd905ec48244145330550b4d37f3c7d1aa85acf35ee68cddcb422c7fc8f432b","src/parser.rs":"91e894c607ccb41f41002eff9e7ef193444a65e3225dc632b12be97976d70efc","src/readers.rs":"6986052ea86daf7e09747e1ba3411a1f6b82022d0d12f2b9c925214592a1d0c0","src/readers/component.rs":"b65a243321477082e7e310db6c1a7987af9a2ae73d69520480f5244dce17f96c","src/readers/component/aliases.rs":"384c20e1c1f4d646a1f325e677a8752a2e8a7092f0686dc30556b9ea452279db","src/readers/component/canonicals.rs":"dd791b39ff03d9133d48b950876a0074bf57be3a3e01e0d921e7e051f0284adb","src/readers/component/exports.rs":"47ca4c6f2dcbc02f7d45f331caef84e0f6ba8033fdfbe7c396e31c0509d41b33","src/readers/component/imports.rs":"ab70ec17bcf301ef6a09b6ee52e6f6133c2110a2dda9b401826435296871ea50","src/readers/component/instances.rs":"80b6e5456a6fe787159753955b042a8232bcc73ac90f9b54e2dc8b657218c049","src/readers/component/start.rs":"201fda6866b7a3293597d8ff7b9793510d0f39f96cad7d9badab715f682788df","src/readers/component/types.rs":"b6ee5a3290e6dc823033036f6c6232617a3f0180b1f5da4d7f8d112f1c0416aa","src/readers/core.rs":"6fa41494fce1e9e6bb9f890db4089c1ba5fa6a440927c37b1754d5b08f7f9c49","src/readers/core/code.rs":"563a20baf2121547762defab467ebb55878e5c42adc374213875bada4412c439","src/readers/core/custom.rs":"f80d3a994e8778a912319834228cbb772c65a4b6b1f25b41fe00d220d388831f","src/readers/core/data.rs":"6060f1d7e791225902b619c124099a130123b1c9f8b803504bfa719d8dd30368","src/readers/core/elements.rs":"b6a89d305b8296d5b54dd331013c53a6541d7e6e10838c75aba9cc5892a3a70d","src/readers/core/exports.rs":"e89609dc8459afd6b8ac21674d1274a3f715a68340b96edddc4548ccdaa5297a","src/readers/core/functions.rs":"a5cd2ea6b23268bceaa508322597223c824eb74fbcc98de784311cedccac4e9d","src/readers/core/globals.rs":"6fa4592234aa129ba50c77b2d8bd9b78c5aff16b4797d17a146c5145a582805c","src/readers/core/imports.rs":"a698e134dae961a0bd23ac8e6f4f0c6ce2a6c4b84011b2f71a9ad3375f9a4dc4","src/readers/core/init.rs":"d85665d1fd7e2714d24d19f59c699efa878ea460182dd755634fc7332f604960","src/readers/core/linking.rs":"bef98836b6e99c3be4631e5000512ee12a89405da33ff275b133d456ead2eda2","src/readers/core/memories.rs":"8b1b3ae7ae755f5ac234fcec00207e6927532f7eecb1ba16870b154fbbcac622","src/readers/core/names.rs":"844eef46d57a41846863377c431eaeafe5bc56d5d5f1ceb486724258ba175454","src/readers/core/operators.rs":"bf9d3bbd9ad8019e7f7741d59500d5e77fecc2cd549fbd7a7ec59ba59d6b5a3d","src/readers/core/producers.rs":"3ddeecdcb31f1314c95151dce97b7f6e7bb9eea892a7027a4bce5cabb751b9ba","src/readers/core/relocs.rs":"de256db170e95ec65e463d03982a93f4b512c5723c9945e1c8237512c36cd3d9","src/readers/core/tables.rs":"a7bae8a527b4dfec7ae7f09d1fb44b725ef269b2b595ead9f301b7e2cbcac3c6","src/readers/core/tags.rs":"84ee3ac75c5787f51886ed397e0460da7a98539568ee9fed70be098cdb6be841","src/readers/core/types.rs":"3de6e5d4ad3eed8e8f45bf415ae95a8bd1eb55d8440fcc3c55ac62f23944a329","src/resources.rs":"17517657f7ca17a31c59e4f45d77b89cce9ed9a9c226d10b6df5cf1a904f558a","src/validator.rs":"e28022c245c5751587369f4ff125a9a95122877a43a4e618d3cb6bcc58ab5d16","src/validator/component.rs":"4b6e410752d6d3676e330284144422535ec31648ee884d9edc34fe88d4ccec36","src/validator/core.rs":"32123d72668f13505f7a77a8646c1be406712fada24b690a6d8cb996e7f6b5cf","src/validator/func.rs":"a865a283a7fb46c65f4f8c85f1ac324b6c1ddb8ff99dadee73f8ab596559d7e3","src/validator/operators.rs":"feb197e9a1f59ff5463e3c58dd4a1c1a8838109779bdb19b5f567c47b3e0282d","src/validator/types.rs":"99668d8d26e32c286534ff302c0e6d9368ea78c772185aad2444f7cb17e7fffb"},"package":"5c04e207cd2e8ecb6f9bd28a2cf3119b4c6bfeee6fe3a25cc1daf8041d00a875"}
|
291
third_party/rust/wasmparser/Cargo.lock
generated
vendored
291
third_party/rust/wasmparser/Cargo.lock
generated
vendored
@ -4,9 +4,9 @@ version = 3
|
||||
|
||||
[[package]]
|
||||
name = "anyhow"
|
||||
version = "1.0.40"
|
||||
version = "1.0.58"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "28b2cd92db5cbd74e8e5028f7e27dd7aa3090e89e4f2a197cc7c8dfb69c7063b"
|
||||
checksum = "bb07d2053ccdbe10e2af2995a2f116c1330396493dc1269f6a91d0ae82e19704"
|
||||
|
||||
[[package]]
|
||||
name = "atty"
|
||||
@ -21,21 +21,21 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "autocfg"
|
||||
version = "1.0.1"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a"
|
||||
checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "1.2.1"
|
||||
version = "1.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693"
|
||||
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
|
||||
|
||||
[[package]]
|
||||
name = "bstr"
|
||||
version = "0.2.16"
|
||||
version = "0.2.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "90682c8d613ad3373e66de8c6411e0ae2ab2571e879d2efbf73558cc66f21279"
|
||||
checksum = "ba3569f383e8f1598449f1a423e72e99569137b47740b1da11ef19af3d5c3223"
|
||||
dependencies = [
|
||||
"lazy_static",
|
||||
"memchr",
|
||||
@ -45,21 +45,15 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "bumpalo"
|
||||
version = "3.6.1"
|
||||
version = "3.10.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "63396b8a4b9de3f4fdfb320ab6080762242f66a8ef174c49d8e19b674db4cdbe"
|
||||
|
||||
[[package]]
|
||||
name = "byteorder"
|
||||
version = "1.4.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610"
|
||||
checksum = "37ccbd214614c6783386c1af30caf03192f17891059cecc394b4fb119e363de3"
|
||||
|
||||
[[package]]
|
||||
name = "cast"
|
||||
version = "0.2.6"
|
||||
version = "0.2.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "57cdfa5d50aad6cb4d44dcab6101a7f79925bd59d82ca42f38a9856a28865374"
|
||||
checksum = "4c24dab4283a142afa2fdca129b80ad2c6284e073930f964c3a1293c225ee39a"
|
||||
dependencies = [
|
||||
"rustc_version",
|
||||
]
|
||||
@ -72,9 +66,9 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||
|
||||
[[package]]
|
||||
name = "clap"
|
||||
version = "2.33.3"
|
||||
version = "2.34.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "37e58ac78573c40708d45522f0d80fa2f01cc4f9b4e2bf749807255454312002"
|
||||
checksum = "a0610544180c38b88101fecf2dd634b174a62eef6946f84dfc6a7127512b381c"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"textwrap",
|
||||
@ -83,16 +77,16 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "criterion"
|
||||
version = "0.3.4"
|
||||
version = "0.3.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ab327ed7354547cc2ef43cbe20ef68b988e70b4b593cbd66a2a61733123a3d23"
|
||||
checksum = "1604dafd25fba2fe2d5895a9da139f8dc9b319a5fe5354ca137cbbce4e178d10"
|
||||
dependencies = [
|
||||
"atty",
|
||||
"cast",
|
||||
"clap",
|
||||
"criterion-plot",
|
||||
"csv",
|
||||
"itertools 0.10.0",
|
||||
"itertools",
|
||||
"lazy_static",
|
||||
"num-traits",
|
||||
"oorandom",
|
||||
@ -109,19 +103,19 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "criterion-plot"
|
||||
version = "0.4.3"
|
||||
version = "0.4.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e022feadec601fba1649cfa83586381a4ad31c6bf3a9ab7d408118b05dd9889d"
|
||||
checksum = "d00996de9f2f7559f7f4dc286073197f83e92256a59ed395f9aac01fe717da57"
|
||||
dependencies = [
|
||||
"cast",
|
||||
"itertools 0.9.0",
|
||||
"itertools",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-channel"
|
||||
version = "0.5.1"
|
||||
version = "0.5.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "06ed27e177f16d65f0f0c22a213e17c696ace5dd64b14258b52f9417ccb52db4"
|
||||
checksum = "4c02a4d71819009c192cf4872265391563fd6a84c81ff2c0f2a7026ca4c1d85c"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"crossbeam-utils",
|
||||
@ -129,9 +123,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-deque"
|
||||
version = "0.8.0"
|
||||
version = "0.8.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "94af6efb46fef72616855b036a624cf27ba656ffc9be1b9a3c931cfc7749a9a9"
|
||||
checksum = "6455c0ca19f0d2fbf751b908d5c55c1f5cbc65e03c4225427254b46890bdde1e"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"crossbeam-epoch",
|
||||
@ -140,26 +134,26 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-epoch"
|
||||
version = "0.9.4"
|
||||
version = "0.9.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "52fb27eab85b17fbb9f6fd667089e07d6a2eb8743d02639ee7f6a7a7729c9c94"
|
||||
checksum = "07db9d94cbd326813772c968ccd25999e5f8ae22f4f8d1b11effa37ef6ce281d"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"cfg-if",
|
||||
"crossbeam-utils",
|
||||
"lazy_static",
|
||||
"memoffset",
|
||||
"once_cell",
|
||||
"scopeguard",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-utils"
|
||||
version = "0.8.4"
|
||||
version = "0.8.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4feb231f0d4d6af81aed15928e58ecf5816aa62a2393e2c82f46973e92a9a278"
|
||||
checksum = "7d82ee10ce34d7bc12c2122495e7593a9c41347ecdd64185af4ecf72cb1a7f83"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"cfg-if",
|
||||
"lazy_static",
|
||||
"once_cell",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -170,7 +164,7 @@ checksum = "22813a6dc45b335f9bade10bf7271dc477e81113e89eb251a0bc2a8a81c536e1"
|
||||
dependencies = [
|
||||
"bstr",
|
||||
"csv-core",
|
||||
"itoa",
|
||||
"itoa 0.4.8",
|
||||
"ryu",
|
||||
"serde",
|
||||
]
|
||||
@ -186,9 +180,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "either"
|
||||
version = "1.6.1"
|
||||
version = "1.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457"
|
||||
checksum = "3f107b87b6afc2a64fd13cac55fe06d6c8859f12d4b14cbcdd2c67d0976781be"
|
||||
|
||||
[[package]]
|
||||
name = "getopts"
|
||||
@ -201,48 +195,61 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "half"
|
||||
version = "1.7.1"
|
||||
version = "1.8.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "62aca2aba2d62b4a7f5b33f3712cb1b0692779a56fb510499d5c0aa594daeaf3"
|
||||
checksum = "eabb4a44450da02c90444cf74558da904edde8fb4e9035a9a6a4e15445af0bd7"
|
||||
|
||||
[[package]]
|
||||
name = "hashbrown"
|
||||
version = "0.12.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "db0d4cf898abf0081f964436dc980e96670a0f36863e4b83aaacdb65c9d7ccc3"
|
||||
|
||||
[[package]]
|
||||
name = "hermit-abi"
|
||||
version = "0.1.18"
|
||||
version = "0.1.19"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "322f4de77956e22ed0e5032c359a0f1273f1f7f0d79bfa3b8ffbc730d7fbcc5c"
|
||||
checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "itertools"
|
||||
version = "0.9.0"
|
||||
name = "indexmap"
|
||||
version = "1.9.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "284f18f85651fe11e8a991b2adb42cb078325c996ed026d994719efcfca1d54b"
|
||||
checksum = "10a35a97730320ffe8e2d410b5d3b69279b98d2c14bdb8b70ea89ecf7888d41e"
|
||||
dependencies = [
|
||||
"either",
|
||||
"autocfg",
|
||||
"hashbrown",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "itertools"
|
||||
version = "0.10.0"
|
||||
version = "0.10.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "37d572918e350e82412fe766d24b15e6682fb2ed2bbe018280caa810397cb319"
|
||||
checksum = "a9a9d19fa1e79b6215ff29b9d6880b706147f16e9b1dbb1e4e5947b5b02bc5e3"
|
||||
dependencies = [
|
||||
"either",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "itoa"
|
||||
version = "0.4.7"
|
||||
version = "0.4.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dd25036021b0de88a0aff6b850051563c6516d0bf53f8638938edbb9de732736"
|
||||
checksum = "b71991ff56294aa922b450139ee08b3bfc70982c6b2c7562771375cf73542dd4"
|
||||
|
||||
[[package]]
|
||||
name = "itoa"
|
||||
version = "1.0.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "112c678d4050afce233f4f2852bb2eb519230b3cf12f33585275537d7e41578d"
|
||||
|
||||
[[package]]
|
||||
name = "js-sys"
|
||||
version = "0.3.51"
|
||||
version = "0.3.58"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "83bdfbace3a0e81a4253f73b49e960b053e396a11012cbd49b9b74d6a2b67062"
|
||||
checksum = "c3fac17f7123a73ca62df411b1bf727ccc805daa070338fda671c86dac1bdc27"
|
||||
dependencies = [
|
||||
"wasm-bindgen",
|
||||
]
|
||||
@ -255,73 +262,70 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.94"
|
||||
version = "0.2.126"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "18794a8ad5b29321f790b55d93dfba91e125cb1a9edbd4f8e3150acc771c1a5e"
|
||||
checksum = "349d5a591cd28b49e1d1037471617a32ddcda5731b99419008085f72d5a53836"
|
||||
|
||||
[[package]]
|
||||
name = "log"
|
||||
version = "0.4.14"
|
||||
version = "0.4.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710"
|
||||
checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "memchr"
|
||||
version = "2.4.0"
|
||||
version = "2.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b16bd47d9e329435e309c58469fe0791c2d0d1ba96ec0954152a5ae2b04387dc"
|
||||
checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d"
|
||||
|
||||
[[package]]
|
||||
name = "memoffset"
|
||||
version = "0.6.3"
|
||||
version = "0.6.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f83fb6581e8ed1f85fd45c116db8405483899489e38406156c25eb743554361d"
|
||||
checksum = "5aa361d4faea93603064a027415f07bd8e1d5c88c9fbf68bf56a285428fd79ce"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-traits"
|
||||
version = "0.2.14"
|
||||
version = "0.2.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290"
|
||||
checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num_cpus"
|
||||
version = "1.13.0"
|
||||
version = "1.13.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "05499f3756671c15885fee9034446956fff3f243d6077b91e5767df161f766b3"
|
||||
checksum = "19e64526ebdee182341572e50e9ad03965aa510cd94427a4549448f285e957a1"
|
||||
dependencies = [
|
||||
"hermit-abi",
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "once_cell"
|
||||
version = "1.13.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "18a6dbe30758c9f83eb00cbea4ac95966305f5a7772f3f42ebfc7fc7eddbd8e1"
|
||||
|
||||
[[package]]
|
||||
name = "oorandom"
|
||||
version = "11.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0ab1bc2a289d34bd04a330323ac98a1b4bc82c9d9fcb1e66b63caa84da26b575"
|
||||
|
||||
[[package]]
|
||||
name = "pest"
|
||||
version = "2.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "10f4872ae94d7b90ae48754df22fd42ad52ce740b8f370b03da4835417403e53"
|
||||
dependencies = [
|
||||
"ucd-trie",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "plotters"
|
||||
version = "0.3.0"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "45ca0ae5f169d0917a7c7f5a9c1a3d3d9598f18f529dd2b8373ed988efea307a"
|
||||
checksum = "32a3fd9ec30b9749ce28cd91f255d569591cdf937fe280c312143e3c4bad6f2a"
|
||||
dependencies = [
|
||||
"num-traits",
|
||||
"plotters-backend",
|
||||
@ -332,42 +336,42 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "plotters-backend"
|
||||
version = "0.3.0"
|
||||
version = "0.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b07fffcddc1cb3a1de753caa4e4df03b79922ba43cf882acc1bdd7e8df9f4590"
|
||||
checksum = "d88417318da0eaf0fdcdb51a0ee6c3bed624333bff8f946733049380be67ac1c"
|
||||
|
||||
[[package]]
|
||||
name = "plotters-svg"
|
||||
version = "0.3.0"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b38a02e23bd9604b842a812063aec4ef702b57989c37b655254bb61c471ad211"
|
||||
checksum = "521fa9638fa597e1dc53e9412a4f9cefb01187ee1f7413076f9e6749e2885ba9"
|
||||
dependencies = [
|
||||
"plotters-backend",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.26"
|
||||
version = "1.0.40"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a152013215dca273577e18d2bf00fa862b89b24169fb78c4c95aeb07992c9cec"
|
||||
checksum = "dd96a1e8ed2596c337f8eae5f24924ec83f5ad5ab21ea8e455d3566c69fbcaf7"
|
||||
dependencies = [
|
||||
"unicode-xid",
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.9"
|
||||
version = "1.0.20"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c3d0b9745dc2debf507c8422de05d7226cc1f0644216dfdfead988f9b1ab32a7"
|
||||
checksum = "3bcdf212e9776fbcb2d23ab029360416bb1706b1aea2d1a5ba002727cbcab804"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rayon"
|
||||
version = "1.5.1"
|
||||
version = "1.5.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c06aca804d41dbc8ba42dfd964f0d01334eceb64314b9ecf7c5fad5188a06d90"
|
||||
checksum = "bd99e5772ead8baa5215278c9b15bf92087709e9c1b2d1f97cdb5a183c933a7d"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"crossbeam-deque",
|
||||
@ -377,55 +381,51 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "rayon-core"
|
||||
version = "1.9.1"
|
||||
version = "1.9.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d78120e2c850279833f1dd3582f730c4ab53ed95aeaaaa862a2a5c71b1656d8e"
|
||||
checksum = "258bcdb5ac6dad48491bb2992db6b7cf74878b0384908af124823d118c99683f"
|
||||
dependencies = [
|
||||
"crossbeam-channel",
|
||||
"crossbeam-deque",
|
||||
"crossbeam-utils",
|
||||
"lazy_static",
|
||||
"num_cpus",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex"
|
||||
version = "1.5.4"
|
||||
version = "1.5.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d07a8629359eb56f1e2fb1652bb04212c072a87ba68546a04065d525673ac461"
|
||||
checksum = "d83f127d94bdbcda4c8cc2e50f6f84f4b611f69c902699ca385a39c3a75f9ff1"
|
||||
dependencies = [
|
||||
"regex-syntax",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex-automata"
|
||||
version = "0.1.9"
|
||||
version = "0.1.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ae1ded71d66a4a97f5e961fd0cb25a5f366a42a41570d16a763a69c092c26ae4"
|
||||
dependencies = [
|
||||
"byteorder",
|
||||
]
|
||||
checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132"
|
||||
|
||||
[[package]]
|
||||
name = "regex-syntax"
|
||||
version = "0.6.25"
|
||||
version = "0.6.26"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b"
|
||||
checksum = "49b3de9ec5dc0a3417da371aab17d729997c15010e7fd24ff707773a33bddb64"
|
||||
|
||||
[[package]]
|
||||
name = "rustc_version"
|
||||
version = "0.3.3"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f0dfe2087c51c460008730de8b57e6a320782fbfb312e1f4d520e6c6fae155ee"
|
||||
checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366"
|
||||
dependencies = [
|
||||
"semver",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ryu"
|
||||
version = "1.0.5"
|
||||
version = "1.0.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e"
|
||||
checksum = "f3f6f92acf49d1b98f7a81226834412ada05458b7364277387724a237f062695"
|
||||
|
||||
[[package]]
|
||||
name = "same-file"
|
||||
@ -444,33 +444,21 @@ checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
|
||||
|
||||
[[package]]
|
||||
name = "semver"
|
||||
version = "0.11.0"
|
||||
version = "1.0.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f301af10236f6df4160f7c3f04eec6dbc70ace82d23326abad5edee88801c6b6"
|
||||
dependencies = [
|
||||
"semver-parser",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "semver-parser"
|
||||
version = "0.10.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "00b0bef5b7f9e0df16536d3961cfb6e84331c065b4066afb39768d0e319411f7"
|
||||
dependencies = [
|
||||
"pest",
|
||||
]
|
||||
checksum = "a2333e6df6d6598f2b1974829f853c2b4c5f4a6e503c10af918081aa6f8564e1"
|
||||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.126"
|
||||
version = "1.0.138"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ec7505abeacaec74ae4778d9d9328fe5a5d04253220a85c4ee022239fc996d03"
|
||||
checksum = "1578c6245786b9d168c5447eeacfb96856573ca56c9d68fdcf394be134882a47"
|
||||
|
||||
[[package]]
|
||||
name = "serde_cbor"
|
||||
version = "0.11.1"
|
||||
version = "0.11.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1e18acfa2f90e8b735b2836ab8d538de304cbb6729a7360729ea5a895d15a622"
|
||||
checksum = "2bef2ebfde456fb76bbcf9f59315333decc4fda0b2b44b420243c11e0f5ec1f5"
|
||||
dependencies = [
|
||||
"half",
|
||||
"serde",
|
||||
@ -478,9 +466,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "serde_derive"
|
||||
version = "1.0.126"
|
||||
version = "1.0.138"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "963a7dbc9895aeac7ac90e74f34a5d5261828f79df35cbed41e10189d3804d43"
|
||||
checksum = "023e9b1467aef8a10fb88f25611870ada9800ef7e22afce356bb0d2387b6f27c"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
@ -489,24 +477,24 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "serde_json"
|
||||
version = "1.0.64"
|
||||
version = "1.0.82"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "799e97dc9fdae36a5c8b8f2cae9ce2ee9fdce2058c57a93e6099d919fd982f79"
|
||||
checksum = "82c2c1fdcd807d1098552c5b9a36e425e42e9fbd7c6a37a8425f390f781f7fa7"
|
||||
dependencies = [
|
||||
"itoa",
|
||||
"itoa 1.0.2",
|
||||
"ryu",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "1.0.72"
|
||||
version = "1.0.98"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a1e8cdbefb79a9a5a65e0db8b47b723ee907b7c7f8496c76a1770b5c310bab82"
|
||||
checksum = "c50aef8a904de4c23c788f104b7dddc7d6f79c647c7c8ce4cc8f73eb0ca773dd"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"unicode-xid",
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -529,22 +517,16 @@ dependencies = [
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ucd-trie"
|
||||
version = "0.1.3"
|
||||
name = "unicode-ident"
|
||||
version = "1.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "56dee185309b50d1f11bfedef0fe6d036842e3fb77413abef29f8f8d1c5d4c1c"
|
||||
checksum = "5bd2fe26506023ed7b5e1e315add59d6f584c621d037f9368fea9cfb988f368c"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-width"
|
||||
version = "0.1.8"
|
||||
version = "0.1.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9337591893a19b88d8d87f2cec1e73fad5cdfd10e5a6f349f498ad6ea2ffb1e3"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-xid"
|
||||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3"
|
||||
checksum = "3ed742d4ea2bd1176e236172c8429aaf54486e7ac098db29ffe6529e0ce50973"
|
||||
|
||||
[[package]]
|
||||
name = "walkdir"
|
||||
@ -559,9 +541,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen"
|
||||
version = "0.2.74"
|
||||
version = "0.2.81"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d54ee1d4ed486f78874278e63e4069fc1ab9f6a18ca492076ffb90c5eb2997fd"
|
||||
checksum = "7c53b543413a17a202f4be280a7e5c62a1c69345f5de525ee64f8cfdbc954994"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"wasm-bindgen-macro",
|
||||
@ -569,9 +551,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-backend"
|
||||
version = "0.2.74"
|
||||
version = "0.2.81"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3b33f6a0694ccfea53d94db8b2ed1c3a8a4c86dd936b13b9f0a15ec4a451b900"
|
||||
checksum = "5491a68ab4500fa6b4d726bd67408630c3dbe9c4fe7bda16d5c82a1fd8c7340a"
|
||||
dependencies = [
|
||||
"bumpalo",
|
||||
"lazy_static",
|
||||
@ -584,9 +566,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-macro"
|
||||
version = "0.2.74"
|
||||
version = "0.2.81"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "088169ca61430fe1e58b8096c24975251700e7b1f6fd91cc9d59b04fb9b18bd4"
|
||||
checksum = "c441e177922bc58f1e12c022624b6216378e5febc2f0533e41ba443d505b80aa"
|
||||
dependencies = [
|
||||
"quote",
|
||||
"wasm-bindgen-macro-support",
|
||||
@ -594,9 +576,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-macro-support"
|
||||
version = "0.2.74"
|
||||
version = "0.2.81"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "be2241542ff3d9f241f5e2cb6dd09b37efe786df8851c54957683a49f0987a97"
|
||||
checksum = "7d94ac45fcf608c1f45ef53e748d35660f168490c10b23704c7779ab8f5c3048"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
@ -607,25 +589,26 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-shared"
|
||||
version = "0.2.74"
|
||||
version = "0.2.81"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d7cff876b8f18eed75a66cf49b65e7f967cb354a7aa16003fb55dbfd25b44b4f"
|
||||
checksum = "6a89911bd99e5f3659ec4acf9c4d93b0a90fe4a2a11f15328472058edc5261be"
|
||||
|
||||
[[package]]
|
||||
name = "wasmparser"
|
||||
version = "0.78.2"
|
||||
version = "0.87.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"criterion",
|
||||
"getopts",
|
||||
"indexmap",
|
||||
"rayon",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "web-sys"
|
||||
version = "0.3.51"
|
||||
version = "0.3.58"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e828417b379f3df7111d3a2a9e5753706cae29c41f7c4029ee9fd77f3e09e582"
|
||||
checksum = "2fed94beee57daf8dd7d51f2b15dc2bcde92d7a72304cdf662a4371008b71b90"
|
||||
dependencies = [
|
||||
"js-sys",
|
||||
"wasm-bindgen",
|
||||
|
29
third_party/rust/wasmparser/Cargo.toml
vendored
29
third_party/rust/wasmparser/Cargo.toml
vendored
@ -3,27 +3,38 @@
|
||||
# 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
|
||||
# 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)
|
||||
# If you are reading this file be aware that the original Cargo.toml
|
||||
# will likely look very different (and much more reasonable).
|
||||
# See Cargo.toml.orig for the original contents.
|
||||
|
||||
[package]
|
||||
edition = "2018"
|
||||
edition = "2021"
|
||||
name = "wasmparser"
|
||||
version = "0.78.2"
|
||||
version = "0.87.0"
|
||||
authors = ["Yury Delendik <ydelendik@mozilla.com>"]
|
||||
description = "A simple event-driven library for parsing WebAssembly binary files.\n"
|
||||
description = """
|
||||
A simple event-driven library for parsing WebAssembly binary files.
|
||||
"""
|
||||
homepage = "https://github.com/bytecodealliance/wasm-tools/tree/main/crates/wasmparser"
|
||||
keywords = ["parser", "WebAssembly", "wasm"]
|
||||
readme = "README.md"
|
||||
keywords = [
|
||||
"parser",
|
||||
"WebAssembly",
|
||||
"wasm",
|
||||
]
|
||||
license = "Apache-2.0 WITH LLVM-exception"
|
||||
repository = "https://github.com/bytecodealliance/wasm-tools/tree/main/crates/wasmparser"
|
||||
resolver = "2"
|
||||
|
||||
[[bench]]
|
||||
name = "benchmark"
|
||||
harness = false
|
||||
|
||||
[dependencies.indexmap]
|
||||
version = "1.8.0"
|
||||
|
||||
[dev-dependencies.anyhow]
|
||||
version = "1.0"
|
||||
|
||||
|
83
third_party/rust/wasmparser/benches/benchmark.rs
vendored
83
third_party/rust/wasmparser/benches/benchmark.rs
vendored
@ -60,7 +60,7 @@ fn collect_test_files(path: &Path, list: &mut Vec<BenchmarkInput>) -> Result<()>
|
||||
};
|
||||
for directive in wast.directives {
|
||||
match directive {
|
||||
wast::WastDirective::Module(mut module) => {
|
||||
wast::WastDirective::Wat(mut module) => {
|
||||
let wasm = module.encode()?;
|
||||
list.push(BenchmarkInput::new(path.clone(), wasm));
|
||||
}
|
||||
@ -92,18 +92,6 @@ fn read_all_wasm(wasm: &[u8]) -> Result<()> {
|
||||
item?;
|
||||
}
|
||||
}
|
||||
AliasSection(s) => {
|
||||
for item in s {
|
||||
item?;
|
||||
}
|
||||
}
|
||||
InstanceSection(s) => {
|
||||
for item in s {
|
||||
for arg in item?.args()? {
|
||||
arg?;
|
||||
}
|
||||
}
|
||||
}
|
||||
FunctionSection(s) => {
|
||||
for item in s {
|
||||
item?;
|
||||
@ -119,7 +107,7 @@ fn read_all_wasm(wasm: &[u8]) -> Result<()> {
|
||||
item?;
|
||||
}
|
||||
}
|
||||
EventSection(s) => {
|
||||
TagSection(s) => {
|
||||
for item in s {
|
||||
item?;
|
||||
}
|
||||
@ -168,15 +156,63 @@ fn read_all_wasm(wasm: &[u8]) -> Result<()> {
|
||||
}
|
||||
}
|
||||
|
||||
// Component sections
|
||||
ModuleSection { .. } => {}
|
||||
InstanceSection(s) => {
|
||||
for item in s {
|
||||
item?;
|
||||
}
|
||||
}
|
||||
AliasSection(s) => {
|
||||
for item in s {
|
||||
item?;
|
||||
}
|
||||
}
|
||||
CoreTypeSection(s) => {
|
||||
for item in s {
|
||||
item?;
|
||||
}
|
||||
}
|
||||
ComponentSection { .. } => {}
|
||||
ComponentInstanceSection(s) => {
|
||||
for item in s {
|
||||
item?;
|
||||
}
|
||||
}
|
||||
ComponentAliasSection(s) => {
|
||||
for item in s {
|
||||
item?;
|
||||
}
|
||||
}
|
||||
ComponentTypeSection(s) => {
|
||||
for item in s {
|
||||
item?;
|
||||
}
|
||||
}
|
||||
ComponentCanonicalSection(s) => {
|
||||
for item in s {
|
||||
item?;
|
||||
}
|
||||
}
|
||||
ComponentStartSection { .. } => {}
|
||||
ComponentImportSection(s) => {
|
||||
for item in s {
|
||||
item?;
|
||||
}
|
||||
}
|
||||
ComponentExportSection(s) => {
|
||||
for item in s {
|
||||
item?;
|
||||
}
|
||||
}
|
||||
|
||||
Version { .. }
|
||||
| StartSection { .. }
|
||||
| DataCountSection { .. }
|
||||
| UnknownSection { .. }
|
||||
| CustomSection { .. }
|
||||
| CodeSectionStart { .. }
|
||||
| ModuleSectionStart { .. }
|
||||
| ModuleSectionEntry { .. }
|
||||
| End => {}
|
||||
| End(_) => {}
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
@ -205,21 +241,24 @@ fn it_works_benchmark(c: &mut Criterion) {
|
||||
|
||||
fn validate_benchmark(c: &mut Criterion) {
|
||||
fn validator() -> Validator {
|
||||
let mut ret = Validator::new();
|
||||
ret.wasm_features(WasmFeatures {
|
||||
Validator::new_with_features(WasmFeatures {
|
||||
reference_types: true,
|
||||
multi_value: true,
|
||||
simd: true,
|
||||
relaxed_simd: true,
|
||||
exceptions: true,
|
||||
module_linking: true,
|
||||
component_model: true,
|
||||
bulk_memory: true,
|
||||
threads: true,
|
||||
tail_call: true,
|
||||
multi_memory: true,
|
||||
memory64: true,
|
||||
extended_const: true,
|
||||
deterministic_only: false,
|
||||
});
|
||||
return ret;
|
||||
mutable_global: true,
|
||||
saturating_float_to_int: true,
|
||||
sign_extension: true,
|
||||
})
|
||||
}
|
||||
let mut inputs = collect_benchmark_inputs();
|
||||
// Filter out all benchmark inputs that fail to validate via `wasmparser`.
|
||||
|
@ -18,13 +18,13 @@ fn main() -> Result<()> {
|
||||
Payload::ExportSection(s) => {
|
||||
for export in s {
|
||||
let export = export?;
|
||||
println!(" Export {} {:?}", export.field, export.kind);
|
||||
println!(" Export {} {:?}", export.name, export.kind);
|
||||
}
|
||||
}
|
||||
Payload::ImportSection(s) => {
|
||||
for import in s {
|
||||
let import = import?;
|
||||
println!(" Import {}::{}", import.module, import.field.unwrap());
|
||||
println!(" Import {}::{}", import.module, import.name);
|
||||
}
|
||||
}
|
||||
_other => {
|
||||
|
1268
third_party/rust/wasmparser/src/binary_reader.rs
vendored
1268
third_party/rust/wasmparser/src/binary_reader.rs
vendored
File diff suppressed because it is too large
Load Diff
13
third_party/rust/wasmparser/src/lib.rs
vendored
13
third_party/rust/wasmparser/src/lib.rs
vendored
@ -16,27 +16,24 @@
|
||||
//! A simple event-driven library for parsing WebAssembly binary files
|
||||
//! (or streams).
|
||||
//!
|
||||
//! The parser library reports events as they happend and only stores
|
||||
//! The parser library reports events as they happen and only stores
|
||||
//! parsing information for a brief period of time, making it very fast
|
||||
//! and memory-efficient. The event-driven model, however, has some drawbacks.
|
||||
//! If you need random access to the entire WebAssembly data-structure,
|
||||
//! this is not the right library for you. You could however, build such
|
||||
//! a data-structure using this library.
|
||||
|
||||
pub use crate::binary_reader::BinaryReader;
|
||||
pub use crate::binary_reader::Range;
|
||||
#![deny(missing_docs)]
|
||||
|
||||
pub use crate::module_resources::*;
|
||||
pub use crate::binary_reader::{BinaryReader, BinaryReaderError, Result};
|
||||
pub use crate::parser::*;
|
||||
pub use crate::primitives::*;
|
||||
pub use crate::readers::*;
|
||||
pub use crate::resources::*;
|
||||
pub use crate::validator::*;
|
||||
|
||||
mod binary_reader;
|
||||
mod limits;
|
||||
mod module_resources;
|
||||
mod operators_validator;
|
||||
mod parser;
|
||||
mod primitives;
|
||||
mod readers;
|
||||
mod resources;
|
||||
mod validator;
|
||||
|
28
third_party/rust/wasmparser/src/limits.rs
vendored
28
third_party/rust/wasmparser/src/limits.rs
vendored
@ -17,14 +17,13 @@
|
||||
// The limits are agreed upon with other engines for consistency.
|
||||
pub const MAX_WASM_TYPES: usize = 1_000_000;
|
||||
pub const MAX_WASM_FUNCTIONS: usize = 1_000_000;
|
||||
pub const MAX_WASM_IMPORTS: usize = 100_000;
|
||||
pub const MAX_WASM_EXPORTS: usize = 100_000;
|
||||
pub const MAX_WASM_GLOBALS: usize = 1_000_000;
|
||||
pub const MAX_WASM_ELEMENT_SEGMENTS: usize = 100_000;
|
||||
pub const MAX_WASM_DATA_SEGMENTS: usize = 100_000;
|
||||
pub const MAX_WASM_MEMORY_PAGES: usize = 65536;
|
||||
pub const MAX_WASM_MEMORY32_PAGES: u64 = 65536;
|
||||
pub const MAX_WASM_MEMORY64_PAGES: u64 = 1 << 48;
|
||||
pub const MAX_WASM_STRING_SIZE: usize = 100_000;
|
||||
pub const _MAX_WASM_MODULE_SIZE: usize = 1024 * 1024 * 1024; //= 1 GiB
|
||||
pub const MAX_WASM_FUNCTION_SIZE: usize = 128 * 1024;
|
||||
pub const MAX_WASM_FUNCTION_LOCALS: usize = 50000;
|
||||
pub const MAX_WASM_FUNCTION_PARAMS: usize = 1000;
|
||||
@ -33,7 +32,26 @@ pub const _MAX_WASM_TABLE_SIZE: usize = 10_000_000;
|
||||
pub const MAX_WASM_TABLE_ENTRIES: usize = 10_000_000;
|
||||
pub const MAX_WASM_TABLES: usize = 100;
|
||||
pub const MAX_WASM_MEMORIES: usize = 100;
|
||||
pub const MAX_WASM_TAGS: usize = 1_000_000;
|
||||
pub const MAX_WASM_BR_TABLE_SIZE: usize = MAX_WASM_FUNCTION_SIZE;
|
||||
|
||||
// Component-related limits
|
||||
pub const MAX_WASM_MODULE_SIZE: usize = 1024 * 1024 * 1024; //= 1 GiB
|
||||
pub const MAX_WASM_MODULE_TYPE_DECLS: usize = 1000;
|
||||
pub const MAX_WASM_COMPONENT_TYPE_DECLS: usize = 1000;
|
||||
pub const MAX_WASM_INSTANCE_TYPE_DECLS: usize = 1000;
|
||||
pub const MAX_WASM_RECORD_FIELDS: usize = 1000;
|
||||
pub const MAX_WASM_VARIANT_CASES: usize = 1000;
|
||||
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_CANONICAL_OPTIONS: usize = 10;
|
||||
pub const MAX_WASM_INSTANTIATION_ARGS: usize = 1000;
|
||||
pub const MAX_WASM_START_ARGS: usize = 1000;
|
||||
pub const MAX_WASM_TYPE_SIZE: usize = 100_000;
|
||||
pub const MAX_WASM_MODULES: usize = 1_000;
|
||||
pub const MAX_WASM_COMPONENTS: usize = 1_000;
|
||||
pub const MAX_WASM_INSTANCES: usize = 1_000;
|
||||
pub const MAX_WASM_EVENTS: usize = 1_000_000;
|
||||
pub const MAX_TYPE_SIZE: u32 = 100_000;
|
||||
pub const MAX_WASM_VALUES: usize = 1_000;
|
||||
|
884
third_party/rust/wasmparser/src/parser.rs
vendored
884
third_party/rust/wasmparser/src/parser.rs
vendored
File diff suppressed because it is too large
Load Diff
@ -13,29 +13,54 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
use super::{BinaryReaderError, Range, Result};
|
||||
use crate::{BinaryReaderError, Result};
|
||||
use std::ops::Range;
|
||||
|
||||
mod component;
|
||||
mod core;
|
||||
|
||||
pub use self::component::*;
|
||||
pub use self::core::*;
|
||||
|
||||
/// A trait implemented by section readers.
|
||||
pub trait SectionReader {
|
||||
/// The item returned by the reader.
|
||||
type Item;
|
||||
|
||||
/// Reads an item from the section.
|
||||
fn read(&mut self) -> Result<Self::Item>;
|
||||
|
||||
/// Determines if the reader is at end-of-section.
|
||||
fn eof(&self) -> bool;
|
||||
|
||||
/// Gets the original position of the reader.
|
||||
fn original_position(&self) -> usize;
|
||||
fn range(&self) -> Range;
|
||||
|
||||
/// Gets the range of the reader.
|
||||
fn range(&self) -> Range<usize>;
|
||||
|
||||
/// Ensures the reader is at the end of the section.
|
||||
///
|
||||
/// This methods returns an error if there is more data in the section
|
||||
/// than what is described by the section's header.
|
||||
fn ensure_end(&self) -> Result<()> {
|
||||
if self.eof() {
|
||||
return Ok(());
|
||||
}
|
||||
Err(BinaryReaderError::new(
|
||||
"Unexpected data at the end of the section",
|
||||
"section size mismatch: unexpected data at the end of the section",
|
||||
self.original_position(),
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
/// Implemented by sections with a limited number of items.
|
||||
pub trait SectionWithLimitedItems {
|
||||
/// Gets the count of the items in the section.
|
||||
fn get_count(&self) -> u32;
|
||||
}
|
||||
|
||||
/// An iterator over items in a section.
|
||||
pub struct SectionIterator<R>
|
||||
where
|
||||
R: SectionReader,
|
||||
@ -48,6 +73,7 @@ impl<R> SectionIterator<R>
|
||||
where
|
||||
R: SectionReader,
|
||||
{
|
||||
/// Constructs a new `SectionIterator` for the given section reader.
|
||||
pub fn new(reader: R) -> SectionIterator<R> {
|
||||
SectionIterator { reader, err: false }
|
||||
}
|
||||
@ -69,6 +95,7 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
/// An iterator over a limited section iterator.
|
||||
pub struct SectionIteratorLimited<R>
|
||||
where
|
||||
R: SectionReader + SectionWithLimitedItems,
|
||||
@ -82,6 +109,7 @@ impl<R> SectionIteratorLimited<R>
|
||||
where
|
||||
R: SectionReader + SectionWithLimitedItems,
|
||||
{
|
||||
/// Constructs a new `SectionIteratorLimited` for the given limited section reader.
|
||||
pub fn new(reader: R) -> SectionIteratorLimited<R> {
|
||||
let left = reader.get_count();
|
||||
SectionIteratorLimited {
|
@ -1,110 +0,0 @@
|
||||
use crate::{
|
||||
BinaryReader, BinaryReaderError, ExternalKind, Range, Result, SectionIteratorLimited,
|
||||
SectionReader, SectionWithLimitedItems,
|
||||
};
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct AliasSectionReader<'a> {
|
||||
reader: BinaryReader<'a>,
|
||||
count: u32,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub enum Alias<'a> {
|
||||
OuterType {
|
||||
relative_depth: u32,
|
||||
index: u32,
|
||||
},
|
||||
OuterModule {
|
||||
relative_depth: u32,
|
||||
index: u32,
|
||||
},
|
||||
InstanceExport {
|
||||
instance: u32,
|
||||
kind: ExternalKind,
|
||||
export: &'a str,
|
||||
},
|
||||
}
|
||||
|
||||
impl<'a> AliasSectionReader<'a> {
|
||||
pub fn new(data: &'a [u8], offset: usize) -> Result<AliasSectionReader<'a>> {
|
||||
let mut reader = BinaryReader::new_with_offset(data, offset);
|
||||
let count = reader.read_var_u32()?;
|
||||
Ok(AliasSectionReader { reader, count })
|
||||
}
|
||||
|
||||
pub fn original_position(&self) -> usize {
|
||||
self.reader.original_position()
|
||||
}
|
||||
|
||||
pub fn get_count(&self) -> u32 {
|
||||
self.count
|
||||
}
|
||||
|
||||
pub fn read(&mut self) -> Result<Alias<'a>> {
|
||||
Ok(match self.reader.read_u8()? {
|
||||
0x00 => Alias::InstanceExport {
|
||||
instance: self.reader.read_var_u32()?,
|
||||
kind: self.reader.read_external_kind()?,
|
||||
export: self.reader.read_string()?,
|
||||
},
|
||||
0x01 => {
|
||||
let relative_depth = self.reader.read_var_u32()?;
|
||||
match self.reader.read_external_kind()? {
|
||||
ExternalKind::Type => Alias::OuterType {
|
||||
relative_depth,
|
||||
index: self.reader.read_var_u32()?,
|
||||
},
|
||||
ExternalKind::Module => Alias::OuterModule {
|
||||
relative_depth,
|
||||
index: self.reader.read_var_u32()?,
|
||||
},
|
||||
_ => {
|
||||
return Err(BinaryReaderError::new(
|
||||
"invalid external kind in alias",
|
||||
self.original_position() - 1,
|
||||
))
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
return Err(BinaryReaderError::new(
|
||||
"invalid byte in alias",
|
||||
self.original_position() - 1,
|
||||
))
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> SectionReader for AliasSectionReader<'a> {
|
||||
type Item = Alias<'a>;
|
||||
|
||||
fn read(&mut self) -> Result<Self::Item> {
|
||||
AliasSectionReader::read(self)
|
||||
}
|
||||
fn eof(&self) -> bool {
|
||||
self.reader.eof()
|
||||
}
|
||||
fn original_position(&self) -> usize {
|
||||
AliasSectionReader::original_position(self)
|
||||
}
|
||||
fn range(&self) -> Range {
|
||||
self.reader.range()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> SectionWithLimitedItems for AliasSectionReader<'a> {
|
||||
fn get_count(&self) -> u32 {
|
||||
AliasSectionReader::get_count(self)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> IntoIterator for AliasSectionReader<'a> {
|
||||
type Item = Result<Alias<'a>>;
|
||||
type IntoIter = SectionIteratorLimited<AliasSectionReader<'a>>;
|
||||
|
||||
fn into_iter(self) -> Self::IntoIter {
|
||||
SectionIteratorLimited::new(self)
|
||||
}
|
||||
}
|
15
third_party/rust/wasmparser/src/readers/component.rs
vendored
Normal file
15
third_party/rust/wasmparser/src/readers/component.rs
vendored
Normal file
@ -0,0 +1,15 @@
|
||||
mod aliases;
|
||||
mod canonicals;
|
||||
mod exports;
|
||||
mod imports;
|
||||
mod instances;
|
||||
mod start;
|
||||
mod types;
|
||||
|
||||
pub use self::aliases::*;
|
||||
pub use self::canonicals::*;
|
||||
pub use self::exports::*;
|
||||
pub use self::imports::*;
|
||||
pub use self::instances::*;
|
||||
pub use self::start::*;
|
||||
pub use self::types::*;
|
225
third_party/rust/wasmparser/src/readers/component/aliases.rs
vendored
Normal file
225
third_party/rust/wasmparser/src/readers/component/aliases.rs
vendored
Normal file
@ -0,0 +1,225 @@
|
||||
use crate::{
|
||||
BinaryReader, ComponentExternalKind, ExternalKind, Result, SectionIteratorLimited,
|
||||
SectionReader, SectionWithLimitedItems,
|
||||
};
|
||||
use std::ops::Range;
|
||||
|
||||
/// Represents the kind of an outer core alias in a WebAssembly component.
|
||||
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
|
||||
pub enum OuterAliasKind {
|
||||
/// The alias is to a core type.
|
||||
Type,
|
||||
}
|
||||
|
||||
/// Represents a core alias for a WebAssembly module.
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum Alias<'a> {
|
||||
/// The alias is to an export of a module instance.
|
||||
InstanceExport {
|
||||
/// The alias kind.
|
||||
kind: ExternalKind,
|
||||
/// The instance index.
|
||||
instance_index: u32,
|
||||
/// The export name.
|
||||
name: &'a str,
|
||||
},
|
||||
/// The alias is to an outer item.
|
||||
Outer {
|
||||
/// The alias kind.
|
||||
kind: OuterAliasKind,
|
||||
/// The outward count, starting at zero for the current component.
|
||||
count: u32,
|
||||
/// The index of the item within the outer component.
|
||||
index: u32,
|
||||
},
|
||||
}
|
||||
|
||||
/// A reader for the core alias section of a WebAssembly component.
|
||||
#[derive(Clone)]
|
||||
pub struct AliasSectionReader<'a> {
|
||||
reader: BinaryReader<'a>,
|
||||
count: u32,
|
||||
}
|
||||
|
||||
impl<'a> AliasSectionReader<'a> {
|
||||
/// Constructs a new `AliasSectionReader` for the given data and offset.
|
||||
pub fn new(data: &'a [u8], offset: usize) -> Result<Self> {
|
||||
let mut reader = BinaryReader::new_with_offset(data, offset);
|
||||
let count = reader.read_var_u32()?;
|
||||
Ok(Self { reader, count })
|
||||
}
|
||||
|
||||
/// Gets the original position of the section reader.
|
||||
pub fn original_position(&self) -> usize {
|
||||
self.reader.original_position()
|
||||
}
|
||||
|
||||
/// Gets the count of items in the section.
|
||||
pub fn get_count(&self) -> u32 {
|
||||
self.count
|
||||
}
|
||||
|
||||
/// Reads content of the core alias section.
|
||||
///
|
||||
/// # Examples
|
||||
/// ```
|
||||
/// use wasmparser::AliasSectionReader;
|
||||
/// let data: &[u8] = &[0x01, 0x00, 0x00, 0x00, 0x03, b'f', b'o', b'o'];
|
||||
/// let mut reader = AliasSectionReader::new(data, 0).unwrap();
|
||||
/// for _ in 0..reader.get_count() {
|
||||
/// let alias = reader.read().expect("alias");
|
||||
/// println!("Alias: {:?}", alias);
|
||||
/// }
|
||||
/// ```
|
||||
pub fn read(&mut self) -> Result<Alias<'a>> {
|
||||
self.reader.read_alias()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> SectionReader for AliasSectionReader<'a> {
|
||||
type Item = Alias<'a>;
|
||||
|
||||
fn read(&mut self) -> Result<Self::Item> {
|
||||
Self::read(self)
|
||||
}
|
||||
|
||||
fn eof(&self) -> bool {
|
||||
self.reader.eof()
|
||||
}
|
||||
|
||||
fn original_position(&self) -> usize {
|
||||
Self::original_position(self)
|
||||
}
|
||||
|
||||
fn range(&self) -> Range<usize> {
|
||||
self.reader.range()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> SectionWithLimitedItems for AliasSectionReader<'a> {
|
||||
fn get_count(&self) -> u32 {
|
||||
Self::get_count(self)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> IntoIterator for AliasSectionReader<'a> {
|
||||
type Item = Result<Alias<'a>>;
|
||||
type IntoIter = SectionIteratorLimited<Self>;
|
||||
|
||||
fn into_iter(self) -> Self::IntoIter {
|
||||
SectionIteratorLimited::new(self)
|
||||
}
|
||||
}
|
||||
|
||||
/// Represents the kind of an outer alias in a WebAssembly component.
|
||||
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
|
||||
pub enum ComponentOuterAliasKind {
|
||||
/// The alias is to a core module.
|
||||
CoreModule,
|
||||
/// The alias is to a core type.
|
||||
CoreType,
|
||||
/// The alias is to a component type.
|
||||
Type,
|
||||
/// The alias is to a component.
|
||||
Component,
|
||||
}
|
||||
|
||||
/// Represents an alias in a WebAssembly component.
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum ComponentAlias<'a> {
|
||||
/// The alias is to an export of a component instance.
|
||||
InstanceExport {
|
||||
/// The alias kind.
|
||||
kind: ComponentExternalKind,
|
||||
/// The instance index.
|
||||
instance_index: u32,
|
||||
/// The export name.
|
||||
name: &'a str,
|
||||
},
|
||||
/// The alias is to an outer item.
|
||||
Outer {
|
||||
/// The alias kind.
|
||||
kind: ComponentOuterAliasKind,
|
||||
/// The outward count, starting at zero for the current component.
|
||||
count: u32,
|
||||
/// The index of the item within the outer component.
|
||||
index: u32,
|
||||
},
|
||||
}
|
||||
|
||||
/// A reader for the alias section of a WebAssembly component.
|
||||
#[derive(Clone)]
|
||||
pub struct ComponentAliasSectionReader<'a> {
|
||||
reader: BinaryReader<'a>,
|
||||
count: u32,
|
||||
}
|
||||
|
||||
impl<'a> ComponentAliasSectionReader<'a> {
|
||||
/// Constructs a new `ComponentAliasSectionReader` for the given data and offset.
|
||||
pub fn new(data: &'a [u8], offset: usize) -> Result<Self> {
|
||||
let mut reader = BinaryReader::new_with_offset(data, offset);
|
||||
let count = reader.read_var_u32()?;
|
||||
Ok(Self { reader, count })
|
||||
}
|
||||
|
||||
/// Gets the original position of the section reader.
|
||||
pub fn original_position(&self) -> usize {
|
||||
self.reader.original_position()
|
||||
}
|
||||
|
||||
/// Gets the count of items in the section.
|
||||
pub fn get_count(&self) -> u32 {
|
||||
self.count
|
||||
}
|
||||
|
||||
/// Reads content of the alias section.
|
||||
///
|
||||
/// # Examples
|
||||
/// ```
|
||||
/// use wasmparser::ComponentAliasSectionReader;
|
||||
/// let data: &[u8] = &[0x01, 0x01, 0x00, 0x00, 0x03, b'f', b'o', b'o'];
|
||||
/// let mut reader = ComponentAliasSectionReader::new(data, 0).unwrap();
|
||||
/// for _ in 0..reader.get_count() {
|
||||
/// let alias = reader.read().expect("alias");
|
||||
/// println!("Alias: {:?}", alias);
|
||||
/// }
|
||||
/// ```
|
||||
pub fn read(&mut self) -> Result<ComponentAlias<'a>> {
|
||||
self.reader.read_component_alias()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> SectionReader for ComponentAliasSectionReader<'a> {
|
||||
type Item = ComponentAlias<'a>;
|
||||
|
||||
fn read(&mut self) -> Result<Self::Item> {
|
||||
Self::read(self)
|
||||
}
|
||||
|
||||
fn eof(&self) -> bool {
|
||||
self.reader.eof()
|
||||
}
|
||||
|
||||
fn original_position(&self) -> usize {
|
||||
Self::original_position(self)
|
||||
}
|
||||
|
||||
fn range(&self) -> Range<usize> {
|
||||
self.reader.range()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> SectionWithLimitedItems for ComponentAliasSectionReader<'a> {
|
||||
fn get_count(&self) -> u32 {
|
||||
Self::get_count(self)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> IntoIterator for ComponentAliasSectionReader<'a> {
|
||||
type Item = Result<ComponentAlias<'a>>;
|
||||
type IntoIter = SectionIteratorLimited<Self>;
|
||||
|
||||
fn into_iter(self) -> Self::IntoIter {
|
||||
SectionIteratorLimited::new(self)
|
||||
}
|
||||
}
|
124
third_party/rust/wasmparser/src/readers/component/canonicals.rs
vendored
Normal file
124
third_party/rust/wasmparser/src/readers/component/canonicals.rs
vendored
Normal file
@ -0,0 +1,124 @@
|
||||
use crate::{BinaryReader, Result, SectionIteratorLimited, SectionReader, SectionWithLimitedItems};
|
||||
use std::ops::Range;
|
||||
|
||||
/// Represents options for component functions.
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub enum CanonicalOption {
|
||||
/// The string types in the function signature are UTF-8 encoded.
|
||||
UTF8,
|
||||
/// The string types in the function signature are UTF-16 encoded.
|
||||
UTF16,
|
||||
/// The string types in the function signature are compact UTF-16 encoded.
|
||||
CompactUTF16,
|
||||
/// The memory to use if the lifting or lowering of a function requires memory access.
|
||||
///
|
||||
/// The value is an index to a core memory.
|
||||
Memory(u32),
|
||||
/// The realloc function to use if the lifting or lowering of a function requires memory
|
||||
/// allocation.
|
||||
///
|
||||
/// The value is an index to a core function of type `(func (param i32 i32 i32 i32) (result i32))`.
|
||||
Realloc(u32),
|
||||
/// The post-return function to use if the lifting of a function requires
|
||||
/// cleanup after the function returns.
|
||||
PostReturn(u32),
|
||||
}
|
||||
|
||||
/// Represents a canonical function in a WebAssembly component.
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum CanonicalFunction {
|
||||
/// The function lifts a core WebAssembly function to the canonical ABI.
|
||||
Lift {
|
||||
/// The index of the core WebAssembly function to lift.
|
||||
core_func_index: u32,
|
||||
/// The index of the lifted function's type.
|
||||
type_index: u32,
|
||||
/// The canonical options for the function.
|
||||
options: Box<[CanonicalOption]>,
|
||||
},
|
||||
/// The function lowers a canonical ABI function to a core WebAssembly function.
|
||||
Lower {
|
||||
/// The index of the function to lower.
|
||||
func_index: u32,
|
||||
/// The canonical options for the function.
|
||||
options: Box<[CanonicalOption]>,
|
||||
},
|
||||
}
|
||||
|
||||
/// A reader for the canonical section of a WebAssembly component.
|
||||
#[derive(Clone)]
|
||||
pub struct ComponentCanonicalSectionReader<'a> {
|
||||
reader: BinaryReader<'a>,
|
||||
count: u32,
|
||||
}
|
||||
|
||||
impl<'a> ComponentCanonicalSectionReader<'a> {
|
||||
/// Constructs a new `ComponentFunctionSectionReader` for the given data and offset.
|
||||
pub fn new(data: &'a [u8], offset: usize) -> Result<Self> {
|
||||
let mut reader = BinaryReader::new_with_offset(data, offset);
|
||||
let count = reader.read_var_u32()?;
|
||||
Ok(Self { reader, count })
|
||||
}
|
||||
|
||||
/// Gets the original position of the section reader.
|
||||
pub fn original_position(&self) -> usize {
|
||||
self.reader.original_position()
|
||||
}
|
||||
|
||||
/// Gets the count of items in the section.
|
||||
pub fn get_count(&self) -> u32 {
|
||||
self.count
|
||||
}
|
||||
|
||||
/// Reads function type index from the function section.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use wasmparser::ComponentCanonicalSectionReader;
|
||||
/// # let data: &[u8] = &[0x01, 0x00, 0x00, 0x00, 0x01, 0x03, 0x00, 0x00];
|
||||
/// let mut reader = ComponentCanonicalSectionReader::new(data, 0).unwrap();
|
||||
/// for _ in 0..reader.get_count() {
|
||||
/// let func = reader.read().expect("func");
|
||||
/// println!("Function: {:?}", func);
|
||||
/// }
|
||||
/// ```
|
||||
pub fn read(&mut self) -> Result<CanonicalFunction> {
|
||||
self.reader.read_canonical_func()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> SectionReader for ComponentCanonicalSectionReader<'a> {
|
||||
type Item = CanonicalFunction;
|
||||
|
||||
fn read(&mut self) -> Result<Self::Item> {
|
||||
Self::read(self)
|
||||
}
|
||||
|
||||
fn eof(&self) -> bool {
|
||||
self.reader.eof()
|
||||
}
|
||||
|
||||
fn original_position(&self) -> usize {
|
||||
Self::original_position(self)
|
||||
}
|
||||
|
||||
fn range(&self) -> Range<usize> {
|
||||
self.reader.range()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> SectionWithLimitedItems for ComponentCanonicalSectionReader<'a> {
|
||||
fn get_count(&self) -> u32 {
|
||||
Self::get_count(self)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> IntoIterator for ComponentCanonicalSectionReader<'a> {
|
||||
type Item = Result<CanonicalFunction>;
|
||||
type IntoIter = SectionIteratorLimited<Self>;
|
||||
|
||||
fn into_iter(self) -> Self::IntoIter {
|
||||
SectionIteratorLimited::new(self)
|
||||
}
|
||||
}
|
108
third_party/rust/wasmparser/src/readers/component/exports.rs
vendored
Normal file
108
third_party/rust/wasmparser/src/readers/component/exports.rs
vendored
Normal file
@ -0,0 +1,108 @@
|
||||
use crate::{BinaryReader, Result, SectionIteratorLimited, SectionReader, SectionWithLimitedItems};
|
||||
use std::ops::Range;
|
||||
|
||||
/// Represents the kind of an external items of a WebAssembly component.
|
||||
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
|
||||
pub enum ComponentExternalKind {
|
||||
/// The external kind is a core module.
|
||||
Module,
|
||||
/// The external kind is a function.
|
||||
Func,
|
||||
/// The external kind is a value.
|
||||
Value,
|
||||
/// The external kind is a type.
|
||||
Type,
|
||||
/// The external kind is an instance.
|
||||
Instance,
|
||||
/// The external kind is a 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 kind of the export.
|
||||
pub kind: ComponentExternalKind,
|
||||
/// The index of the exported item.
|
||||
pub index: u32,
|
||||
}
|
||||
|
||||
/// A reader for the export section of a WebAssembly component.
|
||||
#[derive(Clone)]
|
||||
pub struct ComponentExportSectionReader<'a> {
|
||||
reader: BinaryReader<'a>,
|
||||
count: u32,
|
||||
}
|
||||
|
||||
impl<'a> ComponentExportSectionReader<'a> {
|
||||
/// Constructs a new `ComponentExportSectionReader` for the given data and offset.
|
||||
pub fn new(data: &'a [u8], offset: usize) -> Result<Self> {
|
||||
let mut reader = BinaryReader::new_with_offset(data, offset);
|
||||
let count = reader.read_var_u32()?;
|
||||
Ok(Self { reader, count })
|
||||
}
|
||||
|
||||
/// Gets the original position of the section reader.
|
||||
pub fn original_position(&self) -> usize {
|
||||
self.reader.original_position()
|
||||
}
|
||||
|
||||
/// Gets the count of items in the section.
|
||||
pub fn get_count(&self) -> u32 {
|
||||
self.count
|
||||
}
|
||||
|
||||
/// Reads content of the export section.
|
||||
///
|
||||
/// # Examples
|
||||
/// ```
|
||||
/// use wasmparser::ComponentExportSectionReader;
|
||||
///
|
||||
/// # let data: &[u8] = &[0x01, 0x03, b'f', b'o', b'o', 0x01, 0x00];
|
||||
/// let mut reader = ComponentExportSectionReader::new(data, 0).unwrap();
|
||||
/// for _ in 0..reader.get_count() {
|
||||
/// let export = reader.read().expect("export");
|
||||
/// println!("Export: {:?}", export);
|
||||
/// }
|
||||
/// ```
|
||||
pub fn read(&mut self) -> Result<ComponentExport<'a>> {
|
||||
self.reader.read_component_export()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> SectionReader for ComponentExportSectionReader<'a> {
|
||||
type Item = ComponentExport<'a>;
|
||||
|
||||
fn read(&mut self) -> Result<Self::Item> {
|
||||
Self::read(self)
|
||||
}
|
||||
|
||||
fn eof(&self) -> bool {
|
||||
self.reader.eof()
|
||||
}
|
||||
|
||||
fn original_position(&self) -> usize {
|
||||
Self::original_position(self)
|
||||
}
|
||||
|
||||
fn range(&self) -> Range<usize> {
|
||||
self.reader.range()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> SectionWithLimitedItems for ComponentExportSectionReader<'a> {
|
||||
fn get_count(&self) -> u32 {
|
||||
Self::get_count(self)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> IntoIterator for ComponentExportSectionReader<'a> {
|
||||
type Item = Result<ComponentExport<'a>>;
|
||||
type IntoIter = SectionIteratorLimited<Self>;
|
||||
|
||||
fn into_iter(self) -> Self::IntoIter {
|
||||
SectionIteratorLimited::new(self)
|
||||
}
|
||||
}
|
125
third_party/rust/wasmparser/src/readers/component/imports.rs
vendored
Normal file
125
third_party/rust/wasmparser/src/readers/component/imports.rs
vendored
Normal file
@ -0,0 +1,125 @@
|
||||
use crate::{
|
||||
BinaryReader, ComponentValType, Result, SectionIteratorLimited, SectionReader,
|
||||
SectionWithLimitedItems,
|
||||
};
|
||||
use std::ops::Range;
|
||||
|
||||
/// Represents the type bounds for imports and exports.
|
||||
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
|
||||
pub enum TypeBounds {
|
||||
/// The type is bounded by equality.
|
||||
Eq,
|
||||
}
|
||||
|
||||
/// Represents a reference to a component type.
|
||||
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
|
||||
pub enum ComponentTypeRef {
|
||||
/// The reference is to a core module type.
|
||||
///
|
||||
/// The index is expected to be core type index to a core module type.
|
||||
Module(u32),
|
||||
/// The reference is to a function type.
|
||||
///
|
||||
/// The index is expected to be a type index to a function type.
|
||||
Func(u32),
|
||||
/// 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),
|
||||
/// The reference is to an instance type.
|
||||
///
|
||||
/// The index is a type index to an instance type.
|
||||
Instance(u32),
|
||||
/// The reference is to a component type.
|
||||
///
|
||||
/// The index is a type index to a component type.
|
||||
Component(u32),
|
||||
}
|
||||
|
||||
/// Represents an import in a WebAssembly component
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
pub struct ComponentImport<'a> {
|
||||
/// The name of the imported item.
|
||||
pub name: &'a str,
|
||||
/// The type reference for the import.
|
||||
pub ty: ComponentTypeRef,
|
||||
}
|
||||
|
||||
/// A reader for the import section of a WebAssembly component.
|
||||
#[derive(Clone)]
|
||||
pub struct ComponentImportSectionReader<'a> {
|
||||
reader: BinaryReader<'a>,
|
||||
count: u32,
|
||||
}
|
||||
|
||||
impl<'a> ComponentImportSectionReader<'a> {
|
||||
/// Constructs a new `ComponentImportSectionReader` for the given data and offset.
|
||||
pub fn new(data: &'a [u8], offset: usize) -> Result<Self> {
|
||||
let mut reader = BinaryReader::new_with_offset(data, offset);
|
||||
let count = reader.read_var_u32()?;
|
||||
Ok(Self { reader, count })
|
||||
}
|
||||
|
||||
/// Gets the original position of the section reader.
|
||||
pub fn original_position(&self) -> usize {
|
||||
self.reader.original_position()
|
||||
}
|
||||
|
||||
/// Gets the count of items in the section.
|
||||
pub fn get_count(&self) -> u32 {
|
||||
self.count
|
||||
}
|
||||
|
||||
/// Reads content of the import section.
|
||||
///
|
||||
/// # Examples
|
||||
/// ```
|
||||
/// use wasmparser::ComponentImportSectionReader;
|
||||
/// let data: &[u8] = &[0x01, 0x01, 0x41, 0x01, 0x66, 0x00, 0x00];
|
||||
/// let mut reader = ComponentImportSectionReader::new(data, 0).unwrap();
|
||||
/// for _ in 0..reader.get_count() {
|
||||
/// let import = reader.read().expect("import");
|
||||
/// println!("Import: {:?}", import);
|
||||
/// }
|
||||
/// ```
|
||||
pub fn read(&mut self) -> Result<ComponentImport<'a>> {
|
||||
self.reader.read_component_import()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> SectionReader for ComponentImportSectionReader<'a> {
|
||||
type Item = ComponentImport<'a>;
|
||||
|
||||
fn read(&mut self) -> Result<Self::Item> {
|
||||
Self::read(self)
|
||||
}
|
||||
|
||||
fn eof(&self) -> bool {
|
||||
self.reader.eof()
|
||||
}
|
||||
|
||||
fn original_position(&self) -> usize {
|
||||
Self::original_position(self)
|
||||
}
|
||||
|
||||
fn range(&self) -> Range<usize> {
|
||||
self.reader.range()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> SectionWithLimitedItems for ComponentImportSectionReader<'a> {
|
||||
fn get_count(&self) -> u32 {
|
||||
Self::get_count(self)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> IntoIterator for ComponentImportSectionReader<'a> {
|
||||
type Item = Result<ComponentImport<'a>>;
|
||||
type IntoIter = SectionIteratorLimited<Self>;
|
||||
|
||||
fn into_iter(self) -> Self::IntoIter {
|
||||
SectionIteratorLimited::new(self)
|
||||
}
|
||||
}
|
240
third_party/rust/wasmparser/src/readers/component/instances.rs
vendored
Normal file
240
third_party/rust/wasmparser/src/readers/component/instances.rs
vendored
Normal file
@ -0,0 +1,240 @@
|
||||
use crate::{
|
||||
BinaryReader, ComponentExport, ComponentExternalKind, Export, Result, SectionIteratorLimited,
|
||||
SectionReader, SectionWithLimitedItems,
|
||||
};
|
||||
use std::ops::Range;
|
||||
|
||||
/// Represents the kind of an instantiation argument for a core instance.
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
|
||||
pub enum InstantiationArgKind {
|
||||
/// The instantiation argument is a core instance.
|
||||
Instance,
|
||||
}
|
||||
|
||||
/// Represents an argument to instantiating a WebAssembly module.
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct InstantiationArg<'a> {
|
||||
/// The name of the module argument.
|
||||
pub name: &'a str,
|
||||
/// The kind of the module argument.
|
||||
pub kind: InstantiationArgKind,
|
||||
/// The index of the argument item.
|
||||
pub index: u32,
|
||||
}
|
||||
|
||||
/// Represents an instance of a WebAssembly module.
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum Instance<'a> {
|
||||
/// The instance is from instantiating a WebAssembly module.
|
||||
Instantiate {
|
||||
/// The module index.
|
||||
module_index: u32,
|
||||
/// The module's instantiation arguments.
|
||||
args: Box<[InstantiationArg<'a>]>,
|
||||
},
|
||||
/// The instance is a from exporting local items.
|
||||
FromExports(Box<[Export<'a>]>),
|
||||
}
|
||||
|
||||
/// A reader for the core instance section of a WebAssembly component.
|
||||
#[derive(Clone)]
|
||||
pub struct InstanceSectionReader<'a> {
|
||||
reader: BinaryReader<'a>,
|
||||
count: u32,
|
||||
}
|
||||
|
||||
impl<'a> InstanceSectionReader<'a> {
|
||||
/// Constructs a new `InstanceSectionReader` for the given data and offset.
|
||||
pub fn new(data: &'a [u8], offset: usize) -> Result<Self> {
|
||||
let mut reader = BinaryReader::new_with_offset(data, offset);
|
||||
let count = reader.read_var_u32()?;
|
||||
Ok(Self { reader, count })
|
||||
}
|
||||
|
||||
/// Gets the original position of the section reader.
|
||||
pub fn original_position(&self) -> usize {
|
||||
self.reader.original_position()
|
||||
}
|
||||
|
||||
/// Gets the count of items in the section.
|
||||
pub fn get_count(&self) -> u32 {
|
||||
self.count
|
||||
}
|
||||
|
||||
/// Reads content of the instance section.
|
||||
///
|
||||
/// # Examples
|
||||
/// ```
|
||||
/// use wasmparser::InstanceSectionReader;
|
||||
/// # let data: &[u8] = &[0x01, 0x00, 0x00, 0x01, 0x03, b'f', b'o', b'o', 0x12, 0x00];
|
||||
/// let mut reader = InstanceSectionReader::new(data, 0).unwrap();
|
||||
/// for _ in 0..reader.get_count() {
|
||||
/// let instance = reader.read().expect("instance");
|
||||
/// println!("Instance: {:?}", instance);
|
||||
/// }
|
||||
/// ```
|
||||
pub fn read(&mut self) -> Result<Instance<'a>> {
|
||||
self.reader.read_instance()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> SectionReader for InstanceSectionReader<'a> {
|
||||
type Item = Instance<'a>;
|
||||
|
||||
fn read(&mut self) -> Result<Self::Item> {
|
||||
Self::read(self)
|
||||
}
|
||||
|
||||
fn eof(&self) -> bool {
|
||||
self.reader.eof()
|
||||
}
|
||||
|
||||
fn original_position(&self) -> usize {
|
||||
Self::original_position(self)
|
||||
}
|
||||
|
||||
fn range(&self) -> Range<usize> {
|
||||
self.reader.range()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> SectionWithLimitedItems for InstanceSectionReader<'a> {
|
||||
fn get_count(&self) -> u32 {
|
||||
Self::get_count(self)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> IntoIterator for InstanceSectionReader<'a> {
|
||||
type Item = Result<Instance<'a>>;
|
||||
type IntoIter = SectionIteratorLimited<Self>;
|
||||
|
||||
/// Implements iterator over the instance section.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use wasmparser::InstanceSectionReader;
|
||||
/// # let data: &[u8] = &[0x01, 0x00, 0x00, 0x01, 0x03, b'f', b'o', b'o', 0x12, 0x00];
|
||||
/// let mut reader = InstanceSectionReader::new(data, 0).unwrap();
|
||||
/// for inst in reader {
|
||||
/// println!("Instance {:?}", inst.expect("instance"));
|
||||
/// }
|
||||
/// ```
|
||||
fn into_iter(self) -> Self::IntoIter {
|
||||
SectionIteratorLimited::new(self)
|
||||
}
|
||||
}
|
||||
|
||||
/// Represents an argument to instantiating a WebAssembly component.
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct ComponentInstantiationArg<'a> {
|
||||
/// The name of the component argument.
|
||||
pub name: &'a str,
|
||||
/// The kind of the component argument.
|
||||
pub kind: ComponentExternalKind,
|
||||
/// The index of the argument item.
|
||||
pub index: u32,
|
||||
}
|
||||
|
||||
/// Represents an instance in a WebAssembly component.
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum ComponentInstance<'a> {
|
||||
/// The instance is from instantiating a WebAssembly component.
|
||||
Instantiate {
|
||||
/// The component index.
|
||||
component_index: u32,
|
||||
/// The component's instantiation arguments.
|
||||
args: Box<[ComponentInstantiationArg<'a>]>,
|
||||
},
|
||||
/// The instance is a from exporting local items.
|
||||
FromExports(Box<[ComponentExport<'a>]>),
|
||||
}
|
||||
|
||||
/// A reader for the component instance section of a WebAssembly component.
|
||||
#[derive(Clone)]
|
||||
pub struct ComponentInstanceSectionReader<'a> {
|
||||
reader: BinaryReader<'a>,
|
||||
count: u32,
|
||||
}
|
||||
|
||||
impl<'a> ComponentInstanceSectionReader<'a> {
|
||||
/// Constructs a new `ComponentInstanceSectionReader` for the given data and offset.
|
||||
pub fn new(data: &'a [u8], offset: usize) -> Result<Self> {
|
||||
let mut reader = BinaryReader::new_with_offset(data, offset);
|
||||
let count = reader.read_var_u32()?;
|
||||
Ok(Self { reader, count })
|
||||
}
|
||||
|
||||
/// Gets the original position of the section reader.
|
||||
pub fn original_position(&self) -> usize {
|
||||
self.reader.original_position()
|
||||
}
|
||||
|
||||
/// Gets the count of items in the section.
|
||||
pub fn get_count(&self) -> u32 {
|
||||
self.count
|
||||
}
|
||||
|
||||
/// Reads content of the instance section.
|
||||
///
|
||||
/// # Examples
|
||||
/// ```
|
||||
/// use wasmparser::ComponentInstanceSectionReader;
|
||||
/// # let data: &[u8] = &[0x01, 0x00, 0x00, 0x01, 0x03, b'f', b'o', b'o', 0x01, 0x00];
|
||||
/// let mut reader = ComponentInstanceSectionReader::new(data, 0).unwrap();
|
||||
/// for _ in 0..reader.get_count() {
|
||||
/// let instance = reader.read().expect("instance");
|
||||
/// println!("Instance: {:?}", instance);
|
||||
/// }
|
||||
/// ```
|
||||
pub fn read(&mut self) -> Result<ComponentInstance<'a>> {
|
||||
self.reader.read_component_instance()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> SectionReader for ComponentInstanceSectionReader<'a> {
|
||||
type Item = ComponentInstance<'a>;
|
||||
|
||||
fn read(&mut self) -> Result<Self::Item> {
|
||||
Self::read(self)
|
||||
}
|
||||
|
||||
fn eof(&self) -> bool {
|
||||
self.reader.eof()
|
||||
}
|
||||
|
||||
fn original_position(&self) -> usize {
|
||||
Self::original_position(self)
|
||||
}
|
||||
|
||||
fn range(&self) -> Range<usize> {
|
||||
self.reader.range()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> SectionWithLimitedItems for ComponentInstanceSectionReader<'a> {
|
||||
fn get_count(&self) -> u32 {
|
||||
Self::get_count(self)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> IntoIterator for ComponentInstanceSectionReader<'a> {
|
||||
type Item = Result<ComponentInstance<'a>>;
|
||||
type IntoIter = SectionIteratorLimited<Self>;
|
||||
|
||||
/// Implements iterator over the instance section.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use wasmparser::ComponentInstanceSectionReader;
|
||||
/// # let data: &[u8] = &[0x01, 0x00, 0x00, 0x01, 0x03, b'f', b'o', b'o', 0x01, 0x00];
|
||||
/// let mut reader = ComponentInstanceSectionReader::new(data, 0).unwrap();
|
||||
/// for inst in reader {
|
||||
/// println!("Instance {:?}", inst.expect("instance"));
|
||||
/// }
|
||||
/// ```
|
||||
fn into_iter(self) -> Self::IntoIter {
|
||||
SectionIteratorLimited::new(self)
|
||||
}
|
||||
}
|
64
third_party/rust/wasmparser/src/readers/component/start.rs
vendored
Normal file
64
third_party/rust/wasmparser/src/readers/component/start.rs
vendored
Normal file
@ -0,0 +1,64 @@
|
||||
use crate::{BinaryReader, Result, SectionReader};
|
||||
use std::ops::Range;
|
||||
|
||||
/// Represents the start function in a WebAssembly component.
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct ComponentStartFunction {
|
||||
/// The index to the start function.
|
||||
pub func_index: u32,
|
||||
/// The start function arguments.
|
||||
///
|
||||
/// The arguments are specified by value index.
|
||||
pub arguments: Box<[u32]>,
|
||||
}
|
||||
|
||||
/// A reader for the start section of a WebAssembly component.
|
||||
#[derive(Clone)]
|
||||
pub struct ComponentStartSectionReader<'a>(BinaryReader<'a>);
|
||||
|
||||
impl<'a> ComponentStartSectionReader<'a> {
|
||||
/// Constructs a new `ComponentStartSectionReader` for the given data and offset.
|
||||
pub fn new(data: &'a [u8], offset: usize) -> Result<Self> {
|
||||
Ok(Self(BinaryReader::new_with_offset(data, offset)))
|
||||
}
|
||||
|
||||
/// Gets the original position of the section reader.
|
||||
pub fn original_position(&self) -> usize {
|
||||
self.0.original_position()
|
||||
}
|
||||
|
||||
/// Reads the start function from the section.
|
||||
///
|
||||
/// # Examples
|
||||
/// ```
|
||||
/// use wasmparser::ComponentStartSectionReader;
|
||||
///
|
||||
/// # let data: &[u8] = &[0x00, 0x03, 0x01, 0x02, 0x03];
|
||||
/// let mut reader = ComponentStartSectionReader::new(data, 0).unwrap();
|
||||
/// let start = reader.read().expect("start");
|
||||
/// println!("Start: {:?}", start);
|
||||
/// ```
|
||||
pub fn read(&mut self) -> Result<ComponentStartFunction> {
|
||||
self.0.read_component_start()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> SectionReader for ComponentStartSectionReader<'a> {
|
||||
type Item = ComponentStartFunction;
|
||||
|
||||
fn read(&mut self) -> Result<Self::Item> {
|
||||
Self::read(self)
|
||||
}
|
||||
|
||||
fn eof(&self) -> bool {
|
||||
self.0.eof()
|
||||
}
|
||||
|
||||
fn original_position(&self) -> usize {
|
||||
Self::original_position(self)
|
||||
}
|
||||
|
||||
fn range(&self) -> Range<usize> {
|
||||
self.0.range()
|
||||
}
|
||||
}
|
393
third_party/rust/wasmparser/src/readers/component/types.rs
vendored
Normal file
393
third_party/rust/wasmparser/src/readers/component/types.rs
vendored
Normal file
@ -0,0 +1,393 @@
|
||||
use crate::{
|
||||
Alias, BinaryReader, ComponentAlias, ComponentImport, ComponentTypeRef, FuncType, Import,
|
||||
Result, SectionIteratorLimited, SectionReader, SectionWithLimitedItems, Type, TypeRef,
|
||||
};
|
||||
use std::ops::Range;
|
||||
|
||||
/// Represents a core type in a WebAssembly component.
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum CoreType<'a> {
|
||||
/// The type is for a core function.
|
||||
Func(FuncType),
|
||||
/// The type is for a core module.
|
||||
Module(Box<[ModuleTypeDeclaration<'a>]>),
|
||||
}
|
||||
|
||||
/// Represents a module type declaration in a WebAssembly component.
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum ModuleTypeDeclaration<'a> {
|
||||
/// The module type definition is for a type.
|
||||
Type(Type),
|
||||
/// The module type definition is for an export.
|
||||
Export {
|
||||
/// The name of the exported item.
|
||||
name: &'a str,
|
||||
/// The type reference of the export.
|
||||
ty: TypeRef,
|
||||
},
|
||||
/// The module type declaration is for an alias.
|
||||
Alias(Alias<'a>),
|
||||
/// The module type definition is for an import.
|
||||
Import(Import<'a>),
|
||||
}
|
||||
|
||||
/// A reader for the core type section of a WebAssembly component.
|
||||
#[derive(Clone)]
|
||||
pub struct CoreTypeSectionReader<'a> {
|
||||
reader: BinaryReader<'a>,
|
||||
count: u32,
|
||||
}
|
||||
|
||||
impl<'a> CoreTypeSectionReader<'a> {
|
||||
/// Constructs a new `CoreTypeSectionReader` for the given data and offset.
|
||||
pub fn new(data: &'a [u8], offset: usize) -> Result<Self> {
|
||||
let mut reader = BinaryReader::new_with_offset(data, offset);
|
||||
let count = reader.read_var_u32()?;
|
||||
Ok(Self { reader, count })
|
||||
}
|
||||
|
||||
/// Gets the original position of the reader.
|
||||
pub fn original_position(&self) -> usize {
|
||||
self.reader.original_position()
|
||||
}
|
||||
|
||||
/// Gets a count of items in the section.
|
||||
pub fn get_count(&self) -> u32 {
|
||||
self.count
|
||||
}
|
||||
|
||||
/// Reads content of the type section.
|
||||
///
|
||||
/// # Examples
|
||||
/// ```
|
||||
/// use wasmparser::CoreTypeSectionReader;
|
||||
/// let data: &[u8] = &[0x01, 0x60, 0x00, 0x00];
|
||||
/// let mut reader = CoreTypeSectionReader::new(data, 0).unwrap();
|
||||
/// for _ in 0..reader.get_count() {
|
||||
/// let ty = reader.read().expect("type");
|
||||
/// println!("Type {:?}", ty);
|
||||
/// }
|
||||
/// ```
|
||||
pub fn read(&mut self) -> Result<CoreType<'a>> {
|
||||
self.reader.read_core_type()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> SectionReader for CoreTypeSectionReader<'a> {
|
||||
type Item = CoreType<'a>;
|
||||
|
||||
fn read(&mut self) -> Result<Self::Item> {
|
||||
Self::read(self)
|
||||
}
|
||||
|
||||
fn eof(&self) -> bool {
|
||||
self.reader.eof()
|
||||
}
|
||||
|
||||
fn original_position(&self) -> usize {
|
||||
Self::original_position(self)
|
||||
}
|
||||
|
||||
fn range(&self) -> Range<usize> {
|
||||
self.reader.range()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> SectionWithLimitedItems for CoreTypeSectionReader<'a> {
|
||||
fn get_count(&self) -> u32 {
|
||||
Self::get_count(self)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> IntoIterator for CoreTypeSectionReader<'a> {
|
||||
type Item = Result<CoreType<'a>>;
|
||||
type IntoIter = SectionIteratorLimited<Self>;
|
||||
|
||||
/// Implements iterator over the type section.
|
||||
///
|
||||
/// # Examples
|
||||
/// ```
|
||||
/// use wasmparser::CoreTypeSectionReader;
|
||||
/// # let data: &[u8] = &[0x01, 0x60, 0x00, 0x00];
|
||||
/// let mut reader = CoreTypeSectionReader::new(data, 0).unwrap();
|
||||
/// for ty in reader {
|
||||
/// println!("Type {:?}", ty.expect("type"));
|
||||
/// }
|
||||
/// ```
|
||||
fn into_iter(self) -> Self::IntoIter {
|
||||
SectionIteratorLimited::new(self)
|
||||
}
|
||||
}
|
||||
|
||||
/// Represents a value type in a WebAssembly component.
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub enum ComponentValType {
|
||||
/// The value type is a primitive type.
|
||||
Primitive(PrimitiveValType),
|
||||
/// The value type is a reference to a defined type.
|
||||
Type(u32),
|
||||
}
|
||||
|
||||
/// Represents a primitive value type.
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub enum PrimitiveValType {
|
||||
/// The type is the unit type.
|
||||
Unit,
|
||||
/// The type is a boolean.
|
||||
Bool,
|
||||
/// The type is a signed 8-bit integer.
|
||||
S8,
|
||||
/// The type is an unsigned 8-bit integer.
|
||||
U8,
|
||||
/// The type is a signed 16-bit integer.
|
||||
S16,
|
||||
/// The type is an unsigned 16-bit integer.
|
||||
U16,
|
||||
/// The type is a signed 32-bit integer.
|
||||
S32,
|
||||
/// The type is an unsigned 32-bit integer.
|
||||
U32,
|
||||
/// The type is a signed 64-bit integer.
|
||||
S64,
|
||||
/// The type is an unsigned 64-bit integer.
|
||||
U64,
|
||||
/// The type is a 32-bit floating point number.
|
||||
Float32,
|
||||
/// The type is a 64-bit floating point number.
|
||||
Float64,
|
||||
/// The type is a Unicode character.
|
||||
Char,
|
||||
/// The type is a string.
|
||||
String,
|
||||
}
|
||||
|
||||
impl PrimitiveValType {
|
||||
pub(crate) fn requires_realloc(&self) -> bool {
|
||||
matches!(self, Self::String)
|
||||
}
|
||||
|
||||
pub(crate) fn is_subtype_of(&self, other: &Self) -> bool {
|
||||
// Subtyping rules according to
|
||||
// https://github.com/WebAssembly/component-model/blob/17f94ed1270a98218e0e796ca1dad1feb7e5c507/design/mvp/Subtyping.md
|
||||
self == other
|
||||
|| matches!(
|
||||
(self, other),
|
||||
(_, Self::Unit)
|
||||
| (Self::S8, Self::S16)
|
||||
| (Self::S8, Self::S32)
|
||||
| (Self::S8, Self::S64)
|
||||
| (Self::U8, Self::U16)
|
||||
| (Self::U8, Self::U32)
|
||||
| (Self::U8, Self::U64)
|
||||
| (Self::U8, Self::S16)
|
||||
| (Self::U8, Self::S32)
|
||||
| (Self::U8, Self::S64)
|
||||
| (Self::S16, Self::S32)
|
||||
| (Self::S16, Self::S64)
|
||||
| (Self::U16, Self::U32)
|
||||
| (Self::U16, Self::U64)
|
||||
| (Self::U16, Self::S32)
|
||||
| (Self::U16, Self::S64)
|
||||
| (Self::S32, Self::S64)
|
||||
| (Self::U32, Self::U64)
|
||||
| (Self::U32, Self::S64)
|
||||
| (Self::Float32, Self::Float64)
|
||||
)
|
||||
}
|
||||
|
||||
pub(crate) fn type_size(&self) -> usize {
|
||||
match self {
|
||||
Self::Unit => 0,
|
||||
_ => 1,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Represents a type in a WebAssembly component.
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum ComponentType<'a> {
|
||||
/// The type is a component defined type.
|
||||
Defined(ComponentDefinedType<'a>),
|
||||
/// The type is a function type.
|
||||
Func(ComponentFuncType<'a>),
|
||||
/// The type is a component type.
|
||||
Component(Box<[ComponentTypeDeclaration<'a>]>),
|
||||
/// The type is an instance type.
|
||||
Instance(Box<[InstanceTypeDeclaration<'a>]>),
|
||||
}
|
||||
|
||||
/// Represents part of a component type declaration in a WebAssembly component.
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum ComponentTypeDeclaration<'a> {
|
||||
/// The component type declaration is for a core type.
|
||||
CoreType(CoreType<'a>),
|
||||
/// The component type declaration is for a type.
|
||||
Type(ComponentType<'a>),
|
||||
/// The component type declaration is for an alias.
|
||||
Alias(ComponentAlias<'a>),
|
||||
/// The component type declaration is for an export.
|
||||
Export {
|
||||
/// The name of the export.
|
||||
name: &'a str,
|
||||
/// The type reference for the export.
|
||||
ty: ComponentTypeRef,
|
||||
},
|
||||
/// The component type declaration is for an import.
|
||||
Import(ComponentImport<'a>),
|
||||
}
|
||||
|
||||
/// Represents an instance type declaration in a WebAssembly component.
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum InstanceTypeDeclaration<'a> {
|
||||
/// The component type declaration is for a core type.
|
||||
CoreType(CoreType<'a>),
|
||||
/// The instance type declaration is for a type.
|
||||
Type(ComponentType<'a>),
|
||||
/// The instance type declaration is for an alias.
|
||||
Alias(ComponentAlias<'a>),
|
||||
/// The instance type declaration is for an export.
|
||||
Export {
|
||||
/// The name of the export.
|
||||
name: &'a str,
|
||||
/// The type reference for the export.
|
||||
ty: ComponentTypeRef,
|
||||
},
|
||||
}
|
||||
|
||||
/// Represents a type of a function in a WebAssembly component.
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct ComponentFuncType<'a> {
|
||||
/// The function parameter types.
|
||||
pub params: Box<[(Option<&'a str>, ComponentValType)]>,
|
||||
/// The function result type.
|
||||
pub result: ComponentValType,
|
||||
}
|
||||
|
||||
/// Represents a case in a variant type.
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub struct VariantCase<'a> {
|
||||
/// The name of the variant case.
|
||||
pub name: &'a str,
|
||||
/// The value type of the variant case.
|
||||
pub ty: ComponentValType,
|
||||
/// The index of the variant case that is refined by this one.
|
||||
pub refines: Option<u32>,
|
||||
}
|
||||
|
||||
/// Represents a defined type in a WebAssembly component.
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub enum ComponentDefinedType<'a> {
|
||||
/// The type is one of the primitive value types.
|
||||
Primitive(PrimitiveValType),
|
||||
/// The type is a record with the given fields.
|
||||
Record(Box<[(&'a str, ComponentValType)]>),
|
||||
/// The type is a variant with the given cases.
|
||||
Variant(Box<[VariantCase<'a>]>),
|
||||
/// The type is a list of the given value type.
|
||||
List(ComponentValType),
|
||||
/// The type is a tuple of the given value types.
|
||||
Tuple(Box<[ComponentValType]>),
|
||||
/// The type is flags with the given names.
|
||||
Flags(Box<[&'a str]>),
|
||||
/// The type is an enum with the given tags.
|
||||
Enum(Box<[&'a str]>),
|
||||
/// The type is a union of the given value types.
|
||||
Union(Box<[ComponentValType]>),
|
||||
/// The type is an option of the given value type.
|
||||
Option(ComponentValType),
|
||||
/// The type is an expected type.
|
||||
Expected {
|
||||
/// The type returned for success.
|
||||
ok: ComponentValType,
|
||||
/// The type returned for failure.
|
||||
error: ComponentValType,
|
||||
},
|
||||
}
|
||||
|
||||
/// A reader for the type section of a WebAssembly component.
|
||||
#[derive(Clone)]
|
||||
pub struct ComponentTypeSectionReader<'a> {
|
||||
reader: BinaryReader<'a>,
|
||||
count: u32,
|
||||
}
|
||||
|
||||
impl<'a> ComponentTypeSectionReader<'a> {
|
||||
/// Constructs a new `ComponentTypeSectionReader` for the given data and offset.
|
||||
pub fn new(data: &'a [u8], offset: usize) -> Result<Self> {
|
||||
let mut reader = BinaryReader::new_with_offset(data, offset);
|
||||
let count = reader.read_var_u32()?;
|
||||
Ok(Self { reader, count })
|
||||
}
|
||||
|
||||
/// Gets the original position of the reader.
|
||||
pub fn original_position(&self) -> usize {
|
||||
self.reader.original_position()
|
||||
}
|
||||
|
||||
/// Gets a count of items in the section.
|
||||
pub fn get_count(&self) -> u32 {
|
||||
self.count
|
||||
}
|
||||
|
||||
/// Reads content of the type section.
|
||||
///
|
||||
/// # Examples
|
||||
/// ```
|
||||
/// use wasmparser::ComponentTypeSectionReader;
|
||||
/// let data: &[u8] = &[0x01, 0x40, 0x01, 0x01, 0x03, b'f', b'o', b'o', 0x72, 0x72];
|
||||
/// let mut reader = ComponentTypeSectionReader::new(data, 0).unwrap();
|
||||
/// for _ in 0..reader.get_count() {
|
||||
/// let ty = reader.read().expect("type");
|
||||
/// println!("Type {:?}", ty);
|
||||
/// }
|
||||
/// ```
|
||||
pub fn read(&mut self) -> Result<ComponentType<'a>> {
|
||||
self.reader.read_component_type()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> SectionReader for ComponentTypeSectionReader<'a> {
|
||||
type Item = ComponentType<'a>;
|
||||
|
||||
fn read(&mut self) -> Result<Self::Item> {
|
||||
Self::read(self)
|
||||
}
|
||||
|
||||
fn eof(&self) -> bool {
|
||||
self.reader.eof()
|
||||
}
|
||||
|
||||
fn original_position(&self) -> usize {
|
||||
Self::original_position(self)
|
||||
}
|
||||
|
||||
fn range(&self) -> Range<usize> {
|
||||
self.reader.range()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> SectionWithLimitedItems for ComponentTypeSectionReader<'a> {
|
||||
fn get_count(&self) -> u32 {
|
||||
Self::get_count(self)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> IntoIterator for ComponentTypeSectionReader<'a> {
|
||||
type Item = Result<ComponentType<'a>>;
|
||||
type IntoIter = SectionIteratorLimited<Self>;
|
||||
|
||||
/// Implements iterator over the type section.
|
||||
///
|
||||
/// # Examples
|
||||
/// ```
|
||||
/// use wasmparser::ComponentTypeSectionReader;
|
||||
/// let data: &[u8] = &[0x01, 0x40, 0x01, 0x01, 0x03, b'f', b'o', b'o', 0x72, 0x72];
|
||||
/// let mut reader = ComponentTypeSectionReader::new(data, 0).unwrap();
|
||||
/// for ty in reader {
|
||||
/// println!("Type {:?}", ty.expect("type"));
|
||||
/// }
|
||||
/// ```
|
||||
fn into_iter(self) -> Self::IntoIter {
|
||||
SectionIteratorLimited::new(self)
|
||||
}
|
||||
}
|
37
third_party/rust/wasmparser/src/readers/core.rs
vendored
Normal file
37
third_party/rust/wasmparser/src/readers/core.rs
vendored
Normal file
@ -0,0 +1,37 @@
|
||||
mod code;
|
||||
mod custom;
|
||||
mod data;
|
||||
mod elements;
|
||||
mod exports;
|
||||
mod functions;
|
||||
mod globals;
|
||||
mod imports;
|
||||
mod init;
|
||||
mod linking;
|
||||
mod memories;
|
||||
mod names;
|
||||
mod operators;
|
||||
mod producers;
|
||||
mod relocs;
|
||||
mod tables;
|
||||
mod tags;
|
||||
mod types;
|
||||
|
||||
pub use self::code::*;
|
||||
pub use self::custom::*;
|
||||
pub use self::data::*;
|
||||
pub use self::elements::*;
|
||||
pub use self::exports::*;
|
||||
pub use self::functions::*;
|
||||
pub use self::globals::*;
|
||||
pub use self::imports::*;
|
||||
pub use self::init::*;
|
||||
pub use self::linking::*;
|
||||
pub use self::memories::*;
|
||||
pub use self::names::*;
|
||||
pub use self::operators::*;
|
||||
pub use self::producers::*;
|
||||
pub use self::relocs::*;
|
||||
pub use self::tables::*;
|
||||
pub use self::tags::*;
|
||||
pub use self::types::*;
|
@ -13,38 +13,59 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
use super::{
|
||||
BinaryReader, BinaryReaderError, OperatorsReader, Range, Result, SectionIteratorLimited,
|
||||
SectionReader, SectionWithLimitedItems, Type,
|
||||
use crate::{
|
||||
BinaryReader, BinaryReaderError, OperatorsReader, Result, SectionIteratorLimited,
|
||||
SectionReader, SectionWithLimitedItems, ValType,
|
||||
};
|
||||
use std::ops::Range;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
/// Represents a WebAssembly function body.
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub struct FunctionBody<'a> {
|
||||
offset: usize,
|
||||
data: &'a [u8],
|
||||
allow_memarg64: bool,
|
||||
}
|
||||
|
||||
impl<'a> FunctionBody<'a> {
|
||||
/// Constructs a new `FunctionBody` for the given data and offset.
|
||||
pub fn new(offset: usize, data: &'a [u8]) -> Self {
|
||||
Self { offset, data }
|
||||
Self {
|
||||
offset,
|
||||
data,
|
||||
allow_memarg64: false,
|
||||
}
|
||||
}
|
||||
|
||||
/// Whether or not to allow 64-bit memory arguments in the
|
||||
/// function body.
|
||||
///
|
||||
/// This is intended to be `true` when support for the memory64
|
||||
/// WebAssembly proposal is also enabled.
|
||||
pub fn allow_memarg64(&mut self, allow: bool) {
|
||||
self.allow_memarg64 = allow;
|
||||
}
|
||||
|
||||
/// Gets a binary reader for this function body.
|
||||
pub fn get_binary_reader<'b>(&self) -> BinaryReader<'b>
|
||||
where
|
||||
'a: 'b,
|
||||
{
|
||||
BinaryReader::new_with_offset(self.data, self.offset)
|
||||
let mut reader = BinaryReader::new_with_offset(self.data, self.offset);
|
||||
reader.allow_memarg64(self.allow_memarg64);
|
||||
reader
|
||||
}
|
||||
|
||||
fn skip_locals(reader: &mut BinaryReader) -> Result<()> {
|
||||
let count = reader.read_var_u32()?;
|
||||
for _ in 0..count {
|
||||
reader.skip_var_32()?;
|
||||
reader.skip_type()?;
|
||||
reader.read_var_u32()?;
|
||||
reader.read_var_u32()?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Gets the locals reader for this function body.
|
||||
pub fn get_locals_reader<'b>(&self) -> Result<LocalsReader<'b>>
|
||||
where
|
||||
'a: 'b,
|
||||
@ -54,6 +75,7 @@ impl<'a> FunctionBody<'a> {
|
||||
Ok(LocalsReader { reader, count })
|
||||
}
|
||||
|
||||
/// Gets the operators reader for this function body.
|
||||
pub fn get_operators_reader<'b>(&self) -> Result<OperatorsReader<'b>>
|
||||
where
|
||||
'a: 'b,
|
||||
@ -61,45 +83,44 @@ impl<'a> FunctionBody<'a> {
|
||||
let mut reader = BinaryReader::new_with_offset(self.data, self.offset);
|
||||
Self::skip_locals(&mut reader)?;
|
||||
let pos = reader.position;
|
||||
Ok(OperatorsReader::new(&self.data[pos..], self.offset + pos))
|
||||
let mut reader = OperatorsReader::new(&self.data[pos..], self.offset + pos);
|
||||
reader.allow_memarg64(self.allow_memarg64);
|
||||
Ok(reader)
|
||||
}
|
||||
|
||||
pub fn range(&self) -> Range {
|
||||
Range {
|
||||
start: self.offset,
|
||||
end: self.offset + self.data.len(),
|
||||
}
|
||||
/// Gets the range of the function body.
|
||||
pub fn range(&self) -> Range<usize> {
|
||||
self.offset..self.offset + self.data.len()
|
||||
}
|
||||
}
|
||||
|
||||
/// A reader for a function body's locals.
|
||||
pub struct LocalsReader<'a> {
|
||||
reader: BinaryReader<'a>,
|
||||
count: u32,
|
||||
}
|
||||
|
||||
impl<'a> LocalsReader<'a> {
|
||||
/// Gets the count of locals in the function body.
|
||||
pub fn get_count(&self) -> u32 {
|
||||
self.count
|
||||
}
|
||||
|
||||
/// Gets the original position of the reader.
|
||||
pub fn original_position(&self) -> usize {
|
||||
self.reader.original_position()
|
||||
}
|
||||
|
||||
pub fn read(&mut self) -> Result<(u32, Type)> {
|
||||
/// Reads an item from the reader.
|
||||
pub fn read(&mut self) -> Result<(u32, ValType)> {
|
||||
let count = self.reader.read_var_u32()?;
|
||||
let value_type = self.reader.read_type()?;
|
||||
let value_type = self.reader.read_val_type()?;
|
||||
Ok((count, value_type))
|
||||
}
|
||||
}
|
||||
|
||||
pub struct CodeSectionReader<'a> {
|
||||
reader: BinaryReader<'a>,
|
||||
count: u32,
|
||||
}
|
||||
|
||||
impl<'a> IntoIterator for LocalsReader<'a> {
|
||||
type Item = Result<(u32, Type)>;
|
||||
type Item = Result<(u32, ValType)>;
|
||||
type IntoIter = LocalsIterator<'a>;
|
||||
fn into_iter(self) -> Self::IntoIter {
|
||||
let count = self.count;
|
||||
@ -111,6 +132,7 @@ impl<'a> IntoIterator for LocalsReader<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
/// An iterator over locals in a function body.
|
||||
pub struct LocalsIterator<'a> {
|
||||
reader: LocalsReader<'a>,
|
||||
left: u32,
|
||||
@ -118,7 +140,7 @@ pub struct LocalsIterator<'a> {
|
||||
}
|
||||
|
||||
impl<'a> Iterator for LocalsIterator<'a> {
|
||||
type Item = Result<(u32, Type)>;
|
||||
type Item = Result<(u32, ValType)>;
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
if self.err || self.left == 0 {
|
||||
return None;
|
||||
@ -134,17 +156,26 @@ impl<'a> Iterator for LocalsIterator<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
/// A reader for the code section of a WebAssembly module.
|
||||
pub struct CodeSectionReader<'a> {
|
||||
reader: BinaryReader<'a>,
|
||||
count: u32,
|
||||
}
|
||||
|
||||
impl<'a> CodeSectionReader<'a> {
|
||||
/// Constructs a new `CodeSectionReader` for the given data and offset.
|
||||
pub fn new(data: &'a [u8], offset: usize) -> Result<CodeSectionReader<'a>> {
|
||||
let mut reader = BinaryReader::new_with_offset(data, offset);
|
||||
let count = reader.read_var_u32()?;
|
||||
Ok(CodeSectionReader { reader, count })
|
||||
}
|
||||
|
||||
/// Gets the original position of the reader.
|
||||
pub fn original_position(&self) -> usize {
|
||||
self.reader.original_position()
|
||||
}
|
||||
|
||||
/// Gets the count of items in the section.
|
||||
pub fn get_count(&self) -> u32 {
|
||||
self.count
|
||||
}
|
||||
@ -152,7 +183,7 @@ impl<'a> CodeSectionReader<'a> {
|
||||
fn verify_body_end(&self, end: usize) -> Result<()> {
|
||||
if self.reader.buffer.len() < end {
|
||||
return Err(BinaryReaderError::new(
|
||||
"Function body extends past end of the code section",
|
||||
"function body extends past end of the code section",
|
||||
self.reader.original_offset + self.reader.buffer.len(),
|
||||
));
|
||||
}
|
||||
@ -187,6 +218,7 @@ impl<'a> CodeSectionReader<'a> {
|
||||
Ok(FunctionBody {
|
||||
offset: self.reader.original_offset + body_start,
|
||||
data: &self.reader.buffer[body_start..body_end],
|
||||
allow_memarg64: false,
|
||||
})
|
||||
}
|
||||
}
|
||||
@ -202,7 +234,7 @@ impl<'a> SectionReader for CodeSectionReader<'a> {
|
||||
fn original_position(&self) -> usize {
|
||||
CodeSectionReader::original_position(self)
|
||||
}
|
||||
fn range(&self) -> Range {
|
||||
fn range(&self) -> Range<usize> {
|
||||
self.reader.range()
|
||||
}
|
||||
}
|
63
third_party/rust/wasmparser/src/readers/core/custom.rs
vendored
Normal file
63
third_party/rust/wasmparser/src/readers/core/custom.rs
vendored
Normal file
@ -0,0 +1,63 @@
|
||||
use crate::{BinaryReader, Result};
|
||||
use std::ops::Range;
|
||||
|
||||
/// A reader for custom sections of a WebAssembly module.
|
||||
#[derive(Clone)]
|
||||
pub struct CustomSectionReader<'a> {
|
||||
// NB: these fields are public to the crate to make testing easier.
|
||||
pub(crate) name: &'a str,
|
||||
pub(crate) data_offset: usize,
|
||||
pub(crate) data: &'a [u8],
|
||||
pub(crate) range: Range<usize>,
|
||||
}
|
||||
|
||||
impl<'a> CustomSectionReader<'a> {
|
||||
/// Constructs a new `CustomSectionReader` for the given data and offset.
|
||||
pub fn new(data: &'a [u8], offset: usize) -> Result<CustomSectionReader<'a>> {
|
||||
let mut reader = BinaryReader::new_with_offset(data, offset);
|
||||
let name = reader.read_string()?;
|
||||
let data_offset = reader.original_position();
|
||||
let data = reader.remaining_buffer();
|
||||
let range = reader.range();
|
||||
Ok(CustomSectionReader {
|
||||
name,
|
||||
data_offset,
|
||||
data,
|
||||
range,
|
||||
})
|
||||
}
|
||||
|
||||
/// The name of the custom section.
|
||||
pub fn name(&self) -> &'a str {
|
||||
self.name
|
||||
}
|
||||
|
||||
/// The offset, relative to the start of the original module or component,
|
||||
/// that the `data` payload for this custom section starts at.
|
||||
pub fn data_offset(&self) -> usize {
|
||||
self.data_offset
|
||||
}
|
||||
|
||||
/// The actual contents of the custom section.
|
||||
pub fn data(&self) -> &'a [u8] {
|
||||
self.data
|
||||
}
|
||||
|
||||
/// The range of bytes that specify this whole custom section (including
|
||||
/// both the name of this custom section and its data) specified in
|
||||
/// offsets relative to the start of the byte stream.
|
||||
pub fn range(&self) -> Range<usize> {
|
||||
self.range.clone()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> std::fmt::Debug for CustomSectionReader<'a> {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
f.debug_struct("CustomSectionReader")
|
||||
.field("name", &self.name)
|
||||
.field("data_offset", &self.data_offset)
|
||||
.field("data", &"...")
|
||||
.field("range", &self.range)
|
||||
.finish()
|
||||
}
|
||||
}
|
@ -13,60 +13,66 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
use super::{
|
||||
BinaryReader, BinaryReaderError, InitExpr, Range, Result, SectionIteratorLimited,
|
||||
SectionReader, SectionWithLimitedItems,
|
||||
use crate::{
|
||||
BinaryReader, BinaryReaderError, InitExpr, Result, SectionIteratorLimited, SectionReader,
|
||||
SectionWithLimitedItems,
|
||||
};
|
||||
use std::ops::Range;
|
||||
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
/// Represents a data segment in a core WebAssembly module.
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Data<'a> {
|
||||
/// The kind of data segment.
|
||||
pub kind: DataKind<'a>,
|
||||
/// The data of the data segment.
|
||||
pub data: &'a [u8],
|
||||
/// The range of the data segment.
|
||||
pub range: Range<usize>,
|
||||
}
|
||||
|
||||
/// The kind of data segment.
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
pub enum DataKind<'a> {
|
||||
/// The data segment is passive.
|
||||
Passive,
|
||||
/// The data segment is active.
|
||||
Active {
|
||||
/// The memory index for the data segment.
|
||||
memory_index: u32,
|
||||
/// The initialization expression for the data segment.
|
||||
init_expr: InitExpr<'a>,
|
||||
},
|
||||
}
|
||||
|
||||
/// A reader for the data section of a WebAssembly module.
|
||||
#[derive(Clone)]
|
||||
pub struct DataSectionReader<'a> {
|
||||
reader: BinaryReader<'a>,
|
||||
count: u32,
|
||||
forbid_bulk_memory: bool,
|
||||
}
|
||||
|
||||
impl<'a> DataSectionReader<'a> {
|
||||
/// Constructs a new `DataSectionReader` for the given data and offset.
|
||||
pub fn new(data: &'a [u8], offset: usize) -> Result<DataSectionReader<'a>> {
|
||||
let mut reader = BinaryReader::new_with_offset(data, offset);
|
||||
let count = reader.read_var_u32()?;
|
||||
Ok(DataSectionReader {
|
||||
reader,
|
||||
count,
|
||||
forbid_bulk_memory: false,
|
||||
})
|
||||
Ok(DataSectionReader { reader, count })
|
||||
}
|
||||
|
||||
/// Gets the original position of the section reader.
|
||||
pub fn original_position(&self) -> usize {
|
||||
self.reader.original_position()
|
||||
}
|
||||
|
||||
/// Gets the count of items in the section.
|
||||
pub fn get_count(&self) -> u32 {
|
||||
self.count
|
||||
}
|
||||
|
||||
pub fn forbid_bulk_memory(&mut self, forbid: bool) {
|
||||
self.forbid_bulk_memory = forbid;
|
||||
}
|
||||
|
||||
fn verify_data_end(&self, end: usize) -> Result<()> {
|
||||
if self.reader.buffer.len() < end {
|
||||
return Err(BinaryReaderError::new(
|
||||
"Data segment extends past end of the data section",
|
||||
"unexpected end of section or function: data segment extends past end of the data section",
|
||||
self.reader.original_offset + self.reader.buffer.len(),
|
||||
));
|
||||
}
|
||||
@ -95,38 +101,59 @@ impl<'a> DataSectionReader<'a> {
|
||||
where
|
||||
'a: 'b,
|
||||
{
|
||||
let segment_start = self.reader.original_position();
|
||||
|
||||
// The current handling of the flags is largely specified in the `bulk-memory` proposal,
|
||||
// which at the time this commend is written has been merged to the main specification
|
||||
// draft.
|
||||
//
|
||||
// Notably, this proposal allows multiple different encodings of the memory index 0. `00`
|
||||
// and `02 00` are both valid ways to specify the 0-th memory. However it also makes
|
||||
// another encoding of the 0-th memory `80 00` no longer valid.
|
||||
//
|
||||
// We, however maintain this by parsing `flags` as a LEB128 integer. In that case, `80 00`
|
||||
// encoding is parsed out as `0` and is therefore assigned a `memidx` 0, even though the
|
||||
// current specification draft does not allow for this.
|
||||
//
|
||||
// See also https://github.com/WebAssembly/spec/issues/1439
|
||||
let flags = self.reader.read_var_u32()?;
|
||||
let kind = if !self.forbid_bulk_memory && flags == 1 {
|
||||
DataKind::Passive
|
||||
} else {
|
||||
let memory_index = match flags {
|
||||
0 => 0,
|
||||
_ if self.forbid_bulk_memory => flags,
|
||||
2 => self.reader.read_var_u32()?,
|
||||
_ => {
|
||||
return Err(BinaryReaderError::new(
|
||||
"invalid flags byte in data segment",
|
||||
self.reader.original_position() - 1,
|
||||
));
|
||||
let kind = match flags {
|
||||
1 => DataKind::Passive,
|
||||
0 | 2 => {
|
||||
let memory_index = if flags == 0 {
|
||||
0
|
||||
} else {
|
||||
self.reader.read_var_u32()?
|
||||
};
|
||||
let init_expr = {
|
||||
let expr_offset = self.reader.position;
|
||||
self.reader.skip_init_expr()?;
|
||||
let data = &self.reader.buffer[expr_offset..self.reader.position];
|
||||
InitExpr::new(data, self.reader.original_offset + expr_offset)
|
||||
};
|
||||
DataKind::Active {
|
||||
memory_index,
|
||||
init_expr,
|
||||
}
|
||||
};
|
||||
let init_expr = {
|
||||
let expr_offset = self.reader.position;
|
||||
self.reader.skip_init_expr()?;
|
||||
let data = &self.reader.buffer[expr_offset..self.reader.position];
|
||||
InitExpr::new(data, self.reader.original_offset + expr_offset)
|
||||
};
|
||||
DataKind::Active {
|
||||
memory_index,
|
||||
init_expr,
|
||||
}
|
||||
_ => {
|
||||
return Err(BinaryReaderError::new(
|
||||
"invalid flags byte in data segment",
|
||||
self.reader.original_position() - 1,
|
||||
));
|
||||
}
|
||||
};
|
||||
|
||||
let data_len = self.reader.read_var_u32()? as usize;
|
||||
let data_end = self.reader.position + data_len;
|
||||
self.verify_data_end(data_end)?;
|
||||
let data = &self.reader.buffer[self.reader.position..data_end];
|
||||
self.reader.skip_to(data_end);
|
||||
Ok(Data { kind, data })
|
||||
|
||||
let segment_end = self.reader.original_position();
|
||||
let range = segment_start..segment_end;
|
||||
|
||||
Ok(Data { kind, data, range })
|
||||
}
|
||||
}
|
||||
|
||||
@ -141,7 +168,7 @@ impl<'a> SectionReader for DataSectionReader<'a> {
|
||||
fn original_position(&self) -> usize {
|
||||
DataSectionReader::original_position(self)
|
||||
}
|
||||
fn range(&self) -> Range {
|
||||
fn range(&self) -> Range<usize> {
|
||||
self.reader.range()
|
||||
}
|
||||
}
|
@ -13,29 +13,42 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
use super::{
|
||||
BinaryReader, BinaryReaderError, InitExpr, Range, Result, SectionIteratorLimited,
|
||||
SectionReader, SectionWithLimitedItems, Type,
|
||||
use crate::{
|
||||
BinaryReader, BinaryReaderError, ExternalKind, InitExpr, Result, SectionIteratorLimited,
|
||||
SectionReader, SectionWithLimitedItems, ValType,
|
||||
};
|
||||
use crate::{ExternalKind, Operator};
|
||||
use std::ops::Range;
|
||||
|
||||
/// Represents a core WebAssembly element segment.
|
||||
#[derive(Clone)]
|
||||
pub struct Element<'a> {
|
||||
/// The kind of the element segment.
|
||||
pub kind: ElementKind<'a>,
|
||||
/// The initial elements of the element segment.
|
||||
pub items: ElementItems<'a>,
|
||||
pub ty: Type,
|
||||
/// The type of the elements.
|
||||
pub ty: ValType,
|
||||
/// The range of the the element segment.
|
||||
pub range: Range<usize>,
|
||||
}
|
||||
|
||||
/// The kind of element segment.
|
||||
#[derive(Clone)]
|
||||
pub enum ElementKind<'a> {
|
||||
/// The element segment is passive.
|
||||
Passive,
|
||||
/// The element segment is active.
|
||||
Active {
|
||||
/// The index of the table being initialized.
|
||||
table_index: u32,
|
||||
/// The initial expression of the element segment.
|
||||
init_expr: InitExpr<'a>,
|
||||
},
|
||||
/// The element segment is declared.
|
||||
Declared,
|
||||
}
|
||||
|
||||
/// Represents the items of an element segment.
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
pub struct ElementItems<'a> {
|
||||
exprs: bool,
|
||||
@ -43,13 +56,17 @@ pub struct ElementItems<'a> {
|
||||
data: &'a [u8],
|
||||
}
|
||||
|
||||
/// Represents an individual item of an element segment.
|
||||
#[derive(Debug)]
|
||||
pub enum ElementItem {
|
||||
Null(Type),
|
||||
pub enum ElementItem<'a> {
|
||||
/// The item is a function index.
|
||||
Func(u32),
|
||||
/// The item is an initialization expression.
|
||||
Expr(InitExpr<'a>),
|
||||
}
|
||||
|
||||
impl<'a> ElementItems<'a> {
|
||||
/// Gets an items reader for the items in an element segment.
|
||||
pub fn get_items_reader<'b>(&self) -> Result<ElementItemsReader<'b>>
|
||||
where
|
||||
'a: 'b,
|
||||
@ -58,6 +75,7 @@ impl<'a> ElementItems<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
/// A reader for element items in an element segment.
|
||||
pub struct ElementItemsReader<'a> {
|
||||
reader: BinaryReader<'a>,
|
||||
count: u32,
|
||||
@ -65,6 +83,7 @@ pub struct ElementItemsReader<'a> {
|
||||
}
|
||||
|
||||
impl<'a> ElementItemsReader<'a> {
|
||||
/// Constructs a new `ElementItemsReader` for the given data and offset.
|
||||
pub fn new(data: &[u8], offset: usize, exprs: bool) -> Result<ElementItemsReader> {
|
||||
let mut reader = BinaryReader::new_with_offset(data, offset);
|
||||
let count = reader.read_var_u32()?;
|
||||
@ -75,39 +94,35 @@ impl<'a> ElementItemsReader<'a> {
|
||||
})
|
||||
}
|
||||
|
||||
/// Gets the original position of the reader.
|
||||
pub fn original_position(&self) -> usize {
|
||||
self.reader.original_position()
|
||||
}
|
||||
|
||||
/// Gets the count of element items in the segment.
|
||||
pub fn get_count(&self) -> u32 {
|
||||
self.count
|
||||
}
|
||||
|
||||
/// Whether or not initialization expressions are used.
|
||||
pub fn uses_exprs(&self) -> bool {
|
||||
self.exprs
|
||||
}
|
||||
|
||||
pub fn read(&mut self) -> Result<ElementItem> {
|
||||
/// Reads an element item from the segment.
|
||||
pub fn read(&mut self) -> Result<ElementItem<'a>> {
|
||||
if self.exprs {
|
||||
let offset = self.reader.original_position();
|
||||
let ret = match self.reader.read_operator()? {
|
||||
Operator::RefNull { ty } => ElementItem::Null(ty),
|
||||
Operator::RefFunc { function_index } => ElementItem::Func(function_index),
|
||||
_ => return Err(BinaryReaderError::new("invalid passive segment", offset)),
|
||||
};
|
||||
match self.reader.read_operator()? {
|
||||
Operator::End => {}
|
||||
_ => return Err(BinaryReaderError::new("invalid passive segment", offset)),
|
||||
}
|
||||
Ok(ret)
|
||||
let expr = self.reader.read_init_expr()?;
|
||||
Ok(ElementItem::Expr(expr))
|
||||
} else {
|
||||
self.reader.read_var_u32().map(ElementItem::Func)
|
||||
let idx = self.reader.read_var_u32()?;
|
||||
Ok(ElementItem::Func(idx))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> IntoIterator for ElementItemsReader<'a> {
|
||||
type Item = Result<ElementItem>;
|
||||
type Item = Result<ElementItem<'a>>;
|
||||
type IntoIter = ElementItemsIterator<'a>;
|
||||
fn into_iter(self) -> Self::IntoIter {
|
||||
let count = self.count;
|
||||
@ -119,6 +134,7 @@ impl<'a> IntoIterator for ElementItemsReader<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
/// An iterator over element items in an element segment.
|
||||
pub struct ElementItemsIterator<'a> {
|
||||
reader: ElementItemsReader<'a>,
|
||||
left: u32,
|
||||
@ -126,7 +142,7 @@ pub struct ElementItemsIterator<'a> {
|
||||
}
|
||||
|
||||
impl<'a> Iterator for ElementItemsIterator<'a> {
|
||||
type Item = Result<ElementItem>;
|
||||
type Item = Result<ElementItem<'a>>;
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
if self.err || self.left == 0 {
|
||||
return None;
|
||||
@ -142,6 +158,7 @@ impl<'a> Iterator for ElementItemsIterator<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
/// A reader for the element section of a WebAssembly module.
|
||||
#[derive(Clone)]
|
||||
pub struct ElementSectionReader<'a> {
|
||||
reader: BinaryReader<'a>,
|
||||
@ -149,16 +166,19 @@ pub struct ElementSectionReader<'a> {
|
||||
}
|
||||
|
||||
impl<'a> ElementSectionReader<'a> {
|
||||
/// Constructs a new `ElementSectionReader` for the given data and offset.
|
||||
pub fn new(data: &'a [u8], offset: usize) -> Result<ElementSectionReader<'a>> {
|
||||
let mut reader = BinaryReader::new_with_offset(data, offset);
|
||||
let count = reader.read_var_u32()?;
|
||||
Ok(ElementSectionReader { reader, count })
|
||||
}
|
||||
|
||||
/// Gets the original position of the section reader.
|
||||
pub fn original_position(&self) -> usize {
|
||||
self.reader.original_position()
|
||||
}
|
||||
|
||||
/// Gets the count of items in the section.
|
||||
pub fn get_count(&self) -> u32 {
|
||||
self.count
|
||||
}
|
||||
@ -189,6 +209,20 @@ impl<'a> ElementSectionReader<'a> {
|
||||
where
|
||||
'a: 'b,
|
||||
{
|
||||
let elem_start = self.reader.original_position();
|
||||
// The current handling of the flags is largely specified in the `bulk-memory` proposal,
|
||||
// which at the time this commend is written has been merged to the main specification
|
||||
// draft.
|
||||
//
|
||||
// Notably, this proposal allows multiple different encodings of the table index 0. `00`
|
||||
// and `02 00` are both valid ways to specify the 0-th table. However it also makes
|
||||
// another encoding of the 0-th memory `80 00` no longer valid.
|
||||
//
|
||||
// We, however maintain this support by parsing `flags` as a LEB128 integer. In that case,
|
||||
// `80 00` encoding is parsed out as `0` and is therefore assigned a `tableidx` 0, even
|
||||
// though the current specification draft does not allow for this.
|
||||
//
|
||||
// See also https://github.com/WebAssembly/spec/issues/1439
|
||||
let flags = self.reader.read_var_u32()?;
|
||||
if (flags & !0b111) != 0 {
|
||||
return Err(BinaryReaderError::new(
|
||||
@ -222,10 +256,10 @@ impl<'a> ElementSectionReader<'a> {
|
||||
let exprs = flags & 0b100 != 0;
|
||||
let ty = if flags & 0b011 != 0 {
|
||||
if exprs {
|
||||
self.reader.read_type()?
|
||||
self.reader.read_val_type()?
|
||||
} else {
|
||||
match self.reader.read_external_kind()? {
|
||||
ExternalKind::Function => Type::FuncRef,
|
||||
ExternalKind::Func => ValType::FuncRef,
|
||||
_ => {
|
||||
return Err(BinaryReaderError::new(
|
||||
"only the function external type is supported in elem segment",
|
||||
@ -235,7 +269,7 @@ impl<'a> ElementSectionReader<'a> {
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Type::FuncRef
|
||||
ValType::FuncRef
|
||||
};
|
||||
let data_start = self.reader.position;
|
||||
let items_count = self.reader.read_var_u32()?;
|
||||
@ -245,7 +279,7 @@ impl<'a> ElementSectionReader<'a> {
|
||||
}
|
||||
} else {
|
||||
for _ in 0..items_count {
|
||||
self.reader.skip_var_32()?;
|
||||
self.reader.read_var_u32()?;
|
||||
}
|
||||
}
|
||||
let data_end = self.reader.position;
|
||||
@ -254,7 +288,16 @@ impl<'a> ElementSectionReader<'a> {
|
||||
data: &self.reader.buffer[data_start..data_end],
|
||||
exprs,
|
||||
};
|
||||
Ok(Element { kind, items, ty })
|
||||
|
||||
let elem_end = self.reader.original_position();
|
||||
let range = elem_start..elem_end;
|
||||
|
||||
Ok(Element {
|
||||
kind,
|
||||
items,
|
||||
ty,
|
||||
range,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@ -269,7 +312,7 @@ impl<'a> SectionReader for ElementSectionReader<'a> {
|
||||
fn original_position(&self) -> usize {
|
||||
ElementSectionReader::original_position(self)
|
||||
}
|
||||
fn range(&self) -> Range {
|
||||
fn range(&self) -> Range<usize> {
|
||||
self.reader.range()
|
||||
}
|
||||
}
|
@ -13,18 +13,38 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
use super::{
|
||||
BinaryReader, ExternalKind, Range, Result, SectionIteratorLimited, SectionReader,
|
||||
SectionWithLimitedItems,
|
||||
};
|
||||
use crate::{BinaryReader, Result, SectionIteratorLimited, SectionReader, SectionWithLimitedItems};
|
||||
use std::ops::Range;
|
||||
|
||||
/// External types as defined [here].
|
||||
///
|
||||
/// [here]: https://webassembly.github.io/spec/core/syntax/types.html#external-types
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
|
||||
pub enum ExternalKind {
|
||||
/// The external kind is a function.
|
||||
Func,
|
||||
/// The external kind if a table.
|
||||
Table,
|
||||
/// The external kind is a memory.
|
||||
Memory,
|
||||
/// The external kind is a global.
|
||||
Global,
|
||||
/// The external kind is a tag.
|
||||
Tag,
|
||||
}
|
||||
|
||||
/// Represents an export in a WebAssembly module.
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
pub struct Export<'a> {
|
||||
pub field: &'a str,
|
||||
/// The name of the exported item.
|
||||
pub name: &'a str,
|
||||
/// The kind of the export.
|
||||
pub kind: ExternalKind,
|
||||
/// The index of the exported item.
|
||||
pub index: u32,
|
||||
}
|
||||
|
||||
/// A reader for the export section of a WebAssembly module.
|
||||
#[derive(Clone)]
|
||||
pub struct ExportSectionReader<'a> {
|
||||
reader: BinaryReader<'a>,
|
||||
@ -32,16 +52,19 @@ pub struct ExportSectionReader<'a> {
|
||||
}
|
||||
|
||||
impl<'a> ExportSectionReader<'a> {
|
||||
pub fn new(data: &'a [u8], offset: usize) -> Result<ExportSectionReader<'a>> {
|
||||
/// Constructs a new `ExportSectionReader` for the given data and offset.
|
||||
pub fn new(data: &'a [u8], offset: usize) -> Result<Self> {
|
||||
let mut reader = BinaryReader::new_with_offset(data, offset);
|
||||
let count = reader.read_var_u32()?;
|
||||
Ok(ExportSectionReader { reader, count })
|
||||
Ok(Self { reader, count })
|
||||
}
|
||||
|
||||
/// Gets the original position of the section reader.
|
||||
pub fn original_position(&self) -> usize {
|
||||
self.reader.original_position()
|
||||
}
|
||||
|
||||
/// Gets the count of items in the section.
|
||||
pub fn get_count(&self) -> u32 {
|
||||
self.count
|
||||
}
|
||||
@ -53,48 +76,46 @@ impl<'a> ExportSectionReader<'a> {
|
||||
/// use wasmparser::ExportSectionReader;
|
||||
///
|
||||
/// # let data: &[u8] = &[0x01, 0x01, 0x65, 0x00, 0x00];
|
||||
/// let mut export_reader = ExportSectionReader::new(data, 0).unwrap();
|
||||
/// for _ in 0..export_reader.get_count() {
|
||||
/// let export = export_reader.read().expect("export");
|
||||
/// let mut reader = ExportSectionReader::new(data, 0).unwrap();
|
||||
/// for _ in 0..reader.get_count() {
|
||||
/// let export = reader.read().expect("export");
|
||||
/// println!("Export: {:?}", export);
|
||||
/// }
|
||||
/// ```
|
||||
pub fn read<'b>(&mut self) -> Result<Export<'b>>
|
||||
where
|
||||
'a: 'b,
|
||||
{
|
||||
let field = self.reader.read_string()?;
|
||||
let kind = self.reader.read_external_kind()?;
|
||||
let index = self.reader.read_var_u32()?;
|
||||
Ok(Export { field, kind, index })
|
||||
pub fn read(&mut self) -> Result<Export<'a>> {
|
||||
self.reader.read_export()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> SectionReader for ExportSectionReader<'a> {
|
||||
type Item = Export<'a>;
|
||||
|
||||
fn read(&mut self) -> Result<Self::Item> {
|
||||
ExportSectionReader::read(self)
|
||||
Self::read(self)
|
||||
}
|
||||
|
||||
fn eof(&self) -> bool {
|
||||
self.reader.eof()
|
||||
}
|
||||
|
||||
fn original_position(&self) -> usize {
|
||||
ExportSectionReader::original_position(self)
|
||||
Self::original_position(self)
|
||||
}
|
||||
fn range(&self) -> Range {
|
||||
|
||||
fn range(&self) -> Range<usize> {
|
||||
self.reader.range()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> SectionWithLimitedItems for ExportSectionReader<'a> {
|
||||
fn get_count(&self) -> u32 {
|
||||
ExportSectionReader::get_count(self)
|
||||
Self::get_count(self)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> IntoIterator for ExportSectionReader<'a> {
|
||||
type Item = Result<Export<'a>>;
|
||||
type IntoIter = SectionIteratorLimited<ExportSectionReader<'a>>;
|
||||
type IntoIter = SectionIteratorLimited<Self>;
|
||||
|
||||
fn into_iter(self) -> Self::IntoIter {
|
||||
SectionIteratorLimited::new(self)
|
@ -13,10 +13,10 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
use super::{
|
||||
BinaryReader, Range, Result, SectionIteratorLimited, SectionReader, SectionWithLimitedItems,
|
||||
};
|
||||
use crate::{BinaryReader, Result, SectionIteratorLimited, SectionReader, SectionWithLimitedItems};
|
||||
use std::ops::Range;
|
||||
|
||||
/// A reader for the function section of a WebAssembly module.
|
||||
#[derive(Clone)]
|
||||
pub struct FunctionSectionReader<'a> {
|
||||
reader: BinaryReader<'a>,
|
||||
@ -24,16 +24,19 @@ pub struct FunctionSectionReader<'a> {
|
||||
}
|
||||
|
||||
impl<'a> FunctionSectionReader<'a> {
|
||||
pub fn new(data: &'a [u8], offset: usize) -> Result<FunctionSectionReader<'a>> {
|
||||
/// Constructs a new `FunctionSectionReader` for the given data and offset.
|
||||
pub fn new(data: &'a [u8], offset: usize) -> Result<Self> {
|
||||
let mut reader = BinaryReader::new_with_offset(data, offset);
|
||||
let count = reader.read_var_u32()?;
|
||||
Ok(FunctionSectionReader { reader, count })
|
||||
Ok(Self { reader, count })
|
||||
}
|
||||
|
||||
/// Gets the original position of the section reader.
|
||||
pub fn original_position(&self) -> usize {
|
||||
self.reader.original_position()
|
||||
}
|
||||
|
||||
/// Gets the count of items in the section.
|
||||
pub fn get_count(&self) -> u32 {
|
||||
self.count
|
||||
}
|
||||
@ -45,9 +48,9 @@ impl<'a> FunctionSectionReader<'a> {
|
||||
/// ```
|
||||
/// use wasmparser::FunctionSectionReader;
|
||||
/// # let data: &[u8] = &[0x01, 0x00];
|
||||
/// let mut function_reader = FunctionSectionReader::new(data, 0).unwrap();
|
||||
/// for _ in 0..function_reader.get_count() {
|
||||
/// let ty = function_reader.read().expect("function type index");
|
||||
/// let mut reader = FunctionSectionReader::new(data, 0).unwrap();
|
||||
/// for _ in 0..reader.get_count() {
|
||||
/// let ty = reader.read().expect("function type index");
|
||||
/// println!("Function type index: {}", ty);
|
||||
/// }
|
||||
/// ```
|
||||
@ -58,29 +61,33 @@ impl<'a> FunctionSectionReader<'a> {
|
||||
|
||||
impl<'a> SectionReader for FunctionSectionReader<'a> {
|
||||
type Item = u32;
|
||||
|
||||
fn read(&mut self) -> Result<Self::Item> {
|
||||
FunctionSectionReader::read(self)
|
||||
Self::read(self)
|
||||
}
|
||||
|
||||
fn eof(&self) -> bool {
|
||||
self.reader.eof()
|
||||
}
|
||||
|
||||
fn original_position(&self) -> usize {
|
||||
FunctionSectionReader::original_position(self)
|
||||
Self::original_position(self)
|
||||
}
|
||||
fn range(&self) -> Range {
|
||||
|
||||
fn range(&self) -> Range<usize> {
|
||||
self.reader.range()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> SectionWithLimitedItems for FunctionSectionReader<'a> {
|
||||
fn get_count(&self) -> u32 {
|
||||
FunctionSectionReader::get_count(self)
|
||||
Self::get_count(self)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> IntoIterator for FunctionSectionReader<'a> {
|
||||
type Item = Result<u32>;
|
||||
type IntoIter = SectionIteratorLimited<FunctionSectionReader<'a>>;
|
||||
type IntoIter = SectionIteratorLimited<Self>;
|
||||
|
||||
fn into_iter(self) -> Self::IntoIter {
|
||||
SectionIteratorLimited::new(self)
|
@ -13,17 +13,22 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
use super::{
|
||||
BinaryReader, GlobalType, InitExpr, Range, Result, SectionIteratorLimited, SectionReader,
|
||||
use crate::{
|
||||
BinaryReader, GlobalType, InitExpr, Result, SectionIteratorLimited, SectionReader,
|
||||
SectionWithLimitedItems,
|
||||
};
|
||||
use std::ops::Range;
|
||||
|
||||
/// Represents a core WebAssembly global.
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
pub struct Global<'a> {
|
||||
/// The global's type.
|
||||
pub ty: GlobalType,
|
||||
/// The global's initialization expression.
|
||||
pub init_expr: InitExpr<'a>,
|
||||
}
|
||||
|
||||
/// A reader for the global section of a WebAssembly module.
|
||||
#[derive(Clone)]
|
||||
pub struct GlobalSectionReader<'a> {
|
||||
reader: BinaryReader<'a>,
|
||||
@ -31,16 +36,19 @@ pub struct GlobalSectionReader<'a> {
|
||||
}
|
||||
|
||||
impl<'a> GlobalSectionReader<'a> {
|
||||
/// Constructs a new `GlobalSectionReader` for the given data and offset.
|
||||
pub fn new(data: &'a [u8], offset: usize) -> Result<GlobalSectionReader<'a>> {
|
||||
let mut reader = BinaryReader::new_with_offset(data, offset);
|
||||
let count = reader.read_var_u32()?;
|
||||
Ok(GlobalSectionReader { reader, count })
|
||||
}
|
||||
|
||||
/// Gets the original position of the section reader.
|
||||
pub fn original_position(&self) -> usize {
|
||||
self.reader.original_position()
|
||||
}
|
||||
|
||||
/// Gets the count of items in the section.
|
||||
pub fn get_count(&self) -> u32 {
|
||||
self.count
|
||||
}
|
||||
@ -65,10 +73,7 @@ impl<'a> GlobalSectionReader<'a> {
|
||||
'a: 'b,
|
||||
{
|
||||
let ty = self.reader.read_global_type()?;
|
||||
let expr_offset = self.reader.position;
|
||||
self.reader.skip_init_expr()?;
|
||||
let data = &self.reader.buffer[expr_offset..self.reader.position];
|
||||
let init_expr = InitExpr::new(data, self.reader.original_offset + expr_offset);
|
||||
let init_expr = self.reader.read_init_expr()?;
|
||||
Ok(Global { ty, init_expr })
|
||||
}
|
||||
}
|
||||
@ -84,7 +89,7 @@ impl<'a> SectionReader for GlobalSectionReader<'a> {
|
||||
fn original_position(&self) -> usize {
|
||||
GlobalSectionReader::original_position(self)
|
||||
}
|
||||
fn range(&self) -> Range {
|
||||
fn range(&self) -> Range<usize> {
|
||||
self.reader.range()
|
||||
}
|
||||
}
|
@ -14,17 +14,44 @@
|
||||
*/
|
||||
|
||||
use crate::{
|
||||
BinaryReader, ImportSectionEntryType, Range, Result, SectionIteratorLimited, SectionReader,
|
||||
SectionWithLimitedItems,
|
||||
BinaryReader, GlobalType, MemoryType, Result, SectionIteratorLimited, SectionReader,
|
||||
SectionWithLimitedItems, TableType, TagType,
|
||||
};
|
||||
use std::ops::Range;
|
||||
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
pub struct Import<'a> {
|
||||
pub module: &'a str,
|
||||
pub field: Option<&'a str>,
|
||||
pub ty: ImportSectionEntryType,
|
||||
/// Represents a reference to a type definition in a WebAssembly module.
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub enum TypeRef {
|
||||
/// The type is a function.
|
||||
///
|
||||
/// The value is an index into the type section.
|
||||
Func(u32),
|
||||
/// The type is a table.
|
||||
Table(TableType),
|
||||
/// The type is a memory.
|
||||
Memory(MemoryType),
|
||||
/// The type is a global.
|
||||
Global(GlobalType),
|
||||
/// The type is a tag.
|
||||
///
|
||||
/// This variant is only used for the exception handling proposal.
|
||||
///
|
||||
/// The value is an index in the types index space.
|
||||
Tag(TagType),
|
||||
}
|
||||
|
||||
/// Represents an import in a WebAssembly module.
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
pub struct Import<'a> {
|
||||
/// The module being imported from.
|
||||
pub module: &'a str,
|
||||
/// The name of the imported item.
|
||||
pub name: &'a str,
|
||||
/// The type of the imported item.
|
||||
pub ty: TypeRef,
|
||||
}
|
||||
|
||||
/// A reader for the import section of a WebAssembly module.
|
||||
#[derive(Clone)]
|
||||
pub struct ImportSectionReader<'a> {
|
||||
reader: BinaryReader<'a>,
|
||||
@ -32,16 +59,19 @@ pub struct ImportSectionReader<'a> {
|
||||
}
|
||||
|
||||
impl<'a> ImportSectionReader<'a> {
|
||||
pub fn new(data: &'a [u8], offset: usize) -> Result<ImportSectionReader<'a>> {
|
||||
/// Constructs a new `ImportSectionReader` for the given data and offset.
|
||||
pub fn new(data: &'a [u8], offset: usize) -> Result<Self> {
|
||||
let mut reader = BinaryReader::new_with_offset(data, offset);
|
||||
let count = reader.read_var_u32()?;
|
||||
Ok(ImportSectionReader { reader, count })
|
||||
Ok(Self { reader, count })
|
||||
}
|
||||
|
||||
/// Gets the original position of the section reader.
|
||||
pub fn original_position(&self) -> usize {
|
||||
self.reader.original_position()
|
||||
}
|
||||
|
||||
/// Gets the count of items in the section.
|
||||
pub fn get_count(&self) -> u32 {
|
||||
self.count
|
||||
}
|
||||
@ -51,46 +81,47 @@ impl<'a> ImportSectionReader<'a> {
|
||||
/// # Examples
|
||||
/// ```
|
||||
/// use wasmparser::ImportSectionReader;
|
||||
/// # let data: &[u8] = &[0x01, 0x01, 0x41, 0x01, 0x66, 0x00, 0x00];
|
||||
/// let mut import_reader = ImportSectionReader::new(data, 0).unwrap();
|
||||
/// for _ in 0..import_reader.get_count() {
|
||||
/// let import = import_reader.read().expect("import");
|
||||
/// let data: &[u8] = &[0x01, 0x01, 0x41, 0x01, 0x66, 0x00, 0x00];
|
||||
/// let mut reader = ImportSectionReader::new(data, 0).unwrap();
|
||||
/// for _ in 0..reader.get_count() {
|
||||
/// let import = reader.read().expect("import");
|
||||
/// println!("Import: {:?}", import);
|
||||
/// }
|
||||
/// ```
|
||||
pub fn read<'b>(&mut self) -> Result<Import<'b>>
|
||||
where
|
||||
'a: 'b,
|
||||
{
|
||||
pub fn read(&mut self) -> Result<Import<'a>> {
|
||||
self.reader.read_import()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> SectionReader for ImportSectionReader<'a> {
|
||||
type Item = Import<'a>;
|
||||
|
||||
fn read(&mut self) -> Result<Self::Item> {
|
||||
ImportSectionReader::read(self)
|
||||
Self::read(self)
|
||||
}
|
||||
|
||||
fn eof(&self) -> bool {
|
||||
self.reader.eof()
|
||||
}
|
||||
|
||||
fn original_position(&self) -> usize {
|
||||
ImportSectionReader::original_position(self)
|
||||
Self::original_position(self)
|
||||
}
|
||||
fn range(&self) -> Range {
|
||||
|
||||
fn range(&self) -> Range<usize> {
|
||||
self.reader.range()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> SectionWithLimitedItems for ImportSectionReader<'a> {
|
||||
fn get_count(&self) -> u32 {
|
||||
ImportSectionReader::get_count(self)
|
||||
Self::get_count(self)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> IntoIterator for ImportSectionReader<'a> {
|
||||
type Item = Result<Import<'a>>;
|
||||
type IntoIter = SectionIteratorLimited<ImportSectionReader<'a>>;
|
||||
type IntoIter = SectionIteratorLimited<Self>;
|
||||
|
||||
fn into_iter(self) -> Self::IntoIter {
|
||||
SectionIteratorLimited::new(self)
|
@ -13,8 +13,9 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
use super::{BinaryReader, OperatorsReader};
|
||||
use crate::{BinaryReader, OperatorsReader};
|
||||
|
||||
/// Represents an initialization expression.
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
pub struct InitExpr<'a> {
|
||||
offset: usize,
|
||||
@ -22,10 +23,12 @@ pub struct InitExpr<'a> {
|
||||
}
|
||||
|
||||
impl<'a> InitExpr<'a> {
|
||||
/// Constructs a new `InitExpr` from the given data and offset.
|
||||
pub fn new(data: &[u8], offset: usize) -> InitExpr {
|
||||
InitExpr { offset, data }
|
||||
}
|
||||
|
||||
/// Gets a binary reader for the initialization expression.
|
||||
pub fn get_binary_reader<'b>(&self) -> BinaryReader<'b>
|
||||
where
|
||||
'a: 'b,
|
||||
@ -33,6 +36,7 @@ impl<'a> InitExpr<'a> {
|
||||
BinaryReader::new_with_offset(self.data, self.offset)
|
||||
}
|
||||
|
||||
/// Gets an operators reader for the initialization expression.
|
||||
pub fn get_operators_reader<'b>(&self) -> OperatorsReader<'b>
|
||||
where
|
||||
'a: 'b,
|
@ -13,36 +13,46 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
use super::{
|
||||
BinaryReader, LinkingType, Range, Result, SectionIteratorLimited, SectionReader,
|
||||
SectionWithLimitedItems,
|
||||
};
|
||||
use crate::{BinaryReader, Result, SectionIteratorLimited, SectionReader, SectionWithLimitedItems};
|
||||
use std::ops::Range;
|
||||
|
||||
/// Represents a linking type.
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
pub enum LinkingType {
|
||||
/// The linking uses a stack pointer.
|
||||
StackPointer(u32),
|
||||
}
|
||||
|
||||
/// A reader for the linking custom section of a WebAssembly module.
|
||||
pub struct LinkingSectionReader<'a> {
|
||||
reader: BinaryReader<'a>,
|
||||
count: u32,
|
||||
}
|
||||
|
||||
impl<'a> LinkingSectionReader<'a> {
|
||||
/// Constructs a new `LinkingSectionReader` for the given data and offset.
|
||||
pub fn new(data: &'a [u8], offset: usize) -> Result<LinkingSectionReader<'a>> {
|
||||
let mut reader = BinaryReader::new_with_offset(data, offset);
|
||||
let count = reader.read_var_u32()?;
|
||||
Ok(LinkingSectionReader { reader, count })
|
||||
}
|
||||
|
||||
/// Gets the count of items in the section.
|
||||
pub fn get_count(&self) -> u32 {
|
||||
self.count
|
||||
}
|
||||
|
||||
/// Gets the original position of the reader.
|
||||
pub fn original_position(&self) -> usize {
|
||||
self.reader.original_position()
|
||||
}
|
||||
|
||||
/// Reads an item from the section.
|
||||
pub fn read<'b>(&mut self) -> Result<LinkingType>
|
||||
where
|
||||
'a: 'b,
|
||||
{
|
||||
Ok(self.reader.read_linking_type()?)
|
||||
self.reader.read_linking_type()
|
||||
}
|
||||
}
|
||||
|
||||
@ -57,7 +67,7 @@ impl<'a> SectionReader for LinkingSectionReader<'a> {
|
||||
fn original_position(&self) -> usize {
|
||||
LinkingSectionReader::original_position(self)
|
||||
}
|
||||
fn range(&self) -> Range {
|
||||
fn range(&self) -> Range<usize> {
|
||||
self.reader.range()
|
||||
}
|
||||
}
|
@ -13,11 +13,13 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
use super::{
|
||||
BinaryReader, MemoryType, Range, Result, SectionIteratorLimited, SectionReader,
|
||||
use crate::{
|
||||
BinaryReader, MemoryType, Result, SectionIteratorLimited, SectionReader,
|
||||
SectionWithLimitedItems,
|
||||
};
|
||||
use std::ops::Range;
|
||||
|
||||
/// A reader for the memory section of a WebAssembly module.
|
||||
#[derive(Clone)]
|
||||
pub struct MemorySectionReader<'a> {
|
||||
reader: BinaryReader<'a>,
|
||||
@ -25,16 +27,19 @@ pub struct MemorySectionReader<'a> {
|
||||
}
|
||||
|
||||
impl<'a> MemorySectionReader<'a> {
|
||||
/// Constructs a new `MemorySectionReader` for the given data and offset.
|
||||
pub fn new(data: &'a [u8], offset: usize) -> Result<MemorySectionReader<'a>> {
|
||||
let mut reader = BinaryReader::new_with_offset(data, offset);
|
||||
let count = reader.read_var_u32()?;
|
||||
Ok(MemorySectionReader { reader, count })
|
||||
}
|
||||
|
||||
/// Gets the original position of the section reader.
|
||||
pub fn original_position(&self) -> usize {
|
||||
self.reader.original_position()
|
||||
}
|
||||
|
||||
/// Gets the count of items in the section.
|
||||
pub fn get_count(&self) -> u32 {
|
||||
self.count
|
||||
}
|
||||
@ -67,7 +72,7 @@ impl<'a> SectionReader for MemorySectionReader<'a> {
|
||||
fn original_position(&self) -> usize {
|
||||
MemorySectionReader::original_position(self)
|
||||
}
|
||||
fn range(&self) -> Range {
|
||||
fn range(&self) -> Range<usize> {
|
||||
self.reader.range()
|
||||
}
|
||||
}
|
@ -13,18 +13,56 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
use super::{
|
||||
BinaryReader, BinaryReaderError, NameType, Naming, Range, Result, SectionIterator,
|
||||
SectionReader,
|
||||
};
|
||||
use crate::{BinaryReader, BinaryReaderError, Result, SectionIterator, SectionReader};
|
||||
use std::ops::Range;
|
||||
|
||||
/// Represents a name for an index from the names section.
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
pub struct ModuleName<'a> {
|
||||
pub struct Naming<'a> {
|
||||
/// The index being named.
|
||||
pub index: u32,
|
||||
/// The name for the index.
|
||||
pub name: &'a str,
|
||||
}
|
||||
|
||||
/// Represents the type of name.
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
pub enum NameType {
|
||||
/// The name is for a module.
|
||||
Module,
|
||||
/// The name is for a function.
|
||||
Function,
|
||||
/// The name is for a local.
|
||||
Local,
|
||||
/// The name is for a label.
|
||||
Label,
|
||||
/// The name is for a type.
|
||||
Type,
|
||||
/// The name is for a table.
|
||||
Table,
|
||||
/// The name is for a memory.
|
||||
Memory,
|
||||
/// The name is for a global.
|
||||
Global,
|
||||
/// The name is for an element segment.
|
||||
Element,
|
||||
/// The name is for a data segment.
|
||||
Data,
|
||||
/// The name is unknown.
|
||||
///
|
||||
/// The value is the unknown section identifier.
|
||||
Unknown(u8),
|
||||
}
|
||||
|
||||
/// Represents a single name in the names custom section.
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
pub struct SingleName<'a> {
|
||||
data: &'a [u8],
|
||||
offset: usize,
|
||||
}
|
||||
|
||||
impl<'a> ModuleName<'a> {
|
||||
impl<'a> SingleName<'a> {
|
||||
/// Gets the name as a string.
|
||||
pub fn get_name<'b>(&self) -> Result<&'b str>
|
||||
where
|
||||
'a: 'b,
|
||||
@ -33,11 +71,13 @@ impl<'a> ModuleName<'a> {
|
||||
reader.read_string()
|
||||
}
|
||||
|
||||
/// Gets the original position of the name.
|
||||
pub fn original_position(&self) -> usize {
|
||||
self.offset
|
||||
}
|
||||
}
|
||||
|
||||
/// A reader for direct names in the names custom section.
|
||||
pub struct NamingReader<'a> {
|
||||
reader: BinaryReader<'a>,
|
||||
count: u32,
|
||||
@ -53,20 +93,23 @@ impl<'a> NamingReader<'a> {
|
||||
fn skip(reader: &mut BinaryReader) -> Result<()> {
|
||||
let count = reader.read_var_u32()?;
|
||||
for _ in 0..count {
|
||||
reader.skip_var_32()?;
|
||||
reader.read_var_u32()?;
|
||||
reader.skip_string()?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Gets the original position of the reader.
|
||||
pub fn original_position(&self) -> usize {
|
||||
self.reader.original_position()
|
||||
}
|
||||
|
||||
/// Gets the count of items in the section.
|
||||
pub fn get_count(&self) -> u32 {
|
||||
self.count
|
||||
}
|
||||
|
||||
/// Reads a name from the names custom section.
|
||||
pub fn read<'b>(&mut self) -> Result<Naming<'b>>
|
||||
where
|
||||
'a: 'b,
|
||||
@ -77,13 +120,15 @@ impl<'a> NamingReader<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
/// Represents a name map from the names custom section.
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
pub struct FunctionName<'a> {
|
||||
pub struct NameMap<'a> {
|
||||
data: &'a [u8],
|
||||
offset: usize,
|
||||
}
|
||||
|
||||
impl<'a> FunctionName<'a> {
|
||||
impl<'a> NameMap<'a> {
|
||||
/// Gets a naming reader for the map.
|
||||
pub fn get_map<'b>(&self) -> Result<NamingReader<'b>>
|
||||
where
|
||||
'a: 'b,
|
||||
@ -91,19 +136,23 @@ impl<'a> FunctionName<'a> {
|
||||
NamingReader::new(self.data, self.offset)
|
||||
}
|
||||
|
||||
/// Gets the original position of the map.
|
||||
pub fn original_position(&self) -> usize {
|
||||
self.offset
|
||||
}
|
||||
}
|
||||
|
||||
/// Represents an indirect name in the names custom section.
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
pub struct FunctionLocalName<'a> {
|
||||
pub func_index: u32,
|
||||
pub struct IndirectNaming<'a> {
|
||||
/// The indirect index of the name.
|
||||
pub indirect_index: u32,
|
||||
data: &'a [u8],
|
||||
offset: usize,
|
||||
}
|
||||
|
||||
impl<'a> FunctionLocalName<'a> {
|
||||
impl<'a> IndirectNaming<'a> {
|
||||
/// Gets the naming reader for the indirect name.
|
||||
pub fn get_map<'b>(&self) -> Result<NamingReader<'b>>
|
||||
where
|
||||
'a: 'b,
|
||||
@ -111,88 +160,116 @@ impl<'a> FunctionLocalName<'a> {
|
||||
NamingReader::new(self.data, self.offset)
|
||||
}
|
||||
|
||||
/// Gets the original position of the indirect name.
|
||||
pub fn original_position(&self) -> usize {
|
||||
self.offset
|
||||
}
|
||||
}
|
||||
|
||||
pub struct FunctionLocalReader<'a> {
|
||||
/// Represents a reader for indirect names from the names custom section.
|
||||
pub struct IndirectNamingReader<'a> {
|
||||
reader: BinaryReader<'a>,
|
||||
count: u32,
|
||||
}
|
||||
|
||||
impl<'a> FunctionLocalReader<'a> {
|
||||
fn new(data: &'a [u8], offset: usize) -> Result<FunctionLocalReader<'a>> {
|
||||
impl<'a> IndirectNamingReader<'a> {
|
||||
fn new(data: &'a [u8], offset: usize) -> Result<IndirectNamingReader<'a>> {
|
||||
let mut reader = BinaryReader::new_with_offset(data, offset);
|
||||
let count = reader.read_var_u32()?;
|
||||
Ok(FunctionLocalReader { reader, count })
|
||||
Ok(IndirectNamingReader { reader, count })
|
||||
}
|
||||
|
||||
pub fn get_count(&self) -> u32 {
|
||||
/// Gets the count of indirect names.
|
||||
pub fn get_indirect_count(&self) -> u32 {
|
||||
self.count
|
||||
}
|
||||
|
||||
/// Gets the original position of the reader.
|
||||
pub fn original_position(&self) -> usize {
|
||||
self.reader.original_position()
|
||||
}
|
||||
|
||||
pub fn read<'b>(&mut self) -> Result<FunctionLocalName<'b>>
|
||||
/// Reads an indirect name from the reader.
|
||||
pub fn read<'b>(&mut self) -> Result<IndirectNaming<'b>>
|
||||
where
|
||||
'a: 'b,
|
||||
{
|
||||
let func_index = self.reader.read_var_u32()?;
|
||||
let index = self.reader.read_var_u32()?;
|
||||
let start = self.reader.position;
|
||||
NamingReader::skip(&mut self.reader)?;
|
||||
let end = self.reader.position;
|
||||
Ok(FunctionLocalName {
|
||||
func_index,
|
||||
Ok(IndirectNaming {
|
||||
indirect_index: index,
|
||||
data: &self.reader.buffer[start..end],
|
||||
offset: self.reader.original_offset + start,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/// Represents an indirect name map.
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
pub struct LocalName<'a> {
|
||||
pub struct IndirectNameMap<'a> {
|
||||
data: &'a [u8],
|
||||
offset: usize,
|
||||
}
|
||||
|
||||
impl<'a> LocalName<'a> {
|
||||
pub fn get_function_local_reader<'b>(&self) -> Result<FunctionLocalReader<'b>>
|
||||
impl<'a> IndirectNameMap<'a> {
|
||||
/// Gets an indirect naming reader for the map.
|
||||
pub fn get_indirect_map<'b>(&self) -> Result<IndirectNamingReader<'b>>
|
||||
where
|
||||
'a: 'b,
|
||||
{
|
||||
FunctionLocalReader::new(self.data, self.offset)
|
||||
IndirectNamingReader::new(self.data, self.offset)
|
||||
}
|
||||
|
||||
/// Gets an original position of the map.
|
||||
pub fn original_position(&self) -> usize {
|
||||
self.offset
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
/// Represents a name read from the names custom section.
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum Name<'a> {
|
||||
Module(ModuleName<'a>),
|
||||
Function(FunctionName<'a>),
|
||||
Local(LocalName<'a>),
|
||||
/// The name is for the module.
|
||||
Module(SingleName<'a>),
|
||||
/// The name is for the functions.
|
||||
Function(NameMap<'a>),
|
||||
/// The name is for the function locals.
|
||||
Local(IndirectNameMap<'a>),
|
||||
/// The name is for the function labels.
|
||||
Label(IndirectNameMap<'a>),
|
||||
/// The name is for the types.
|
||||
Type(NameMap<'a>),
|
||||
/// The name is for the tables.
|
||||
Table(NameMap<'a>),
|
||||
/// The name is for the memories.
|
||||
Memory(NameMap<'a>),
|
||||
/// The name is for the globals.
|
||||
Global(NameMap<'a>),
|
||||
/// The name is for the element segments.
|
||||
Element(NameMap<'a>),
|
||||
/// The name is for the data segments.
|
||||
Data(NameMap<'a>),
|
||||
/// An unknown [name subsection](https://webassembly.github.io/spec/core/appendix/custom.html#subsections).
|
||||
Unknown {
|
||||
/// The identifier for this subsection.
|
||||
ty: u32,
|
||||
ty: u8,
|
||||
/// The contents of this subsection.
|
||||
data: &'a [u8],
|
||||
/// The range of bytes, relative to the start of the original data
|
||||
/// stream, that the contents of this subsection reside in.
|
||||
range: Range,
|
||||
range: Range<usize>,
|
||||
},
|
||||
}
|
||||
|
||||
/// A reader for the name custom section of a WebAssembly module.
|
||||
pub struct NameSectionReader<'a> {
|
||||
reader: BinaryReader<'a>,
|
||||
}
|
||||
|
||||
impl<'a> NameSectionReader<'a> {
|
||||
/// Constructs a new `NameSectionReader` from the given data and offset.
|
||||
pub fn new(data: &'a [u8], offset: usize) -> Result<NameSectionReader<'a>> {
|
||||
Ok(NameSectionReader {
|
||||
reader: BinaryReader::new_with_offset(data, offset),
|
||||
@ -202,21 +279,24 @@ impl<'a> NameSectionReader<'a> {
|
||||
fn verify_section_end(&self, end: usize) -> Result<()> {
|
||||
if self.reader.buffer.len() < end {
|
||||
return Err(BinaryReaderError::new(
|
||||
"Name entry extends past end of the code section",
|
||||
"name entry extends past end of the code section",
|
||||
self.reader.original_offset + self.reader.buffer.len(),
|
||||
));
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Determines if the reader is at the end of the section.
|
||||
pub fn eof(&self) -> bool {
|
||||
self.reader.eof()
|
||||
}
|
||||
|
||||
/// Gets the original position of the section reader.
|
||||
pub fn original_position(&self) -> usize {
|
||||
self.reader.original_position()
|
||||
}
|
||||
|
||||
/// Reads a name from the section.
|
||||
pub fn read<'b>(&mut self) -> Result<Name<'b>>
|
||||
where
|
||||
'a: 'b,
|
||||
@ -230,13 +310,20 @@ impl<'a> NameSectionReader<'a> {
|
||||
let data = &self.reader.buffer[payload_start..payload_end];
|
||||
self.reader.skip_to(payload_end);
|
||||
Ok(match ty {
|
||||
NameType::Module => Name::Module(ModuleName { data, offset }),
|
||||
NameType::Function => Name::Function(FunctionName { data, offset }),
|
||||
NameType::Local => Name::Local(LocalName { data, offset }),
|
||||
NameType::Module => Name::Module(SingleName { data, offset }),
|
||||
NameType::Function => Name::Function(NameMap { data, offset }),
|
||||
NameType::Local => Name::Local(IndirectNameMap { data, offset }),
|
||||
NameType::Label => Name::Label(IndirectNameMap { data, offset }),
|
||||
NameType::Type => Name::Type(NameMap { data, offset }),
|
||||
NameType::Table => Name::Table(NameMap { data, offset }),
|
||||
NameType::Memory => Name::Memory(NameMap { data, offset }),
|
||||
NameType::Global => Name::Global(NameMap { data, offset }),
|
||||
NameType::Element => Name::Element(NameMap { data, offset }),
|
||||
NameType::Data => Name::Data(NameMap { data, offset }),
|
||||
NameType::Unknown(ty) => Name::Unknown {
|
||||
ty,
|
||||
data,
|
||||
range: Range::new(offset, offset + payload_len),
|
||||
range: offset..offset + payload_len,
|
||||
},
|
||||
})
|
||||
}
|
||||
@ -253,7 +340,7 @@ impl<'a> SectionReader for NameSectionReader<'a> {
|
||||
fn original_position(&self) -> usize {
|
||||
NameSectionReader::original_position(self)
|
||||
}
|
||||
fn range(&self) -> Range {
|
||||
fn range(&self) -> Range<usize> {
|
||||
self.reader.range()
|
||||
}
|
||||
}
|
@ -13,348 +13,116 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
use std::error::Error;
|
||||
use std::fmt;
|
||||
use std::result;
|
||||
use crate::{BinaryReader, BinaryReaderError, Result, ValType};
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct BinaryReaderError {
|
||||
// Wrap the actual error data in a `Box` so that the error is just one
|
||||
// word. This means that we can continue returning small `Result`s in
|
||||
// registers.
|
||||
pub(crate) inner: Box<BinaryReaderErrorInner>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub(crate) struct BinaryReaderErrorInner {
|
||||
pub(crate) message: String,
|
||||
pub(crate) offset: usize,
|
||||
pub(crate) needed_hint: Option<usize>,
|
||||
}
|
||||
|
||||
pub type Result<T, E = BinaryReaderError> = result::Result<T, E>;
|
||||
|
||||
impl Error for BinaryReaderError {}
|
||||
|
||||
impl fmt::Display for BinaryReaderError {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(
|
||||
f,
|
||||
"{} (at offset {})",
|
||||
self.inner.message, self.inner.offset
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl BinaryReaderError {
|
||||
pub(crate) fn new(message: impl Into<String>, offset: usize) -> Self {
|
||||
let message = message.into();
|
||||
BinaryReaderError {
|
||||
inner: Box::new(BinaryReaderErrorInner {
|
||||
message,
|
||||
offset,
|
||||
needed_hint: None,
|
||||
}),
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn eof(offset: usize, needed_hint: usize) -> Self {
|
||||
BinaryReaderError {
|
||||
inner: Box::new(BinaryReaderErrorInner {
|
||||
message: "Unexpected EOF".to_string(),
|
||||
offset,
|
||||
needed_hint: Some(needed_hint),
|
||||
}),
|
||||
}
|
||||
}
|
||||
|
||||
/// Get this error's message.
|
||||
pub fn message(&self) -> &str {
|
||||
&self.inner.message
|
||||
}
|
||||
|
||||
/// Get the offset within the Wasm binary where the error occured.
|
||||
pub fn offset(&self) -> usize {
|
||||
self.inner.offset
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
|
||||
pub enum CustomSectionKind {
|
||||
Unknown,
|
||||
Name,
|
||||
Producers,
|
||||
SourceMappingURL,
|
||||
Reloc,
|
||||
Linking,
|
||||
}
|
||||
|
||||
/// Section code as defined [here].
|
||||
///
|
||||
/// [here]: https://webassembly.github.io/spec/core/binary/modules.html#sections
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
|
||||
pub enum SectionCode<'a> {
|
||||
Custom {
|
||||
name: &'a str,
|
||||
kind: CustomSectionKind,
|
||||
},
|
||||
Type, // Function signature declarations
|
||||
Alias, // Aliased indices from nested/parent modules
|
||||
Import, // Import declarations
|
||||
Module, // Module declarations
|
||||
Instance, // Instance definitions
|
||||
Function, // Function declarations
|
||||
Table, // Indirect function table and other tables
|
||||
Memory, // Memory attributes
|
||||
Global, // Global declarations
|
||||
Export, // Exports
|
||||
Start, // Start function declaration
|
||||
Element, // Elements section
|
||||
ModuleCode, // Module definitions
|
||||
Code, // Function bodies (code)
|
||||
Data, // Data segments
|
||||
DataCount, // Count of passive data segments
|
||||
Event, // Event declarations
|
||||
}
|
||||
|
||||
/// Types as defined [here].
|
||||
///
|
||||
/// [here]: https://webassembly.github.io/spec/core/syntax/types.html#types
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
|
||||
pub enum Type {
|
||||
I32,
|
||||
I64,
|
||||
F32,
|
||||
F64,
|
||||
V128,
|
||||
FuncRef,
|
||||
ExternRef,
|
||||
ExnRef,
|
||||
Func,
|
||||
EmptyBlockType,
|
||||
}
|
||||
|
||||
/// Either a value type or a function type.
|
||||
/// Represents a block type.
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
|
||||
pub enum TypeOrFuncType {
|
||||
/// A value type.
|
||||
pub enum BlockType {
|
||||
/// The block produces consumes nor produces any values.
|
||||
Empty,
|
||||
/// The block produces a singular value of the given type ([] -> \[t]).
|
||||
Type(ValType),
|
||||
/// The block is described by a function type.
|
||||
///
|
||||
/// When used as the type for a block, this type is the optional result
|
||||
/// type: `[] -> [t?]`.
|
||||
Type(Type),
|
||||
|
||||
/// A function type (referenced as an index into the types section).
|
||||
/// The index is to a function type in the types section.
|
||||
FuncType(u32),
|
||||
}
|
||||
|
||||
/// External types as defined [here].
|
||||
///
|
||||
/// [here]: https://webassembly.github.io/spec/core/syntax/types.html#external-types
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
pub enum ExternalKind {
|
||||
Function,
|
||||
Table,
|
||||
Memory,
|
||||
Event,
|
||||
Global,
|
||||
Type,
|
||||
Module,
|
||||
Instance,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum TypeDef<'a> {
|
||||
Func(FuncType),
|
||||
Instance(InstanceType<'a>),
|
||||
Module(ModuleType<'a>),
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Eq, PartialEq, Hash)]
|
||||
pub struct FuncType {
|
||||
pub params: Box<[Type]>,
|
||||
pub returns: Box<[Type]>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct InstanceType<'a> {
|
||||
pub exports: Box<[ExportType<'a>]>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct ModuleType<'a> {
|
||||
pub imports: Box<[crate::Import<'a>]>,
|
||||
pub exports: Box<[ExportType<'a>]>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct ExportType<'a> {
|
||||
pub name: &'a str,
|
||||
pub ty: ImportSectionEntryType,
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
|
||||
pub struct ResizableLimits {
|
||||
pub initial: u32,
|
||||
pub maximum: Option<u32>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
|
||||
pub struct ResizableLimits64 {
|
||||
pub initial: u64,
|
||||
pub maximum: Option<u64>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
|
||||
pub struct TableType {
|
||||
pub element_type: Type,
|
||||
pub limits: ResizableLimits,
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
|
||||
pub enum MemoryType {
|
||||
M32 {
|
||||
limits: ResizableLimits,
|
||||
shared: bool,
|
||||
},
|
||||
M64 {
|
||||
limits: ResizableLimits64,
|
||||
shared: bool,
|
||||
},
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
|
||||
pub struct EventType {
|
||||
pub type_index: u32,
|
||||
}
|
||||
|
||||
impl MemoryType {
|
||||
pub fn index_type(&self) -> Type {
|
||||
match self {
|
||||
MemoryType::M32 { .. } => Type::I32,
|
||||
MemoryType::M64 { .. } => Type::I64,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
|
||||
pub struct GlobalType {
|
||||
pub content_type: Type,
|
||||
pub mutable: bool,
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
pub enum ImportSectionEntryType {
|
||||
Function(u32),
|
||||
Table(TableType),
|
||||
Memory(MemoryType),
|
||||
Event(EventType),
|
||||
Global(GlobalType),
|
||||
Module(u32),
|
||||
Instance(u32),
|
||||
}
|
||||
|
||||
/// Represents a memory immediate in a WebAssembly memory instruction.
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
pub struct MemoryImmediate {
|
||||
/// Alignment, stored as `n` where the actual alignment is `2^n`
|
||||
pub align: u8,
|
||||
pub offset: u32,
|
||||
/// A fixed byte-offset that this memory immediate specifies.
|
||||
///
|
||||
/// Note that the memory64 proposal can specify a full 64-bit byte offset
|
||||
/// while otherwise only 32-bit offsets are allowed. Once validated
|
||||
/// memory immediates for 32-bit memories are guaranteed to be at most
|
||||
/// `u32::MAX` whereas 64-bit memories can use the full 64-bits.
|
||||
pub offset: u64,
|
||||
/// The index of the memory this immediate points to.
|
||||
///
|
||||
/// Note that this points within the module's own memory index space, and
|
||||
/// is always zero unless the multi-memory proposal of WebAssembly is
|
||||
/// enabled.
|
||||
pub memory: u32,
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
pub struct Naming<'a> {
|
||||
pub index: u32,
|
||||
pub name: &'a str,
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
pub enum NameType {
|
||||
Module,
|
||||
Function,
|
||||
Local,
|
||||
Unknown(u32),
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
pub enum LinkingType {
|
||||
StackPointer(u32),
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
pub enum RelocType {
|
||||
FunctionIndexLEB,
|
||||
TableIndexSLEB,
|
||||
TableIndexI32,
|
||||
GlobalAddrLEB,
|
||||
GlobalAddrSLEB,
|
||||
GlobalAddrI32,
|
||||
TypeIndexLEB,
|
||||
GlobalIndexLEB,
|
||||
}
|
||||
|
||||
/// A br_table entries representation.
|
||||
#[derive(Clone)]
|
||||
pub struct BrTable<'a> {
|
||||
pub(crate) reader: crate::BinaryReader<'a>,
|
||||
pub(crate) cnt: usize,
|
||||
pub(crate) cnt: u32,
|
||||
pub(crate) default: u32,
|
||||
}
|
||||
|
||||
/// An IEEE binary32 immediate floating point value, represented as a u32
|
||||
/// containing the bitpattern.
|
||||
/// containing the bit pattern.
|
||||
///
|
||||
/// All bit patterns are allowed.
|
||||
#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)]
|
||||
pub struct Ieee32(pub(crate) u32);
|
||||
|
||||
impl Ieee32 {
|
||||
/// Gets the underlying bits of the 32-bit float.
|
||||
pub fn bits(self) -> u32 {
|
||||
self.0
|
||||
}
|
||||
}
|
||||
|
||||
/// An IEEE binary64 immediate floating point value, represented as a u64
|
||||
/// containing the bitpattern.
|
||||
/// containing the bit pattern.
|
||||
///
|
||||
/// All bit patterns are allowed.
|
||||
#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)]
|
||||
pub struct Ieee64(pub(crate) u64);
|
||||
|
||||
impl Ieee64 {
|
||||
/// Gets the underlying bits of the 64-bit float.
|
||||
pub fn bits(self) -> u64 {
|
||||
self.0
|
||||
}
|
||||
}
|
||||
|
||||
/// Represents a 128-bit vector value.
|
||||
#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)]
|
||||
pub struct V128(pub(crate) [u8; 16]);
|
||||
|
||||
impl V128 {
|
||||
/// Gets the bytes of the vector value.
|
||||
pub fn bytes(&self) -> &[u8; 16] {
|
||||
&self.0
|
||||
}
|
||||
|
||||
/// Gets a signed 128-bit integer value from the vector's bytes.
|
||||
pub fn i128(&self) -> i128 {
|
||||
i128::from_le_bytes(self.0)
|
||||
}
|
||||
}
|
||||
|
||||
/// Represents a SIMD lane index.
|
||||
pub type SIMDLaneIndex = u8;
|
||||
|
||||
/// Instructions as defined [here].
|
||||
///
|
||||
/// [here]: https://webassembly.github.io/spec/core/binary/instructions.html
|
||||
#[derive(Debug, Clone)]
|
||||
#[allow(missing_docs)]
|
||||
pub enum Operator<'a> {
|
||||
Unreachable,
|
||||
Nop,
|
||||
Block {
|
||||
ty: TypeOrFuncType,
|
||||
ty: BlockType,
|
||||
},
|
||||
Loop {
|
||||
ty: TypeOrFuncType,
|
||||
ty: BlockType,
|
||||
},
|
||||
If {
|
||||
ty: TypeOrFuncType,
|
||||
ty: BlockType,
|
||||
},
|
||||
Else,
|
||||
Try {
|
||||
ty: TypeOrFuncType,
|
||||
ty: BlockType,
|
||||
},
|
||||
Catch {
|
||||
index: u32,
|
||||
@ -365,7 +133,6 @@ pub enum Operator<'a> {
|
||||
Rethrow {
|
||||
relative_depth: u32,
|
||||
},
|
||||
Unwind,
|
||||
End,
|
||||
Br {
|
||||
relative_depth: u32,
|
||||
@ -383,6 +150,7 @@ pub enum Operator<'a> {
|
||||
CallIndirect {
|
||||
index: u32,
|
||||
table_index: u32,
|
||||
table_byte: u8,
|
||||
},
|
||||
ReturnCall {
|
||||
function_index: u32,
|
||||
@ -398,7 +166,7 @@ pub enum Operator<'a> {
|
||||
Drop,
|
||||
Select,
|
||||
TypedSelect {
|
||||
ty: Type,
|
||||
ty: ValType,
|
||||
},
|
||||
LocalGet {
|
||||
local_index: u32,
|
||||
@ -505,7 +273,7 @@ pub enum Operator<'a> {
|
||||
value: Ieee64,
|
||||
},
|
||||
RefNull {
|
||||
ty: Type,
|
||||
ty: ValType,
|
||||
},
|
||||
RefIsNull,
|
||||
RefFunc {
|
||||
@ -1220,4 +988,191 @@ pub enum Operator<'a> {
|
||||
F64x2ConvertLowI32x4U,
|
||||
F32x4DemoteF64x2Zero,
|
||||
F64x2PromoteLowF32x4,
|
||||
I8x16RelaxedSwizzle,
|
||||
I32x4RelaxedTruncSatF32x4S,
|
||||
I32x4RelaxedTruncSatF32x4U,
|
||||
I32x4RelaxedTruncSatF64x2SZero,
|
||||
I32x4RelaxedTruncSatF64x2UZero,
|
||||
F32x4Fma,
|
||||
F32x4Fms,
|
||||
F64x2Fma,
|
||||
F64x2Fms,
|
||||
I8x16LaneSelect,
|
||||
I16x8LaneSelect,
|
||||
I32x4LaneSelect,
|
||||
I64x2LaneSelect,
|
||||
F32x4RelaxedMin,
|
||||
F32x4RelaxedMax,
|
||||
F64x2RelaxedMin,
|
||||
F64x2RelaxedMax,
|
||||
}
|
||||
|
||||
/// A reader for a core WebAssembly function's operators.
|
||||
#[derive(Clone)]
|
||||
pub struct OperatorsReader<'a> {
|
||||
pub(crate) reader: BinaryReader<'a>,
|
||||
}
|
||||
|
||||
impl<'a> OperatorsReader<'a> {
|
||||
pub(crate) fn new<'b>(data: &'a [u8], offset: usize) -> OperatorsReader<'b>
|
||||
where
|
||||
'a: 'b,
|
||||
{
|
||||
OperatorsReader {
|
||||
reader: BinaryReader::new_with_offset(data, offset),
|
||||
}
|
||||
}
|
||||
|
||||
/// Determines if the reader is at the end of the operators.
|
||||
pub fn eof(&self) -> bool {
|
||||
self.reader.eof()
|
||||
}
|
||||
|
||||
/// Gets the original position of the reader.
|
||||
pub fn original_position(&self) -> usize {
|
||||
self.reader.original_position()
|
||||
}
|
||||
|
||||
/// Whether or not to allow 64-bit memory arguments in the
|
||||
/// the operators being read.
|
||||
///
|
||||
/// This is intended to be `true` when support for the memory64
|
||||
/// WebAssembly proposal is also enabled.
|
||||
pub fn allow_memarg64(&mut self, allow: bool) {
|
||||
self.reader.allow_memarg64(allow);
|
||||
}
|
||||
|
||||
/// Ensures the reader is at the end.
|
||||
///
|
||||
/// This function returns an error if there is extra data after the operators.
|
||||
pub fn ensure_end(&self) -> Result<()> {
|
||||
if self.eof() {
|
||||
return Ok(());
|
||||
}
|
||||
Err(BinaryReaderError::new(
|
||||
"unexpected data at the end of operators",
|
||||
self.reader.original_position(),
|
||||
))
|
||||
}
|
||||
|
||||
/// Reads an operator from the reader.
|
||||
pub fn read<'b>(&mut self) -> Result<Operator<'b>>
|
||||
where
|
||||
'a: 'b,
|
||||
{
|
||||
self.reader.read_operator()
|
||||
}
|
||||
|
||||
/// Converts to an iterator of operators paired with offsets.
|
||||
pub fn into_iter_with_offsets<'b>(self) -> OperatorsIteratorWithOffsets<'b>
|
||||
where
|
||||
'a: 'b,
|
||||
{
|
||||
OperatorsIteratorWithOffsets {
|
||||
reader: self,
|
||||
err: false,
|
||||
}
|
||||
}
|
||||
|
||||
/// Reads an operator with its offset.
|
||||
pub fn read_with_offset<'b>(&mut self) -> Result<(Operator<'b>, usize)>
|
||||
where
|
||||
'a: 'b,
|
||||
{
|
||||
let pos = self.reader.original_position();
|
||||
Ok((self.read()?, pos))
|
||||
}
|
||||
|
||||
/// Gets a binary reader from this operators reader.
|
||||
pub fn get_binary_reader(&self) -> BinaryReader<'a> {
|
||||
self.reader.clone()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> IntoIterator for OperatorsReader<'a> {
|
||||
type Item = Result<Operator<'a>>;
|
||||
type IntoIter = OperatorsIterator<'a>;
|
||||
|
||||
/// Reads content of the code section.
|
||||
///
|
||||
/// # Examples
|
||||
/// ```
|
||||
/// use wasmparser::{Operator, CodeSectionReader, Result};
|
||||
/// # let data: &[u8] = &[
|
||||
/// # 0x01, 0x03, 0x00, 0x01, 0x0b];
|
||||
/// let mut code_reader = CodeSectionReader::new(data, 0).unwrap();
|
||||
/// for _ in 0..code_reader.get_count() {
|
||||
/// let body = code_reader.read().expect("function body");
|
||||
/// let mut op_reader = body.get_operators_reader().expect("op reader");
|
||||
/// let ops = op_reader.into_iter().collect::<Result<Vec<Operator>>>().expect("ops");
|
||||
/// assert!(
|
||||
/// if let [Operator::Nop, Operator::End] = ops.as_slice() { true } else { false },
|
||||
/// "found {:?}",
|
||||
/// ops
|
||||
/// );
|
||||
/// }
|
||||
/// ```
|
||||
fn into_iter(self) -> Self::IntoIter {
|
||||
OperatorsIterator {
|
||||
reader: self,
|
||||
err: false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// An iterator over a function's operators.
|
||||
pub struct OperatorsIterator<'a> {
|
||||
reader: OperatorsReader<'a>,
|
||||
err: bool,
|
||||
}
|
||||
|
||||
impl<'a> Iterator for OperatorsIterator<'a> {
|
||||
type Item = Result<Operator<'a>>;
|
||||
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
if self.err || self.reader.eof() {
|
||||
return None;
|
||||
}
|
||||
let result = self.reader.read();
|
||||
self.err = result.is_err();
|
||||
Some(result)
|
||||
}
|
||||
}
|
||||
|
||||
/// An iterator over a function's operators with offsets.
|
||||
pub struct OperatorsIteratorWithOffsets<'a> {
|
||||
reader: OperatorsReader<'a>,
|
||||
err: bool,
|
||||
}
|
||||
|
||||
impl<'a> Iterator for OperatorsIteratorWithOffsets<'a> {
|
||||
type Item = Result<(Operator<'a>, usize)>;
|
||||
|
||||
/// Reads content of the code section with offsets.
|
||||
///
|
||||
/// # Examples
|
||||
/// ```
|
||||
/// use wasmparser::{Operator, CodeSectionReader, Result};
|
||||
/// # let data: &[u8] = &[
|
||||
/// # 0x01, 0x03, 0x00, /* offset = 23 */ 0x01, 0x0b];
|
||||
/// let mut code_reader = CodeSectionReader::new(data, 20).unwrap();
|
||||
/// for _ in 0..code_reader.get_count() {
|
||||
/// let body = code_reader.read().expect("function body");
|
||||
/// let mut op_reader = body.get_operators_reader().expect("op reader");
|
||||
/// let ops = op_reader.into_iter_with_offsets().collect::<Result<Vec<(Operator, usize)>>>().expect("ops");
|
||||
/// assert!(
|
||||
/// if let [(Operator::Nop, 23), (Operator::End, 24)] = ops.as_slice() { true } else { false },
|
||||
/// "found {:?}",
|
||||
/// ops
|
||||
/// );
|
||||
/// }
|
||||
/// ```
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
if self.err || self.reader.eof() {
|
||||
return None;
|
||||
}
|
||||
let result = self.reader.read_with_offset();
|
||||
self.err = result.is_err();
|
||||
Some(result)
|
||||
}
|
||||
}
|
@ -13,26 +13,31 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
use super::{
|
||||
BinaryReader, Range, Result, SectionIteratorLimited, SectionReader, SectionWithLimitedItems,
|
||||
};
|
||||
use crate::{BinaryReader, Result, SectionIteratorLimited, SectionReader, SectionWithLimitedItems};
|
||||
use std::ops::Range;
|
||||
|
||||
/// Represents a field value in the producers custom section.
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
pub struct ProducersFieldValue<'a> {
|
||||
/// The field name.
|
||||
pub name: &'a str,
|
||||
/// The field version.
|
||||
pub version: &'a str,
|
||||
}
|
||||
|
||||
/// A reader for fields in the producers custom section.
|
||||
pub struct ProducersFieldValuesReader<'a> {
|
||||
reader: BinaryReader<'a>,
|
||||
count: u32,
|
||||
}
|
||||
|
||||
impl<'a> ProducersFieldValuesReader<'a> {
|
||||
/// Gets the count of items in the reader.
|
||||
pub fn get_count(&self) -> u32 {
|
||||
self.count
|
||||
}
|
||||
|
||||
/// Gets the original position of the reader.
|
||||
pub fn original_position(&self) -> usize {
|
||||
self.reader.original_position()
|
||||
}
|
||||
@ -45,6 +50,7 @@ impl<'a> ProducersFieldValuesReader<'a> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Reads a field from the reader.
|
||||
pub fn read<'b>(&mut self) -> Result<ProducersFieldValue<'b>>
|
||||
where
|
||||
'a: 'b,
|
||||
@ -68,6 +74,7 @@ impl<'a> IntoIterator for ProducersFieldValuesReader<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
/// An iterator over fields in the producers custom section.
|
||||
pub struct ProducersFieldValuesIterator<'a> {
|
||||
reader: ProducersFieldValuesReader<'a>,
|
||||
left: u32,
|
||||
@ -91,8 +98,10 @@ impl<'a> Iterator for ProducersFieldValuesIterator<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
/// A field from the producers custom section.
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
pub struct ProducersField<'a> {
|
||||
/// The name of the field.
|
||||
pub name: &'a str,
|
||||
values_count: u32,
|
||||
values_data: &'a [u8],
|
||||
@ -100,6 +109,7 @@ pub struct ProducersField<'a> {
|
||||
}
|
||||
|
||||
impl<'a> ProducersField<'a> {
|
||||
/// Gets a reader of values for the field.
|
||||
pub fn get_producer_field_values_reader<'b>(&self) -> Result<ProducersFieldValuesReader<'b>>
|
||||
where
|
||||
'a: 'b,
|
||||
@ -111,6 +121,7 @@ impl<'a> ProducersField<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
/// A reader for the producers custom section of a WebAssembly module.
|
||||
pub struct ProducersSectionReader<'a> {
|
||||
reader: BinaryReader<'a>,
|
||||
count: u32,
|
||||
@ -139,14 +150,17 @@ impl<'a> ProducersSectionReader<'a> {
|
||||
Ok(ProducersSectionReader { reader, count })
|
||||
}
|
||||
|
||||
/// Gets the original position of the reader.
|
||||
pub fn original_position(&self) -> usize {
|
||||
self.reader.original_position()
|
||||
}
|
||||
|
||||
/// Gets the count of items in the reader.
|
||||
pub fn get_count(&self) -> u32 {
|
||||
self.count
|
||||
}
|
||||
|
||||
/// Reads an item from the reader.
|
||||
pub fn read<'b>(&mut self) -> Result<ProducersField<'b>>
|
||||
where
|
||||
'a: 'b,
|
||||
@ -176,7 +190,7 @@ impl<'a> SectionReader for ProducersSectionReader<'a> {
|
||||
fn original_position(&self) -> usize {
|
||||
ProducersSectionReader::original_position(self)
|
||||
}
|
||||
fn range(&self) -> Range {
|
||||
fn range(&self) -> Range<usize> {
|
||||
self.reader.range()
|
||||
}
|
||||
}
|
@ -13,19 +13,94 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
use super::{
|
||||
BinaryReader, Range, RelocType, Result, SectionCode, SectionIteratorLimited, SectionReader,
|
||||
SectionWithLimitedItems,
|
||||
};
|
||||
use crate::{BinaryReader, Result, SectionIteratorLimited, SectionReader, SectionWithLimitedItems};
|
||||
use std::ops::Range;
|
||||
|
||||
/// Represents a relocation type.
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
#[allow(missing_docs)]
|
||||
pub enum RelocType {
|
||||
FunctionIndexLEB,
|
||||
TableIndexSLEB,
|
||||
TableIndexI32,
|
||||
GlobalAddrLEB,
|
||||
GlobalAddrSLEB,
|
||||
GlobalAddrI32,
|
||||
TypeIndexLEB,
|
||||
GlobalIndexLEB,
|
||||
}
|
||||
|
||||
/// Represents known custom section kinds.
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
|
||||
pub enum CustomSectionKind {
|
||||
/// The custom section is not known.
|
||||
Unknown,
|
||||
/// The name custom section.
|
||||
Name,
|
||||
/// The producers custom section.
|
||||
Producers,
|
||||
/// The source mapping URL custom section.
|
||||
SourceMappingURL,
|
||||
/// The reloc custom section.
|
||||
Reloc,
|
||||
/// The linking custom section.
|
||||
Linking,
|
||||
}
|
||||
|
||||
/// Section code as defined [here].
|
||||
///
|
||||
/// [here]: https://webassembly.github.io/spec/core/binary/modules.html#sections
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
|
||||
pub enum SectionCode<'a> {
|
||||
/// The custom section.
|
||||
Custom {
|
||||
/// The name of the custom section.
|
||||
name: &'a str,
|
||||
/// The kind of the custom section.
|
||||
kind: CustomSectionKind,
|
||||
},
|
||||
/// The type section.
|
||||
Type,
|
||||
/// The import section.
|
||||
Import,
|
||||
/// The function section.
|
||||
Function,
|
||||
/// The table section.
|
||||
Table,
|
||||
/// The memory section.
|
||||
Memory,
|
||||
/// The global section.
|
||||
Global,
|
||||
/// The export section.
|
||||
Export,
|
||||
/// The start section.
|
||||
Start,
|
||||
/// The element section.
|
||||
Element,
|
||||
/// The code section.
|
||||
Code,
|
||||
/// The data section.
|
||||
Data,
|
||||
/// The passive data count section.
|
||||
DataCount,
|
||||
/// The tag section.
|
||||
Tag,
|
||||
}
|
||||
|
||||
/// Represents a relocation entry.
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
pub struct Reloc {
|
||||
/// The relocation type.
|
||||
pub ty: RelocType,
|
||||
/// The relocation offset.
|
||||
pub offset: u32,
|
||||
/// The relocation index.
|
||||
pub index: u32,
|
||||
/// The relocation addend.
|
||||
pub addend: Option<u32>,
|
||||
}
|
||||
|
||||
/// A reader for the relocations custom section of a WebAssembly module.
|
||||
pub struct RelocSectionReader<'a> {
|
||||
reader: BinaryReader<'a>,
|
||||
section_code: SectionCode<'a>,
|
||||
@ -33,11 +108,12 @@ pub struct RelocSectionReader<'a> {
|
||||
}
|
||||
|
||||
impl<'a> RelocSectionReader<'a> {
|
||||
/// Constructs a new `RelocSectionReader` for the given data and offset.
|
||||
pub fn new(data: &'a [u8], offset: usize) -> Result<RelocSectionReader<'a>> {
|
||||
let mut reader = BinaryReader::new_with_offset(data, offset);
|
||||
|
||||
let section_id_position = reader.position;
|
||||
let section_id = reader.read_var_u7()?;
|
||||
let section_id = reader.read_u7()?;
|
||||
let section_code = reader.read_section_code(section_id, section_id_position)?;
|
||||
|
||||
let count = reader.read_var_u32()?;
|
||||
@ -48,10 +124,12 @@ impl<'a> RelocSectionReader<'a> {
|
||||
})
|
||||
}
|
||||
|
||||
/// Gets a count of items in the section.
|
||||
pub fn get_count(&self) -> u32 {
|
||||
self.count
|
||||
}
|
||||
|
||||
/// Gets the section code from the section.
|
||||
pub fn get_section_code<'b>(&self) -> SectionCode<'b>
|
||||
where
|
||||
'a: 'b,
|
||||
@ -59,10 +137,12 @@ impl<'a> RelocSectionReader<'a> {
|
||||
self.section_code
|
||||
}
|
||||
|
||||
/// Gets the original position of the reader.
|
||||
pub fn original_position(&self) -> usize {
|
||||
self.reader.original_position()
|
||||
}
|
||||
|
||||
/// Reads an item from the reader.
|
||||
pub fn read(&mut self) -> Result<Reloc> {
|
||||
let ty = self.reader.read_reloc_type()?;
|
||||
let offset = self.reader.read_var_u32()?;
|
||||
@ -97,7 +177,7 @@ impl<'a> SectionReader for RelocSectionReader<'a> {
|
||||
fn original_position(&self) -> usize {
|
||||
RelocSectionReader::original_position(self)
|
||||
}
|
||||
fn range(&self) -> Range {
|
||||
fn range(&self) -> Range<usize> {
|
||||
self.reader.range()
|
||||
}
|
||||
}
|
@ -13,11 +13,12 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
use super::{
|
||||
BinaryReader, Range, Result, SectionIteratorLimited, SectionReader, SectionWithLimitedItems,
|
||||
TableType,
|
||||
use crate::{
|
||||
BinaryReader, Result, SectionIteratorLimited, SectionReader, SectionWithLimitedItems, TableType,
|
||||
};
|
||||
use std::ops::Range;
|
||||
|
||||
/// A reader for the table section of a WebAssembly module.
|
||||
#[derive(Clone)]
|
||||
pub struct TableSectionReader<'a> {
|
||||
reader: BinaryReader<'a>,
|
||||
@ -25,16 +26,19 @@ pub struct TableSectionReader<'a> {
|
||||
}
|
||||
|
||||
impl<'a> TableSectionReader<'a> {
|
||||
/// Constructs a new `TableSectionReader` for the given data and offset.
|
||||
pub fn new(data: &'a [u8], offset: usize) -> Result<TableSectionReader<'a>> {
|
||||
let mut reader = BinaryReader::new_with_offset(data, offset);
|
||||
let count = reader.read_var_u32()?;
|
||||
Ok(TableSectionReader { reader, count })
|
||||
}
|
||||
|
||||
/// Gets the original position of the section reader.
|
||||
pub fn original_position(&self) -> usize {
|
||||
self.reader.original_position()
|
||||
}
|
||||
|
||||
/// Gets the count of items in the section.
|
||||
pub fn get_count(&self) -> u32 {
|
||||
self.count
|
||||
}
|
||||
@ -68,7 +72,7 @@ impl<'a> SectionReader for TableSectionReader<'a> {
|
||||
fn original_position(&self) -> usize {
|
||||
TableSectionReader::original_position(self)
|
||||
}
|
||||
fn range(&self) -> Range {
|
||||
fn range(&self) -> Range<usize> {
|
||||
self.reader.range()
|
||||
}
|
||||
}
|
@ -13,74 +13,78 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
use super::{
|
||||
BinaryReader, EventType, Range, Result, SectionIteratorLimited, SectionReader,
|
||||
SectionWithLimitedItems,
|
||||
use crate::{
|
||||
BinaryReader, Result, SectionIteratorLimited, SectionReader, SectionWithLimitedItems, TagType,
|
||||
};
|
||||
use std::ops::Range;
|
||||
|
||||
/// A reader for the tags section of a WebAssembly module.
|
||||
#[derive(Clone)]
|
||||
pub struct EventSectionReader<'a> {
|
||||
pub struct TagSectionReader<'a> {
|
||||
reader: BinaryReader<'a>,
|
||||
count: u32,
|
||||
}
|
||||
|
||||
impl<'a> EventSectionReader<'a> {
|
||||
pub fn new(data: &'a [u8], offset: usize) -> Result<EventSectionReader<'a>> {
|
||||
impl<'a> TagSectionReader<'a> {
|
||||
/// Constructs a new `TagSectionReader` for the given data and offset.
|
||||
pub fn new(data: &'a [u8], offset: usize) -> Result<TagSectionReader<'a>> {
|
||||
let mut reader = BinaryReader::new_with_offset(data, offset);
|
||||
let count = reader.read_var_u32()?;
|
||||
Ok(EventSectionReader { reader, count })
|
||||
Ok(TagSectionReader { reader, count })
|
||||
}
|
||||
|
||||
/// Gets the original position of the section reader.
|
||||
pub fn original_position(&self) -> usize {
|
||||
self.reader.original_position()
|
||||
}
|
||||
|
||||
/// Gets the count of items in the section.
|
||||
pub fn get_count(&self) -> u32 {
|
||||
self.count
|
||||
}
|
||||
|
||||
/// Reads content of the event section.
|
||||
/// Reads content of the tag section.
|
||||
///
|
||||
/// # Examples
|
||||
/// ```
|
||||
/// use wasmparser::EventSectionReader;
|
||||
/// use wasmparser::TagSectionReader;
|
||||
/// # let data: &[u8] = &[0x01, 0x00, 0x01];
|
||||
/// let mut event_reader = EventSectionReader::new(data, 0).unwrap();
|
||||
/// for _ in 0..event_reader.get_count() {
|
||||
/// let et = event_reader.read().expect("event_type");
|
||||
/// println!("Event: {:?}", et);
|
||||
/// let mut reader = TagSectionReader::new(data, 0).unwrap();
|
||||
/// for _ in 0..reader.get_count() {
|
||||
/// let ty = reader.read().expect("tag type");
|
||||
/// println!("Tag type: {:?}", ty);
|
||||
/// }
|
||||
/// ```
|
||||
pub fn read(&mut self) -> Result<EventType> {
|
||||
self.reader.read_event_type()
|
||||
pub fn read(&mut self) -> Result<TagType> {
|
||||
self.reader.read_tag_type()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> SectionReader for EventSectionReader<'a> {
|
||||
type Item = EventType;
|
||||
impl<'a> SectionReader for TagSectionReader<'a> {
|
||||
type Item = TagType;
|
||||
fn read(&mut self) -> Result<Self::Item> {
|
||||
EventSectionReader::read(self)
|
||||
TagSectionReader::read(self)
|
||||
}
|
||||
fn eof(&self) -> bool {
|
||||
self.reader.eof()
|
||||
}
|
||||
fn original_position(&self) -> usize {
|
||||
EventSectionReader::original_position(self)
|
||||
TagSectionReader::original_position(self)
|
||||
}
|
||||
fn range(&self) -> Range {
|
||||
fn range(&self) -> Range<usize> {
|
||||
self.reader.range()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> SectionWithLimitedItems for EventSectionReader<'a> {
|
||||
impl<'a> SectionWithLimitedItems for TagSectionReader<'a> {
|
||||
fn get_count(&self) -> u32 {
|
||||
EventSectionReader::get_count(self)
|
||||
TagSectionReader::get_count(self)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> IntoIterator for EventSectionReader<'a> {
|
||||
type Item = Result<EventType>;
|
||||
type IntoIter = SectionIteratorLimited<EventSectionReader<'a>>;
|
||||
impl<'a> IntoIterator for TagSectionReader<'a> {
|
||||
type Item = Result<TagType>;
|
||||
type IntoIter = SectionIteratorLimited<TagSectionReader<'a>>;
|
||||
|
||||
fn into_iter(self) -> Self::IntoIter {
|
||||
SectionIteratorLimited::new(self)
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user