diff --git a/cli/build/main.rs b/cli/build/main.rs index b32ed02..9ed2d90 100644 --- a/cli/build/main.rs +++ b/cli/build/main.rs @@ -122,8 +122,9 @@ fn do_main() -> Result<(), Error> { .get_matches(); - let target_dir = matches.value_of("target").expect("is required; qed"); - let wasm_binary = matches.value_of("wasm").expect("is required; qed"); + let target_dir = matches.value_of("target").expect("is required; qed"); + let wasm_binary = matches.value_of("wasm").expect("is required; qed"); + let mut source_input = source::SourceInput::new(target_dir, wasm_binary); let source_target_val = matches.value_of("source_target").unwrap_or_else(|| source::EMSCRIPTEN_TRIPLET); diff --git a/cli/check/main.rs b/cli/check/main.rs index fafffb8..5d85b74 100644 --- a/cli/check/main.rs +++ b/cli/check/main.rs @@ -7,96 +7,96 @@ use clap::{App, Arg}; use parity_wasm::elements; fn fail(msg: &str) -> ! { - eprintln!("{}", msg); - std::process::exit(1) + eprintln!("{}", msg); + std::process::exit(1) } const ALLOWED_IMPORTS: &'static [&'static str] = &[ - "ret", - "storage_read", - "storage_write", - "balance", - "sender", - "origin", - "fetch_input", - "input_length", - "ccall", - "dcall", - "scall", - "create", - "balance", - "blockhash", - "blocknumber", - "coinbase", - "timestamp", - "difficulty", - "gaslimit", - "address", - "value", - "suicide", - "panic", - "elog", - "abort" + "ret", + "storage_read", + "storage_write", + "balance", + "sender", + "origin", + "fetch_input", + "input_length", + "ccall", + "dcall", + "scall", + "create", + "balance", + "blockhash", + "blocknumber", + "coinbase", + "timestamp", + "difficulty", + "gaslimit", + "address", + "value", + "suicide", + "panic", + "elog", + "abort" ]; fn main() { - logger::init_log(); + logger::init_log(); - let matches = App::new("wasm-check") - .arg(Arg::with_name("input") - .index(1) - .required(true) - .help("Input WASM file")) - .get_matches(); + let matches = App::new("wasm-check") + .arg(Arg::with_name("input") + .index(1) + .required(true) + .help("Input WASM file")) + .get_matches(); - let input = matches.value_of("input").expect("is required; qed"); + let input = matches.value_of("input").expect("is required; qed"); - let module = parity_wasm::deserialize_file(&input).expect("Input module deserialization failed"); + let module = parity_wasm::deserialize_file(&input).expect("Input module deserialization failed"); - for section in module.sections() { - match *section { - elements::Section::Import(ref import_section) => { - let mut has_imported_memory_properly_named = false; - for entry in import_section.entries() { - if entry.module() != "env" { - fail("All imports should be from env"); - } - match *entry.external() { - elements::External::Function(_) => { - if !ALLOWED_IMPORTS.contains(&entry.field()) { - fail(&format!("'{}' is not supported by the runtime", entry.field())); - } - }, - elements::External::Memory(m) => { - if entry.field() == "memory" { - has_imported_memory_properly_named = true; - } + for section in module.sections() { + match *section { + elements::Section::Import(ref import_section) => { + let mut has_imported_memory_properly_named = false; + for entry in import_section.entries() { + if entry.module() != "env" { + fail("All imports should be from env"); + } + match *entry.external() { + elements::External::Function(_) => { + if !ALLOWED_IMPORTS.contains(&entry.field()) { + fail(&format!("'{}' is not supported by the runtime", entry.field())); + } + }, + elements::External::Memory(m) => { + if entry.field() == "memory" { + has_imported_memory_properly_named = true; + } - let max = if let Some(max) = m.limits().maximum() { - max - } else { - fail("There is a limit on memory in Parity runtime, and this program does not limit memory"); - }; + let max = if let Some(max) = m.limits().maximum() { + max + } else { + fail("There is a limit on memory in Parity runtime, and this program does not limit memory"); + }; - if max > 16 { - fail(&format!( - "Parity runtime has 1Mb limit (16 pages) on max contract memory, this program speicifies {}", - max - )); - } - }, - elements::External::Global(_) => { - fail("Parity runtime does not provide any globals") - }, - _ => { continue; } - } - } + if max > 16 { + fail(&format!( + "Parity runtime has 1Mb limit (16 pages) on max contract memory, this program speicifies {}", + max + )); + } + }, + elements::External::Global(_) => { + fail("Parity runtime does not provide any globals") + }, + _ => { continue; } + } + } - if !has_imported_memory_properly_named { - fail("No imported memory from env::memory in the contract"); - } - } - _ => { continue; } - } - } + if !has_imported_memory_properly_named { + fail("No imported memory from env::memory in the contract"); + } + } + _ => { continue; } + } + } } diff --git a/cli/pack/main.rs b/cli/pack/main.rs index 5a0b98c..5f163e2 100644 --- a/cli/pack/main.rs +++ b/cli/pack/main.rs @@ -6,32 +6,32 @@ extern crate clap; use clap::{App, Arg}; fn main() { - logger::init_log(); + logger::init_log(); let target_runtime = utils::TargetRuntime::pwasm(); - let matches = App::new("wasm-pack") - .arg(Arg::with_name("input") - .index(1) - .required(true) - .help("Input WASM file")) - .arg(Arg::with_name("output") - .index(2) - .required(true) - .help("Output WASM file")) - .get_matches(); + let matches = App::new("wasm-pack") + .arg(Arg::with_name("input") + .index(1) + .required(true) + .help("Input WASM file")) + .arg(Arg::with_name("output") + .index(2) + .required(true) + .help("Output WASM file")) + .get_matches(); - let input = matches.value_of("input").expect("is required; qed"); - let output = matches.value_of("output").expect("is required; qed"); + let input = matches.value_of("input").expect("is required; qed"); + let output = matches.value_of("output").expect("is required; qed"); - let module = parity_wasm::deserialize_file(&input).expect("Input module deserialization failed"); - let ctor_module = module.clone(); + let module = parity_wasm::deserialize_file(&input).expect("Input module deserialization failed"); + let ctor_module = module.clone(); let raw_module = parity_wasm::serialize(module).expect("Serialization failed"); - // Invoke packer - let mut result_module = utils::pack_instance(raw_module, ctor_module, &utils::TargetRuntime::pwasm()).expect("Packing failed"); - // Optimize constructor, since it does not need everything - utils::optimize(&mut result_module, vec![target_runtime.symbols().call]).expect("Optimization failed"); + // Invoke packer + let mut result_module = utils::pack_instance(raw_module, ctor_module, &utils::TargetRuntime::pwasm()).expect("Packing failed"); + // Optimize constructor, since it does not need everything + utils::optimize(&mut result_module, vec![target_runtime.symbols().call]).expect("Optimization failed"); - parity_wasm::serialize_to_file(&output, result_module).expect("Serialization failed"); + parity_wasm::serialize_to_file(&output, result_module).expect("Serialization failed"); } diff --git a/cli/prune/main.rs b/cli/prune/main.rs index e44fa79..c23ba58 100644 --- a/cli/prune/main.rs +++ b/cli/prune/main.rs @@ -6,42 +6,42 @@ extern crate clap; use clap::{App, Arg}; fn main() { - logger::init_log(); + logger::init_log(); let target_runtime = utils::TargetRuntime::pwasm(); - let matches = App::new("wasm-prune") - .arg(Arg::with_name("input") - .index(1) - .required(true) - .help("Input WASM file")) - .arg(Arg::with_name("output") - .index(2) - .required(true) - .help("Output WASM file")) - .arg(Arg::with_name("exports") - .long("exports") - .short("e") - .takes_value(true) - .value_name("functions") - .help(&format!("Comma-separated list of exported functions to keep. Default: '{}'", target_runtime.symbols().call))) - .get_matches(); + let matches = App::new("wasm-prune") + .arg(Arg::with_name("input") + .index(1) + .required(true) + .help("Input WASM file")) + .arg(Arg::with_name("output") + .index(2) + .required(true) + .help("Output WASM file")) + .arg(Arg::with_name("exports") + .long("exports") + .short("e") + .takes_value(true) + .value_name("functions") + .help(&format!("Comma-separated list of exported functions to keep. Default: '{}'", target_runtime.symbols().call))) + .get_matches(); - let exports = matches - .value_of("exports") - .unwrap_or(target_runtime.symbols().call) - .split(',') - .collect(); + let exports = matches + .value_of("exports") + .unwrap_or(target_runtime.symbols().call) + .split(',') + .collect(); - let input = matches.value_of("input").expect("is required; qed"); - let output = matches.value_of("output").expect("is required; qed"); + let input = matches.value_of("input").expect("is required; qed"); + let output = matches.value_of("output").expect("is required; qed"); - let mut module = parity_wasm::deserialize_file(&input).unwrap(); + let mut module = parity_wasm::deserialize_file(&input).unwrap(); - // Invoke optimizer - // Contract is supposed to have only these functions as public api - // All other symbols not usable by this list is optimized away - utils::optimize(&mut module, exports).expect("Optimizer failed"); + // Invoke optimizer + // Contract is supposed to have only these functions as public api + // All other symbols not usable by this list is optimized away + utils::optimize(&mut module, exports).expect("Optimizer failed"); - parity_wasm::serialize_to_file(&output, module).expect("Serialization failed"); + parity_wasm::serialize_to_file(&output, module).expect("Serialization failed"); } diff --git a/src/lib.rs b/src/lib.rs index 6f034ff..dd0c685 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -27,7 +27,7 @@ pub mod stack_height; pub use build::{build, Error as BuildError, SourceTarget}; pub use ext::{ - externalize, externalize_mem, shrink_unknown_stack, underscore_funcs, ununderscore_funcs, + externalize, externalize_mem, shrink_unknown_stack, underscore_funcs, ununderscore_funcs, }; pub use gas::inject_gas_counter; pub use optimizer::{optimize, Error as OptimizerError}; @@ -37,47 +37,47 @@ pub use graph::{Module, parse as graph_parse, generate as graph_generate}; pub use ref_list::{RefList, Entry, EntryRef, DeleteTransaction}; pub struct TargetSymbols { - pub create: &'static str, - pub call: &'static str, - pub ret: &'static str, + pub create: &'static str, + pub call: &'static str, + pub ret: &'static str, } pub enum TargetRuntime { - Substrate(TargetSymbols), - PWasm(TargetSymbols), + Substrate(TargetSymbols), + PWasm(TargetSymbols), } impl TargetRuntime { - pub fn substrate() -> TargetRuntime { - TargetRuntime::Substrate(TargetSymbols { - create: "deploy", - call: "call", - ret: "ext_return", - }) - } + pub fn substrate() -> TargetRuntime { + TargetRuntime::Substrate(TargetSymbols { + create: "deploy", + call: "call", + ret: "ext_return", + }) + } - pub fn pwasm() -> TargetRuntime { - TargetRuntime::PWasm(TargetSymbols { - create: "deploy", - call: "call", - ret: "ret", - }) - } + pub fn pwasm() -> TargetRuntime { + TargetRuntime::PWasm(TargetSymbols { + create: "deploy", + call: "call", + ret: "ret", + }) + } - pub fn symbols(&self) -> &TargetSymbols { - match self { + pub fn symbols(&self) -> &TargetSymbols { + match self { TargetRuntime::Substrate(s) => s, TargetRuntime::PWasm(s) => s, } - } + } } #[cfg(not(feature = "std"))] mod std { - pub use alloc::{borrow, boxed, string, vec}; - pub use core::*; + pub use alloc::{borrow, boxed, string, vec}; + pub use core::*; pub mod rc { pub use alloc::rc::Rc; diff --git a/src/pack.rs b/src/pack.rs index 8563178..b850ed9 100644 --- a/src/pack.rs +++ b/src/pack.rs @@ -3,8 +3,8 @@ use std::vec::Vec; use std::borrow::ToOwned; use parity_wasm::elements::{ - self, Section, DataSection, Instruction, DataSegment, InitExpr, Internal, External, - ImportCountType, + self, Section, DataSection, Instruction, DataSegment, InitExpr, Internal, External, + ImportCountType, }; use parity_wasm::builder; use super::TargetRuntime; @@ -16,29 +16,29 @@ use super::gas::update_call_index; /// When they are violated, pack_instance returns one of these. #[derive(Debug)] pub enum Error { - MalformedModule, - NoTypeSection, - NoExportSection, - NoCodeSection, - InvalidCreateSignature(&'static str), - NoCreateSymbol(&'static str), - InvalidCreateMember(&'static str), - NoImportSection, + MalformedModule, + NoTypeSection, + NoExportSection, + NoCodeSection, + InvalidCreateSignature(&'static str), + NoCreateSymbol(&'static str), + InvalidCreateMember(&'static str), + NoImportSection, } impl fmt::Display for Error { - fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> { - match *self { - Error::MalformedModule => write!(f, "Module internal references are inconsistent"), - Error::NoTypeSection => write!(f, "No type section in the module"), - Error::NoExportSection => write!(f, "No export section in the module"), - Error::NoCodeSection => write!(f, "No code section inthe module"), - Error::InvalidCreateSignature(sym) => write!(f, "Exported symbol `{}` has invalid signature, should be () -> ()", sym), - Error::InvalidCreateMember(sym) => write!(f, "Exported symbol `{}` should be a function", sym), - Error::NoCreateSymbol(sym) => write!(f, "No exported `{}` symbol", sym), - Error::NoImportSection => write!(f, "No import section in the module"), - } - } + fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> { + match *self { + Error::MalformedModule => write!(f, "Module internal references are inconsistent"), + Error::NoTypeSection => write!(f, "No type section in the module"), + Error::NoExportSection => write!(f, "No export section in the module"), + Error::NoCodeSection => write!(f, "No code section inthe module"), + Error::InvalidCreateSignature(sym) => write!(f, "Exported symbol `{}` has invalid signature, should be () -> ()", sym), + Error::InvalidCreateMember(sym) => write!(f, "Exported symbol `{}` should be a function", sym), + Error::NoCreateSymbol(sym) => write!(f, "No exported `{}` symbol", sym), + Error::NoImportSection => write!(f, "No import section in the module"), + } + } } /// If a pwasm module has an exported function matching "create" symbol we want to pack it into "constructor". @@ -46,290 +46,290 @@ impl fmt::Display for Error { /// `ctor_module` is the constructor which should return `raw_module` pub fn pack_instance(raw_module: Vec, mut ctor_module: elements::Module, target: &TargetRuntime) -> Result { - // Total number of constructor module import functions - let ctor_import_functions = ctor_module.import_section().map(|x| x.functions()).unwrap_or(0); + // Total number of constructor module import functions + let ctor_import_functions = ctor_module.import_section().map(|x| x.functions()).unwrap_or(0); - // We need to find an internal ID of function which is exported as `symbols().create` - // in order to find it in the Code section of the module - let mut create_func_id = { - let found_entry = ctor_module.export_section().ok_or(Error::NoExportSection)?.entries().iter() - .find(|entry| target.symbols().create == entry.field()).ok_or_else(|| Error::NoCreateSymbol(target.symbols().create))?; + // We need to find an internal ID of function which is exported as `symbols().create` + // in order to find it in the Code section of the module + let mut create_func_id = { + let found_entry = ctor_module.export_section().ok_or(Error::NoExportSection)?.entries().iter() + .find(|entry| target.symbols().create == entry.field()).ok_or_else(|| Error::NoCreateSymbol(target.symbols().create))?; - let function_index: usize = match found_entry.internal() { - &Internal::Function(index) => index as usize, - _ => { return Err(Error::InvalidCreateMember(target.symbols().create)) }, - }; + let function_index: usize = match found_entry.internal() { + &Internal::Function(index) => index as usize, + _ => { return Err(Error::InvalidCreateMember(target.symbols().create)) }, + }; - // Calculates a function index within module's function section - let function_internal_index = function_index - ctor_import_functions; + // Calculates a function index within module's function section + let function_internal_index = function_index - ctor_import_functions; - // Constructor should be of signature `func()` (void), fail otherwise - let type_id = ctor_module.function_section().ok_or(Error::NoCodeSection)? - .entries().get(function_index - ctor_import_functions).ok_or(Error::MalformedModule)? - .type_ref(); + // Constructor should be of signature `func()` (void), fail otherwise + let type_id = ctor_module.function_section().ok_or(Error::NoCodeSection)? + .entries().get(function_index - ctor_import_functions).ok_or(Error::MalformedModule)? + .type_ref(); - let &elements::Type::Function(ref func) = ctor_module.type_section().ok_or(Error::NoTypeSection)? - .types().get(type_id as usize).ok_or(Error::MalformedModule)?; + let &elements::Type::Function(ref func) = ctor_module.type_section().ok_or(Error::NoTypeSection)? + .types().get(type_id as usize).ok_or(Error::MalformedModule)?; - // Deploy should have no arguments and also should return nothing - if !func.params().is_empty() { - return Err(Error::InvalidCreateSignature(target.symbols().create)); - } - if func.return_type().is_some() { - return Err(Error::InvalidCreateSignature(target.symbols().create)); - } + // Deploy should have no arguments and also should return nothing + if !func.params().is_empty() { + return Err(Error::InvalidCreateSignature(target.symbols().create)); + } + if func.return_type().is_some() { + return Err(Error::InvalidCreateSignature(target.symbols().create)); + } - function_internal_index - }; + function_internal_index + }; - let ret_function_id = { - let mut id = 0; - let mut found = false; - for entry in ctor_module.import_section().ok_or(Error::NoImportSection)?.entries().iter() { - if let External::Function(_) = *entry.external() { - if entry.field() == target.symbols().ret { found = true; break; } - else { id += 1; } - } - } - if !found { - let mut mbuilder = builder::from_module(ctor_module); - let import_sig = mbuilder.push_signature( - builder::signature() - .param().i32().param().i32() - .build_sig() - ); + let ret_function_id = { + let mut id = 0; + let mut found = false; + for entry in ctor_module.import_section().ok_or(Error::NoImportSection)?.entries().iter() { + if let External::Function(_) = *entry.external() { + if entry.field() == target.symbols().ret { found = true; break; } + else { id += 1; } + } + } + if !found { + let mut mbuilder = builder::from_module(ctor_module); + let import_sig = mbuilder.push_signature( + builder::signature() + .param().i32().param().i32() + .build_sig() + ); - mbuilder.push_import( - builder::import() - .module("env") - .field(&target.symbols().ret) - .external().func(import_sig) - .build() - ); + mbuilder.push_import( + builder::import() + .module("env") + .field(&target.symbols().ret) + .external().func(import_sig) + .build() + ); - ctor_module = mbuilder.build(); + ctor_module = mbuilder.build(); - let ret_func = ctor_module.import_count(ImportCountType::Function) as u32 - 1; + let ret_func = ctor_module.import_count(ImportCountType::Function) as u32 - 1; - for section in ctor_module.sections_mut() { - match *section { - elements::Section::Code(ref mut code_section) => { - for ref mut func_body in code_section.bodies_mut() { - update_call_index(func_body.code_mut(), ret_func); - } - }, - elements::Section::Export(ref mut export_section) => { - for ref mut export in export_section.entries_mut() { - if let &mut elements::Internal::Function(ref mut func_index) = export.internal_mut() { - if *func_index >= ret_func { *func_index += 1} - } - } - }, - elements::Section::Element(ref mut elements_section) => { - for ref mut segment in elements_section.entries_mut() { - // update all indirect call addresses initial values - for func_index in segment.members_mut() { - if *func_index >= ret_func { *func_index += 1} - } - } - }, - _ => { } - } - } + for section in ctor_module.sections_mut() { + match *section { + elements::Section::Code(ref mut code_section) => { + for ref mut func_body in code_section.bodies_mut() { + update_call_index(func_body.code_mut(), ret_func); + } + }, + elements::Section::Export(ref mut export_section) => { + for ref mut export in export_section.entries_mut() { + if let &mut elements::Internal::Function(ref mut func_index) = export.internal_mut() { + if *func_index >= ret_func { *func_index += 1} + } + } + }, + elements::Section::Element(ref mut elements_section) => { + for ref mut segment in elements_section.entries_mut() { + // update all indirect call addresses initial values + for func_index in segment.members_mut() { + if *func_index >= ret_func { *func_index += 1} + } + } + }, + _ => { } + } + } - create_func_id += 1; - ret_func - } - else { id } - }; + create_func_id += 1; + ret_func + } + else { id } + }; - // If new function is put in ctor module, it will have this callable index - let last_function_index = ctor_module.functions_space(); + // If new function is put in ctor module, it will have this callable index + let last_function_index = ctor_module.functions_space(); - // We ensure here that module has the DataSection - if ctor_module - .sections() - .iter() - .find(|section| match **section { Section::Data(ref _d) => true, _ => false }) - .is_none() { - // DataSection has to be the last non-custom section according the to the spec - ctor_module.sections_mut().push(Section::Data(DataSection::with_entries(vec![]))); - } + // We ensure here that module has the DataSection + if ctor_module + .sections() + .iter() + .find(|section| match **section { Section::Data(ref _d) => true, _ => false }) + .is_none() { + // DataSection has to be the last non-custom section according the to the spec + ctor_module.sections_mut().push(Section::Data(DataSection::with_entries(vec![]))); + } - // Code data address is an address where we put the contract's code (raw_module) - let mut code_data_address = 0i32; + // Code data address is an address where we put the contract's code (raw_module) + let mut code_data_address = 0i32; - for section in ctor_module.sections_mut() { - if let &mut Section::Data(ref mut data_section) = section { - let (index, offset) = if let Some(ref entry) = data_section.entries().iter().last() { - if let Instruction::I32Const(offst) = entry.offset().code()[0] { - let len = entry.value().len() as i32; - let offst = offst as i32; - (entry.index(), offst + (len + 4) - len % 4) - } else { - (0, 0) - } - } else { - (0, 0) - }; - let code_data = DataSegment::new( - index, - InitExpr::new(vec![Instruction::I32Const(offset), Instruction::End]), - raw_module.clone() - ); - data_section.entries_mut().push(code_data); - code_data_address = offset; - } - } + for section in ctor_module.sections_mut() { + if let &mut Section::Data(ref mut data_section) = section { + let (index, offset) = if let Some(ref entry) = data_section.entries().iter().last() { + if let Instruction::I32Const(offst) = entry.offset().code()[0] { + let len = entry.value().len() as i32; + let offst = offst as i32; + (entry.index(), offst + (len + 4) - len % 4) + } else { + (0, 0) + } + } else { + (0, 0) + }; + let code_data = DataSegment::new( + index, + InitExpr::new(vec![Instruction::I32Const(offset), Instruction::End]), + raw_module.clone() + ); + data_section.entries_mut().push(code_data); + code_data_address = offset; + } + } - let mut new_module = builder::from_module(ctor_module) - .function() - .signature().build() - .body().with_instructions(elements::Instructions::new( - vec![ - Instruction::Call((create_func_id + ctor_import_functions) as u32), - Instruction::I32Const(code_data_address), - Instruction::I32Const(raw_module.len() as i32), - Instruction::Call(ret_function_id as u32), - Instruction::End, - ])).build() - .build() - .build(); + let mut new_module = builder::from_module(ctor_module) + .function() + .signature().build() + .body().with_instructions(elements::Instructions::new( + vec![ + Instruction::Call((create_func_id + ctor_import_functions) as u32), + Instruction::I32Const(code_data_address), + Instruction::I32Const(raw_module.len() as i32), + Instruction::Call(ret_function_id as u32), + Instruction::End, + ])).build() + .build() + .build(); - for section in new_module.sections_mut() { - if let &mut Section::Export(ref mut export_section) = section { - for entry in export_section.entries_mut().iter_mut() { - if target.symbols().create == entry.field() { - // change `create` symbol export name into default `call` symbol name. - *entry.field_mut() = target.symbols().call.to_owned(); - *entry.internal_mut() = elements::Internal::Function(last_function_index as u32); - } - } - } - }; + for section in new_module.sections_mut() { + if let &mut Section::Export(ref mut export_section) = section { + for entry in export_section.entries_mut().iter_mut() { + if target.symbols().create == entry.field() { + // change `create` symbol export name into default `call` symbol name. + *entry.field_mut() = target.symbols().call.to_owned(); + *entry.internal_mut() = elements::Internal::Function(last_function_index as u32); + } + } + } + }; - Ok(new_module) + Ok(new_module) } #[cfg(test)] mod test { - extern crate parity_wasm; + extern crate parity_wasm; - use parity_wasm::builder; - use super::*; - use super::super::optimize; + use parity_wasm::builder; + use super::*; + use super::super::optimize; - fn test_packer(mut module: elements::Module, target_runtime: &TargetRuntime) { - let mut ctor_module = module.clone(); - optimize(&mut module, vec![target_runtime.symbols().call]).expect("Optimizer to finish without errors"); - optimize(&mut ctor_module, vec![target_runtime.symbols().create]).expect("Optimizer to finish without errors"); + fn test_packer(mut module: elements::Module, target_runtime: &TargetRuntime) { + let mut ctor_module = module.clone(); + optimize(&mut module, vec![target_runtime.symbols().call]).expect("Optimizer to finish without errors"); + optimize(&mut ctor_module, vec![target_runtime.symbols().create]).expect("Optimizer to finish without errors"); - let raw_module = parity_wasm::serialize(module).unwrap(); - let ctor_module = pack_instance(raw_module.clone(), ctor_module, target_runtime).expect("Packing failed"); + let raw_module = parity_wasm::serialize(module).unwrap(); + let ctor_module = pack_instance(raw_module.clone(), ctor_module, target_runtime).expect("Packing failed"); - let data_section = ctor_module.data_section().expect("Packed module has to have a data section"); - let data_segment = data_section.entries().iter().last().expect("Packed module has to have a data section with at least one entry"); - assert!(data_segment.value() == AsRef::<[u8]>::as_ref(&raw_module), "Last data segment should be equal to the raw module"); - } + let data_section = ctor_module.data_section().expect("Packed module has to have a data section"); + let data_segment = data_section.entries().iter().last().expect("Packed module has to have a data section with at least one entry"); + assert!(data_segment.value() == AsRef::<[u8]>::as_ref(&raw_module), "Last data segment should be equal to the raw module"); + } - #[test] - fn no_data_section() { + #[test] + fn no_data_section() { let target_runtime = TargetRuntime::pwasm(); - test_packer(builder::module() - .import() - .module("env") - .field("memory") - .external().memory(1 as u32, Some(1 as u32)) - .build() - .function() - .signature() - .params().i32().i32().build() - .build() - .body().build() - .build() - .function() - .signature().build() - .body() - .with_instructions(elements::Instructions::new( - vec![ - elements::Instruction::End - ] - )) - .build() - .build() - .function() - .signature().build() - .body() - .with_instructions(elements::Instructions::new( - vec![ - elements::Instruction::End - ] - )) - .build() - .build() - .export() - .field(target_runtime.symbols().call) - .internal().func(1) - .build() - .export() - .field(target_runtime.symbols().create) - .internal().func(2) - .build() - .build(), + test_packer(builder::module() + .import() + .module("env") + .field("memory") + .external().memory(1 as u32, Some(1 as u32)) + .build() + .function() + .signature() + .params().i32().i32().build() + .build() + .body().build() + .build() + .function() + .signature().build() + .body() + .with_instructions(elements::Instructions::new( + vec![ + elements::Instruction::End + ] + )) + .build() + .build() + .function() + .signature().build() + .body() + .with_instructions(elements::Instructions::new( + vec![ + elements::Instruction::End + ] + )) + .build() + .build() + .export() + .field(target_runtime.symbols().call) + .internal().func(1) + .build() + .export() + .field(target_runtime.symbols().create) + .internal().func(2) + .build() + .build(), &target_runtime, - ); - } + ); + } - #[test] - fn with_data_section() { + #[test] + fn with_data_section() { let target_runtime = TargetRuntime::pwasm(); - test_packer(builder::module() - .import() - .module("env") - .field("memory") - .external().memory(1 as u32, Some(1 as u32)) - .build() - .data() - .offset(elements::Instruction::I32Const(16)).value(vec![0u8]) - .build() - .function() - .signature() - .params().i32().i32().build() - .build() - .body().build() - .build() - .function() - .signature().build() - .body() - .with_instructions(elements::Instructions::new( - vec![ - elements::Instruction::End - ] - )) - .build() - .build() - .function() - .signature().build() - .body() - .with_instructions(elements::Instructions::new( - vec![ - elements::Instruction::End - ] - )) - .build() - .build() - .export() - .field(target_runtime.symbols().call) - .internal().func(1) - .build() - .export() - .field(target_runtime.symbols().create) - .internal().func(2) - .build() - .build(), + test_packer(builder::module() + .import() + .module("env") + .field("memory") + .external().memory(1 as u32, Some(1 as u32)) + .build() + .data() + .offset(elements::Instruction::I32Const(16)).value(vec![0u8]) + .build() + .function() + .signature() + .params().i32().i32().build() + .build() + .body().build() + .build() + .function() + .signature().build() + .body() + .with_instructions(elements::Instructions::new( + vec![ + elements::Instruction::End + ] + )) + .build() + .build() + .function() + .signature().build() + .body() + .with_instructions(elements::Instructions::new( + vec![ + elements::Instruction::End + ] + )) + .build() + .build() + .export() + .field(target_runtime.symbols().call) + .internal().func(1) + .build() + .export() + .field(target_runtime.symbols().create) + .internal().func(2) + .build() + .build(), &target_runtime, - ); - } + ); + } } diff --git a/src/rules.rs b/src/rules.rs index 673812d..78fe153 100644 --- a/src/rules.rs +++ b/src/rules.rs @@ -9,307 +9,307 @@ pub struct UnknownInstruction; #[derive(Debug, PartialEq, Eq, Copy, Clone)] pub enum Metering { - Regular, - Forbidden, - Fixed(u32), + Regular, + Forbidden, + Fixed(u32), } #[derive(Debug, Hash, PartialEq, Eq, PartialOrd, Ord, Copy, Clone)] pub enum InstructionType { - Bit, - Add, - Mul, - Div, - Load, - Store, - Const, - FloatConst, - Local, - Global, - ControlFlow, - IntegerComparsion, - FloatComparsion, - Float, - Conversion, - FloatConversion, - Reinterpretation, - Unreachable, - Nop, - CurrentMemory, - GrowMemory, + Bit, + Add, + Mul, + Div, + Load, + Store, + Const, + FloatConst, + Local, + Global, + ControlFlow, + IntegerComparsion, + FloatComparsion, + Float, + Conversion, + FloatConversion, + Reinterpretation, + Unreachable, + Nop, + CurrentMemory, + GrowMemory, } impl ::std::str::FromStr for InstructionType { - type Err = UnknownInstruction; + type Err = UnknownInstruction; - fn from_str(s: &str) -> Result { - match s { - "bit" => Ok(InstructionType::Bit), - "add" => Ok(InstructionType::Add), - "mul" => Ok(InstructionType::Mul), - "div" => Ok(InstructionType::Div), - "load" => Ok(InstructionType::Load), - "store" => Ok(InstructionType::Store), - "const" => Ok(InstructionType::Const), - "local" => Ok(InstructionType::Local), - "global" => Ok(InstructionType::Global), - "flow" => Ok(InstructionType::ControlFlow), - "integer_comp" => Ok(InstructionType::IntegerComparsion), - "float_comp" => Ok(InstructionType::FloatComparsion), - "float" => Ok(InstructionType::Float), - "conversion" => Ok(InstructionType::Conversion), - "float_conversion" => Ok(InstructionType::FloatConversion), - "reinterpret" => Ok(InstructionType::Reinterpretation), - "unreachable" => Ok(InstructionType::Unreachable), - "nop" => Ok(InstructionType::Nop), - "current_mem" => Ok(InstructionType::CurrentMemory), - "grow_mem" => Ok(InstructionType::GrowMemory), - _ => Err(UnknownInstruction), - } - } + fn from_str(s: &str) -> Result { + match s { + "bit" => Ok(InstructionType::Bit), + "add" => Ok(InstructionType::Add), + "mul" => Ok(InstructionType::Mul), + "div" => Ok(InstructionType::Div), + "load" => Ok(InstructionType::Load), + "store" => Ok(InstructionType::Store), + "const" => Ok(InstructionType::Const), + "local" => Ok(InstructionType::Local), + "global" => Ok(InstructionType::Global), + "flow" => Ok(InstructionType::ControlFlow), + "integer_comp" => Ok(InstructionType::IntegerComparsion), + "float_comp" => Ok(InstructionType::FloatComparsion), + "float" => Ok(InstructionType::Float), + "conversion" => Ok(InstructionType::Conversion), + "float_conversion" => Ok(InstructionType::FloatConversion), + "reinterpret" => Ok(InstructionType::Reinterpretation), + "unreachable" => Ok(InstructionType::Unreachable), + "nop" => Ok(InstructionType::Nop), + "current_mem" => Ok(InstructionType::CurrentMemory), + "grow_mem" => Ok(InstructionType::GrowMemory), + _ => Err(UnknownInstruction), + } + } } impl InstructionType { - pub fn op(instruction: &elements::Instruction) -> Self { - use parity_wasm::elements::Instruction::*; + pub fn op(instruction: &elements::Instruction) -> Self { + use parity_wasm::elements::Instruction::*; - match *instruction { - Unreachable => InstructionType::Unreachable, - Nop => InstructionType::Nop, - Block(_) => InstructionType::ControlFlow, - Loop(_) => InstructionType::ControlFlow, - If(_) => InstructionType::ControlFlow, - Else => InstructionType::ControlFlow, - End => InstructionType::ControlFlow, - Br(_) => InstructionType::ControlFlow, - BrIf(_) => InstructionType::ControlFlow, - BrTable(_, _) => InstructionType::ControlFlow, - Return => InstructionType::ControlFlow, - Call(_) => InstructionType::ControlFlow, - CallIndirect(_, _) => InstructionType::ControlFlow, - Drop => InstructionType::ControlFlow, - Select => InstructionType::ControlFlow, + match *instruction { + Unreachable => InstructionType::Unreachable, + Nop => InstructionType::Nop, + Block(_) => InstructionType::ControlFlow, + Loop(_) => InstructionType::ControlFlow, + If(_) => InstructionType::ControlFlow, + Else => InstructionType::ControlFlow, + End => InstructionType::ControlFlow, + Br(_) => InstructionType::ControlFlow, + BrIf(_) => InstructionType::ControlFlow, + BrTable(_, _) => InstructionType::ControlFlow, + Return => InstructionType::ControlFlow, + Call(_) => InstructionType::ControlFlow, + CallIndirect(_, _) => InstructionType::ControlFlow, + Drop => InstructionType::ControlFlow, + Select => InstructionType::ControlFlow, - GetLocal(_) => InstructionType::Local, - SetLocal(_) => InstructionType::Local, - TeeLocal(_) => InstructionType::Local, - GetGlobal(_) => InstructionType::Local, - SetGlobal(_) => InstructionType::Local, + GetLocal(_) => InstructionType::Local, + SetLocal(_) => InstructionType::Local, + TeeLocal(_) => InstructionType::Local, + GetGlobal(_) => InstructionType::Local, + SetGlobal(_) => InstructionType::Local, - I32Load(_, _) => InstructionType::Load, - I64Load(_, _) => InstructionType::Load, - F32Load(_, _) => InstructionType::Load, - F64Load(_, _) => InstructionType::Load, - I32Load8S(_, _) => InstructionType::Load, - I32Load8U(_, _) => InstructionType::Load, - I32Load16S(_, _) => InstructionType::Load, - I32Load16U(_, _) => InstructionType::Load, - I64Load8S(_, _) => InstructionType::Load, - I64Load8U(_, _) => InstructionType::Load, - I64Load16S(_, _) => InstructionType::Load, - I64Load16U(_, _) => InstructionType::Load, - I64Load32S(_, _) => InstructionType::Load, - I64Load32U(_, _) => InstructionType::Load, + I32Load(_, _) => InstructionType::Load, + I64Load(_, _) => InstructionType::Load, + F32Load(_, _) => InstructionType::Load, + F64Load(_, _) => InstructionType::Load, + I32Load8S(_, _) => InstructionType::Load, + I32Load8U(_, _) => InstructionType::Load, + I32Load16S(_, _) => InstructionType::Load, + I32Load16U(_, _) => InstructionType::Load, + I64Load8S(_, _) => InstructionType::Load, + I64Load8U(_, _) => InstructionType::Load, + I64Load16S(_, _) => InstructionType::Load, + I64Load16U(_, _) => InstructionType::Load, + I64Load32S(_, _) => InstructionType::Load, + I64Load32U(_, _) => InstructionType::Load, - I32Store(_, _) => InstructionType::Store, - I64Store(_, _) => InstructionType::Store, - F32Store(_, _) => InstructionType::Store, - F64Store(_, _) => InstructionType::Store, - I32Store8(_, _) => InstructionType::Store, - I32Store16(_, _) => InstructionType::Store, - I64Store8(_, _) => InstructionType::Store, - I64Store16(_, _) => InstructionType::Store, - I64Store32(_, _) => InstructionType::Store, + I32Store(_, _) => InstructionType::Store, + I64Store(_, _) => InstructionType::Store, + F32Store(_, _) => InstructionType::Store, + F64Store(_, _) => InstructionType::Store, + I32Store8(_, _) => InstructionType::Store, + I32Store16(_, _) => InstructionType::Store, + I64Store8(_, _) => InstructionType::Store, + I64Store16(_, _) => InstructionType::Store, + I64Store32(_, _) => InstructionType::Store, - CurrentMemory(_) => InstructionType::CurrentMemory, - GrowMemory(_) => InstructionType::GrowMemory, + CurrentMemory(_) => InstructionType::CurrentMemory, + GrowMemory(_) => InstructionType::GrowMemory, - I32Const(_) => InstructionType::Const, - I64Const(_) => InstructionType::Const, + I32Const(_) => InstructionType::Const, + I64Const(_) => InstructionType::Const, - F32Const(_) => InstructionType::FloatConst, - F64Const(_) => InstructionType::FloatConst, + F32Const(_) => InstructionType::FloatConst, + F64Const(_) => InstructionType::FloatConst, - I32Eqz => InstructionType::IntegerComparsion, - I32Eq => InstructionType::IntegerComparsion, - I32Ne => InstructionType::IntegerComparsion, - I32LtS => InstructionType::IntegerComparsion, - I32LtU => InstructionType::IntegerComparsion, - I32GtS => InstructionType::IntegerComparsion, - I32GtU => InstructionType::IntegerComparsion, - I32LeS => InstructionType::IntegerComparsion, - I32LeU => InstructionType::IntegerComparsion, - I32GeS => InstructionType::IntegerComparsion, - I32GeU => InstructionType::IntegerComparsion, + I32Eqz => InstructionType::IntegerComparsion, + I32Eq => InstructionType::IntegerComparsion, + I32Ne => InstructionType::IntegerComparsion, + I32LtS => InstructionType::IntegerComparsion, + I32LtU => InstructionType::IntegerComparsion, + I32GtS => InstructionType::IntegerComparsion, + I32GtU => InstructionType::IntegerComparsion, + I32LeS => InstructionType::IntegerComparsion, + I32LeU => InstructionType::IntegerComparsion, + I32GeS => InstructionType::IntegerComparsion, + I32GeU => InstructionType::IntegerComparsion, - I64Eqz => InstructionType::IntegerComparsion, - I64Eq => InstructionType::IntegerComparsion, - I64Ne => InstructionType::IntegerComparsion, - I64LtS => InstructionType::IntegerComparsion, - I64LtU => InstructionType::IntegerComparsion, - I64GtS => InstructionType::IntegerComparsion, - I64GtU => InstructionType::IntegerComparsion, - I64LeS => InstructionType::IntegerComparsion, - I64LeU => InstructionType::IntegerComparsion, - I64GeS => InstructionType::IntegerComparsion, - I64GeU => InstructionType::IntegerComparsion, + I64Eqz => InstructionType::IntegerComparsion, + I64Eq => InstructionType::IntegerComparsion, + I64Ne => InstructionType::IntegerComparsion, + I64LtS => InstructionType::IntegerComparsion, + I64LtU => InstructionType::IntegerComparsion, + I64GtS => InstructionType::IntegerComparsion, + I64GtU => InstructionType::IntegerComparsion, + I64LeS => InstructionType::IntegerComparsion, + I64LeU => InstructionType::IntegerComparsion, + I64GeS => InstructionType::IntegerComparsion, + I64GeU => InstructionType::IntegerComparsion, - F32Eq => InstructionType::FloatComparsion, - F32Ne => InstructionType::FloatComparsion, - F32Lt => InstructionType::FloatComparsion, - F32Gt => InstructionType::FloatComparsion, - F32Le => InstructionType::FloatComparsion, - F32Ge => InstructionType::FloatComparsion, + F32Eq => InstructionType::FloatComparsion, + F32Ne => InstructionType::FloatComparsion, + F32Lt => InstructionType::FloatComparsion, + F32Gt => InstructionType::FloatComparsion, + F32Le => InstructionType::FloatComparsion, + F32Ge => InstructionType::FloatComparsion, - F64Eq => InstructionType::FloatComparsion, - F64Ne => InstructionType::FloatComparsion, - F64Lt => InstructionType::FloatComparsion, - F64Gt => InstructionType::FloatComparsion, - F64Le => InstructionType::FloatComparsion, - F64Ge => InstructionType::FloatComparsion, + F64Eq => InstructionType::FloatComparsion, + F64Ne => InstructionType::FloatComparsion, + F64Lt => InstructionType::FloatComparsion, + F64Gt => InstructionType::FloatComparsion, + F64Le => InstructionType::FloatComparsion, + F64Ge => InstructionType::FloatComparsion, - I32Clz => InstructionType::Bit, - I32Ctz => InstructionType::Bit, - I32Popcnt => InstructionType::Bit, - I32Add => InstructionType::Add, - I32Sub => InstructionType::Add, - I32Mul => InstructionType::Mul, - I32DivS => InstructionType::Div, - I32DivU => InstructionType::Div, - I32RemS => InstructionType::Div, - I32RemU => InstructionType::Div, - I32And => InstructionType::Bit, - I32Or => InstructionType::Bit, - I32Xor => InstructionType::Bit, - I32Shl => InstructionType::Bit, - I32ShrS => InstructionType::Bit, - I32ShrU => InstructionType::Bit, - I32Rotl => InstructionType::Bit, - I32Rotr => InstructionType::Bit, + I32Clz => InstructionType::Bit, + I32Ctz => InstructionType::Bit, + I32Popcnt => InstructionType::Bit, + I32Add => InstructionType::Add, + I32Sub => InstructionType::Add, + I32Mul => InstructionType::Mul, + I32DivS => InstructionType::Div, + I32DivU => InstructionType::Div, + I32RemS => InstructionType::Div, + I32RemU => InstructionType::Div, + I32And => InstructionType::Bit, + I32Or => InstructionType::Bit, + I32Xor => InstructionType::Bit, + I32Shl => InstructionType::Bit, + I32ShrS => InstructionType::Bit, + I32ShrU => InstructionType::Bit, + I32Rotl => InstructionType::Bit, + I32Rotr => InstructionType::Bit, - I64Clz => InstructionType::Bit, - I64Ctz => InstructionType::Bit, - I64Popcnt => InstructionType::Bit, - I64Add => InstructionType::Add, - I64Sub => InstructionType::Add, - I64Mul => InstructionType::Mul, - I64DivS => InstructionType::Div, - I64DivU => InstructionType::Div, - I64RemS => InstructionType::Div, - I64RemU => InstructionType::Div, - I64And => InstructionType::Bit, - I64Or => InstructionType::Bit, - I64Xor => InstructionType::Bit, - I64Shl => InstructionType::Bit, - I64ShrS => InstructionType::Bit, - I64ShrU => InstructionType::Bit, - I64Rotl => InstructionType::Bit, - I64Rotr => InstructionType::Bit, + I64Clz => InstructionType::Bit, + I64Ctz => InstructionType::Bit, + I64Popcnt => InstructionType::Bit, + I64Add => InstructionType::Add, + I64Sub => InstructionType::Add, + I64Mul => InstructionType::Mul, + I64DivS => InstructionType::Div, + I64DivU => InstructionType::Div, + I64RemS => InstructionType::Div, + I64RemU => InstructionType::Div, + I64And => InstructionType::Bit, + I64Or => InstructionType::Bit, + I64Xor => InstructionType::Bit, + I64Shl => InstructionType::Bit, + I64ShrS => InstructionType::Bit, + I64ShrU => InstructionType::Bit, + I64Rotl => InstructionType::Bit, + I64Rotr => InstructionType::Bit, - F32Abs => InstructionType::Float, - F32Neg => InstructionType::Float, - F32Ceil => InstructionType::Float, - F32Floor => InstructionType::Float, - F32Trunc => InstructionType::Float, - F32Nearest => InstructionType::Float, - F32Sqrt => InstructionType::Float, - F32Add => InstructionType::Float, - F32Sub => InstructionType::Float, - F32Mul => InstructionType::Float, - F32Div => InstructionType::Float, - F32Min => InstructionType::Float, - F32Max => InstructionType::Float, - F32Copysign => InstructionType::Float, - F64Abs => InstructionType::Float, - F64Neg => InstructionType::Float, - F64Ceil => InstructionType::Float, - F64Floor => InstructionType::Float, - F64Trunc => InstructionType::Float, - F64Nearest => InstructionType::Float, - F64Sqrt => InstructionType::Float, - F64Add => InstructionType::Float, - F64Sub => InstructionType::Float, - F64Mul => InstructionType::Float, - F64Div => InstructionType::Float, - F64Min => InstructionType::Float, - F64Max => InstructionType::Float, - F64Copysign => InstructionType::Float, + F32Abs => InstructionType::Float, + F32Neg => InstructionType::Float, + F32Ceil => InstructionType::Float, + F32Floor => InstructionType::Float, + F32Trunc => InstructionType::Float, + F32Nearest => InstructionType::Float, + F32Sqrt => InstructionType::Float, + F32Add => InstructionType::Float, + F32Sub => InstructionType::Float, + F32Mul => InstructionType::Float, + F32Div => InstructionType::Float, + F32Min => InstructionType::Float, + F32Max => InstructionType::Float, + F32Copysign => InstructionType::Float, + F64Abs => InstructionType::Float, + F64Neg => InstructionType::Float, + F64Ceil => InstructionType::Float, + F64Floor => InstructionType::Float, + F64Trunc => InstructionType::Float, + F64Nearest => InstructionType::Float, + F64Sqrt => InstructionType::Float, + F64Add => InstructionType::Float, + F64Sub => InstructionType::Float, + F64Mul => InstructionType::Float, + F64Div => InstructionType::Float, + F64Min => InstructionType::Float, + F64Max => InstructionType::Float, + F64Copysign => InstructionType::Float, - I32WrapI64 => InstructionType::Conversion, - I64ExtendSI32 => InstructionType::Conversion, - I64ExtendUI32 => InstructionType::Conversion, + I32WrapI64 => InstructionType::Conversion, + I64ExtendSI32 => InstructionType::Conversion, + I64ExtendUI32 => InstructionType::Conversion, - I32TruncSF32 => InstructionType::FloatConversion, - I32TruncUF32 => InstructionType::FloatConversion, - I32TruncSF64 => InstructionType::FloatConversion, - I32TruncUF64 => InstructionType::FloatConversion, - I64TruncSF32 => InstructionType::FloatConversion, - I64TruncUF32 => InstructionType::FloatConversion, - I64TruncSF64 => InstructionType::FloatConversion, - I64TruncUF64 => InstructionType::FloatConversion, - F32ConvertSI32 => InstructionType::FloatConversion, - F32ConvertUI32 => InstructionType::FloatConversion, - F32ConvertSI64 => InstructionType::FloatConversion, - F32ConvertUI64 => InstructionType::FloatConversion, - F32DemoteF64 => InstructionType::FloatConversion, - F64ConvertSI32 => InstructionType::FloatConversion, - F64ConvertUI32 => InstructionType::FloatConversion, - F64ConvertSI64 => InstructionType::FloatConversion, - F64ConvertUI64 => InstructionType::FloatConversion, - F64PromoteF32 => InstructionType::FloatConversion, + I32TruncSF32 => InstructionType::FloatConversion, + I32TruncUF32 => InstructionType::FloatConversion, + I32TruncSF64 => InstructionType::FloatConversion, + I32TruncUF64 => InstructionType::FloatConversion, + I64TruncSF32 => InstructionType::FloatConversion, + I64TruncUF32 => InstructionType::FloatConversion, + I64TruncSF64 => InstructionType::FloatConversion, + I64TruncUF64 => InstructionType::FloatConversion, + F32ConvertSI32 => InstructionType::FloatConversion, + F32ConvertUI32 => InstructionType::FloatConversion, + F32ConvertSI64 => InstructionType::FloatConversion, + F32ConvertUI64 => InstructionType::FloatConversion, + F32DemoteF64 => InstructionType::FloatConversion, + F64ConvertSI32 => InstructionType::FloatConversion, + F64ConvertUI32 => InstructionType::FloatConversion, + F64ConvertSI64 => InstructionType::FloatConversion, + F64ConvertUI64 => InstructionType::FloatConversion, + F64PromoteF32 => InstructionType::FloatConversion, - I32ReinterpretF32 => InstructionType::Reinterpretation, - I64ReinterpretF64 => InstructionType::Reinterpretation, - F32ReinterpretI32 => InstructionType::Reinterpretation, - F64ReinterpretI64 => InstructionType::Reinterpretation, - } - } + I32ReinterpretF32 => InstructionType::Reinterpretation, + I64ReinterpretF64 => InstructionType::Reinterpretation, + F32ReinterpretI32 => InstructionType::Reinterpretation, + F64ReinterpretI64 => InstructionType::Reinterpretation, + } + } } #[derive(Debug)] pub struct Set { - regular: u32, - entries: Map, - grow: u32, + regular: u32, + entries: Map, + grow: u32, } impl Default for Set { - fn default() -> Self { - Set { - regular: 1, - entries: Map::new(), - grow: 0, - } - } + fn default() -> Self { + Set { + regular: 1, + entries: Map::new(), + grow: 0, + } + } } impl Set { - pub fn new(regular: u32, entries: Map) -> Self { - Set { regular: regular, entries: entries, grow: 0 } - } + pub fn new(regular: u32, entries: Map) -> Self { + Set { regular: regular, entries: entries, grow: 0 } + } - pub fn process(&self, instruction: &elements::Instruction) -> Result { - match self.entries.get(&InstructionType::op(instruction)).map(|x| *x) { - None | Some(Metering::Regular) => Ok(self.regular), - Some(Metering::Forbidden) => Err(()), - Some(Metering::Fixed(val)) => Ok(val), - } - } + pub fn process(&self, instruction: &elements::Instruction) -> Result { + match self.entries.get(&InstructionType::op(instruction)).map(|x| *x) { + None | Some(Metering::Regular) => Ok(self.regular), + Some(Metering::Forbidden) => Err(()), + Some(Metering::Fixed(val)) => Ok(val), + } + } - pub fn grow_cost(&self) -> u32 { - self.grow - } + pub fn grow_cost(&self) -> u32 { + self.grow + } - pub fn with_grow_cost(mut self, val: u32) -> Self { - self.grow = val; - self - } + pub fn with_grow_cost(mut self, val: u32) -> Self { + self.grow = val; + self + } - pub fn with_forbidden_floats(mut self) -> Self { - self.entries.insert(InstructionType::Float, Metering::Forbidden); - self.entries.insert(InstructionType::FloatComparsion, Metering::Forbidden); - self.entries.insert(InstructionType::FloatConst, Metering::Forbidden); - self.entries.insert(InstructionType::FloatConversion, Metering::Forbidden); - self - } + pub fn with_forbidden_floats(mut self) -> Self { + self.entries.insert(InstructionType::Float, Metering::Forbidden); + self.entries.insert(InstructionType::FloatComparsion, Metering::Forbidden); + self.entries.insert(InstructionType::FloatConst, Metering::Forbidden); + self.entries.insert(InstructionType::FloatConversion, Metering::Forbidden); + self + } } diff --git a/src/stack_height/max_height.rs b/src/stack_height/max_height.rs index eae4ad8..834f445 100644 --- a/src/stack_height/max_height.rs +++ b/src/stack_height/max_height.rs @@ -497,19 +497,19 @@ mod tests { (module (memory 0) (func - ;; Push two values and then pop them. - ;; This will make max depth to be equal to 2. - i32.const 0 - i32.const 1 - drop - drop + ;; Push two values and then pop them. + ;; This will make max depth to be equal to 2. + i32.const 0 + i32.const 1 + drop + drop - ;; Code after `unreachable` shouldn't have an effect - ;; on the max depth. - unreachable - i32.const 0 - i32.const 1 - i32.const 2 + ;; Code after `unreachable` shouldn't have an effect + ;; on the max depth. + unreachable + i32.const 0 + i32.const 1 + i32.const 2 ) ) "#; diff --git a/src/stack_height/mod.rs b/src/stack_height/mod.rs index 165e3b9..209ba53 100644 --- a/src/stack_height/mod.rs +++ b/src/stack_height/mod.rs @@ -415,11 +415,11 @@ mod tests { let module = parse_wat( r#" (module - (func (export "i32.add") (param i32 i32) (result i32) - get_local 0 + (func (export "i32.add") (param i32 i32) (result i32) + get_local 0 get_local 1 i32.add - ) + ) ) "#, ); diff --git a/tests/diff.rs b/tests/diff.rs index 0a9392e..e19f6b7 100644 --- a/tests/diff.rs +++ b/tests/diff.rs @@ -9,10 +9,10 @@ use std::path::{Path, PathBuf}; use parity_wasm::elements; fn slurp>(path: P) -> io::Result> { - let mut f = fs::File::open(path)?; - let mut buf = vec![]; - f.read_to_end(&mut buf)?; - Ok(buf) + let mut f = fs::File::open(path)?; + let mut buf = vec![]; + f.read_to_end(&mut buf)?; + Ok(buf) } fn dump>(path: P, buf: &[u8]) -> io::Result<()> {