1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175
mod branch_hints;
mod code;
mod custom;
mod data;
mod dump;
mod elements;
mod exports;
mod functions;
mod globals;
mod imports;
mod linking;
mod memories;
mod names;
mod producers;
mod start;
mod tables;
mod tags;
mod types;
pub use branch_hints::*;
pub use code::*;
pub use custom::*;
pub use data::*;
pub use dump::*;
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 producers::*;
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;
/// Appends this section to the specified destination list of bytes.
fn append_to(&self, dst: &mut Vec<u8>) {
dst.push(self.id());
self.encode(dst);
}
}
/// 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 {
/// The 8-byte header at the beginning of all core wasm modules.
#[rustfmt::skip]
pub const HEADER: [u8; 8] = [
// Magic
0x00, 0x61, 0x73, 0x6D,
// Version
0x01, 0x00, 0x00, 0x00,
];
/// Begin writing a new `Module`.
#[rustfmt::skip]
pub fn new() -> Self {
Module {
bytes: Self::HEADER.to_vec(),
}
}
/// 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
}
/// Give the current size of the module in bytes.
pub fn len(&self) -> usize {
self.bytes.len()
}
/// 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()
}
}