refactor to reflist

This commit is contained in:
NikVolf
2019-01-22 12:19:29 +03:00
parent db4070b96c
commit 33ff0cbe1d
2 changed files with 47 additions and 62 deletions

View File

@ -1,8 +1,7 @@
//! Wasm binary graph format //! Wasm binary graph format
use parity_wasm::elements; use parity_wasm::elements;
use std::cell::RefCell; use super::ref_list::{RefList, EntryRef};
use std::rc::Rc;
enum ImportedOrDeclared<T=()> { enum ImportedOrDeclared<T=()> {
Imported(String, String), Imported(String, String),
@ -26,38 +25,20 @@ type GlobalOrigin = ImportedOrDeclared<Vec<Instruction>>;
type MemoryOrigin = ImportedOrDeclared; type MemoryOrigin = ImportedOrDeclared;
type TableOrigin = ImportedOrDeclared; type TableOrigin = ImportedOrDeclared;
type TypeRef = Rc<RefCell<elements::Type>>;
type FuncRef = Rc<RefCell<Func>>;
type GlobalRef = Rc<RefCell<Global>>;
type MemoryRef = Rc<RefCell<Memory>>;
type TableRef = Rc<RefCell<Table>>;
struct Func { struct Func {
type_ref: TypeRef, type_ref: EntryRef<elements::Type>,
origin: FuncOrigin, origin: FuncOrigin,
} }
impl Func {
fn into_ref(self) -> Rc<RefCell<Self>> {
Rc::from(RefCell::from(self))
}
}
struct Global { struct Global {
content: elements::ValueType, content: elements::ValueType,
is_mut: bool, is_mut: bool,
origin: GlobalOrigin, origin: GlobalOrigin,
} }
impl Global {
fn into_ref(self) -> Rc<RefCell<Self>> {
Rc::from(RefCell::from(self))
}
}
enum Instruction { enum Instruction {
Plain(elements::Instruction), Plain(elements::Instruction),
Call(FuncRef), Call(EntryRef<Func>),
} }
struct Memory { struct Memory {
@ -65,23 +46,11 @@ struct Memory {
origin: MemoryOrigin, origin: MemoryOrigin,
} }
impl Memory {
fn into_ref(self) -> Rc<RefCell<Self>> {
Rc::from(RefCell::from(self))
}
}
struct Table { struct Table {
origin: TableOrigin, origin: TableOrigin,
limits: elements::ResizableLimits, limits: elements::ResizableLimits,
} }
impl Table {
fn into_ref(self) -> Rc<RefCell<Self>> {
Rc::from(RefCell::from(self))
}
}
struct DataSegment { struct DataSegment {
offset_expr: Vec<Instruction>, offset_expr: Vec<Instruction>,
data: Vec<u8>, data: Vec<u8>,
@ -93,19 +62,19 @@ struct ElementSegment {
} }
enum Export { enum Export {
Func(FuncRef), Func(EntryRef<Func>),
Global(GlobalRef), Global(EntryRef<Global>),
Table(TableRef), Table(EntryRef<Table>),
Memory(MemoryRef), Memory(EntryRef<Memory>),
} }
#[derive(Default)] #[derive(Default)]
struct Module { struct Module {
types: Vec<TypeRef>, types: RefList<elements::Type>,
funcs: Vec<FuncRef>, funcs: RefList<Func>,
tables: Vec<TableRef>, tables: RefList<Table>,
memory: Vec<MemoryRef>, memory: RefList<Memory>,
globals: Vec<GlobalRef>, globals: RefList<Global>,
elements: Vec<ElementSegment>, elements: Vec<ElementSegment>,
data: Vec<DataSegment>, data: Vec<DataSegment>,
exports: Vec<Export>, exports: Vec<Export>,
@ -120,43 +89,37 @@ impl Module {
for section in module.sections() { for section in module.sections() {
match section { match section {
elements::Section::Type(type_section) => { elements::Section::Type(type_section) => {
res.types = type_section res.types = RefList::from_slice(type_section.types());
.types()
.iter()
.cloned()
.map(RefCell::<_>::from)
.map(Rc::<_>::from)
.collect();
}, },
elements::Section::Import(import_section) => { elements::Section::Import(import_section) => {
for entry in import_section.entries() { for entry in import_section.entries() {
match *entry.external() { match *entry.external() {
elements::External::Function(f) => { elements::External::Function(f) => {
res.funcs.push(Func { 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(), origin: entry.into(),
}.into_ref()) });
}, },
elements::External::Memory(m) => { elements::External::Memory(m) => {
res.memory.push(Memory { res.memory.push(Memory {
limits: m.limits().clone(), limits: m.limits().clone(),
origin: entry.into(), origin: entry.into(),
}.into_ref()) });
}, },
elements::External::Global(g) => { elements::External::Global(g) => {
res.globals.push(Global { res.globals.push(Global {
content: g.content_type(), content: g.content_type(),
is_mut: g.is_mutable(), is_mut: g.is_mutable(),
origin: entry.into(), origin: entry.into(),
}.into_ref()) });
}, },
elements::External::Table(t) => { elements::External::Table(t) => {
res.tables.push(Table { res.tables.push(Table {
limits: t.limits().clone(), limits: t.limits().clone(),
origin: entry.into(), origin: entry.into(),
}.into_ref()) });
}, },
} };
} }
}, },
_ => continue, _ => continue,

View File

@ -44,7 +44,7 @@ impl<T> ::std::ops::Deref for Entry<T> {
} }
} }
struct EntryRef<T>(Rc<RefCell<Entry<T>>>); pub struct EntryRef<T>(Rc<RefCell<Entry<T>>>);
impl<T> Clone for EntryRef<T> { impl<T> Clone for EntryRef<T> {
fn clone(&self) -> Self { fn clone(&self) -> Self {
@ -72,15 +72,21 @@ impl<T> EntryRef<T> {
} }
} }
struct RefList<T> { pub struct RefList<T> {
items: Vec<EntryRef<T>>, items: Vec<EntryRef<T>>,
} }
impl<T> Default for RefList<T> {
fn default() -> Self {
RefList { items: Default::default() }
}
}
impl<T> RefList<T> { impl<T> RefList<T> {
pub fn new() -> Self { RefList { items: Default::default() } } pub fn new() -> Self { Self::default() }
fn push(&mut self, t: T) -> EntryRef<T> { pub fn push(&mut self, t: T) -> EntryRef<T> {
let idx = self.items.len(); let idx = self.items.len();
let val: EntryRef<_> = Entry::new(t, idx).into(); let val: EntryRef<_> = Entry::new(t, idx).into();
self.items.push(val.clone()); self.items.push(val.clone());
@ -94,6 +100,10 @@ impl<T> RefList<T> {
} }
} }
pub fn get(&self, idx: usize) -> Option<EntryRef<T>> {
self.items.get(idx).cloned()
}
fn done_delete(&mut self, indices: &[usize]) { fn done_delete(&mut self, indices: &[usize]) {
let mut index = 0; let mut index = 0;
@ -115,13 +125,25 @@ impl<T> RefList<T> {
} }
} }
pub fn delete(&mut self, inddices: &[usize]) { pub fn delete(&mut self, indices: &[usize]) {
self.done_delete(inddices) self.done_delete(indices)
} }
pub fn delete_one(&mut self, index: usize) { pub fn delete_one(&mut self, index: usize) {
self.done_delete(&[index]) 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] #[must_use]