diff --git a/src/graph.rs b/src/graph.rs index e5079b1..4ba046a 100644 --- a/src/graph.rs +++ b/src/graph.rs @@ -9,6 +9,18 @@ enum ImportedOrDeclared { Declared(T), } +impl ImportedOrDeclared { + fn imported(module: String, name: String) -> Self { + ImportedOrDeclared::Imported(module, name) + } +} + +impl From<&elements::ImportEntry> for ImportedOrDeclared { + fn from(v: &elements::ImportEntry) -> Self { + ImportedOrDeclared::Imported(v.module().to_owned(), v.field().to_owned()) + } +} + type FuncOrigin = ImportedOrDeclared>; type GlobalOrigin = ImportedOrDeclared>; type MemoryOrigin = ImportedOrDeclared; @@ -17,18 +29,32 @@ type TableOrigin = ImportedOrDeclared; type TypeRef = Rc>; type FuncRef = Rc>; type GlobalRef = Rc>; +type MemoryRef = Rc>; +type TableRef = Rc>; struct Func { type_ref: TypeRef, origin: FuncOrigin, } +impl Func { + fn into_ref(self) -> Rc> { + Rc::from(RefCell::from(self)) + } +} + struct Global { content: elements::ValueType, is_mut: bool, origin: GlobalOrigin, } +impl Global { + fn into_ref(self) -> Rc> { + Rc::from(RefCell::from(self)) + } +} + enum Instruction { Plain(elements::Instruction), Call(FuncRef), @@ -39,8 +65,21 @@ struct Memory { origin: MemoryOrigin, } +impl Memory { + fn into_ref(self) -> Rc> { + Rc::from(RefCell::from(self)) + } +} + struct Table { origin: TableOrigin, + limits: elements::ResizableLimits, +} + +impl Table { + fn into_ref(self) -> Rc> { + Rc::from(RefCell::from(self)) + } } struct DataSegment { @@ -56,14 +95,16 @@ struct ElementSegment { enum Export { Func(FuncRef), Global(GlobalRef), + Table(TableRef), + Memory(MemoryRef), } #[derive(Default)] struct Module { types: Vec, funcs: Vec, - tables: Vec, - memories: Vec, + tables: Vec, + memory: Vec, globals: Vec, elements: Vec, data: Vec, @@ -72,7 +113,6 @@ struct Module { impl Module { - fn from_elements(module: &elements::Module) -> Self { let mut res = Module::default(); @@ -80,7 +120,44 @@ impl Module { for section in module.sections() { match section { elements::Section::Type(type_section) => { - res.types = type_section.types().iter().cloned().map(|t| Rc::new(RefCell::new(t))).collect(); + res.types = type_section + .types() + .iter() + .cloned() + .map(RefCell::<_>::from) + .map(Rc::<_>::from) + .collect(); + }, + elements::Section::Import(import_section) => { + for entry in import_section.entries() { + match *entry.external() { + elements::External::Function(f) => { + res.funcs.push(Func { + type_ref: res.types[f as usize].clone(), + origin: entry.into(), + }.into_ref()) + }, + elements::External::Memory(m) => { + res.memory.push(Memory { + limits: m.limits().clone(), + origin: entry.into(), + }.into_ref()) + }, + elements::External::Global(g) => { + res.globals.push(Global { + content: g.content_type(), + is_mut: g.is_mutable(), + origin: entry.into(), + }.into_ref()) + }, + elements::External::Table(t) => { + res.tables.push(Table { + limits: t.limits().clone(), + origin: entry.into(), + }.into_ref()) + }, + } + } }, _ => continue, }