diff --git a/src/graph.rs b/src/graph.rs index 4ba046a..cab7e4c 100644 --- a/src/graph.rs +++ b/src/graph.rs @@ -1,8 +1,7 @@ //! Wasm binary graph format use parity_wasm::elements; -use std::cell::RefCell; -use std::rc::Rc; +use super::ref_list::{RefList, EntryRef}; enum ImportedOrDeclared { Imported(String, String), @@ -26,38 +25,20 @@ type GlobalOrigin = ImportedOrDeclared>; type MemoryOrigin = ImportedOrDeclared; type TableOrigin = ImportedOrDeclared; -type TypeRef = Rc>; -type FuncRef = Rc>; -type GlobalRef = Rc>; -type MemoryRef = Rc>; -type TableRef = Rc>; - struct Func { - type_ref: TypeRef, + type_ref: EntryRef, 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), + Call(EntryRef), } struct Memory { @@ -65,23 +46,11 @@ 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 { offset_expr: Vec, data: Vec, @@ -93,19 +62,19 @@ struct ElementSegment { } enum Export { - Func(FuncRef), - Global(GlobalRef), - Table(TableRef), - Memory(MemoryRef), + Func(EntryRef), + Global(EntryRef), + Table(EntryRef), + Memory(EntryRef), } #[derive(Default)] struct Module { - types: Vec, - funcs: Vec, - tables: Vec, - memory: Vec, - globals: Vec, + types: RefList, + funcs: RefList, + tables: RefList
, + memory: RefList, + globals: RefList, elements: Vec, data: Vec, exports: Vec, @@ -120,43 +89,37 @@ impl Module { for section in module.sections() { match section { elements::Section::Type(type_section) => { - res.types = type_section - .types() - .iter() - .cloned() - .map(RefCell::<_>::from) - .map(Rc::<_>::from) - .collect(); + res.types = RefList::from_slice(type_section.types()); }, 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(), + type_ref: res.types.get(f as usize).expect("validated; qed").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, diff --git a/src/ref_list.rs b/src/ref_list.rs index b9a114c..c349393 100644 --- a/src/ref_list.rs +++ b/src/ref_list.rs @@ -44,7 +44,7 @@ impl ::std::ops::Deref for Entry { } } -struct EntryRef(Rc>>); +pub struct EntryRef(Rc>>); impl Clone for EntryRef { fn clone(&self) -> Self { @@ -72,15 +72,21 @@ impl EntryRef { } } -struct RefList { +pub struct RefList { items: Vec>, } +impl Default for RefList { + fn default() -> Self { + RefList { items: Default::default() } + } +} + impl RefList { - pub fn new() -> Self { RefList { items: Default::default() } } + pub fn new() -> Self { Self::default() } - fn push(&mut self, t: T) -> EntryRef { + pub fn push(&mut self, t: T) -> EntryRef { let idx = self.items.len(); let val: EntryRef<_> = Entry::new(t, idx).into(); self.items.push(val.clone()); @@ -94,6 +100,10 @@ impl RefList { } } + pub fn get(&self, idx: usize) -> Option> { + self.items.get(idx).cloned() + } + fn done_delete(&mut self, indices: &[usize]) { let mut index = 0; @@ -115,13 +125,25 @@ impl RefList { } } - pub fn delete(&mut self, inddices: &[usize]) { - self.done_delete(inddices) + pub fn delete(&mut self, indices: &[usize]) { + self.done_delete(indices) } pub fn delete_one(&mut self, index: usize) { self.done_delete(&[index]) } + + pub fn from_slice(list: &[T]) -> Self + where T: Clone + { + let mut res = Self::new(); + + for t in list { + res.push(t.clone()); + } + + res + } } #[must_use]