ordering and filtering

This commit is contained in:
NikVolf 2019-01-22 17:14:37 +03:00
parent 76b6743c64
commit c520d334cd

View File

@ -245,24 +245,26 @@ impl Module {
custom_round(&self.other, &mut idx, &mut sections); custom_round(&self.other, &mut idx, &mut sections);
// TYPE SECTION (1) if self.types.len() > 0 {
// TYPE SECTION (1)
let mut type_section = elements::TypeSection::default();
{
let mut types = type_section.types_mut();
let mut type_section = elements::TypeSection::default(); for type_entry in self.types.iter() {
{ types.push(type_entry.read().clone())
let mut types = type_section.types_mut(); }
for type_entry in self.types.iter() {
types.push(type_entry.read().clone())
} }
} sections.push(elements::Section::Type(type_section));
sections.push(elements::Section::Type(type_section)); idx += 1;
idx += 1;
custom_round(&self.other, &mut idx, &mut sections); custom_round(&self.other, &mut idx, &mut sections);
}
// IMPORT SECTION (2) // IMPORT SECTION (2)
let mut import_section = elements::ImportSection::default(); let mut import_section = elements::ImportSection::default();
{
let add = {
let mut imports = import_section.entries_mut(); let mut imports = import_section.entries_mut();
for func in self.funcs.iter() { for func in self.funcs.iter() {
match func.read().origin { match func.read().origin {
@ -341,101 +343,168 @@ impl Module {
_ => continue, _ => continue,
} }
} }
imports.len() > 0
};
if add {
sections.push(elements::Section::Import(import_section));
idx += 1;
custom_round(&self.other, &mut idx, &mut sections);
} }
sections.push(elements::Section::Import(import_section)); if self.funcs.len() > 0 {
idx += 1; // FUNC SECTION (3)
let mut func_section = elements::FunctionSection::default();
{
let mut funcs = func_section.entries_mut();
custom_round(&self.other, &mut idx, &mut sections); for func in self.funcs.iter() {
match func.read().origin {
// FUNC SECTION (3) Declared(_) => {
let mut func_section = elements::FunctionSection::default(); funcs.push(elements::Func::new(
{ func.read().type_ref.order()
let mut funcs = func_section.entries_mut(); .expect("detached func encountered somehow!") as u32
));
for func in self.funcs.iter() { },
match func.read().origin { _ => continue,
Declared(_) => { }
funcs.push(elements::Func::new(
func.read().type_ref.order()
.expect("detached func encountered somehow!") as u32
));
},
_ => continue,
} }
} }
sections.push(elements::Section::Function(func_section));
idx += 1;
custom_round(&self.other, &mut idx, &mut sections);
} }
sections.push(elements::Section::Function(func_section));
idx += 1;
custom_round(&self.other, &mut idx, &mut sections); if self.tables.len() > 0 {
// TABLE SECTION (4)
let mut table_section = elements::TableSection::default();
{
let mut tables = table_section.entries_mut();
// TABLE SECTION (4) for table in self.tables.iter() {
let mut table_section = elements::TableSection::default(); match table.read().origin {
{ Declared(_) => {
let mut tables = table_section.entries_mut(); tables.push(elements::TableType::new(
table.read().limits.initial(),
for table in self.tables.iter() { table.read().limits.maximum(),
match table.read().origin { ));
Declared(_) => { },
tables.push(elements::TableType::new( _ => continue,
table.read().limits.initial(), }
table.read().limits.maximum(),
));
},
_ => continue,
} }
} }
sections.push(elements::Section::Table(table_section));
idx += 1;
custom_round(&self.other, &mut idx, &mut sections);
} }
sections.push(elements::Section::Table(table_section));
idx += 1;
custom_round(&self.other, &mut idx, &mut sections); if self.memory.len() > 0 {
// MEMORY SECTION (5)
let mut memory_section = elements::MemorySection::default();
{
let mut memories = memory_section.entries_mut();
// TABLE SECTION (4) for memory in self.memory.iter() {
let mut memory_section = elements::MemorySection::default(); match memory.read().origin {
{ Declared(_) => {
let mut memories = memory_section.entries_mut(); memories.push(elements::MemoryType::new(
memory.read().limits.initial(),
for memory in self.memory.iter() { memory.read().limits.maximum(),
match memory.read().origin { ));
Declared(_) => { },
memories.push(elements::MemoryType::new( _ => continue,
memory.read().limits.initial(), }
memory.read().limits.maximum(),
));
},
_ => continue,
} }
} }
sections.push(elements::Section::Memory(memory_section));
idx += 1;
custom_round(&self.other, &mut idx, &mut sections);
} }
sections.push(elements::Section::Memory(memory_section));
idx += 1;
custom_round(&self.other, &mut idx, &mut sections); if self.globals.len() > 0 {
// GLOBAL SECTION (6)
let mut global_section = elements::GlobalSection::default();
{
let mut globals = global_section.entries_mut();
// CODE SECTION (10) for global in self.globals.iter() {
let mut code_section = elements::CodeSection::default(); match global.read().origin {
{ Declared(_) => {
let mut funcs = code_section.bodies_mut(); globals.push(elements::GlobalEntry::new(
elements::GlobalType::new(global.read().content, global.read().is_mut),
for func in self.funcs.iter() { // TODO: generate init expr
match func.read().origin { elements::InitExpr::empty(),
Declared(_) => { ));
// TODO: generate body },
funcs.push(elements::FuncBody::new( _ => continue,
Vec::new(), }
elements::Instructions::empty(),
));
},
_ => continue,
} }
} }
} sections.push(elements::Section::Global(global_section));
sections.push(elements::Section::Code(code_section)); idx += 1;
idx += 1;
custom_round(&self.other, &mut idx, &mut sections); custom_round(&self.other, &mut idx, &mut sections);
}
if self.exports.len() > 0 {
// EXPORT SECTION (6)
let mut export_section = elements::ExportSection::default();
{
let mut exports = export_section.entries_mut();
for export in self.exports.iter() {
let internal = match export.local {
ExportLocal::Func(ref func_ref) => {
elements::Internal::Function(func_ref.order().expect("detached func ref") as u32)
},
ExportLocal::Global(ref global_ref) => {
elements::Internal::Global(global_ref.order().expect("detached global ref") as u32)
},
ExportLocal::Table(ref table_ref) => {
elements::Internal::Table(table_ref.order().expect("detached table ref") as u32)
},
ExportLocal::Memory(ref memory_ref) => {
elements::Internal::Memory(memory_ref.order().expect("detached memory ref") as u32)
},
_ => continue,
};
exports.push(elements::ExportEntry::new(export.name.to_owned(), internal));
}
}
sections.push(elements::Section::Export(export_section));
idx += 1;
custom_round(&self.other, &mut idx, &mut sections);
}
if self.funcs.len() > 0 {
// CODE SECTION (10)
let mut code_section = elements::CodeSection::default();
{
let mut funcs = code_section.bodies_mut();
for func in self.funcs.iter() {
match func.read().origin {
Declared(_) => {
// TODO: generate body
funcs.push(elements::FuncBody::new(
Vec::new(),
elements::Instructions::empty(),
));
},
_ => continue,
}
}
}
sections.push(elements::Section::Code(code_section));
idx += 1;
custom_round(&self.other, &mut idx, &mut sections);
}
elements::Module::new(sections) elements::Module::new(sections)
} }
@ -456,6 +525,11 @@ fn parse(wasm: &[u8]) -> Module {
Module::from_elements(&::parity_wasm::deserialize_buffer(wasm).expect("failed to parse wasm")) Module::from_elements(&::parity_wasm::deserialize_buffer(wasm).expect("failed to parse wasm"))
} }
fn generate(f: &Module) -> Vec<u8> {
let pm = f.generate();
::parity_wasm::serialize(pm).expect("failed to generate wasm")
}
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
@ -484,4 +558,26 @@ mod tests {
assert_eq!(f.types.get_ref(0).link_count(), 1); assert_eq!(f.types.get_ref(0).link_count(), 1);
assert_eq!(f.funcs.get_ref(0).link_count(), 1); assert_eq!(f.funcs.get_ref(0).link_count(), 1);
} }
#[test]
#[ignore]
fn simple_round_trip() {
let wat = r#"
(module
(type (func))
(func (type 0))
(memory 0 1)
(export "simple" (func 0))
)
"#;
let wasm = wabt::wat2wasm(wat).expect("Failed to read fixture");
let f = super::parse(&wasm[..]);
let wasm_new = super::generate(&f);
let wat_new = wabt::wasm2wat(&wasm_new).expect("Failed to generate expectation");
assert_eq!(&wat_new, wat);
}
} }