use crate::{encoders, GlobalType, MemoryType, RawSection, Section, TableType};
mod aliases;
mod exports;
mod imports;
mod instances;
mod modules;
mod types;
pub use aliases::*;
pub use exports::*;
pub use imports::*;
pub use instances::*;
pub use modules::*;
pub use types::*;
const INDEX_REF_INSTANCE: u8 = 0x00;
const INDEX_REF_MODULE: u8 = 0x01;
const INDEX_REF_FUNCTION: u8 = 0x02;
const INDEX_REF_TABLE: u8 = 0x03;
const INDEX_REF_MEMORY: u8 = 0x04;
const INDEX_REF_GLOBAL: u8 = 0x05;
const TYPE_REF_INSTANCE: u8 = 0x00;
const TYPE_REF_MODULE: u8 = 0x01;
const TYPE_REF_FUNCTION: u8 = 0x02;
const TYPE_REF_TABLE: u8 = 0x03;
const TYPE_REF_MEMORY: u8 = 0x04;
const TYPE_REF_GLOBAL: u8 = 0x05;
pub trait AdapterModuleSection {
fn id(&self) -> u8;
fn encode<S>(&self, sink: &mut S)
where
S: Extend<u8>;
}
impl AdapterModuleSection for RawSection<'_> {
fn id(&self) -> u8 {
self.id
}
fn encode<S>(&self, sink: &mut S)
where
S: Extend<u8>,
{
<Self as Section>::encode(self, sink);
}
}
#[derive(Clone, Debug)]
pub struct AdapterModule {
pub(crate) bytes: Vec<u8>,
}
impl AdapterModule {
pub fn new() -> Self {
Self {
bytes: vec![
0x00, 0x61, 0x73, 0x6D, 0x0a, 0x00, 0x01, 0x00, ],
}
}
pub fn finish(self) -> Vec<u8> {
self.bytes
}
pub fn section(&mut self, section: &impl AdapterModuleSection) -> &mut Self {
self.bytes.push(section.id());
section.encode(&mut self.bytes);
self
}
}
impl Default for AdapterModule {
fn default() -> Self {
Self::new()
}
}
#[derive(Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd)]
#[repr(u8)]
pub enum SectionId {
Custom = 0,
Type = 1,
Import = 2,
Module = 3,
Instance = 4,
Alias = 5,
Export = 6,
}
impl From<SectionId> for u8 {
#[inline]
fn from(id: SectionId) -> u8 {
id as u8
}
}
#[derive(Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd)]
pub enum IndexRef {
Instance(u32),
Module(u32),
Function(u32),
Table(u32),
Memory(u32),
Global(u32),
}
impl IndexRef {
pub(crate) fn encode(&self, bytes: &mut Vec<u8>) {
match self {
IndexRef::Instance(index) => {
bytes.push(INDEX_REF_INSTANCE);
bytes.extend(encoders::u32(*index));
}
IndexRef::Module(index) => {
bytes.push(INDEX_REF_MODULE);
bytes.extend(encoders::u32(*index));
}
IndexRef::Function(index) => {
bytes.push(INDEX_REF_FUNCTION);
bytes.extend(encoders::u32(*index));
}
IndexRef::Table(index) => {
bytes.push(INDEX_REF_TABLE);
bytes.extend(encoders::u32(*index));
}
IndexRef::Memory(index) => {
bytes.push(INDEX_REF_MEMORY);
bytes.extend(encoders::u32(*index));
}
IndexRef::Global(index) => {
bytes.push(INDEX_REF_GLOBAL);
bytes.extend(encoders::u32(*index));
}
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum TypeRef {
Instance(u32),
Module(u32),
Function(u32),
Table(TableType),
Memory(MemoryType),
Global(GlobalType),
}
impl TypeRef {
pub(crate) fn encode(&self, bytes: &mut Vec<u8>) {
match self {
Self::Instance(index) => {
bytes.push(TYPE_REF_INSTANCE);
bytes.extend(encoders::u32(*index));
}
Self::Module(index) => {
bytes.push(TYPE_REF_MODULE);
bytes.extend(encoders::u32(*index));
}
Self::Function(index) => {
bytes.push(TYPE_REF_FUNCTION);
bytes.extend(encoders::u32(*index));
}
Self::Table(ty) => {
bytes.push(TYPE_REF_TABLE);
ty.encode(bytes);
}
Self::Memory(ty) => {
bytes.push(TYPE_REF_MEMORY);
ty.encode(bytes);
}
Self::Global(ty) => {
bytes.push(TYPE_REF_GLOBAL);
ty.encode(bytes);
}
}
}
}
impl From<TableType> for TypeRef {
fn from(t: TableType) -> Self {
Self::Table(t)
}
}
impl From<MemoryType> for TypeRef {
fn from(t: MemoryType) -> Self {
Self::Memory(t)
}
}
impl From<GlobalType> for TypeRef {
fn from(t: GlobalType) -> Self {
Self::Global(t)
}
}
#[cfg(test)]
mod test {
use super::*;
#[test]
fn it_encodes_an_adapter_module() {
let bytes = AdapterModule::new().finish();
assert_eq!(
bytes,
[0x00, 'a' as u8, 's' as u8, 'm' as u8, 0x0a, 0x00, 0x01, 0x00]
);
}
}