wasm-utils/src/graph.rs

131 lines
2.6 KiB
Rust
Raw Normal View History

2019-01-21 17:04:31 +03:00
//! Wasm binary graph format
use parity_wasm::elements;
2019-01-22 12:19:29 +03:00
use super::ref_list::{RefList, EntryRef};
2019-01-21 17:04:31 +03:00
enum ImportedOrDeclared<T=()> {
Imported(String, String),
Declared(T),
}
2019-01-21 17:56:30 +03:00
impl<T> From<&elements::ImportEntry> for ImportedOrDeclared<T> {
fn from(v: &elements::ImportEntry) -> Self {
ImportedOrDeclared::Imported(v.module().to_owned(), v.field().to_owned())
}
}
2019-01-21 17:04:31 +03:00
type FuncOrigin = ImportedOrDeclared<Vec<Instruction>>;
type GlobalOrigin = ImportedOrDeclared<Vec<Instruction>>;
type MemoryOrigin = ImportedOrDeclared;
type TableOrigin = ImportedOrDeclared;
struct Func {
2019-01-22 12:19:29 +03:00
type_ref: EntryRef<elements::Type>,
2019-01-21 17:04:31 +03:00
origin: FuncOrigin,
}
struct Global {
content: elements::ValueType,
is_mut: bool,
origin: GlobalOrigin,
}
enum Instruction {
Plain(elements::Instruction),
2019-01-22 12:19:29 +03:00
Call(EntryRef<Func>),
2019-01-21 17:04:31 +03:00
}
struct Memory {
limits: elements::ResizableLimits,
origin: MemoryOrigin,
}
struct Table {
origin: TableOrigin,
2019-01-21 17:56:30 +03:00
limits: elements::ResizableLimits,
}
2019-01-21 17:04:31 +03:00
struct DataSegment {
offset_expr: Vec<Instruction>,
data: Vec<u8>,
}
struct ElementSegment {
offset_expr: Vec<Instruction>,
data: Vec<u32>,
}
enum Export {
2019-01-22 12:19:29 +03:00
Func(EntryRef<Func>),
Global(EntryRef<Global>),
Table(EntryRef<Table>),
Memory(EntryRef<Memory>),
2019-01-21 17:04:31 +03:00
}
#[derive(Default)]
struct Module {
2019-01-22 12:19:29 +03:00
types: RefList<elements::Type>,
funcs: RefList<Func>,
tables: RefList<Table>,
memory: RefList<Memory>,
globals: RefList<Global>,
2019-01-21 17:04:31 +03:00
elements: Vec<ElementSegment>,
data: Vec<DataSegment>,
exports: Vec<Export>,
}
impl Module {
fn from_elements(module: &elements::Module) -> Self {
let mut res = Module::default();
for section in module.sections() {
match section {
elements::Section::Type(type_section) => {
2019-01-22 12:19:29 +03:00
res.types = RefList::from_slice(type_section.types());
2019-01-21 17:56:30 +03:00
},
elements::Section::Import(import_section) => {
for entry in import_section.entries() {
match *entry.external() {
elements::External::Function(f) => {
res.funcs.push(Func {
2019-01-22 12:19:29 +03:00
type_ref: res.types.get(f as usize).expect("validated; qed").clone(),
2019-01-21 17:56:30 +03:00
origin: entry.into(),
2019-01-22 12:19:29 +03:00
});
2019-01-21 17:56:30 +03:00
},
elements::External::Memory(m) => {
res.memory.push(Memory {
limits: m.limits().clone(),
origin: entry.into(),
2019-01-22 12:19:29 +03:00
});
2019-01-21 17:56:30 +03:00
},
elements::External::Global(g) => {
res.globals.push(Global {
content: g.content_type(),
is_mut: g.is_mutable(),
origin: entry.into(),
2019-01-22 12:19:29 +03:00
});
2019-01-21 17:56:30 +03:00
},
elements::External::Table(t) => {
res.tables.push(Table {
limits: t.limits().clone(),
origin: entry.into(),
2019-01-22 12:19:29 +03:00
});
2019-01-21 17:56:30 +03:00
},
2019-01-22 12:19:29 +03:00
};
2019-01-21 17:56:30 +03:00
}
2019-01-21 17:04:31 +03:00
},
_ => continue,
}
}
res
}
}
#[cfg(test)]
mod tests {
}