usecrate::{ConstExpr, Encode, RefType, Section, SectionId, encode_section}; use alloc::borrow::Cow; use alloc::vec::Vec;
/// An encoder for the element section. /// /// Element sections are only supported for modules. /// /// # Example /// /// ``` /// use std::borrow::Cow; /// use wasm_encoder::{ /// Elements, ElementSection, Module, TableSection, TableType, /// RefType, ConstExpr /// }; /// /// let mut tables = TableSection::new(); /// tables.table(TableType { /// element_type: RefType::FUNCREF, /// minimum: 128, /// maximum: None, /// table64: false, /// shared: false, /// }); /// /// let mut elements = ElementSection::new(); /// let table_index = 0; /// let offset = ConstExpr::i32_const(42); /// let functions = Elements::Functions(Cow::Borrowed(&[ /// // Function indices... /// ])); /// elements.active(Some(table_index), &offset, functions); /// /// let mut module = Module::new(); /// module /// .section(&tables) /// .section(&elements); /// /// let wasm_bytes = module.finish(); /// ``` #[derive(Clone, Default, Debug)] pubstruct ElementSection {
bytes: Vec<u8>,
num_added: u32,
}
/// A sequence of elements in a segment in the element section. #[derive(Clone, Debug)] pubenum Elements<'a> { /// A sequences of references to functions by their indices.
Functions(Cow<'a, [u32]>), /// A sequence of reference expressions.
Expressions(RefType, Cow<'a, [ConstExpr]>),
}
/// An element segment's mode. #[derive(Clone, Debug)] pubenum ElementMode<'a> { /// A passive element segment. /// /// Passive segments are part of the bulk memory proposal.
Passive, /// A declared element segment. /// /// Declared segments are part of the bulk memory proposal.
Declared, /// An active element segment.
Active { /// The table index. /// /// `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: &'a ConstExpr,
},
}
/// An element segment in the element section. #[derive(Clone, Debug)] pubstruct ElementSegment<'a> { /// The element segment's mode. pub mode: ElementMode<'a>, /// This segment's elements. pub elements: Elements<'a>,
}
impl ElementSection { /// Create a new element section encoder. pubfn new() -> Self { Self::default()
}
/// The number of element segments in the section. pubfn len(&self) -> u32 { self.num_added
}
/// Determines if the section is empty. pubfn is_empty(&self) -> bool { self.num_added == 0
}
/// Define an element segment. pubfn segment<'a>(&mut self, segment: ElementSegment<'a>) -> &mutSelf { let expr_bit = match segment.elements {
Elements::Expressions(..) => 0b100u32,
Elements::Functions(_) => 0b000u32,
}; letmut encode_type = false; match &segment.mode {
ElementMode::Passive => {
(0x01 | expr_bit).encode(&mutself.bytes);
encode_type = true;
}
ElementMode::Active { table, offset } => { match (table, &segment.elements) { // If the `table` is not specified then the 0x00 encoding // can be used with either function indices or expressions // that have a `funcref` type.
(None, Elements::Functions(_) | Elements::Expressions(RefType::FUNCREF, _)) => {
(/* 0x00 | */expr_bit).encode(&mut self.bytes);
}
// ... otherwise fall through for all other expressions here // with table 0 or an explicitly specified table to the 0x02 // encoding.
(None, Elements::Expressions(..)) | (Some(_), _) => {
(0x02 | expr_bit).encode(&mutself.bytes);
table.unwrap_or(0).encode(&mutself.bytes);
encode_type = true;
}
}
offset.encode(&mutself.bytes);
}
ElementMode::Declared => {
(0x03 | expr_bit).encode(&mutself.bytes);
encode_type = true;
}
}
match segment.elements {
Elements::Functions(fs) => { if encode_type { // elemkind == funcref self.bytes.push(0x00);
}
fs.encode(&mutself.bytes);
}
Elements::Expressions(ty, e) => { if encode_type {
ty.encode(&mutself.bytes);
}
e.len().encode(&mutself.bytes); for expr in e.iter() {
expr.encode(&mutself.bytes);
}
}
}
self.num_added += 1; self
}
/// Define an active element segment. /// /// `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. pubfn active(
&mutself,
table_index: Option<u32>,
offset: &ConstExpr,
elements: Elements<'_>,
) -> &mutSelf { self.segment(ElementSegment {
mode: ElementMode::Active {
table: table_index,
offset,
},
elements,
})
}
/// Encode a passive element segment. /// /// Passive segments are part of the bulk memory proposal. pubfn passive<'a>(&mut self, elements: Elements<'a>) -> &mutSelf { self.segment(ElementSegment {
mode: ElementMode::Passive,
elements,
})
}
/// Encode a declared element segment. /// /// Declared segments are part of the bulk memory proposal. pubfn declared<'a>(&mut self, elements: Elements<'a>) -> &mutSelf { self.segment(ElementSegment {
mode: ElementMode::Declared,
elements,
})
}
/// Copy a raw, already-encoded element segment into this elements section. pubfn raw(&mutself, raw_bytes: &[u8]) -> &mutSelf { self.bytes.extend_from_slice(raw_bytes); self.num_added += 1; self
}
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.