/// To compute the arity (param and result counts) of "variable-arity" /// operators, the operator_arity macro needs information about the /// module's types and the current control stack. The ModuleArity /// trait exposes this information. pubtrait ModuleArity { /// Type with given index fn sub_type_at(&self, type_idx: u32) -> Option<&SubType>;
/// Arity (param and result counts) of tag with given index fn tag_type_arity(&self, at: u32) -> Option<(u32, u32)>;
/// Type index of function with given index fn type_index_of_function(&self, function_idx: u32) -> Option<u32>;
/// Function type for a given continuation type fn func_type_of_cont_type(&self, c: &ContType) -> Option<&FuncType>;
/// Sub type for a given reference type fn sub_type_of_ref_type(&self, rt: &RefType) -> Option<&SubType>;
/// Current height of control stack fn control_stack_height(&self) -> u32;
/// BlockType and FrameKind of label with given index fn label_block(&self, depth: u32) -> Option<(BlockType, FrameKind)>;
/// Computes arity of given SubType fn sub_type_arity(&self, t: &SubType) -> Option<(u32, u32)> { match &t.composite_type.inner {
CompositeInnerType::Func(f) => {
Some((f.params().len() as u32, f.results().len() as u32))
}
CompositeInnerType::Struct(s) => Some((s.fields.len() as u32, s.fields.len() as u32)),
CompositeInnerType::Array(_) => None,
CompositeInnerType::Cont(c) => { let f = self.func_type_of_cont_type(c)?;
Some((f.params().len() as u32, f.results().len() as u32))
}
}
}
/// Computes arity of given BlockType fn block_type_arity(&self, ty: BlockType) -> Option<(u32, u32)> { match ty {
BlockType::Empty => Some((0, 0)),
BlockType::Type(_) => Some((0, 1)),
BlockType::FuncType(t) => self.sub_type_arity(self.sub_type_at(t)?),
}
}
}
impl BinaryReader<'_> { /// Read the next operator and compute its arity (param and result counts) pubfn operator_arity(&self, module: &impl ModuleArity) -> Result<(u32, u32)> { self.clone()
.read_operator()?
.operator_arity(module)
.ok_or_else(|| {
BinaryReaderError::new("operator arity is unknown", self.original_position())
})
}
}
/// The operator_arity macro interprets the annotations in the for_each_operator macro /// to compute the arity of each operator. It needs access to a ModuleArity implementation.
macro_rules! operator_arity {
(arity $self:ident $({ $($arg:ident: $argty:ty),* })? arity $($ann:tt)*) => {
{ let params = (|| -> Option<(i32, i32)> { operator_arity!(params $self { $($($arg: $argty),*)? } $($ann)*) })(); let results = (|| -> Option<(i32, i32)> { operator_arity!(results $self { $($($arg: $argty),*)? } $($ann)*) })(); match (params, results) {
(Some((a,_)), Some((_,d))) if a >= 0 && d >= 0 => (Some((a as u32, d as u32))),
_ => None,
}
}
};
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.