From f915a89b9dfce49adecee775972f18777c285311 Mon Sep 17 00:00:00 2001 From: NikVolf Date: Tue, 23 Jan 2018 22:47:20 +0300 Subject: [PATCH] spaces to tabs --- examples/build.rs | 62 +- examples/data.rs | 58 +- examples/exports.rs | 116 +- examples/info.rs | 66 +- examples/inject.rs | 92 +- examples/interpret.rs | 42 +- examples/invoke.rs | 123 +- examples/roundtrip.rs | 36 +- fuzz/fuzz_targets/deserialize.rs | 16 +- spec/src/fixtures.rs | 24 +- spec/src/run.rs | 458 +++---- spec/src/test.rs | 170 +-- src/builder/code.rs | 492 +++---- src/builder/data.rs | 76 +- src/builder/export.rs | 146 +-- src/builder/global.rs | 116 +- src/builder/import.rs | 170 +-- src/builder/memory.rs | 110 +- src/builder/misc.rs | 118 +- src/builder/mod.rs | 4 +- src/builder/module.rs | 838 ++++++------ src/builder/table.rs | 110 +- src/elements/export_entry.rs | 126 +- src/elements/func.rs | 150 +-- src/elements/global_entry.rs | 62 +- src/elements/import_entry.rs | 392 +++--- src/elements/index_map.rs | 940 +++++++------- src/elements/mod.rs | 228 ++-- src/elements/module.rs | 778 +++++------ src/elements/name_section.rs | 382 +++--- src/elements/ops.rs | 2080 +++++++++++++++--------------- src/elements/primitives.rs | 1008 +++++++-------- src/elements/section.rs | 1650 ++++++++++++------------ src/elements/segment.rs | 174 +-- src/elements/types.rs | 318 ++--- src/lib.rs | 20 +- 36 files changed, 5875 insertions(+), 5876 deletions(-) diff --git a/examples/build.rs b/examples/build.rs index 5f09964..6049466 100644 --- a/examples/build.rs +++ b/examples/build.rs @@ -11,37 +11,37 @@ use parity_wasm::elements; fn main() { - // Example binary accepts one parameter which is the output file - // where generated wasm module will be written at the end of execution - let args = env::args().collect::>(); - if args.len() != 2 { - println!("Usage: {} output_file.wasm", args[0]); - return; - } + // Example binary accepts one parameter which is the output file + // where generated wasm module will be written at the end of execution + let args = env::args().collect::>(); + if args.len() != 2 { + println!("Usage: {} output_file.wasm", args[0]); + return; + } - // Main entry for the builder api is the module function - // It returns empty module builder structure which can be further - // appended with various wasm artefacts - let module = builder::module() - // Here we append function to the builder - // function() function returns a function builder attached - // to the module builder. - .function() - // We describe signature for the function via signature() - // function. In our simple example it's just one input - // argument of type 'i32' without return value - .signature().with_param(elements::ValueType::I32).build() - // body() without any further arguments means that the body - // of the function will be empty - .body().build() - // This is the end of the function builder. When `build()` is - // invoked, function builder returns original module builder - // from which it was invoked - .build() - // And finally we finish our module builder to produce actual - // wasm module. - .build(); + // Main entry for the builder api is the module function + // It returns empty module builder structure which can be further + // appended with various wasm artefacts + let module = builder::module() + // Here we append function to the builder + // function() function returns a function builder attached + // to the module builder. + .function() + // We describe signature for the function via signature() + // function. In our simple example it's just one input + // argument of type 'i32' without return value + .signature().with_param(elements::ValueType::I32).build() + // body() without any further arguments means that the body + // of the function will be empty + .body().build() + // This is the end of the function builder. When `build()` is + // invoked, function builder returns original module builder + // from which it was invoked + .build() + // And finally we finish our module builder to produce actual + // wasm module. + .build(); - // Module structure can be serialzed to produce a valid wasm file - parity_wasm::serialize_to_file(&args[1], module).unwrap(); + // Module structure can be serialzed to produce a valid wasm file + parity_wasm::serialize_to_file(&args[1], module).unwrap(); } \ No newline at end of file diff --git a/examples/data.rs b/examples/data.rs index c14b9bb..2d739a9 100644 --- a/examples/data.rs +++ b/examples/data.rs @@ -7,40 +7,40 @@ use std::env; fn main() { - // Example executable takes one argument which must - // refernce the existing file with a valid wasm module - let args = env::args().collect::>(); - if args.len() != 2 { - println!("Usage: {} somefile.wasm", args[0]); - return; - } + // Example executable takes one argument which must + // refernce the existing file with a valid wasm module + let args = env::args().collect::>(); + if args.len() != 2 { + println!("Usage: {} somefile.wasm", args[0]); + return; + } - // Here we load module using dedicated for this purpose - // `deserialize_file` function (which works only with modules) - let module = parity_wasm::deserialize_file(&args[1]).expect("Failed to load module"); + // Here we load module using dedicated for this purpose + // `deserialize_file` function (which works only with modules) + let module = parity_wasm::deserialize_file(&args[1]).expect("Failed to load module"); - // We query module for data section. Note that not every valid - // wasm module must contain a data section. So in case the provided - // module does not contain data section, we panic with an error - let data_section = module.data_section().expect("no data section in module"); + // We query module for data section. Note that not every valid + // wasm module must contain a data section. So in case the provided + // module does not contain data section, we panic with an error + let data_section = module.data_section().expect("no data section in module"); - // Printing the total count of data segments - println!("Data segments: {}", data_section.entries().len()); + // Printing the total count of data segments + println!("Data segments: {}", data_section.entries().len()); - let mut index = 0; - for entry in data_section.entries() { - // Printing the details info of each data segment - // see `elements::DataSegment` for more properties - // you can query - println!(" Entry #{}", index); + let mut index = 0; + for entry in data_section.entries() { + // Printing the details info of each data segment + // see `elements::DataSegment` for more properties + // you can query + println!(" Entry #{}", index); - // This shows the initialization member of data segment - // (expression which must resolve in the linear memory location). - println!(" init: {}", entry.offset().code()[0]); + // This shows the initialization member of data segment + // (expression which must resolve in the linear memory location). + println!(" init: {}", entry.offset().code()[0]); - // This shows the total length of the data segment in bytes. - println!(" size: {}", entry.value().len()); + // This shows the total length of the data segment in bytes. + println!(" size: {}", entry.value().len()); - index += 1; - } + index += 1; + } } \ No newline at end of file diff --git a/examples/exports.rs b/examples/exports.rs index 763750e..af52ab2 100644 --- a/examples/exports.rs +++ b/examples/exports.rs @@ -10,74 +10,74 @@ use parity_wasm::elements::{Internal, External, Type, FunctionType, Module}; // Auxillary function to resolve function type (signature) given it's callable index fn type_by_index(module: &Module, index: usize) -> FunctionType { - // Demand that function and type section exist. Otherwise, fail with a - // corresponding error. - let function_section = module.function_section().expect("No function section found"); - let type_section = module.type_section().expect("No type section found"); + // Demand that function and type section exist. Otherwise, fail with a + // corresponding error. + let function_section = module.function_section().expect("No function section found"); + let type_section = module.type_section().expect("No type section found"); - // This counts the number of _function_ imports listed by the module, excluding - // the globals, since indexing for actual functions for `call` and `export` purposes - // includes both imported and own functions. So we actualy need the imported function count - // to resolve actual index of the given function in own functions list. - let import_section_len: usize = match module.import_section() { - Some(import) => - import.entries().iter().filter(|entry| match entry.external() { - &External::Function(_) => true, - _ => false, - }).count(), - None => 0, - }; + // This counts the number of _function_ imports listed by the module, excluding + // the globals, since indexing for actual functions for `call` and `export` purposes + // includes both imported and own functions. So we actualy need the imported function count + // to resolve actual index of the given function in own functions list. + let import_section_len: usize = match module.import_section() { + Some(import) => + import.entries().iter().filter(|entry| match entry.external() { + &External::Function(_) => true, + _ => false, + }).count(), + None => 0, + }; - // Substract the value queried in the previous step from the provided index - // to get own function index from which we can query type next. - let function_index_in_section = index - import_section_len; + // Substract the value queried in the previous step from the provided index + // to get own function index from which we can query type next. + let function_index_in_section = index - import_section_len; - // Query the own function given we have it's index - let func_type_ref: usize = function_section.entries()[function_index_in_section].type_ref() as usize; + // Query the own function given we have it's index + let func_type_ref: usize = function_section.entries()[function_index_in_section].type_ref() as usize; - // Finally, return function type (signature) - match type_section.types()[func_type_ref] { - Type::Function(ref func_type) => func_type.clone(), - } + // Finally, return function type (signature) + match type_section.types()[func_type_ref] { + Type::Function(ref func_type) => func_type.clone(), + } } fn main() { - // Example executable takes one argument which must - // refernce the existing file with a valid wasm module - let args: Vec<_> = args().collect(); - if args.len() < 2 { - println!("Prints export function names with and their types"); - println!("Usage: {} ", args[0]); - return; - } + // Example executable takes one argument which must + // refernce the existing file with a valid wasm module + let args: Vec<_> = args().collect(); + if args.len() < 2 { + println!("Prints export function names with and their types"); + println!("Usage: {} ", args[0]); + return; + } - // Here we load module using dedicated for this purpose - // `deserialize_file` function (which works only with modules) - let module = parity_wasm::deserialize_file(&args[1]).expect("File to be deserialized"); + // Here we load module using dedicated for this purpose + // `deserialize_file` function (which works only with modules) + let module = parity_wasm::deserialize_file(&args[1]).expect("File to be deserialized"); - // Query the export section from the loaded module. Note that not every - // wasm module obliged to contain export section. So in case there is no - // any export section, we panic with the corresponding error. - let export_section = module.export_section().expect("No export section found"); + // Query the export section from the loaded module. Note that not every + // wasm module obliged to contain export section. So in case there is no + // any export section, we panic with the corresponding error. + let export_section = module.export_section().expect("No export section found"); - // Process all exports, leaving only those which reference the internal function - // of the wasm module - let exports: Vec = export_section.entries().iter() - .filter_map(|entry| - // This is match on export variant, which can be function, global,table or memory - // We are interested only in functions for an example - match *entry.internal() { - // Return function export name (return by field() function and it's index) - Internal::Function(index) => Some((entry.field(), index as usize)), - _ => None - }) - // Another map to resolve function signature index given it's internal index and return - // the printable string of the export - .map(|(field, index)| format!("{:}: {:?}", field, type_by_index(&module, index).params())).collect(); + // Process all exports, leaving only those which reference the internal function + // of the wasm module + let exports: Vec = export_section.entries().iter() + .filter_map(|entry| + // This is match on export variant, which can be function, global,table or memory + // We are interested only in functions for an example + match *entry.internal() { + // Return function export name (return by field() function and it's index) + Internal::Function(index) => Some((entry.field(), index as usize)), + _ => None + }) + // Another map to resolve function signature index given it's internal index and return + // the printable string of the export + .map(|(field, index)| format!("{:}: {:?}", field, type_by_index(&module, index).params())).collect(); - // Print the result - for export in exports { - println!("{:}", export); - } + // Print the result + for export in exports { + println!("{:}", export); + } } diff --git a/examples/info.rs b/examples/info.rs index 58c5927..e765226 100644 --- a/examples/info.rs +++ b/examples/info.rs @@ -4,40 +4,40 @@ use std::env; use parity_wasm::elements::Section; fn main() { - let args = env::args().collect::>(); - if args.len() != 2 { - println!("Usage: {} somefile.wasm", args[0]); - return; - } + let args = env::args().collect::>(); + if args.len() != 2 { + println!("Usage: {} somefile.wasm", args[0]); + return; + } - let module = parity_wasm::deserialize_file(&args[1]).expect("Failed to load module"); + let module = parity_wasm::deserialize_file(&args[1]).expect("Failed to load module"); - println!("Module sections: {}", module.sections().len()); + println!("Module sections: {}", module.sections().len()); - for section in module.sections() { - match *section { - Section::Import(ref import_section) => { - println!(" Imports: {}", import_section.entries().len()); - import_section.entries().iter().map(|e| println!(" {}.{}", e.module(), e.field())).count(); - }, - Section::Export(ref exports_section) => { - println!(" Exports: {}", exports_section.entries().len()); - exports_section.entries().iter().map(|e| println!(" {}", e.field())).count(); - }, - Section::Function(ref function_section) => { - println!(" Functions: {}", function_section.entries().len()); - }, - Section::Type(ref type_section) => { - println!(" Types: {}", type_section.types().len()); - }, - Section::Global(ref globals_section) => { - println!(" Globals: {}", globals_section.entries().len()); - }, - Section::Data(ref data_section) if data_section.entries().len() > 0 => { - let data = &data_section.entries()[0]; - println!(" Data size: {}", data.value().len()); - }, - _ => {}, - } - } + for section in module.sections() { + match *section { + Section::Import(ref import_section) => { + println!(" Imports: {}", import_section.entries().len()); + import_section.entries().iter().map(|e| println!(" {}.{}", e.module(), e.field())).count(); + }, + Section::Export(ref exports_section) => { + println!(" Exports: {}", exports_section.entries().len()); + exports_section.entries().iter().map(|e| println!(" {}", e.field())).count(); + }, + Section::Function(ref function_section) => { + println!(" Functions: {}", function_section.entries().len()); + }, + Section::Type(ref type_section) => { + println!(" Types: {}", type_section.types().len()); + }, + Section::Global(ref globals_section) => { + println!(" Globals: {}", globals_section.entries().len()); + }, + Section::Data(ref data_section) if data_section.entries().len() > 0 => { + let data = &data_section.entries()[0]; + println!(" Data size: {}", data.value().len()); + }, + _ => {}, + } + } } \ No newline at end of file diff --git a/examples/inject.rs b/examples/inject.rs index a897e8a..b008f84 100644 --- a/examples/inject.rs +++ b/examples/inject.rs @@ -6,58 +6,58 @@ use parity_wasm::elements; use parity_wasm::builder; pub fn inject_nop(opcodes: &mut elements::Opcodes) { - use parity_wasm::elements::Opcode::*; - let opcodes = opcodes.elements_mut(); - let mut position = 0; - loop { - let need_inject = match &opcodes[position] { - &Block(_) | &If(_) => true, - _ => false, - }; - if need_inject { - opcodes.insert(position + 1, Nop); - } + use parity_wasm::elements::Opcode::*; + let opcodes = opcodes.elements_mut(); + let mut position = 0; + loop { + let need_inject = match &opcodes[position] { + &Block(_) | &If(_) => true, + _ => false, + }; + if need_inject { + opcodes.insert(position + 1, Nop); + } - position += 1; - if position >= opcodes.len() { - break; - } - } + position += 1; + if position >= opcodes.len() { + break; + } + } } fn main() { - let args = env::args().collect::>(); - if args.len() != 3 { - println!("Usage: {} input_file.wasm output_file.wasm", args[0]); - return; - } + let args = env::args().collect::>(); + if args.len() != 3 { + println!("Usage: {} input_file.wasm output_file.wasm", args[0]); + return; + } - let mut module = parity_wasm::deserialize_file(&args[1]).unwrap(); + let mut module = parity_wasm::deserialize_file(&args[1]).unwrap(); - for section in module.sections_mut() { - match section { - &mut elements::Section::Code(ref mut code_section) => { - for ref mut func_body in code_section.bodies_mut() { - inject_nop(func_body.code_mut()); - } - }, - _ => { } - } - } + for section in module.sections_mut() { + match section { + &mut elements::Section::Code(ref mut code_section) => { + for ref mut func_body in code_section.bodies_mut() { + inject_nop(func_body.code_mut()); + } + }, + _ => { } + } + } - let mut build = builder::from_module(module); - let import_sig = build.push_signature( - builder::signature() - .param().i32() - .param().i32() - .return_type().i32() - .build_sig() - ); - let build = build.import() - .module("env") - .field("log") - .external().func(import_sig) - .build(); + let mut build = builder::from_module(module); + let import_sig = build.push_signature( + builder::signature() + .param().i32() + .param().i32() + .return_type().i32() + .build_sig() + ); + let build = build.import() + .module("env") + .field("log") + .external().func(import_sig) + .build(); - parity_wasm::serialize_to_file(&args[2], build.build()).unwrap(); + parity_wasm::serialize_to_file(&args[2], build.build()).unwrap(); } \ No newline at end of file diff --git a/examples/interpret.rs b/examples/interpret.rs index b5cd137..59287c9 100644 --- a/examples/interpret.rs +++ b/examples/interpret.rs @@ -7,30 +7,30 @@ use std::env::args; use parity_wasm::ModuleInstanceInterface; fn main() { - let args: Vec<_> = args().collect(); - if args.len() != 3 { - println!("Usage: {} ", args[0]); - println!(" wasm file should contain exported `_call` function with single I32 argument"); - return; - } + let args: Vec<_> = args().collect(); + if args.len() != 3 { + println!("Usage: {} ", args[0]); + println!(" wasm file should contain exported `_call` function with single I32 argument"); + return; + } - // Intrepreter initialization. - let program = parity_wasm::ProgramInstance::new(); + // Intrepreter initialization. + let program = parity_wasm::ProgramInstance::new(); - // Here we load module using dedicated for this purpose - // `deserialize_file` function (which works only with modules) - let module = parity_wasm::deserialize_file(&args[1]).expect("Failed to load module"); + // Here we load module using dedicated for this purpose + // `deserialize_file` function (which works only with modules) + let module = parity_wasm::deserialize_file(&args[1]).expect("Failed to load module"); - // Intialize deserialized module. It adds module into It expects 3 parameters: - // - a name for the module - // - a module declaration - // - "main" module doesn't import native module(s) this is why we don't need to provide external native modules here - // This test shows how to implement native module https://github.com/NikVolf/parity-wasm/blob/master/src/interpreter/tests/basics.rs#L197 - let module = program.add_module("main", module, None).expect("Failed to initialize module"); + // Intialize deserialized module. It adds module into It expects 3 parameters: + // - a name for the module + // - a module declaration + // - "main" module doesn't import native module(s) this is why we don't need to provide external native modules here + // This test shows how to implement native module https://github.com/NikVolf/parity-wasm/blob/master/src/interpreter/tests/basics.rs#L197 + let module = program.add_module("main", module, None).expect("Failed to initialize module"); - // The argument should be parsable as a valid integer - let argument: i32 = args[2].parse().expect("Integer argument required"); + // The argument should be parsable as a valid integer + let argument: i32 = args[2].parse().expect("Integer argument required"); - // "_call" export of function to be executed with an i32 argument and prints the result of execution - println!("Result: {:?}", module.execute_export("_call", vec![parity_wasm::RuntimeValue::I32(argument)].into())); + // "_call" export of function to be executed with an i32 argument and prints the result of execution + println!("Result: {:?}", module.execute_export("_call", vec![parity_wasm::RuntimeValue::I32(argument)].into())); } diff --git a/examples/invoke.rs b/examples/invoke.rs index 424dc67..dac8a7a 100644 --- a/examples/invoke.rs +++ b/examples/invoke.rs @@ -5,80 +5,79 @@ use std::env::args; use parity_wasm::{interpreter, ModuleInstanceInterface, RuntimeValue}; use parity_wasm::elements::{Internal, External, Type, FunctionType, ValueType}; - fn main() { - let args: Vec<_> = args().collect(); - if args.len() < 3 { - println!("Usage: {} [...]", args[0]); - return; - } - let func_name = &args[2]; - let (_, program_args) = args.split_at(3); + let args: Vec<_> = args().collect(); + if args.len() < 3 { + println!("Usage: {} [...]", args[0]); + return; + } + let func_name = &args[2]; + let (_, program_args) = args.split_at(3); - // Intrepreter initialization. - let program = parity_wasm::ProgramInstance::new(); + // Intrepreter initialization. + let program = parity_wasm::ProgramInstance::new(); - let module = parity_wasm::deserialize_file(&args[1]).expect("File to be deserialized"); + let module = parity_wasm::deserialize_file(&args[1]).expect("File to be deserialized"); - // Extracts call arguments from command-line arguments - let execution_params = { - // Export section has an entry with a func_name with an index inside a module - let export_section = module.export_section().expect("No export section found"); - // It's a section with function declarations (which are references to the type section entries) - let function_section = module.function_section().expect("No function section found"); - // Type section stores function types which are referenced by function_section entries - let type_section = module.type_section().expect("No type section found"); + // Extracts call arguments from command-line arguments + let execution_params = { + // Export section has an entry with a func_name with an index inside a module + let export_section = module.export_section().expect("No export section found"); + // It's a section with function declarations (which are references to the type section entries) + let function_section = module.function_section().expect("No function section found"); + // Type section stores function types which are referenced by function_section entries + let type_section = module.type_section().expect("No type section found"); - // Given function name used to find export section entry which contains - // an `internal` field which points to the index in the function index space - let found_entry = export_section.entries().iter() - .find(|entry| func_name == entry.field()).expect(&format!("No export with name {} found", func_name)); + // Given function name used to find export section entry which contains + // an `internal` field which points to the index in the function index space + let found_entry = export_section.entries().iter() + .find(|entry| func_name == entry.field()).expect(&format!("No export with name {} found", func_name)); - // Function index in the function index space (internally-defined + imported) - let function_index: usize = match found_entry.internal() { - &Internal::Function(index) => index as usize, - _ => panic!("Founded export is not a function"), - }; + // Function index in the function index space (internally-defined + imported) + let function_index: usize = match found_entry.internal() { + &Internal::Function(index) => index as usize, + _ => panic!("Founded export is not a function"), + }; - // We need to count import section entries (functions only!) to subtract it from function_index - // and obtain the index within the function section - let import_section_len: usize = match module.import_section() { - Some(import) => - import.entries().iter().filter(|entry| match entry.external() { - &External::Function(_) => true, - _ => false, - }).count(), - None => 0, - }; + // We need to count import section entries (functions only!) to subtract it from function_index + // and obtain the index within the function section + let import_section_len: usize = match module.import_section() { + Some(import) => + import.entries().iter().filter(|entry| match entry.external() { + &External::Function(_) => true, + _ => false, + }).count(), + None => 0, + }; - // Calculates a function index within module's function section - let function_index_in_section = function_index - import_section_len; + // Calculates a function index within module's function section + let function_index_in_section = function_index - import_section_len; - // Getting a type reference from a function section entry - let func_type_ref: usize = function_section.entries()[function_index_in_section].type_ref() as usize; + // Getting a type reference from a function section entry + let func_type_ref: usize = function_section.entries()[function_index_in_section].type_ref() as usize; - // Use the reference to get an actual function type - let function_type: &FunctionType = match &type_section.types()[func_type_ref] { - &Type::Function(ref func_type) => func_type, - }; + // Use the reference to get an actual function type + let function_type: &FunctionType = match &type_section.types()[func_type_ref] { + &Type::Function(ref func_type) => func_type, + }; - // Parses arguments and constructs runtime values in correspondence of their types - let args: Vec = function_type.params().iter().enumerate().map(|(i, value)| match value { - &ValueType::I32 => RuntimeValue::I32(program_args[i].parse::().expect(&format!("Can't parse arg #{} as i32", program_args[i]))), - &ValueType::I64 => RuntimeValue::I64(program_args[i].parse::().expect(&format!("Can't parse arg #{} as i64", program_args[i]))), - &ValueType::F32 => RuntimeValue::F32(program_args[i].parse::().expect(&format!("Can't parse arg #{} as f32", program_args[i]))), - &ValueType::F64 => RuntimeValue::F64(program_args[i].parse::().expect(&format!("Can't parse arg #{} as f64", program_args[i]))), - }).collect(); + // Parses arguments and constructs runtime values in correspondence of their types + let args: Vec = function_type.params().iter().enumerate().map(|(i, value)| match value { + &ValueType::I32 => RuntimeValue::I32(program_args[i].parse::().expect(&format!("Can't parse arg #{} as i32", program_args[i]))), + &ValueType::I64 => RuntimeValue::I64(program_args[i].parse::().expect(&format!("Can't parse arg #{} as i64", program_args[i]))), + &ValueType::F32 => RuntimeValue::F32(program_args[i].parse::().expect(&format!("Can't parse arg #{} as f32", program_args[i]))), + &ValueType::F64 => RuntimeValue::F64(program_args[i].parse::().expect(&format!("Can't parse arg #{} as f64", program_args[i]))), + }).collect(); - interpreter::ExecutionParams::from(args) - }; + interpreter::ExecutionParams::from(args) + }; - // Intialize deserialized module. It adds module into It expects 3 parameters: - // - a name for the module - // - a module declaration - // - "main" module doesn't import native module(s) this is why we don't need to provide external native modules here - // This test shows how to implement native module https://github.com/NikVolf/parity-wasm/blob/master/src/interpreter/tests/basics.rs#L197 - let module = program.add_module("main", module, None).expect("Failed to initialize module"); + // Intialize deserialized module. It adds module into It expects 3 parameters: + // - a name for the module + // - a module declaration + // - "main" module doesn't import native module(s) this is why we don't need to provide external native modules here + // This test shows how to implement native module https://github.com/NikVolf/parity-wasm/blob/master/src/interpreter/tests/basics.rs#L197 + let module = program.add_module("main", module, None).expect("Failed to initialize module"); - println!("Result: {:?}", module.execute_export(func_name, execution_params).expect("")); + println!("Result: {:?}", module.execute_export(func_name, execution_params).expect("")); } diff --git a/examples/roundtrip.rs b/examples/roundtrip.rs index 8f7b84f..4979b5b 100644 --- a/examples/roundtrip.rs +++ b/examples/roundtrip.rs @@ -3,24 +3,24 @@ extern crate parity_wasm; use std::env; fn main() { - let args = env::args().collect::>(); - if args.len() != 3 { - println!("Usage: {} in.wasm out.wasm", args[0]); - return; - } + let args = env::args().collect::>(); + if args.len() != 3 { + println!("Usage: {} in.wasm out.wasm", args[0]); + return; + } - let module = match parity_wasm::deserialize_file(&args[1]) - .expect("Failed to load module") - .parse_names() - { - Ok(m) => m, - Err((errors, m)) => { - for (index, error) in errors.into_iter() { - println!("Custom section #{} parse error: {:?}", index, error); - } - m - } - }; + let module = match parity_wasm::deserialize_file(&args[1]) + .expect("Failed to load module") + .parse_names() + { + Ok(m) => m, + Err((errors, m)) => { + for (index, error) in errors.into_iter() { + println!("Custom section #{} parse error: {:?}", index, error); + } + m + } + }; - parity_wasm::serialize_to_file(&args[2], module).expect("Failed to write module"); + parity_wasm::serialize_to_file(&args[2], module).expect("Failed to write module"); } diff --git a/fuzz/fuzz_targets/deserialize.rs b/fuzz/fuzz_targets/deserialize.rs index e676d93..da5ec87 100644 --- a/fuzz/fuzz_targets/deserialize.rs +++ b/fuzz/fuzz_targets/deserialize.rs @@ -5,15 +5,15 @@ extern crate parity_wasm; extern crate binaryen; fuzz_target!(|data: &[u8]| { - let binaryen_module = binaryen::tools::translate_to_fuzz(data); + let binaryen_module = binaryen::tools::translate_to_fuzz(data); - // enable binaryen's validation if in doubt. - // assert!(binaryen_module.is_valid()); + // enable binaryen's validation if in doubt. + // assert!(binaryen_module.is_valid()); - let wasm = binaryen_module.write(); + let wasm = binaryen_module.write(); - let _module: parity_wasm::elements::Module = parity_wasm::deserialize_buffer(&wasm) - .expect( - "deserialize output of wasm-opt, indicating possible bug in deserializer", - ); + let _module: parity_wasm::elements::Module = parity_wasm::deserialize_buffer(&wasm) + .expect( + "deserialize output of wasm-opt, indicating possible bug in deserializer", + ); }); diff --git a/spec/src/fixtures.rs b/spec/src/fixtures.rs index 814535c..e7af523 100644 --- a/spec/src/fixtures.rs +++ b/spec/src/fixtures.rs @@ -1,16 +1,16 @@ macro_rules! run_test { - ($label: expr, $test_name: ident, fail) => ( - #[test] - fn $test_name() { - ::run::failing_spec($label) - } - ); - ($label: expr, $test_name: ident) => ( - #[test] - fn $test_name() { - ::run::spec($label) - } - ); + ($label: expr, $test_name: ident, fail) => ( + #[test] + fn $test_name() { + ::run::failing_spec($label) + } + ); + ($label: expr, $test_name: ident) => ( + #[test] + fn $test_name() { + ::run::spec($label) + } + ); } run_test!("address-offset-range.fail", wasm_address_offset_range_fail, fail); diff --git a/spec/src/run.rs b/spec/src/run.rs index bb6111e..a727e73 100644 --- a/spec/src/run.rs +++ b/spec/src/run.rs @@ -10,276 +10,276 @@ use serde_json; use test; use parity_wasm::{self, elements, builder}; use parity_wasm::interpreter::{ - RuntimeValue, - ProgramInstance, ModuleInstance, - ItemIndex, ExportEntryType, - Error as InterpreterError, + RuntimeValue, + ProgramInstance, ModuleInstance, + ItemIndex, ExportEntryType, + Error as InterpreterError, }; fn spec_test_module() -> elements::Module { - builder::module() - .function().signature().build().body().build().build() - .function().signature().param().i32().build().body().build().build() - .function().signature().param().i64().build().body().build().build() - .function().signature().param().f32().build().body().build().build() - .function().signature().param().f64().build().body().build().build() - .function().signature().param().i32().param().f32().build().body().build().build() - .function().signature().param().f64().param().f64().build().body().build().build() - .global().value_type().i32().init_expr(elements::Opcode::I32Const(666)).build() - .with_table(elements::TableType::new(100, None)) - .memory().with_min(1).with_max(Some(2)).build() - .export().field("print").internal().func(0).build() - .export().field("print").internal().func(1).build() - .export().field("print").internal().func(2).build() - .export().field("print").internal().func(3).build() - .export().field("print").internal().func(4).build() - .export().field("print").internal().func(5).build() - .export().field("print").internal().func(6).build() - .export().field("global").internal().global(0).build() - .export().field("table").internal().table(0).build() - .export().field("memory").internal().memory(0).build() - .build() + builder::module() + .function().signature().build().body().build().build() + .function().signature().param().i32().build().body().build().build() + .function().signature().param().i64().build().body().build().build() + .function().signature().param().f32().build().body().build().build() + .function().signature().param().f64().build().body().build().build() + .function().signature().param().i32().param().f32().build().body().build().build() + .function().signature().param().f64().param().f64().build().body().build().build() + .global().value_type().i32().init_expr(elements::Opcode::I32Const(666)).build() + .with_table(elements::TableType::new(100, None)) + .memory().with_min(1).with_max(Some(2)).build() + .export().field("print").internal().func(0).build() + .export().field("print").internal().func(1).build() + .export().field("print").internal().func(2).build() + .export().field("print").internal().func(3).build() + .export().field("print").internal().func(4).build() + .export().field("print").internal().func(5).build() + .export().field("print").internal().func(6).build() + .export().field("global").internal().global(0).build() + .export().field("table").internal().table(0).build() + .export().field("memory").internal().memory(0).build() + .build() } fn load_module(base_dir: &str, path: &str, name: &Option, program: &ProgramInstance) -> Arc { - let module = try_deserialize(base_dir, path).expect(&format!("Wasm file {} failed to load", path)); + let module = try_deserialize(base_dir, path).expect(&format!("Wasm file {} failed to load", path)); - program.add_module("spectest", spec_test_module(), None).expect("Failed adding 'spectest' module"); + program.add_module("spectest", spec_test_module(), None).expect("Failed adding 'spectest' module"); - let module_name = name.as_ref().map(|s| s.as_ref()).unwrap_or("wasm_test").trim_left_matches('$'); - let module_instance = program.add_module(module_name, module, None).expect(&format!("Failed adding {} module", module_name)); - module_instance + let module_name = name.as_ref().map(|s| s.as_ref()).unwrap_or("wasm_test").trim_left_matches('$'); + let module_instance = program.add_module(module_name, module, None).expect(&format!("Failed adding {} module", module_name)); + module_instance } fn try_deserialize(base_dir: &str, module_path: &str) -> Result { - let mut wasm_path = PathBuf::from(base_dir.clone()); - wasm_path.push(module_path); - parity_wasm::deserialize_file(&wasm_path) + let mut wasm_path = PathBuf::from(base_dir.clone()); + wasm_path.push(module_path); + parity_wasm::deserialize_file(&wasm_path) } fn try_load(base_dir: &str, module_path: &str) -> Result<(), InterpreterError> { - let module = try_deserialize(base_dir, module_path).map_err(|e| parity_wasm::interpreter::Error::Program(format!("{:?}", e)))?; - let program = ProgramInstance::new(); - program.add_module("try_load", module, None).map(|_| ()) + let module = try_deserialize(base_dir, module_path).map_err(|e| parity_wasm::interpreter::Error::Program(format!("{:?}", e)))?; + let program = ProgramInstance::new(); + program.add_module("try_load", module, None).map(|_| ()) } fn runtime_value(test_val: &test::RuntimeValue) -> parity_wasm::RuntimeValue { - match test_val.value_type.as_ref() { - "i32" => { - let unsigned: u32 = test_val.value.parse().expect("Literal parse error"); - parity_wasm::RuntimeValue::I32(unsigned as i32) - }, - "i64" => { - let unsigned: u64 = test_val.value.parse().expect("Literal parse error"); - parity_wasm::RuntimeValue::I64(unsigned as i64) - }, - "f32" => { - let unsigned: u32 = test_val.value.parse().expect("Literal parse error"); - parity_wasm::RuntimeValue::decode_f32(unsigned) - }, - "f64" => { - let unsigned: u64 = test_val.value.parse().expect("Literal parse error"); - parity_wasm::RuntimeValue::decode_f64(unsigned) - }, - _ => panic!("Unknwon runtime value type"), - } + match test_val.value_type.as_ref() { + "i32" => { + let unsigned: u32 = test_val.value.parse().expect("Literal parse error"); + parity_wasm::RuntimeValue::I32(unsigned as i32) + }, + "i64" => { + let unsigned: u64 = test_val.value.parse().expect("Literal parse error"); + parity_wasm::RuntimeValue::I64(unsigned as i64) + }, + "f32" => { + let unsigned: u32 = test_val.value.parse().expect("Literal parse error"); + parity_wasm::RuntimeValue::decode_f32(unsigned) + }, + "f64" => { + let unsigned: u64 = test_val.value.parse().expect("Literal parse error"); + parity_wasm::RuntimeValue::decode_f64(unsigned) + }, + _ => panic!("Unknwon runtime value type"), + } } fn runtime_values(test_vals: &[test::RuntimeValue]) -> Vec { - test_vals.iter().map(runtime_value).collect::>() + test_vals.iter().map(runtime_value).collect::>() } fn run_action(program: &ProgramInstance, action: &test::Action) - -> Result, InterpreterError> + -> Result, InterpreterError> { - match *action { - test::Action::Invoke { ref module, ref field, ref args } => { - let module = module.clone().unwrap_or("wasm_test".into()); - let module = module.trim_left_matches('$'); - let module = program.module(&module).expect(&format!("Expected program to have loaded module {}", module)); - module.execute_export(&jstring_to_rstring(field), runtime_values(args).into()) - }, - test::Action::Get { ref module, ref field, .. } => { - let module = module.clone().unwrap_or("wasm_test".into()); - let module = module.trim_left_matches('$'); - let module = program.module(&module).expect(&format!("Expected program to have loaded module {}", module)); - let field = jstring_to_rstring(&field); + match *action { + test::Action::Invoke { ref module, ref field, ref args } => { + let module = module.clone().unwrap_or("wasm_test".into()); + let module = module.trim_left_matches('$'); + let module = program.module(&module).expect(&format!("Expected program to have loaded module {}", module)); + module.execute_export(&jstring_to_rstring(field), runtime_values(args).into()) + }, + test::Action::Get { ref module, ref field, .. } => { + let module = module.clone().unwrap_or("wasm_test".into()); + let module = module.trim_left_matches('$'); + let module = program.module(&module).expect(&format!("Expected program to have loaded module {}", module)); + let field = jstring_to_rstring(&field); - module.export_entry(field.as_ref(), &ExportEntryType::Any) - .and_then(|i| match i { - elements::Internal::Global(global_index) => Ok(ItemIndex::IndexSpace(global_index)), - _ => Err(InterpreterError::Global(format!("Expected to have exported global with name {}", field))), - }) - .and_then(|g| module.global(g, None, None).map(|g| Some(g.get()))) - } - } + module.export_entry(field.as_ref(), &ExportEntryType::Any) + .and_then(|i| match i { + elements::Internal::Global(global_index) => Ok(ItemIndex::IndexSpace(global_index)), + _ => Err(InterpreterError::Global(format!("Expected to have exported global with name {}", field))), + }) + .and_then(|g| module.global(g, None, None).map(|g| Some(g.get()))) + } + } } pub struct FixtureParams { - failing: bool, - json: String, + failing: bool, + json: String, } pub fn run_wast2wasm(name: &str) -> FixtureParams { - let outdir = env::var("OUT_DIR").unwrap(); + let outdir = env::var("OUT_DIR").unwrap(); - let mut wast2wasm_path = PathBuf::from(outdir.clone()); - wast2wasm_path.push("bin"); - wast2wasm_path.push("wast2wasm"); + let mut wast2wasm_path = PathBuf::from(outdir.clone()); + wast2wasm_path.push("bin"); + wast2wasm_path.push("wast2wasm"); - let mut json_spec_path = PathBuf::from(outdir.clone()); - json_spec_path.push(&format!("{}.json", name)); + let mut json_spec_path = PathBuf::from(outdir.clone()); + json_spec_path.push(&format!("{}.json", name)); - let wast2wasm_output = Command::new(wast2wasm_path) - .arg("--spec") - .arg("-o") - .arg(&json_spec_path) - .arg(&format!("./wabt/third_party/testsuite/{}.wast", name)) - .output() - .expect("Failed to execute process"); + let wast2wasm_output = Command::new(wast2wasm_path) + .arg("--spec") + .arg("-o") + .arg(&json_spec_path) + .arg(&format!("./wabt/third_party/testsuite/{}.wast", name)) + .output() + .expect("Failed to execute process"); - FixtureParams { - json: json_spec_path.to_str().unwrap().to_owned(), - failing: { - if !wast2wasm_output.status.success() { - println!("wasm2wast error code: {}", wast2wasm_output.status); - println!("wasm2wast stdout: {}", String::from_utf8_lossy(&wast2wasm_output.stdout)); - println!("wasm2wast stderr: {}", String::from_utf8_lossy(&wast2wasm_output.stderr)); - true - } else { - false - } - } - } + FixtureParams { + json: json_spec_path.to_str().unwrap().to_owned(), + failing: { + if !wast2wasm_output.status.success() { + println!("wasm2wast error code: {}", wast2wasm_output.status); + println!("wasm2wast stdout: {}", String::from_utf8_lossy(&wast2wasm_output.stdout)); + println!("wasm2wast stderr: {}", String::from_utf8_lossy(&wast2wasm_output.stderr)); + true + } else { + false + } + } + } } pub fn failing_spec(name: &str) { - let fixture = run_wast2wasm(name); - if !fixture.failing { - panic!("wasm2wast expected to fail, but terminated normally"); - } + let fixture = run_wast2wasm(name); + if !fixture.failing { + panic!("wasm2wast expected to fail, but terminated normally"); + } } pub fn spec(name: &str) { - let outdir = env::var("OUT_DIR").unwrap(); + let outdir = env::var("OUT_DIR").unwrap(); - let fixture = run_wast2wasm(name); - if fixture.failing { - panic!("wasm2wast terminated abnormally, expected to success"); - } + let fixture = run_wast2wasm(name); + if fixture.failing { + panic!("wasm2wast terminated abnormally, expected to success"); + } - let mut f = File::open(&fixture.json) - .expect(&format!("Failed to load json file {}", &fixture.json)); - let spec: test::Spec = serde_json::from_reader(&mut f).expect("Failed to deserialize JSON file"); + let mut f = File::open(&fixture.json) + .expect(&format!("Failed to load json file {}", &fixture.json)); + let spec: test::Spec = serde_json::from_reader(&mut f).expect("Failed to deserialize JSON file"); - let program = ProgramInstance::new(); - let mut last_module = None; - for command in &spec.commands { - println!("command {:?}", command); - match command { - &test::Command::Module { ref name, ref filename, .. } => { - last_module = Some(load_module(&outdir, &filename, &name, &program)); - }, - &test::Command::AssertReturn { line, ref action, ref expected } => { - let result = run_action(&program, action); - match result { - Ok(result) => { - let spec_expected = runtime_values(expected); - let actual_result = result.into_iter().collect::>(); - for (actual_result, spec_expected) in actual_result.iter().zip(spec_expected.iter()) { - assert_eq!(actual_result.variable_type(), spec_expected.variable_type()); - // f32::NAN != f32::NAN - match spec_expected { - &RuntimeValue::F32(val) if val.is_nan() => match actual_result { - &RuntimeValue::F32(val) => assert!(val.is_nan()), - _ => unreachable!(), // checked above that types are same - }, - &RuntimeValue::F64(val) if val.is_nan() => match actual_result { - &RuntimeValue::F64(val) => assert!(val.is_nan()), - _ => unreachable!(), // checked above that types are same - }, - spec_expected @ _ => assert_eq!(actual_result, spec_expected), - } - } - println!("assert_return at line {} - success", line); - }, - Err(e) => { - panic!("Expected action to return value, got error: {:?}", e); - } - } - }, - &test::Command::AssertReturnCanonicalNan { line, ref action } | &test::Command::AssertReturnArithmeticNan { line, ref action } => { - let result = run_action(&program, action); - match result { - Ok(result) => { - for actual_result in result.into_iter().collect::>() { - match actual_result { - RuntimeValue::F32(val) => if !val.is_nan() { panic!("Expected nan value, got {:?}", val) }, - RuntimeValue::F64(val) => if !val.is_nan() { panic!("Expected nan value, got {:?}", val) }, - val @ _ => panic!("Expected action to return float value, got {:?}", val), - } - } - println!("assert_return_nan at line {} - success", line); - }, - Err(e) => { - panic!("Expected action to return value, got error: {:?}", e); - } - } - }, - &test::Command::AssertExhaustion { line, ref action, .. } => { - let result = run_action(&program, action); - match result { - Ok(result) => panic!("Expected exhaustion, got result: {:?}", result), - Err(e) => println!("assert_exhaustion at line {} - success ({:?})", line, e), - } - }, - &test::Command::AssertTrap { line, ref action, .. } => { - let result = run_action(&program, action); - match result { - Ok(result) => { - panic!("Expected action to result in a trap, got result: {:?}", result); - }, - Err(e) => { - println!("assert_trap at line {} - success ({:?})", line, e); - } - } - }, - &test::Command::AssertInvalid { line, ref filename, .. } - | &test::Command::AssertMalformed { line, ref filename, .. } - | &test::Command::AssertUnlinkable { line, ref filename, .. } - => { - let module_load = try_load(&outdir, filename); - match module_load { - Ok(_) => { - panic!("Expected invalid module definition, got some module!") - }, - Err(e) => { - println!("assert_invalid at line {} - success ({:?})", line, e) - } - } - }, - &test::Command::AssertUninstantiable { line, ref filename, .. } => { - match try_load(&outdir, &filename) { - Ok(_) => panic!("Expected error running start function at line {}", line), - Err(e) => println!("assert_uninstantiable - success ({:?})", e), - } - }, - &test::Command::Register { ref name, ref as_name, .. } => { - match name { - &Some(ref name) => assert_eq!(name.trim_left_matches('$'), as_name), // we have already registered this module without $ prefix - &None => program.insert_loaded_module(as_name, last_module.take().expect("Last module must be set for this command")).map(|_| ()).unwrap(), - } - }, - &test::Command::Action { line, ref action } => { - match run_action(&program, action) { - Ok(_) => { }, - Err(e) => { - panic!("Failed to invoke action at line {}: {:?}", line, e) - } - } - }, - } - } + let program = ProgramInstance::new(); + let mut last_module = None; + for command in &spec.commands { + println!("command {:?}", command); + match command { + &test::Command::Module { ref name, ref filename, .. } => { + last_module = Some(load_module(&outdir, &filename, &name, &program)); + }, + &test::Command::AssertReturn { line, ref action, ref expected } => { + let result = run_action(&program, action); + match result { + Ok(result) => { + let spec_expected = runtime_values(expected); + let actual_result = result.into_iter().collect::>(); + for (actual_result, spec_expected) in actual_result.iter().zip(spec_expected.iter()) { + assert_eq!(actual_result.variable_type(), spec_expected.variable_type()); + // f32::NAN != f32::NAN + match spec_expected { + &RuntimeValue::F32(val) if val.is_nan() => match actual_result { + &RuntimeValue::F32(val) => assert!(val.is_nan()), + _ => unreachable!(), // checked above that types are same + }, + &RuntimeValue::F64(val) if val.is_nan() => match actual_result { + &RuntimeValue::F64(val) => assert!(val.is_nan()), + _ => unreachable!(), // checked above that types are same + }, + spec_expected @ _ => assert_eq!(actual_result, spec_expected), + } + } + println!("assert_return at line {} - success", line); + }, + Err(e) => { + panic!("Expected action to return value, got error: {:?}", e); + } + } + }, + &test::Command::AssertReturnCanonicalNan { line, ref action } | &test::Command::AssertReturnArithmeticNan { line, ref action } => { + let result = run_action(&program, action); + match result { + Ok(result) => { + for actual_result in result.into_iter().collect::>() { + match actual_result { + RuntimeValue::F32(val) => if !val.is_nan() { panic!("Expected nan value, got {:?}", val) }, + RuntimeValue::F64(val) => if !val.is_nan() { panic!("Expected nan value, got {:?}", val) }, + val @ _ => panic!("Expected action to return float value, got {:?}", val), + } + } + println!("assert_return_nan at line {} - success", line); + }, + Err(e) => { + panic!("Expected action to return value, got error: {:?}", e); + } + } + }, + &test::Command::AssertExhaustion { line, ref action, .. } => { + let result = run_action(&program, action); + match result { + Ok(result) => panic!("Expected exhaustion, got result: {:?}", result), + Err(e) => println!("assert_exhaustion at line {} - success ({:?})", line, e), + } + }, + &test::Command::AssertTrap { line, ref action, .. } => { + let result = run_action(&program, action); + match result { + Ok(result) => { + panic!("Expected action to result in a trap, got result: {:?}", result); + }, + Err(e) => { + println!("assert_trap at line {} - success ({:?})", line, e); + } + } + }, + &test::Command::AssertInvalid { line, ref filename, .. } + | &test::Command::AssertMalformed { line, ref filename, .. } + | &test::Command::AssertUnlinkable { line, ref filename, .. } + => { + let module_load = try_load(&outdir, filename); + match module_load { + Ok(_) => { + panic!("Expected invalid module definition, got some module!") + }, + Err(e) => { + println!("assert_invalid at line {} - success ({:?})", line, e) + } + } + }, + &test::Command::AssertUninstantiable { line, ref filename, .. } => { + match try_load(&outdir, &filename) { + Ok(_) => panic!("Expected error running start function at line {}", line), + Err(e) => println!("assert_uninstantiable - success ({:?})", e), + } + }, + &test::Command::Register { ref name, ref as_name, .. } => { + match name { + &Some(ref name) => assert_eq!(name.trim_left_matches('$'), as_name), // we have already registered this module without $ prefix + &None => program.insert_loaded_module(as_name, last_module.take().expect("Last module must be set for this command")).map(|_| ()).unwrap(), + } + }, + &test::Command::Action { line, ref action } => { + match run_action(&program, action) { + Ok(_) => { }, + Err(e) => { + panic!("Failed to invoke action at line {}: {:?}", line, e) + } + } + }, + } + } } // Convert json string to correct rust UTF8 string. @@ -287,7 +287,7 @@ pub fn spec(name: &str) { // It is incorrect. Correct BOM representation in json is "\uFEFF" => we need to do a double utf8-parse here. // This conversion is incorrect in general case (casting char to u8)!!! fn jstring_to_rstring(jstring: &str) -> String { - let jstring_chars: Vec = jstring.chars().map(|c| c as u8).collect(); - let rstring = String::from_utf8(jstring_chars).unwrap(); - rstring + let jstring_chars: Vec = jstring.chars().map(|c| c as u8).collect(); + let rstring = String::from_utf8(jstring_chars).unwrap(); + rstring } diff --git a/spec/src/test.rs b/spec/src/test.rs index 8c4a2b3..518cc4a 100644 --- a/spec/src/test.rs +++ b/spec/src/test.rs @@ -2,103 +2,103 @@ #[derive(Deserialize, Debug)] pub struct RuntimeValue { - #[serde(rename = "type")] - pub value_type: String, - pub value: String, + #[serde(rename = "type")] + pub value_type: String, + pub value: String, } #[derive(Deserialize, Debug)] #[serde(tag = "type")] pub enum Action { - #[serde(rename = "invoke")] - Invoke { - module: Option, - field: String, - args: Vec, - }, - #[serde(rename = "get")] - Get { - module: Option, - field: String, - } + #[serde(rename = "invoke")] + Invoke { + module: Option, + field: String, + args: Vec, + }, + #[serde(rename = "get")] + Get { + module: Option, + field: String, + } } #[derive(Deserialize, Debug)] #[serde(tag = "type")] pub enum Command { - #[serde(rename = "module")] - Module { - line: u64, - name: Option, - filename: String - }, - #[serde(rename = "assert_return")] - AssertReturn { - line: u64, - action: Action, - expected: Vec, - }, - #[serde(rename = "assert_return_canonical_nan")] - AssertReturnCanonicalNan { - line: u64, - action: Action, - }, - #[serde(rename = "assert_return_arithmetic_nan")] - AssertReturnArithmeticNan { - line: u64, - action: Action, - }, - #[serde(rename = "assert_trap")] - AssertTrap { - line: u64, - action: Action, - text: String, - }, - #[serde(rename = "assert_invalid")] - AssertInvalid { - line: u64, - filename: String, - text: String, - }, - #[serde(rename = "assert_malformed")] - AssertMalformed { - line: u64, - filename: String, - text: String, - }, - #[serde(rename = "assert_uninstantiable")] - AssertUninstantiable { - line: u64, - filename: String, - text: String, - }, - #[serde(rename = "assert_exhaustion")] - AssertExhaustion { - line: u64, - action: Action, - }, - #[serde(rename = "assert_unlinkable")] - AssertUnlinkable { - line: u64, - filename: String, - text: String, - }, - #[serde(rename = "register")] - Register { - line: u64, - name: Option, - #[serde(rename = "as")] - as_name: String, - }, - #[serde(rename = "action")] - Action { - line: u64, - action: Action, - }, + #[serde(rename = "module")] + Module { + line: u64, + name: Option, + filename: String + }, + #[serde(rename = "assert_return")] + AssertReturn { + line: u64, + action: Action, + expected: Vec, + }, + #[serde(rename = "assert_return_canonical_nan")] + AssertReturnCanonicalNan { + line: u64, + action: Action, + }, + #[serde(rename = "assert_return_arithmetic_nan")] + AssertReturnArithmeticNan { + line: u64, + action: Action, + }, + #[serde(rename = "assert_trap")] + AssertTrap { + line: u64, + action: Action, + text: String, + }, + #[serde(rename = "assert_invalid")] + AssertInvalid { + line: u64, + filename: String, + text: String, + }, + #[serde(rename = "assert_malformed")] + AssertMalformed { + line: u64, + filename: String, + text: String, + }, + #[serde(rename = "assert_uninstantiable")] + AssertUninstantiable { + line: u64, + filename: String, + text: String, + }, + #[serde(rename = "assert_exhaustion")] + AssertExhaustion { + line: u64, + action: Action, + }, + #[serde(rename = "assert_unlinkable")] + AssertUnlinkable { + line: u64, + filename: String, + text: String, + }, + #[serde(rename = "register")] + Register { + line: u64, + name: Option, + #[serde(rename = "as")] + as_name: String, + }, + #[serde(rename = "action")] + Action { + line: u64, + action: Action, + }, } #[derive(Deserialize, Debug)] pub struct Spec { - pub source_filename: String, - pub commands: Vec, + pub source_filename: String, + pub commands: Vec, } \ No newline at end of file diff --git a/src/builder/code.rs b/src/builder/code.rs index 3614f7a..67ae647 100644 --- a/src/builder/code.rs +++ b/src/builder/code.rs @@ -4,170 +4,170 @@ use super::misc::{ValueTypeBuilder, ValueTypesBuilder, OptionalValueTypeBuilder} /// Signature template description pub enum Signature { - TypeReference(u32), - Inline(elements::FunctionType), + TypeReference(u32), + Inline(elements::FunctionType), } /// Signature builder pub struct SignatureBuilder { - callback: F, - signature: elements::FunctionType, + callback: F, + signature: elements::FunctionType, } impl SignatureBuilder { - /// New signature builder - pub fn new() -> Self { - SignatureBuilder::with_callback(Identity) - } + /// New signature builder + pub fn new() -> Self { + SignatureBuilder::with_callback(Identity) + } } impl SignatureBuilder where F: Invoke { - /// New builder with callback function specified - pub fn with_callback(callback: F) -> Self { - SignatureBuilder { - callback: callback, - signature: elements::FunctionType::default(), - } - } + /// New builder with callback function specified + pub fn with_callback(callback: F) -> Self { + SignatureBuilder { + callback: callback, + signature: elements::FunctionType::default(), + } + } - /// Add argument to signature builder - pub fn with_param(mut self, value_type: elements::ValueType) -> Self { - self.signature.params_mut().push(value_type); - self - } + /// Add argument to signature builder + pub fn with_param(mut self, value_type: elements::ValueType) -> Self { + self.signature.params_mut().push(value_type); + self + } - /// Add multiple arguments to signature builder - pub fn with_params(mut self, value_types: Vec) -> Self { - self.signature.params_mut().extend(value_types); - self - } + /// Add multiple arguments to signature builder + pub fn with_params(mut self, value_types: Vec) -> Self { + self.signature.params_mut().extend(value_types); + self + } - /// Override signature return type - pub fn with_return_type(mut self, return_type: Option) -> Self { - *self.signature.return_type_mut() = return_type; - self - } + /// Override signature return type + pub fn with_return_type(mut self, return_type: Option) -> Self { + *self.signature.return_type_mut() = return_type; + self + } - /// Start build new argument - pub fn param(self) -> ValueTypeBuilder { - ValueTypeBuilder::with_callback(self) - } + /// Start build new argument + pub fn param(self) -> ValueTypeBuilder { + ValueTypeBuilder::with_callback(self) + } - /// Start build multiple arguments - pub fn params(self) -> ValueTypesBuilder { - ValueTypesBuilder::with_callback(self) - } + /// Start build multiple arguments + pub fn params(self) -> ValueTypesBuilder { + ValueTypesBuilder::with_callback(self) + } - /// Start building return type - pub fn return_type(self) -> OptionalValueTypeBuilder { - OptionalValueTypeBuilder::with_callback(self) - } + /// Start building return type + pub fn return_type(self) -> OptionalValueTypeBuilder { + OptionalValueTypeBuilder::with_callback(self) + } - /// Finish current builder - pub fn build(self) -> F::Result { - self.callback.invoke(self.signature) - } + /// Finish current builder + pub fn build(self) -> F::Result { + self.callback.invoke(self.signature) + } - /// Finish current builder returning intermediate `Signature` struct - pub fn build_sig(self) -> Signature { - Signature::Inline(self.signature) - } + /// Finish current builder returning intermediate `Signature` struct + pub fn build_sig(self) -> Signature { + Signature::Inline(self.signature) + } } impl Invoke> for SignatureBuilder - where F: Invoke + where F: Invoke { - type Result = Self; + type Result = Self; - fn invoke(self, args: Vec) -> Self { - self.with_params(args) - } + fn invoke(self, args: Vec) -> Self { + self.with_params(args) + } } impl Invoke> for SignatureBuilder - where F: Invoke + where F: Invoke { - type Result = Self; + type Result = Self; - fn invoke(self, arg: Option) -> Self { - self.with_return_type(arg) - } + fn invoke(self, arg: Option) -> Self { + self.with_return_type(arg) + } } impl Invoke for SignatureBuilder - where F: Invoke + where F: Invoke { - type Result = Self; + type Result = Self; - fn invoke(self, arg: elements::ValueType) -> Self { - self.with_param(arg) - } + fn invoke(self, arg: elements::ValueType) -> Self { + self.with_param(arg) + } } /// Type (signature) reference builder (for function/import/indirect call) pub struct TypeRefBuilder { - callback: F, - type_ref: u32, + callback: F, + type_ref: u32, } impl TypeRefBuilder where F: Invoke { - /// New builder chained with specified callback - pub fn with_callback(callback: F) -> Self { - TypeRefBuilder { - callback: callback, - type_ref: 0 - } - } + /// New builder chained with specified callback + pub fn with_callback(callback: F) -> Self { + TypeRefBuilder { + callback: callback, + type_ref: 0 + } + } - /// Set/override of type reference - pub fn val(mut self, val: u32) -> Self { - self.type_ref = val; - self - } + /// Set/override of type reference + pub fn val(mut self, val: u32) -> Self { + self.type_ref = val; + self + } - /// Finish current builder - pub fn build(self) -> F::Result { self.callback.invoke(self.type_ref) } + /// Finish current builder + pub fn build(self) -> F::Result { self.callback.invoke(self.type_ref) } } /// Multiple signatures builder pub struct SignaturesBuilder { - callback: F, - section: Vec, + callback: F, + section: Vec, } impl SignaturesBuilder { - /// New empty functions section builder - pub fn new() -> Self { - SignaturesBuilder::with_callback(Identity) - } + /// New empty functions section builder + pub fn new() -> Self { + SignaturesBuilder::with_callback(Identity) + } } impl SignaturesBuilder { - /// New builder chained with specified callback - pub fn with_callback(callback: F) -> Self { - SignaturesBuilder { - callback: callback, - section: Vec::new(), - } - } + /// New builder chained with specified callback + pub fn with_callback(callback: F) -> Self { + SignaturesBuilder { + callback: callback, + section: Vec::new(), + } + } - /// Push new signature into the builder output - pub fn with_signature(mut self, signature: Signature) -> Self { - self.section.push(signature); - self - } + /// Push new signature into the builder output + pub fn with_signature(mut self, signature: Signature) -> Self { + self.section.push(signature); + self + } - /// Start building new signature with `TypeRefBuilder` - pub fn type_ref(self) -> TypeRefBuilder { - TypeRefBuilder::with_callback(self) - } + /// Start building new signature with `TypeRefBuilder` + pub fn type_ref(self) -> TypeRefBuilder { + TypeRefBuilder::with_callback(self) + } } impl SignaturesBuilder where F: Invoke { - /// Start building new signature with dedicated builder - pub fn signature(self) -> SignatureBuilder { - SignatureBuilder::with_callback(self) - } + /// Start building new signature with dedicated builder + pub fn signature(self) -> SignatureBuilder { + SignatureBuilder::with_callback(self) + } } impl Invoke for SignaturesBuilder { @@ -175,7 +175,7 @@ impl Invoke for SignaturesBuilder { fn invoke(self, signature: elements::FunctionType) -> Self { self.with_signature(Signature::Inline(signature)) - } + } } impl Invoke for SignaturesBuilder { @@ -183,150 +183,150 @@ impl Invoke for SignaturesBuilder { fn invoke(self, type_ref: u32) -> Self { self.with_signature(Signature::TypeReference(type_ref)) - } + } } impl SignaturesBuilder where F: Invoke { - /// Finalize builder spawning element - pub fn build(self) -> F::Result { - let mut result = elements::FunctionSection::default(); - for f in self.section.into_iter() { - if let Signature::TypeReference(type_ref) = f { - result.entries_mut().push(elements::Func::new(type_ref)); - } else { - unreachable!(); // never possible with current generics impl-s - } - } - self.callback.invoke(result) - } + /// Finalize builder spawning element + pub fn build(self) -> F::Result { + let mut result = elements::FunctionSection::default(); + for f in self.section.into_iter() { + if let Signature::TypeReference(type_ref) = f { + result.entries_mut().push(elements::Func::new(type_ref)); + } else { + unreachable!(); // never possible with current generics impl-s + } + } + self.callback.invoke(result) + } } /// Signature bindings pub type SignatureBindings = Vec; impl SignaturesBuilder where F: Invoke { - /// Bind signature list - pub fn bind(self) -> F::Result { - self.callback.invoke(self.section) - } + /// Bind signature list + pub fn bind(self) -> F::Result { + self.callback.invoke(self.section) + } } /// Function body (code) builder pub struct FuncBodyBuilder { - callback: F, - body: elements::FuncBody, + callback: F, + body: elements::FuncBody, } impl FuncBodyBuilder { - /// New body (code) builder given the chain callback - pub fn with_callback(callback: F) -> Self { - FuncBodyBuilder { - callback: callback, - body: elements::FuncBody::new(Vec::new(), elements::Opcodes::empty()), - } - } + /// New body (code) builder given the chain callback + pub fn with_callback(callback: F) -> Self { + FuncBodyBuilder { + callback: callback, + body: elements::FuncBody::new(Vec::new(), elements::Opcodes::empty()), + } + } } impl FuncBodyBuilder where F: Invoke { - /// Set/override entirely with FuncBody struct - pub fn with_func(mut self, func: elements::FuncBody) -> Self { - self.body = func; - self - } + /// Set/override entirely with FuncBody struct + pub fn with_func(mut self, func: elements::FuncBody) -> Self { + self.body = func; + self + } - /// Extend function local list with new entries - pub fn with_locals(mut self, locals: Vec) -> Self { - self.body.locals_mut().extend(locals); - self - } + /// Extend function local list with new entries + pub fn with_locals(mut self, locals: Vec) -> Self { + self.body.locals_mut().extend(locals); + self + } - /// Set code of the function - pub fn with_opcodes(mut self, opcodes: elements::Opcodes) -> Self { - *self.body.code_mut() = opcodes; - self - } + /// Set code of the function + pub fn with_opcodes(mut self, opcodes: elements::Opcodes) -> Self { + *self.body.code_mut() = opcodes; + self + } - /// Finish current builder spawning resulting struct - pub fn build(self) -> F::Result { - self.callback.invoke(self.body) - } + /// Finish current builder spawning resulting struct + pub fn build(self) -> F::Result { + self.callback.invoke(self.body) + } } /// Function definition (extended structure to specify function entirely, incl. signature, mainness and code) pub struct FunctionDefinition { - /// Is this function is start function - pub is_main: bool, - /// Signature description - pub signature: Signature, - /// Body (code) of the function - pub code: elements::FuncBody, + /// Is this function is start function + pub is_main: bool, + /// Signature description + pub signature: Signature, + /// Body (code) of the function + pub code: elements::FuncBody, } impl Default for FunctionDefinition { - fn default() -> Self { - FunctionDefinition { - is_main: false, - signature: Signature::TypeReference(0), - code: elements::FuncBody::empty(), - } - } + fn default() -> Self { + FunctionDefinition { + is_main: false, + signature: Signature::TypeReference(0), + code: elements::FuncBody::empty(), + } + } } /// Function definition builder pub struct FunctionBuilder { - callback: F, - func: FunctionDefinition, + callback: F, + func: FunctionDefinition, } impl FunctionBuilder { - /// New function builder - pub fn new() -> Self { - FunctionBuilder::with_callback(Identity) - } + /// New function builder + pub fn new() -> Self { + FunctionBuilder::with_callback(Identity) + } } impl FunctionBuilder where F: Invoke { - /// New function builder with chained callback - pub fn with_callback(callback: F) -> Self { - FunctionBuilder { - callback: callback, - func: Default::default(), - } - } + /// New function builder with chained callback + pub fn with_callback(callback: F) -> Self { + FunctionBuilder { + callback: callback, + func: Default::default(), + } + } - /// Set that this function is main entry point - pub fn main(mut self) -> Self { - self.func.is_main = true; - self - } + /// Set that this function is main entry point + pub fn main(mut self) -> Self { + self.func.is_main = true; + self + } - /// Start signature builder of the function - pub fn signature(self) -> SignatureBuilder { - SignatureBuilder::with_callback(self) - } + /// Start signature builder of the function + pub fn signature(self) -> SignatureBuilder { + SignatureBuilder::with_callback(self) + } - /// Override current signature entirely with new one from known struct - pub fn with_signature(mut self, signature: Signature) -> Self { - self.func.signature = signature; - self - } + /// Override current signature entirely with new one from known struct + pub fn with_signature(mut self, signature: Signature) -> Self { + self.func.signature = signature; + self + } - /// Start code (body) builder - pub fn body(self) -> FuncBodyBuilder { - FuncBodyBuilder::with_callback(self) - } + /// Start code (body) builder + pub fn body(self) -> FuncBodyBuilder { + FuncBodyBuilder::with_callback(self) + } - /// Set body (code) for this function - pub fn with_body(mut self, body: elements::FuncBody) -> Self { - self.func.code = body; - self - } + /// Set body (code) for this function + pub fn with_body(mut self, body: elements::FuncBody) -> Self { + self.func.code = body; + self + } - /// Finalize current builder spawning resulting struct in the callback - pub fn build(self) -> F::Result { - self.callback.invoke(self.func) - } + /// Finalize current builder spawning resulting struct in the callback + pub fn build(self) -> F::Result { + self.callback.invoke(self.func) + } } impl Invoke for FunctionBuilder where F: Invoke { @@ -334,7 +334,7 @@ impl Invoke for FunctionBuilder where F: Invoke Self { self.with_signature(Signature::Inline(signature)) - } + } } impl Invoke for FunctionBuilder where F: Invoke { @@ -342,70 +342,70 @@ impl Invoke for FunctionBuilder where F: Invoke { fn invoke(self, type_ref: u32) -> Self { self.with_signature(Signature::TypeReference(type_ref)) - } + } } impl Invoke for FunctionBuilder where F: Invoke { - type Result = Self; + type Result = Self; - fn invoke(self, body: elements::FuncBody) -> Self::Result { - self.with_body(body) - } + fn invoke(self, body: elements::FuncBody) -> Self::Result { + self.with_body(body) + } } /// New builder of signature list pub fn signatures() -> SignaturesBuilder { - SignaturesBuilder::new() + SignaturesBuilder::new() } /// New signature builder pub fn signature() -> SignatureBuilder { - SignatureBuilder::new() + SignatureBuilder::new() } /// New builder of function (signature & body) pub fn function() -> FunctionBuilder { - FunctionBuilder::new() + FunctionBuilder::new() } #[cfg(test)] mod tests { - use super::{signatures, function}; - use elements; + use super::{signatures, function}; + use elements; - #[test] - fn example() { - let result = signatures() - .type_ref().val(1).build() - .build(); + #[test] + fn example() { + let result = signatures() + .type_ref().val(1).build() + .build(); - assert_eq!(result.entries().len(), 1); + assert_eq!(result.entries().len(), 1); - let result = signatures() - .signature() - .param().i32() - .param().i32() - .return_type().i64() - .build() - .bind(); + let result = signatures() + .signature() + .param().i32() + .param().i32() + .return_type().i64() + .build() + .bind(); - assert_eq!(result.len(), 1); - } + assert_eq!(result.len(), 1); + } - #[test] - fn func_example() { - let func = function() - .signature() - .param().i32() - .return_type().i32() - .build() - .body() - .with_opcodes(elements::Opcodes::empty()) - .build() - .build(); + #[test] + fn func_example() { + let func = function() + .signature() + .param().i32() + .return_type().i32() + .build() + .body() + .with_opcodes(elements::Opcodes::empty()) + .build() + .build(); - assert_eq!(func.code.locals().len(), 0); - assert_eq!(func.code.code().elements().len(), 1); - } + assert_eq!(func.code.locals().len(), 0); + assert_eq!(func.code.code().elements().len(), 1); + } } \ No newline at end of file diff --git a/src/builder/data.rs b/src/builder/data.rs index 39964fd..7be0f27 100644 --- a/src/builder/data.rs +++ b/src/builder/data.rs @@ -3,53 +3,53 @@ use elements; /// Data segment builder pub struct DataSegmentBuilder { - callback: F, - // todo: add mapper once multiple memory refs possible - mem_index: u32, - offset: elements::InitExpr, - value: Vec, + callback: F, + // todo: add mapper once multiple memory refs possible + mem_index: u32, + offset: elements::InitExpr, + value: Vec, } impl DataSegmentBuilder { - /// New data segment builder - pub fn new() -> Self { - DataSegmentBuilder::with_callback(Identity) - } + /// New data segment builder + pub fn new() -> Self { + DataSegmentBuilder::with_callback(Identity) + } } impl DataSegmentBuilder { - /// New data segment builder inside the chain context - pub fn with_callback(callback: F) -> Self { - DataSegmentBuilder { - callback: callback, - mem_index: 0, - offset: elements::InitExpr::empty(), - value: Vec::new(), - } - } + /// New data segment builder inside the chain context + pub fn with_callback(callback: F) -> Self { + DataSegmentBuilder { + callback: callback, + mem_index: 0, + offset: elements::InitExpr::empty(), + value: Vec::new(), + } + } - /// Set offset initialization opcode. `End` opcode will be added automatically. - pub fn offset(mut self, opcode: elements::Opcode) -> Self { - self.offset = elements::InitExpr::new(vec![opcode, elements::Opcode::End]); - self - } + /// Set offset initialization opcode. `End` opcode will be added automatically. + pub fn offset(mut self, opcode: elements::Opcode) -> Self { + self.offset = elements::InitExpr::new(vec![opcode, elements::Opcode::End]); + self + } - /// Set the bytes value of the segment - pub fn value(mut self, value: Vec) -> Self { - self.value = value; - self - } + /// Set the bytes value of the segment + pub fn value(mut self, value: Vec) -> Self { + self.value = value; + self + } } impl DataSegmentBuilder where F: Invoke { - /// Finish current builder, spawning resulting struct - pub fn build(self) -> F::Result { - self.callback.invoke( - elements::DataSegment::new( - self.mem_index, - self.offset, - self.value, - ) - ) - } + /// Finish current builder, spawning resulting struct + pub fn build(self) -> F::Result { + self.callback.invoke( + elements::DataSegment::new( + self.mem_index, + self.offset, + self.value, + ) + ) + } } \ No newline at end of file diff --git a/src/builder/export.rs b/src/builder/export.rs index 9016441..1393ef1 100644 --- a/src/builder/export.rs +++ b/src/builder/export.rs @@ -3,113 +3,113 @@ use elements; /// Export entry builder pub struct ExportBuilder { - callback: F, - field: String, - binding: elements::Internal, + callback: F, + field: String, + binding: elements::Internal, } impl ExportBuilder { - /// New export builder - pub fn new() -> Self { - ExportBuilder::with_callback(Identity) - } + /// New export builder + pub fn new() -> Self { + ExportBuilder::with_callback(Identity) + } } impl ExportBuilder { - /// New export entry builder in the specified chained context - pub fn with_callback(callback: F) -> Self { - ExportBuilder { - callback: callback, - field: String::new(), - binding: elements::Internal::Function(0), - } - } + /// New export entry builder in the specified chained context + pub fn with_callback(callback: F) -> Self { + ExportBuilder { + callback: callback, + field: String::new(), + binding: elements::Internal::Function(0), + } + } - /// Set the field name of the export entry - pub fn field(mut self, field: &str) -> Self { - self.field = field.to_owned(); - self - } + /// Set the field name of the export entry + pub fn field(mut self, field: &str) -> Self { + self.field = field.to_owned(); + self + } - /// Specify the internal module mapping for this entry - pub fn with_internal(mut self, external: elements::Internal) -> Self { - self.binding = external; - self - } + /// Specify the internal module mapping for this entry + pub fn with_internal(mut self, external: elements::Internal) -> Self { + self.binding = external; + self + } - /// Start the internal builder for this export entry - pub fn internal(self) -> ExportInternalBuilder { - ExportInternalBuilder::with_callback(self) - } + /// Start the internal builder for this export entry + pub fn internal(self) -> ExportInternalBuilder { + ExportInternalBuilder::with_callback(self) + } } impl ExportBuilder where F: Invoke { - /// Finalize export entry builder spawning the resulting struct - pub fn build(self) -> F::Result { - self.callback.invoke(elements::ExportEntry::new(self.field, self.binding)) - } + /// Finalize export entry builder spawning the resulting struct + pub fn build(self) -> F::Result { + self.callback.invoke(elements::ExportEntry::new(self.field, self.binding)) + } } impl Invoke for ExportBuilder { - type Result = Self; - fn invoke(self, val: elements::Internal) -> Self { - self.with_internal(val) - } + type Result = Self; + fn invoke(self, val: elements::Internal) -> Self { + self.with_internal(val) + } } /// Internal mapping builder for export entry pub struct ExportInternalBuilder { - callback: F, - binding: elements::Internal, + callback: F, + binding: elements::Internal, } impl ExportInternalBuilder where F: Invoke { - /// New export entry internal mapping for the chained context - pub fn with_callback(callback: F) -> Self { - ExportInternalBuilder{ - callback: callback, - binding: elements::Internal::Function(0), - } - } + /// New export entry internal mapping for the chained context + pub fn with_callback(callback: F) -> Self { + ExportInternalBuilder{ + callback: callback, + binding: elements::Internal::Function(0), + } + } - /// Map to function by index - pub fn func(mut self, index: u32) -> F::Result { - self.binding = elements::Internal::Function(index); - self.callback.invoke(self.binding) - } + /// Map to function by index + pub fn func(mut self, index: u32) -> F::Result { + self.binding = elements::Internal::Function(index); + self.callback.invoke(self.binding) + } - /// Map to memory - pub fn memory(mut self, index: u32) -> F::Result { - self.binding = elements::Internal::Memory(index); - self.callback.invoke(self.binding) - } + /// Map to memory + pub fn memory(mut self, index: u32) -> F::Result { + self.binding = elements::Internal::Memory(index); + self.callback.invoke(self.binding) + } - /// Map to table - pub fn table(mut self, index: u32) -> F::Result { - self.binding = elements::Internal::Table(index); - self.callback.invoke(self.binding) - } + /// Map to table + pub fn table(mut self, index: u32) -> F::Result { + self.binding = elements::Internal::Table(index); + self.callback.invoke(self.binding) + } - /// Map to global - pub fn global(mut self, index: u32) -> F::Result { - self.binding = elements::Internal::Global(index); - self.callback.invoke(self.binding) - } + /// Map to global + pub fn global(mut self, index: u32) -> F::Result { + self.binding = elements::Internal::Global(index); + self.callback.invoke(self.binding) + } } /// New builder for export entry pub fn export() -> ExportBuilder { - ExportBuilder::new() + ExportBuilder::new() } #[cfg(test)] mod tests { - use super::export; + use super::export; - #[test] - fn example() { - let entry = export().field("memory").internal().memory(0).build(); - assert_eq!(entry.field(), "memory"); - } + #[test] + fn example() { + let entry = export().field("memory").internal().memory(0).build(); + assert_eq!(entry.field(), "memory"); + } } \ No newline at end of file diff --git a/src/builder/global.rs b/src/builder/global.rs index 326572c..1316352 100644 --- a/src/builder/global.rs +++ b/src/builder/global.rs @@ -4,87 +4,87 @@ use elements; /// Global builder pub struct GlobalBuilder { - callback: F, - value_type: elements::ValueType, - is_mutable: bool, - init_expr: elements::InitExpr, + callback: F, + value_type: elements::ValueType, + is_mutable: bool, + init_expr: elements::InitExpr, } impl GlobalBuilder { - /// New global builder - pub fn new() -> Self { - GlobalBuilder::with_callback(Identity) - } + /// New global builder + pub fn new() -> Self { + GlobalBuilder::with_callback(Identity) + } } impl GlobalBuilder { - /// New global builder with callback (in chained context) - pub fn with_callback(callback: F) -> Self { - GlobalBuilder { - callback: callback, - value_type: elements::ValueType::I32, - init_expr: elements::InitExpr::empty(), - is_mutable: false, - } - } + /// New global builder with callback (in chained context) + pub fn with_callback(callback: F) -> Self { + GlobalBuilder { + callback: callback, + value_type: elements::ValueType::I32, + init_expr: elements::InitExpr::empty(), + is_mutable: false, + } + } - /// Set/override resulting global type - pub fn with_type(mut self, value_type: elements::ValueType) -> Self { - self.value_type = value_type; - self - } + /// Set/override resulting global type + pub fn with_type(mut self, value_type: elements::ValueType) -> Self { + self.value_type = value_type; + self + } - /// Set mutabilty to true - pub fn mutable(mut self) -> Self { - self.is_mutable = true; - self - } + /// Set mutabilty to true + pub fn mutable(mut self) -> Self { + self.is_mutable = true; + self + } - /// Set initialization expression opcode for this global (`end` opcode will be added automatically) - pub fn init_expr(mut self, opcode: elements::Opcode) -> Self { - self.init_expr = elements::InitExpr::new(vec![opcode, elements::Opcode::End]); - self - } + /// Set initialization expression opcode for this global (`end` opcode will be added automatically) + pub fn init_expr(mut self, opcode: elements::Opcode) -> Self { + self.init_expr = elements::InitExpr::new(vec![opcode, elements::Opcode::End]); + self + } - /// Start value type builder - pub fn value_type(self) -> ValueTypeBuilder { - ValueTypeBuilder::with_callback(self) - } + /// Start value type builder + pub fn value_type(self) -> ValueTypeBuilder { + ValueTypeBuilder::with_callback(self) + } } impl GlobalBuilder where F: Invoke { - /// Finalize current builder spawning resulting struct - pub fn build(self) -> F::Result { - self.callback.invoke( - elements::GlobalEntry::new( - elements::GlobalType::new(self.value_type, self.is_mutable), - self.init_expr, - ) - ) - } + /// Finalize current builder spawning resulting struct + pub fn build(self) -> F::Result { + self.callback.invoke( + elements::GlobalEntry::new( + elements::GlobalType::new(self.value_type, self.is_mutable), + self.init_expr, + ) + ) + } } impl Invoke for GlobalBuilder { - type Result = Self; - fn invoke(self, the_type: elements::ValueType) -> Self { - self.with_type(the_type) - } + type Result = Self; + fn invoke(self, the_type: elements::ValueType) -> Self { + self.with_type(the_type) + } } /// New builder for export entry pub fn global() -> GlobalBuilder { - GlobalBuilder::new() + GlobalBuilder::new() } #[cfg(test)] mod tests { - use super::global; - use elements; + use super::global; + use elements; - #[test] - fn example() { - let entry = global().value_type().i32().build(); - assert_eq!(entry.global_type().content_type(), elements::ValueType::I32); - assert_eq!(entry.global_type().is_mutable(), false); - } + #[test] + fn example() { + let entry = global().value_type().i32().build(); + assert_eq!(entry.global_type().content_type(), elements::ValueType::I32); + assert_eq!(entry.global_type().is_mutable(), false); + } } \ No newline at end of file diff --git a/src/builder/import.rs b/src/builder/import.rs index 77d51f4..7e5e647 100644 --- a/src/builder/import.rs +++ b/src/builder/import.rs @@ -3,127 +3,127 @@ use elements; /// Import builder pub struct ImportBuilder { - callback: F, - module: String, - field: String, - binding: elements::External, + callback: F, + module: String, + field: String, + binding: elements::External, } impl ImportBuilder { - /// New import builder - pub fn new() -> Self { - ImportBuilder::with_callback(Identity) - } + /// New import builder + pub fn new() -> Self { + ImportBuilder::with_callback(Identity) + } } impl ImportBuilder { - /// New import builder with callback (in chained context) - pub fn with_callback(callback: F) -> Self { - ImportBuilder { - callback: callback, - module: String::new(), - field: String::new(), - binding: elements::External::Function(0), - } - } + /// New import builder with callback (in chained context) + pub fn with_callback(callback: F) -> Self { + ImportBuilder { + callback: callback, + module: String::new(), + field: String::new(), + binding: elements::External::Function(0), + } + } - /// Set/override module name - pub fn module(mut self, name: &str) -> Self { - self.module = name.to_owned(); - self - } + /// Set/override module name + pub fn module(mut self, name: &str) -> Self { + self.module = name.to_owned(); + self + } - /// Set/override field name - pub fn field(mut self, name: &str) -> Self { - self.field = name.to_owned(); - self - } + /// Set/override field name + pub fn field(mut self, name: &str) -> Self { + self.field = name.to_owned(); + self + } - /// Set/override both module name and field name - pub fn path(self, module: &str, field: &str) -> Self { - self.module(module).field(field) - } + /// Set/override both module name and field name + pub fn path(self, module: &str, field: &str) -> Self { + self.module(module).field(field) + } - /// Set/override external mapping for this import - pub fn with_external(mut self, external: elements::External) -> Self { - self.binding = external; - self - } + /// Set/override external mapping for this import + pub fn with_external(mut self, external: elements::External) -> Self { + self.binding = external; + self + } - /// Start new external mapping builder - pub fn external(self) -> ImportExternalBuilder { - ImportExternalBuilder::with_callback(self) - } + /// Start new external mapping builder + pub fn external(self) -> ImportExternalBuilder { + ImportExternalBuilder::with_callback(self) + } } impl ImportBuilder where F: Invoke { - /// Finalize current builder spawning the resulting struct - pub fn build(self) -> F::Result { - self.callback.invoke(elements::ImportEntry::new(self.module, self.field, self.binding)) - } + /// Finalize current builder spawning the resulting struct + pub fn build(self) -> F::Result { + self.callback.invoke(elements::ImportEntry::new(self.module, self.field, self.binding)) + } } impl Invoke for ImportBuilder { - type Result = Self; - fn invoke(self, val: elements::External) -> Self { - self.with_external(val) - } + type Result = Self; + fn invoke(self, val: elements::External) -> Self { + self.with_external(val) + } } /// Import to external mapping builder pub struct ImportExternalBuilder { - callback: F, - binding: elements::External, + callback: F, + binding: elements::External, } impl ImportExternalBuilder where F: Invoke { - /// New import to external mapping builder with callback (in chained context) - pub fn with_callback(callback: F) -> Self { - ImportExternalBuilder{ - callback: callback, - binding: elements::External::Function(0), - } - } + /// New import to external mapping builder with callback (in chained context) + pub fn with_callback(callback: F) -> Self { + ImportExternalBuilder{ + callback: callback, + binding: elements::External::Function(0), + } + } - /// Function mapping with type reference - pub fn func(mut self, index: u32) -> F::Result { - self.binding = elements::External::Function(index); - self.callback.invoke(self.binding) - } + /// Function mapping with type reference + pub fn func(mut self, index: u32) -> F::Result { + self.binding = elements::External::Function(index); + self.callback.invoke(self.binding) + } - /// Memory mapping with specified limits - pub fn memory(mut self, min: u32, max: Option) -> F::Result { - self.binding = elements::External::Memory(elements::MemoryType::new(min, max)); - self.callback.invoke(self.binding) - } + /// Memory mapping with specified limits + pub fn memory(mut self, min: u32, max: Option) -> F::Result { + self.binding = elements::External::Memory(elements::MemoryType::new(min, max)); + self.callback.invoke(self.binding) + } - /// Table mapping with specified limits - pub fn table(mut self, min: u32, max: Option) -> F::Result { - self.binding = elements::External::Table(elements::TableType::new(min, max)); - self.callback.invoke(self.binding) - } + /// Table mapping with specified limits + pub fn table(mut self, min: u32, max: Option) -> F::Result { + self.binding = elements::External::Table(elements::TableType::new(min, max)); + self.callback.invoke(self.binding) + } - /// Global mapping with speciifed type and mutability - pub fn global(mut self, value_type: elements::ValueType, is_mut: bool) -> F::Result { - self.binding = elements::External::Global(elements::GlobalType::new(value_type, is_mut)); - self.callback.invoke(self.binding) - } + /// Global mapping with speciifed type and mutability + pub fn global(mut self, value_type: elements::ValueType, is_mut: bool) -> F::Result { + self.binding = elements::External::Global(elements::GlobalType::new(value_type, is_mut)); + self.callback.invoke(self.binding) + } } /// New builder for import entry pub fn import() -> ImportBuilder { - ImportBuilder::new() + ImportBuilder::new() } #[cfg(test)] mod tests { - use super::import; + use super::import; - #[test] - fn example() { - let entry = import().module("env").field("memory").external().memory(256, Some(256)).build(); + #[test] + fn example() { + let entry = import().module("env").field("memory").external().memory(256, Some(256)).build(); - assert_eq!(entry.module(), "env"); - assert_eq!(entry.field(), "memory"); - } + assert_eq!(entry.module(), "env"); + assert_eq!(entry.field(), "memory"); + } } \ No newline at end of file diff --git a/src/builder/memory.rs b/src/builder/memory.rs index c6fd0b0..a53f1b0 100644 --- a/src/builder/memory.rs +++ b/src/builder/memory.rs @@ -4,81 +4,81 @@ use super::invoke::{Invoke, Identity}; /// Memory definition struct #[derive(Debug)] pub struct MemoryDefinition { - /// Minimum memory size - pub min: u32, - /// Maximum memory size - pub max: Option, - /// Memory data segments (static regions) - pub data: Vec, + /// Minimum memory size + pub min: u32, + /// Maximum memory size + pub max: Option, + /// Memory data segments (static regions) + pub data: Vec, } /// Memory static region entry definition #[derive(Debug)] pub struct MemoryDataDefinition { - /// Segment initialization expression for offset - pub offset: elements::InitExpr, - /// Raw bytes of static region - pub values: Vec, + /// Segment initialization expression for offset + pub offset: elements::InitExpr, + /// Raw bytes of static region + pub values: Vec, } /// Memory and static regions builder pub struct MemoryBuilder { - callback: F, - memory: MemoryDefinition, + callback: F, + memory: MemoryDefinition, } impl MemoryBuilder { - /// New memory builder - pub fn new() -> Self { - MemoryBuilder::with_callback(Identity) - } + /// New memory builder + pub fn new() -> Self { + MemoryBuilder::with_callback(Identity) + } } impl MemoryBuilder where F: Invoke { - /// New memory builder with callback (in chained context) - pub fn with_callback(callback: F) -> Self { - MemoryBuilder { - callback: callback, - memory: Default::default(), - } - } + /// New memory builder with callback (in chained context) + pub fn with_callback(callback: F) -> Self { + MemoryBuilder { + callback: callback, + memory: Default::default(), + } + } - /// Set/override minimum size - pub fn with_min(mut self, min: u32) -> Self { - self.memory.min = min; - self - } + /// Set/override minimum size + pub fn with_min(mut self, min: u32) -> Self { + self.memory.min = min; + self + } - /// Set/override maximum size - pub fn with_max(mut self, max: Option) -> Self { - self.memory.max = max; - self - } + /// Set/override maximum size + pub fn with_max(mut self, max: Option) -> Self { + self.memory.max = max; + self + } - /// Push new static region with initialized offset expression and raw bytes - pub fn with_data(mut self, index: u32, values: Vec) -> Self { - self.memory.data.push(MemoryDataDefinition { - offset: elements::InitExpr::new(vec![ - elements::Opcode::I32Const(index as i32), - elements::Opcode::End, - ]), - values: values, - }); - self - } + /// Push new static region with initialized offset expression and raw bytes + pub fn with_data(mut self, index: u32, values: Vec) -> Self { + self.memory.data.push(MemoryDataDefinition { + offset: elements::InitExpr::new(vec![ + elements::Opcode::I32Const(index as i32), + elements::Opcode::End, + ]), + values: values, + }); + self + } - /// Finalize current builder, spawning resulting struct - pub fn build(self) -> F::Result { - self.callback.invoke(self.memory) - } + /// Finalize current builder, spawning resulting struct + pub fn build(self) -> F::Result { + self.callback.invoke(self.memory) + } } impl Default for MemoryDefinition { - fn default() -> Self { - MemoryDefinition { - min: 1, - max: None, - data: Vec::new(), - } - } + fn default() -> Self { + MemoryDefinition { + min: 1, + max: None, + data: Vec::new(), + } + } } diff --git a/src/builder/misc.rs b/src/builder/misc.rs index 6a18fd2..0bf1a7c 100644 --- a/src/builder/misc.rs +++ b/src/builder/misc.rs @@ -2,91 +2,91 @@ use super::invoke::{Invoke, Identity}; use elements; pub struct ValueTypeBuilder { - callback: F, + callback: F, } impl ValueTypeBuilder where F: Invoke { - pub fn with_callback(callback: F) -> Self { - ValueTypeBuilder { callback: callback } - } + pub fn with_callback(callback: F) -> Self { + ValueTypeBuilder { callback: callback } + } - pub fn i32(self) -> F::Result { - self.callback.invoke(elements::ValueType::I32) - } + pub fn i32(self) -> F::Result { + self.callback.invoke(elements::ValueType::I32) + } - pub fn i64(self) -> F::Result { - self.callback.invoke(elements::ValueType::I64) - } + pub fn i64(self) -> F::Result { + self.callback.invoke(elements::ValueType::I64) + } - pub fn f32(self) -> F::Result { - self.callback.invoke(elements::ValueType::F32) - } + pub fn f32(self) -> F::Result { + self.callback.invoke(elements::ValueType::F32) + } - pub fn f64(self) -> F::Result { - self.callback.invoke(elements::ValueType::F64) - } + pub fn f64(self) -> F::Result { + self.callback.invoke(elements::ValueType::F64) + } } pub struct OptionalValueTypeBuilder { - callback: F, + callback: F, } impl OptionalValueTypeBuilder where F: Invoke> { - pub fn with_callback(callback: F) -> Self { - OptionalValueTypeBuilder { callback: callback } - } + pub fn with_callback(callback: F) -> Self { + OptionalValueTypeBuilder { callback: callback } + } - pub fn i32(self) -> F::Result { - self.callback.invoke(Some(elements::ValueType::I32)) - } + pub fn i32(self) -> F::Result { + self.callback.invoke(Some(elements::ValueType::I32)) + } - pub fn i64(self) -> F::Result { - self.callback.invoke(Some(elements::ValueType::I64)) - } + pub fn i64(self) -> F::Result { + self.callback.invoke(Some(elements::ValueType::I64)) + } - pub fn f32(self) -> F::Result { - self.callback.invoke(Some(elements::ValueType::F32)) - } + pub fn f32(self) -> F::Result { + self.callback.invoke(Some(elements::ValueType::F32)) + } - pub fn f64(self) -> F::Result { - self.callback.invoke(Some(elements::ValueType::F64)) - } + pub fn f64(self) -> F::Result { + self.callback.invoke(Some(elements::ValueType::F64)) + } } pub struct ValueTypesBuilder { - callback: F, - value_types: Vec, + callback: F, + value_types: Vec, } impl ValueTypesBuilder where F: Invoke> { - pub fn with_callback(callback: F) -> Self { - ValueTypesBuilder { - callback: callback, - value_types: Vec::new(), - } - } + pub fn with_callback(callback: F) -> Self { + ValueTypesBuilder { + callback: callback, + value_types: Vec::new(), + } + } - pub fn i32(mut self) -> Self { - self.value_types.push(elements::ValueType::I32); - self - } + pub fn i32(mut self) -> Self { + self.value_types.push(elements::ValueType::I32); + self + } - pub fn i64(mut self) -> Self { - self.value_types.push(elements::ValueType::I64); - self - } + pub fn i64(mut self) -> Self { + self.value_types.push(elements::ValueType::I64); + self + } - pub fn f32(mut self) -> Self { - self.value_types.push(elements::ValueType::F32); - self - } + pub fn f32(mut self) -> Self { + self.value_types.push(elements::ValueType::F32); + self + } - pub fn f64(mut self) -> Self { - self.value_types.push(elements::ValueType::F64); - self - } + pub fn f64(mut self) -> Self { + self.value_types.push(elements::ValueType::F64); + self + } - pub fn build(self) -> F::Result { - self.callback.invoke(self.value_types) - } + pub fn build(self) -> F::Result { + self.callback.invoke(self.value_types) + } } \ No newline at end of file diff --git a/src/builder/mod.rs b/src/builder/mod.rs index 37e9808..b40b05e 100644 --- a/src/builder/mod.rs +++ b/src/builder/mod.rs @@ -12,8 +12,8 @@ mod global; mod data; pub use self::code::{ - signatures, signature, function, SignatureBuilder, SignaturesBuilder, - FunctionBuilder, TypeRefBuilder, FuncBodyBuilder, FunctionDefinition, + signatures, signature, function, SignatureBuilder, SignaturesBuilder, + FunctionBuilder, TypeRefBuilder, FuncBodyBuilder, FunctionDefinition, }; pub use self::data::DataSegmentBuilder; pub use self::export::{export, ExportBuilder, ExportInternalBuilder}; diff --git a/src/builder/module.rs b/src/builder/module.rs index 7deb726..7460ace 100644 --- a/src/builder/module.rs +++ b/src/builder/module.rs @@ -7,484 +7,484 @@ use elements; /// Module builder pub struct ModuleBuilder { - callback: F, - module: ModuleScaffold, + callback: F, + module: ModuleScaffold, } /// Location of the internal module function pub struct CodeLocation { - /// Location (index in 'functions' section) of the signature - pub signature: u32, - /// Location (index in the 'code' section) of the body - pub body: u32, + /// Location (index in 'functions' section) of the signature + pub signature: u32, + /// Location (index in the 'code' section) of the body + pub body: u32, } #[derive(Default)] struct ModuleScaffold { - pub types: elements::TypeSection, - pub import: elements::ImportSection, - pub functions: elements::FunctionSection, - pub table: elements::TableSection, - pub memory: elements::MemorySection, - pub global: elements::GlobalSection, - pub export: elements::ExportSection, - pub start: Option, - pub element: elements::ElementSection, - pub code: elements::CodeSection, - pub data: elements::DataSection, - pub other: Vec, + pub types: elements::TypeSection, + pub import: elements::ImportSection, + pub functions: elements::FunctionSection, + pub table: elements::TableSection, + pub memory: elements::MemorySection, + pub global: elements::GlobalSection, + pub export: elements::ExportSection, + pub start: Option, + pub element: elements::ElementSection, + pub code: elements::CodeSection, + pub data: elements::DataSection, + pub other: Vec, } impl From for ModuleScaffold { - fn from(module: elements::Module) -> Self { - let mut types: Option = None; - let mut import: Option = None; - let mut funcs: Option = None; - let mut table: Option = None; - let mut memory: Option = None; - let mut global: Option = None; - let mut export: Option = None; - let mut start: Option = None; - let mut element: Option = None; - let mut code: Option = None; - let mut data: Option = None; + fn from(module: elements::Module) -> Self { + let mut types: Option = None; + let mut import: Option = None; + let mut funcs: Option = None; + let mut table: Option = None; + let mut memory: Option = None; + let mut global: Option = None; + let mut export: Option = None; + let mut start: Option = None; + let mut element: Option = None; + let mut code: Option = None; + let mut data: Option = None; - let mut sections = module.into_sections(); - while let Some(section) = sections.pop() { - match section { - elements::Section::Type(sect) => { types = Some(sect); } - elements::Section::Import(sect) => { import = Some(sect); } - elements::Section::Function(sect) => { funcs = Some(sect); } - elements::Section::Table(sect) => { table = Some(sect); } - elements::Section::Memory(sect) => { memory = Some(sect); } - elements::Section::Global(sect) => { global = Some(sect); } - elements::Section::Export(sect) => { export = Some(sect); } - elements::Section::Start(index) => { start = Some(index); } - elements::Section::Element(sect) => { element = Some(sect); } - elements::Section::Code(sect) => { code = Some(sect); } - elements::Section::Data(sect) => { data = Some(sect); } - _ => {} - } - } + let mut sections = module.into_sections(); + while let Some(section) = sections.pop() { + match section { + elements::Section::Type(sect) => { types = Some(sect); } + elements::Section::Import(sect) => { import = Some(sect); } + elements::Section::Function(sect) => { funcs = Some(sect); } + elements::Section::Table(sect) => { table = Some(sect); } + elements::Section::Memory(sect) => { memory = Some(sect); } + elements::Section::Global(sect) => { global = Some(sect); } + elements::Section::Export(sect) => { export = Some(sect); } + elements::Section::Start(index) => { start = Some(index); } + elements::Section::Element(sect) => { element = Some(sect); } + elements::Section::Code(sect) => { code = Some(sect); } + elements::Section::Data(sect) => { data = Some(sect); } + _ => {} + } + } - ModuleScaffold { - types: types.unwrap_or_default(), - import: import.unwrap_or_default(), - functions: funcs.unwrap_or_default(), - table: table.unwrap_or_default(), - memory: memory.unwrap_or_default(), - global: global.unwrap_or_default(), - export: export.unwrap_or_default(), - start: start, - element: element.unwrap_or_default(), - code: code.unwrap_or_default(), - data: data.unwrap_or_default(), - other: sections, - } - } + ModuleScaffold { + types: types.unwrap_or_default(), + import: import.unwrap_or_default(), + functions: funcs.unwrap_or_default(), + table: table.unwrap_or_default(), + memory: memory.unwrap_or_default(), + global: global.unwrap_or_default(), + export: export.unwrap_or_default(), + start: start, + element: element.unwrap_or_default(), + code: code.unwrap_or_default(), + data: data.unwrap_or_default(), + other: sections, + } + } } impl From for elements::Module { - fn from(module: ModuleScaffold) -> Self { - let mut sections = Vec::new(); + fn from(module: ModuleScaffold) -> Self { + let mut sections = Vec::new(); - let types = module.types; - if types.types().len() > 0 { - sections.push(elements::Section::Type(types)); - } - let import = module.import; - if import.entries().len() > 0 { - sections.push(elements::Section::Import(import)); - } - let functions = module.functions; - if functions.entries().len() > 0 { - sections.push(elements::Section::Function(functions)); - } - let table = module.table; - if table.entries().len() > 0 { - sections.push(elements::Section::Table(table)); - } - let memory = module.memory; - if memory.entries().len() > 0 { - sections.push(elements::Section::Memory(memory)); - } - let global = module.global; - if global.entries().len() > 0 { - sections.push(elements::Section::Global(global)); - } - let export = module.export; - if export.entries().len() > 0 { - sections.push(elements::Section::Export(export)); - } - if let Some(start) = module.start { - sections.push(elements::Section::Start(start)); - } - let element = module.element; - if element.entries().len() > 0 { - sections.push(elements::Section::Element(element)); - } - let code = module.code; - if code.bodies().len() > 0 { - sections.push(elements::Section::Code(code)); - } - let data = module.data; - if data.entries().len() > 0 { - sections.push(elements::Section::Data(data)); - } - sections.extend(module.other); - elements::Module::new(sections) - } + let types = module.types; + if types.types().len() > 0 { + sections.push(elements::Section::Type(types)); + } + let import = module.import; + if import.entries().len() > 0 { + sections.push(elements::Section::Import(import)); + } + let functions = module.functions; + if functions.entries().len() > 0 { + sections.push(elements::Section::Function(functions)); + } + let table = module.table; + if table.entries().len() > 0 { + sections.push(elements::Section::Table(table)); + } + let memory = module.memory; + if memory.entries().len() > 0 { + sections.push(elements::Section::Memory(memory)); + } + let global = module.global; + if global.entries().len() > 0 { + sections.push(elements::Section::Global(global)); + } + let export = module.export; + if export.entries().len() > 0 { + sections.push(elements::Section::Export(export)); + } + if let Some(start) = module.start { + sections.push(elements::Section::Start(start)); + } + let element = module.element; + if element.entries().len() > 0 { + sections.push(elements::Section::Element(element)); + } + let code = module.code; + if code.bodies().len() > 0 { + sections.push(elements::Section::Code(code)); + } + let data = module.data; + if data.entries().len() > 0 { + sections.push(elements::Section::Data(data)); + } + sections.extend(module.other); + elements::Module::new(sections) + } } impl ModuleBuilder { - /// New empty module builder - pub fn new() -> Self { - ModuleBuilder::with_callback(Identity) - } + /// New empty module builder + pub fn new() -> Self { + ModuleBuilder::with_callback(Identity) + } } impl ModuleBuilder where F: Invoke { - /// New module builder with bound callback - pub fn with_callback(callback: F) -> Self { - ModuleBuilder { - callback: callback, - module: Default::default(), - } - } + /// New module builder with bound callback + pub fn with_callback(callback: F) -> Self { + ModuleBuilder { + callback: callback, + module: Default::default(), + } + } - /// Builder from raw module - pub fn with_module(mut self, module: elements::Module) -> Self { - self.module = module.into(); - self - } + /// Builder from raw module + pub fn with_module(mut self, module: elements::Module) -> Self { + self.module = module.into(); + self + } - /// Fill module with sections from iterator - pub fn with_sections(mut self, sections: I) -> Self - where I: IntoIterator - { - self.module.other.extend(sections); - self - } + /// Fill module with sections from iterator + pub fn with_sections(mut self, sections: I) -> Self + where I: IntoIterator + { + self.module.other.extend(sections); + self + } - /// Add additional section - pub fn with_section(mut self, section: elements::Section) -> Self { - self.module.other.push(section); - self - } + /// Add additional section + pub fn with_section(mut self, section: elements::Section) -> Self { + self.module.other.push(section); + self + } - /// Binds to the type section, creates additional types when required - pub fn with_signatures(mut self, bindings: code::SignatureBindings) -> Self { - self.push_signatures(bindings); - self - } + /// Binds to the type section, creates additional types when required + pub fn with_signatures(mut self, bindings: code::SignatureBindings) -> Self { + self.push_signatures(bindings); + self + } - /// Push stand-alone function definition, creating sections, signature and code blocks - /// in corresponding sections. - /// `FunctionDefinition` can be build using `builder::function` builder - pub fn push_function(&mut self, func: code::FunctionDefinition) -> CodeLocation { - let signature = func.signature; - let body = func.code; + /// Push stand-alone function definition, creating sections, signature and code blocks + /// in corresponding sections. + /// `FunctionDefinition` can be build using `builder::function` builder + pub fn push_function(&mut self, func: code::FunctionDefinition) -> CodeLocation { + let signature = func.signature; + let body = func.code; - let type_ref = self.resolve_type_ref(signature); + let type_ref = self.resolve_type_ref(signature); - self.module.functions.entries_mut().push(elements::Func::new(type_ref)); - let signature_index = self.module.functions.entries_mut().len() as u32 - 1; - self.module.code.bodies_mut().push(body); - let body_index = self.module.code.bodies_mut().len() as u32 - 1; + self.module.functions.entries_mut().push(elements::Func::new(type_ref)); + let signature_index = self.module.functions.entries_mut().len() as u32 - 1; + self.module.code.bodies_mut().push(body); + let body_index = self.module.code.bodies_mut().len() as u32 - 1; - if func.is_main { - self.module.start = Some(body_index); - } + if func.is_main { + self.module.start = Some(body_index); + } - CodeLocation { - signature: signature_index, - body: body_index, - } - } + CodeLocation { + signature: signature_index, + body: body_index, + } + } - /// Push linear memory region - pub fn push_memory(&mut self, mut memory: memory::MemoryDefinition) -> u32 { - let entries = self.module.memory.entries_mut(); - entries.push(elements::MemoryType::new(memory.min, memory.max)); - let memory_index = (entries.len() - 1) as u32; - for data in memory.data.drain(..) { - self.module.data.entries_mut() - .push(elements::DataSegment::new(memory_index, data.offset, data.values)) - } - memory_index - } + /// Push linear memory region + pub fn push_memory(&mut self, mut memory: memory::MemoryDefinition) -> u32 { + let entries = self.module.memory.entries_mut(); + entries.push(elements::MemoryType::new(memory.min, memory.max)); + let memory_index = (entries.len() - 1) as u32; + for data in memory.data.drain(..) { + self.module.data.entries_mut() + .push(elements::DataSegment::new(memory_index, data.offset, data.values)) + } + memory_index + } - /// Push table - pub fn push_table(&mut self, mut table: table::TableDefinition) -> u32 { - let entries = self.module.table.entries_mut(); - entries.push(elements::TableType::new(table.min, table.max)); - let table_index = (entries.len() - 1) as u32; - for entry in table.elements.drain(..) { - self.module.element.entries_mut() - .push(elements::ElementSegment::new(table_index, entry.offset, entry.values)) - } - table_index - } + /// Push table + pub fn push_table(&mut self, mut table: table::TableDefinition) -> u32 { + let entries = self.module.table.entries_mut(); + entries.push(elements::TableType::new(table.min, table.max)); + let table_index = (entries.len() - 1) as u32; + for entry in table.elements.drain(..) { + self.module.element.entries_mut() + .push(elements::ElementSegment::new(table_index, entry.offset, entry.values)) + } + table_index + } - fn resolve_type_ref(&mut self, signature: code::Signature) -> u32 { - match signature { - code::Signature::Inline(func_type) => { - // todo: maybe search for existing type - self.module.types.types_mut().push(elements::Type::Function(func_type)); - self.module.types.types().len() as u32 - 1 - } - code::Signature::TypeReference(type_ref) => { - type_ref - } - } - } + fn resolve_type_ref(&mut self, signature: code::Signature) -> u32 { + match signature { + code::Signature::Inline(func_type) => { + // todo: maybe search for existing type + self.module.types.types_mut().push(elements::Type::Function(func_type)); + self.module.types.types().len() as u32 - 1 + } + code::Signature::TypeReference(type_ref) => { + type_ref + } + } + } - /// Push one function signature, returning it's calling index. - /// Can create corresponding type in type section. - pub fn push_signature(&mut self, signature: code::Signature) -> u32 { - self.resolve_type_ref(signature) - } + /// Push one function signature, returning it's calling index. + /// Can create corresponding type in type section. + pub fn push_signature(&mut self, signature: code::Signature) -> u32 { + self.resolve_type_ref(signature) + } - /// Push signatures in the module, returning corresponding indices of pushed signatures - pub fn push_signatures(&mut self, signatures: code::SignatureBindings) -> Vec { - signatures.into_iter().map(|binding| - self.resolve_type_ref(binding) - ).collect() - } + /// Push signatures in the module, returning corresponding indices of pushed signatures + pub fn push_signatures(&mut self, signatures: code::SignatureBindings) -> Vec { + signatures.into_iter().map(|binding| + self.resolve_type_ref(binding) + ).collect() + } - /// Push import entry to module. Not that it does not update calling indices in - /// function bodies. - pub fn push_import(&mut self, import: elements::ImportEntry) -> u32 { - self.module.import.entries_mut().push(import); - // todo: actually update calling addresses in function bodies - // todo: also batch push + /// Push import entry to module. Not that it does not update calling indices in + /// function bodies. + pub fn push_import(&mut self, import: elements::ImportEntry) -> u32 { + self.module.import.entries_mut().push(import); + // todo: actually update calling addresses in function bodies + // todo: also batch push - self.module.import.entries_mut().len() as u32 - 1 - } + self.module.import.entries_mut().len() as u32 - 1 + } - /// Push export entry to module. - pub fn push_export(&mut self, export: elements::ExportEntry) -> u32 { - self.module.export.entries_mut().push(export); - self.module.export.entries_mut().len() as u32 - 1 - } + /// Push export entry to module. + pub fn push_export(&mut self, export: elements::ExportEntry) -> u32 { + self.module.export.entries_mut().push(export); + self.module.export.entries_mut().len() as u32 - 1 + } - /// Add new function using dedicated builder - pub fn function(self) -> FunctionBuilder { - FunctionBuilder::with_callback(self) - } + /// Add new function using dedicated builder + pub fn function(self) -> FunctionBuilder { + FunctionBuilder::with_callback(self) + } - /// Add new linear memory using dedicated builder - pub fn memory(self) -> MemoryBuilder { - MemoryBuilder::with_callback(self) - } + /// Add new linear memory using dedicated builder + pub fn memory(self) -> MemoryBuilder { + MemoryBuilder::with_callback(self) + } - /// Add new table using dedicated builder - pub fn table(self) -> TableBuilder { - TableBuilder::with_callback(self) - } + /// Add new table using dedicated builder + pub fn table(self) -> TableBuilder { + TableBuilder::with_callback(self) + } - /// Define functions section - pub fn functions(self) -> SignaturesBuilder { - SignaturesBuilder::with_callback(self) - } + /// Define functions section + pub fn functions(self) -> SignaturesBuilder { + SignaturesBuilder::with_callback(self) + } - /// With inserted export entry - pub fn with_export(mut self, entry: elements::ExportEntry) -> Self { - self.module.export.entries_mut().push(entry); - self - } + /// With inserted export entry + pub fn with_export(mut self, entry: elements::ExportEntry) -> Self { + self.module.export.entries_mut().push(entry); + self + } - /// With inserted import entry - pub fn with_import(mut self, entry: elements::ImportEntry) -> Self { - self.module.import.entries_mut().push(entry); - self - } + /// With inserted import entry + pub fn with_import(mut self, entry: elements::ImportEntry) -> Self { + self.module.import.entries_mut().push(entry); + self + } - /// Import entry builder - /// # Examples - /// ``` - /// use parity_wasm::builder::module; - /// - /// let module = module() - /// .import() - /// .module("env") - /// .field("memory") - /// .external().memory(256, Some(256)) - /// .build() - /// .build(); - /// - /// assert_eq!(module.import_section().expect("import section to exist").entries().len(), 1); - /// ``` - pub fn import(self) -> import::ImportBuilder { - import::ImportBuilder::with_callback(self) - } + /// Import entry builder + /// # Examples + /// ``` + /// use parity_wasm::builder::module; + /// + /// let module = module() + /// .import() + /// .module("env") + /// .field("memory") + /// .external().memory(256, Some(256)) + /// .build() + /// .build(); + /// + /// assert_eq!(module.import_section().expect("import section to exist").entries().len(), 1); + /// ``` + pub fn import(self) -> import::ImportBuilder { + import::ImportBuilder::with_callback(self) + } - /// With global variable - pub fn with_global(mut self, global: elements::GlobalEntry) -> Self { - self.module.global.entries_mut().push(global); - self - } + /// With global variable + pub fn with_global(mut self, global: elements::GlobalEntry) -> Self { + self.module.global.entries_mut().push(global); + self + } - /// With table - pub fn with_table(mut self, table: elements::TableType) -> Self { - self.module.table.entries_mut().push(table); - self - } + /// With table + pub fn with_table(mut self, table: elements::TableType) -> Self { + self.module.table.entries_mut().push(table); + self + } - /// Export entry builder - /// # Examples - /// ``` - /// use parity_wasm::builder::module; - /// use parity_wasm::elements::Opcode::*; - /// - /// let module = module() - /// .global() - /// .value_type().i32() - /// .init_expr(I32Const(0)) - /// .build() - /// .export() - /// .field("_zero") - /// .internal().global(0) - /// .build() - /// .build(); - /// - /// assert_eq!(module.export_section().expect("export section to exist").entries().len(), 1); - /// ``` - pub fn export(self) -> export::ExportBuilder { - export::ExportBuilder::with_callback(self) - } + /// Export entry builder + /// # Examples + /// ``` + /// use parity_wasm::builder::module; + /// use parity_wasm::elements::Opcode::*; + /// + /// let module = module() + /// .global() + /// .value_type().i32() + /// .init_expr(I32Const(0)) + /// .build() + /// .export() + /// .field("_zero") + /// .internal().global(0) + /// .build() + /// .build(); + /// + /// assert_eq!(module.export_section().expect("export section to exist").entries().len(), 1); + /// ``` + pub fn export(self) -> export::ExportBuilder { + export::ExportBuilder::with_callback(self) + } - /// Glboal entry builder - /// # Examples - /// ``` - /// use parity_wasm::builder::module; - /// use parity_wasm::elements::Opcode::*; - /// - /// let module = module() - /// .global() - /// .value_type().i32() - /// .init_expr(I32Const(0)) - /// .build() - /// .build(); - /// - /// assert_eq!(module.global_section().expect("global section to exist").entries().len(), 1); - /// ``` - pub fn global(self) -> global::GlobalBuilder { - global::GlobalBuilder::with_callback(self) - } + /// Glboal entry builder + /// # Examples + /// ``` + /// use parity_wasm::builder::module; + /// use parity_wasm::elements::Opcode::*; + /// + /// let module = module() + /// .global() + /// .value_type().i32() + /// .init_expr(I32Const(0)) + /// .build() + /// .build(); + /// + /// assert_eq!(module.global_section().expect("global section to exist").entries().len(), 1); + /// ``` + pub fn global(self) -> global::GlobalBuilder { + global::GlobalBuilder::with_callback(self) + } - /// Add data segment to the builder - pub fn with_data_segment(mut self, segment: elements::DataSegment) -> Self { - self.module.data.entries_mut().push(segment); - self - } + /// Add data segment to the builder + pub fn with_data_segment(mut self, segment: elements::DataSegment) -> Self { + self.module.data.entries_mut().push(segment); + self + } - /// Data entry builder - pub fn data(self) -> data::DataSegmentBuilder { - data::DataSegmentBuilder::with_callback(self) - } + /// Data entry builder + pub fn data(self) -> data::DataSegmentBuilder { + data::DataSegmentBuilder::with_callback(self) + } - /// Build module (final step) - pub fn build(self) -> F::Result { - self.callback.invoke(self.module.into()) - } + /// Build module (final step) + pub fn build(self) -> F::Result { + self.callback.invoke(self.module.into()) + } } -impl Invoke for ModuleBuilder - where F: Invoke +impl Invoke for ModuleBuilder + where F: Invoke { type Result = Self; fn invoke(self, section: elements::FunctionSection) -> Self { self.with_section(elements::Section::Function(section)) - } + } } impl Invoke for ModuleBuilder - where F: Invoke + where F: Invoke { - type Result = Self; + type Result = Self; - fn invoke(self, bindings: code::SignatureBindings) -> Self { - self.with_signatures(bindings) - } + fn invoke(self, bindings: code::SignatureBindings) -> Self { + self.with_signatures(bindings) + } } impl Invoke for ModuleBuilder - where F: Invoke + where F: Invoke { - type Result = Self; + type Result = Self; - fn invoke(self, def: code::FunctionDefinition) -> Self { - let mut b = self; - b.push_function(def); - b - } + fn invoke(self, def: code::FunctionDefinition) -> Self { + let mut b = self; + b.push_function(def); + b + } } impl Invoke for ModuleBuilder - where F: Invoke + where F: Invoke { - type Result = Self; + type Result = Self; - fn invoke(self, def: memory::MemoryDefinition) -> Self { - let mut b = self; - b.push_memory(def); - b - } + fn invoke(self, def: memory::MemoryDefinition) -> Self { + let mut b = self; + b.push_memory(def); + b + } } impl Invoke for ModuleBuilder - where F: Invoke + where F: Invoke { - type Result = Self; + type Result = Self; - fn invoke(self, def: table::TableDefinition) -> Self { - let mut b = self; - b.push_table(def); - b - } + fn invoke(self, def: table::TableDefinition) -> Self { + let mut b = self; + b.push_table(def); + b + } } impl Invoke for ModuleBuilder - where F: Invoke + where F: Invoke { - type Result = Self; + type Result = Self; - fn invoke(self, entry: elements::ImportEntry) -> Self::Result { - self.with_import(entry) - } + fn invoke(self, entry: elements::ImportEntry) -> Self::Result { + self.with_import(entry) + } } impl Invoke for ModuleBuilder - where F: Invoke + where F: Invoke { - type Result = Self; + type Result = Self; - fn invoke(self, entry: elements::ExportEntry) -> Self::Result { - self.with_export(entry) - } + fn invoke(self, entry: elements::ExportEntry) -> Self::Result { + self.with_export(entry) + } } impl Invoke for ModuleBuilder - where F: Invoke + where F: Invoke { - type Result = Self; + type Result = Self; - fn invoke(self, entry: elements::GlobalEntry) -> Self::Result { - self.with_global(entry) - } + fn invoke(self, entry: elements::GlobalEntry) -> Self::Result { + self.with_global(entry) + } } -impl Invoke for ModuleBuilder - where F: Invoke +impl Invoke for ModuleBuilder + where F: Invoke { type Result = Self; fn invoke(self, segment: elements::DataSegment) -> Self { self.with_data_segment(segment) - } + } } /// Start new module builder @@ -492,7 +492,7 @@ impl Invoke for ModuleBuilder /// /// ``` /// use parity_wasm::builder; -/// +/// /// let module = builder::module() /// .function() /// .signature().param().i32().build() @@ -505,66 +505,66 @@ impl Invoke for ModuleBuilder /// assert_eq!(module.code_section().expect("code section to exist").bodies().len(), 1); /// ``` pub fn module() -> ModuleBuilder { - ModuleBuilder::new() + ModuleBuilder::new() } /// Start builder to extend existing module pub fn from_module(module: elements::Module) -> ModuleBuilder { - ModuleBuilder::new().with_module(module) + ModuleBuilder::new().with_module(module) } #[cfg(test)] mod tests { - use super::module; + use super::module; - #[test] - fn smoky() { - let module = module().build(); - assert_eq!(module.sections().len(), 0); - } + #[test] + fn smoky() { + let module = module().build(); + assert_eq!(module.sections().len(), 0); + } - #[test] - fn functions() { - let module = module() - .function() - .signature().param().i32().build() - .body().build() - .build() - .build(); + #[test] + fn functions() { + let module = module() + .function() + .signature().param().i32().build() + .body().build() + .build() + .build(); - assert_eq!(module.type_section().expect("type section to exist").types().len(), 1); - assert_eq!(module.function_section().expect("function section to exist").entries().len(), 1); - assert_eq!(module.code_section().expect("code section to exist").bodies().len(), 1); - } + assert_eq!(module.type_section().expect("type section to exist").types().len(), 1); + assert_eq!(module.function_section().expect("function section to exist").entries().len(), 1); + assert_eq!(module.code_section().expect("code section to exist").bodies().len(), 1); + } - #[test] - fn export() { - let module = module() - .export().field("call").internal().func(0).build() - .build(); + #[test] + fn export() { + let module = module() + .export().field("call").internal().func(0).build() + .build(); - assert_eq!(module.export_section().expect("export section to exist").entries().len(), 1); - } + assert_eq!(module.export_section().expect("export section to exist").entries().len(), 1); + } - #[test] - fn global() { - let module = module() - .global().value_type().i64().mutable().init_expr(::elements::Opcode::I64Const(5)).build() - .build(); + #[test] + fn global() { + let module = module() + .global().value_type().i64().mutable().init_expr(::elements::Opcode::I64Const(5)).build() + .build(); - assert_eq!(module.global_section().expect("global section to exist").entries().len(), 1); - } + assert_eq!(module.global_section().expect("global section to exist").entries().len(), 1); + } - #[test] - fn data() { - let module = module() - .data() - .offset(::elements::Opcode::I32Const(16)) - .value(vec![0u8, 15, 10, 5, 25]) - .build() - .build(); + #[test] + fn data() { + let module = module() + .data() + .offset(::elements::Opcode::I32Const(16)) + .value(vec![0u8, 15, 10, 5, 25]) + .build() + .build(); - assert_eq!(module.data_section().expect("data section to exist").entries().len(), 1); - } + assert_eq!(module.data_section().expect("data section to exist").entries().len(), 1); + } } diff --git a/src/builder/table.rs b/src/builder/table.rs index e5e35b6..c7ebf82 100644 --- a/src/builder/table.rs +++ b/src/builder/table.rs @@ -4,81 +4,81 @@ use super::invoke::{Invoke, Identity}; /// Table definition #[derive(Debug)] pub struct TableDefinition { - /// Minimum length - pub min: u32, - /// Maximum length, if any - pub max: Option, - /// Element segments, if any - pub elements: Vec, + /// Minimum length + pub min: u32, + /// Maximum length, if any + pub max: Option, + /// Element segments, if any + pub elements: Vec, } /// Table elements entry definition #[derive(Debug)] pub struct TableEntryDefinition { - /// Offset initialization expression - pub offset: elements::InitExpr, - /// Values of initialization - pub values: Vec, + /// Offset initialization expression + pub offset: elements::InitExpr, + /// Values of initialization + pub values: Vec, } /// Table builder pub struct TableBuilder { - callback: F, - table: TableDefinition, + callback: F, + table: TableDefinition, } impl TableBuilder { - /// New table builder - pub fn new() -> Self { - TableBuilder::with_callback(Identity) - } + /// New table builder + pub fn new() -> Self { + TableBuilder::with_callback(Identity) + } } impl TableBuilder where F: Invoke { - /// New table builder with callback in chained context - pub fn with_callback(callback: F) -> Self { - TableBuilder { - callback: callback, - table: Default::default(), - } - } + /// New table builder with callback in chained context + pub fn with_callback(callback: F) -> Self { + TableBuilder { + callback: callback, + table: Default::default(), + } + } - /// Set/override minimum length - pub fn with_min(mut self, min: u32) -> Self { - self.table.min = min; - self - } + /// Set/override minimum length + pub fn with_min(mut self, min: u32) -> Self { + self.table.min = min; + self + } - /// Set/override maximum length - pub fn with_max(mut self, max: Option) -> Self { - self.table.max = max; - self - } + /// Set/override maximum length + pub fn with_max(mut self, max: Option) -> Self { + self.table.max = max; + self + } - /// Generate initialization expression and element values on specified index - pub fn with_element(mut self, index: u32, values: Vec) -> Self { - self.table.elements.push(TableEntryDefinition { - offset: elements::InitExpr::new(vec![ - elements::Opcode::I32Const(index as i32), - elements::Opcode::End, - ]), - values: values, - }); - self - } + /// Generate initialization expression and element values on specified index + pub fn with_element(mut self, index: u32, values: Vec) -> Self { + self.table.elements.push(TableEntryDefinition { + offset: elements::InitExpr::new(vec![ + elements::Opcode::I32Const(index as i32), + elements::Opcode::End, + ]), + values: values, + }); + self + } - /// Finalize current builder spawning resulting struct - pub fn build(self) -> F::Result { - self.callback.invoke(self.table) - } + /// Finalize current builder spawning resulting struct + pub fn build(self) -> F::Result { + self.callback.invoke(self.table) + } } impl Default for TableDefinition { - fn default() -> Self { - TableDefinition { - min: 0, - max: None, - elements: Vec::new(), - } - } + fn default() -> Self { + TableDefinition { + min: 0, + max: None, + elements: Vec::new(), + } + } } diff --git a/src/elements/export_entry.rs b/src/elements/export_entry.rs index 68c079b..5348981 100644 --- a/src/elements/export_entry.rs +++ b/src/elements/export_entry.rs @@ -4,98 +4,98 @@ use super::{Deserialize, Serialize, Error, VarUint7, VarUint32}; /// Internal reference of the exported entry. #[derive(Debug, Clone, Copy)] pub enum Internal { - /// Function reference. - Function(u32), - /// Table reference. - Table(u32), - /// Memory reference. - Memory(u32), - /// Global reference. - Global(u32), + /// Function reference. + Function(u32), + /// Table reference. + Table(u32), + /// Memory reference. + Memory(u32), + /// Global reference. + Global(u32), } impl Deserialize for Internal { - type Error = Error; + type Error = Error; - fn deserialize(reader: &mut R) -> Result { - let kind = VarUint7::deserialize(reader)?; - match kind.into() { - 0x00 => Ok(Internal::Function(VarUint32::deserialize(reader)?.into())), - 0x01 => Ok(Internal::Table(VarUint32::deserialize(reader)?.into())), - 0x02 => Ok(Internal::Memory(VarUint32::deserialize(reader)?.into())), - 0x03 => Ok(Internal::Global(VarUint32::deserialize(reader)?.into())), - _ => Err(Error::UnknownInternalKind(kind.into())), - } - } + fn deserialize(reader: &mut R) -> Result { + let kind = VarUint7::deserialize(reader)?; + match kind.into() { + 0x00 => Ok(Internal::Function(VarUint32::deserialize(reader)?.into())), + 0x01 => Ok(Internal::Table(VarUint32::deserialize(reader)?.into())), + 0x02 => Ok(Internal::Memory(VarUint32::deserialize(reader)?.into())), + 0x03 => Ok(Internal::Global(VarUint32::deserialize(reader)?.into())), + _ => Err(Error::UnknownInternalKind(kind.into())), + } + } } impl Serialize for Internal { - type Error = Error; + type Error = Error; - fn serialize(self, writer: &mut W) -> Result<(), Self::Error> { - let (bt, arg) = match self { - Internal::Function(arg) => (0x00, arg), - Internal::Table(arg) => (0x01, arg), - Internal::Memory(arg) => (0x02, arg), - Internal::Global(arg) => (0x03, arg), - }; + fn serialize(self, writer: &mut W) -> Result<(), Self::Error> { + let (bt, arg) = match self { + Internal::Function(arg) => (0x00, arg), + Internal::Table(arg) => (0x01, arg), + Internal::Memory(arg) => (0x02, arg), + Internal::Global(arg) => (0x03, arg), + }; - VarUint7::from(bt).serialize(writer)?; - VarUint32::from(arg).serialize(writer)?; + VarUint7::from(bt).serialize(writer)?; + VarUint32::from(arg).serialize(writer)?; - Ok(()) - } + Ok(()) + } } /// Export entry. #[derive(Debug, Clone)] pub struct ExportEntry { - field_str: String, - internal: Internal, + field_str: String, + internal: Internal, } impl ExportEntry { - /// New export entry - pub fn new(field: String, internal: Internal) -> Self { - ExportEntry { - field_str: field, - internal: internal - } - } + /// New export entry + pub fn new(field: String, internal: Internal) -> Self { + ExportEntry { + field_str: field, + internal: internal + } + } - /// Public name - pub fn field(&self) -> &str { &self.field_str } + /// Public name + pub fn field(&self) -> &str { &self.field_str } - /// Public name (mutable) - pub fn field_mut(&mut self) -> &mut String { &mut self.field_str } + /// Public name (mutable) + pub fn field_mut(&mut self) -> &mut String { &mut self.field_str } - /// Internal reference of the export entry. - pub fn internal(&self) -> &Internal { &self.internal } + /// Internal reference of the export entry. + pub fn internal(&self) -> &Internal { &self.internal } - /// Internal reference of the export entry (mutable). - pub fn internal_mut(&mut self) -> &mut Internal { &mut self.internal } + /// Internal reference of the export entry (mutable). + pub fn internal_mut(&mut self) -> &mut Internal { &mut self.internal } } impl Deserialize for ExportEntry { - type Error = Error; + type Error = Error; - fn deserialize(reader: &mut R) -> Result { - let field_str = String::deserialize(reader)?; - let internal = Internal::deserialize(reader)?; + fn deserialize(reader: &mut R) -> Result { + let field_str = String::deserialize(reader)?; + let internal = Internal::deserialize(reader)?; - Ok(ExportEntry { - field_str: field_str, - internal: internal, - }) - } + Ok(ExportEntry { + field_str: field_str, + internal: internal, + }) + } } impl Serialize for ExportEntry { - type Error = Error; + type Error = Error; - fn serialize(self, writer: &mut W) -> Result<(), Self::Error> { - self.field_str.serialize(writer)?; - self.internal.serialize(writer)?; - Ok(()) - } + fn serialize(self, writer: &mut W) -> Result<(), Self::Error> { + self.field_str.serialize(writer)?; + self.internal.serialize(writer)?; + Ok(()) + } } diff --git a/src/elements/func.rs b/src/elements/func.rs index 256fc94..6630e00 100644 --- a/src/elements/func.rs +++ b/src/elements/func.rs @@ -1,7 +1,7 @@ use std::io; use super::{ - Deserialize, Error, ValueType, VarUint32, CountedList, Opcodes, - Serialize, CountedWriter, CountedListWriter, + Deserialize, Error, ValueType, VarUint32, CountedList, Opcodes, + Serialize, CountedWriter, CountedListWriter, }; /// Function signature (type reference) @@ -9,122 +9,122 @@ use super::{ pub struct Func(u32); impl Func { - /// New function signature - pub fn new(type_ref: u32) -> Self { Func(type_ref) } + /// New function signature + pub fn new(type_ref: u32) -> Self { Func(type_ref) } - /// Function signature type reference. - pub fn type_ref(&self) -> u32 { - self.0 - } + /// Function signature type reference. + pub fn type_ref(&self) -> u32 { + self.0 + } - /// Function signature type reference (mutable). - pub fn type_ref_mut(&mut self) -> &mut u32 { - &mut self.0 - } + /// Function signature type reference (mutable). + pub fn type_ref_mut(&mut self) -> &mut u32 { + &mut self.0 + } } /// Local definition inside the function body. #[derive(Debug, Copy, Clone)] pub struct Local { - count: u32, - value_type: ValueType, + count: u32, + value_type: ValueType, } impl Local { - /// New local with `count` and `value_type`. - pub fn new(count: u32, value_type: ValueType) -> Self { - Local { count: count, value_type: value_type } - } + /// New local with `count` and `value_type`. + pub fn new(count: u32, value_type: ValueType) -> Self { + Local { count: count, value_type: value_type } + } - /// Number of locals with the shared type. - pub fn count(&self) -> u32 { self.count } + /// Number of locals with the shared type. + pub fn count(&self) -> u32 { self.count } - /// Type of the locals. - pub fn value_type(&self) -> ValueType { self.value_type } + /// Type of the locals. + pub fn value_type(&self) -> ValueType { self.value_type } } impl Deserialize for Local { - type Error = Error; + type Error = Error; - fn deserialize(reader: &mut R) -> Result { - let count = VarUint32::deserialize(reader)?; - let value_type = ValueType::deserialize(reader)?; - Ok(Local { count: count.into(), value_type: value_type }) - } + fn deserialize(reader: &mut R) -> Result { + let count = VarUint32::deserialize(reader)?; + let value_type = ValueType::deserialize(reader)?; + Ok(Local { count: count.into(), value_type: value_type }) + } } impl Serialize for Local { - type Error = Error; + type Error = Error; - fn serialize(self, writer: &mut W) -> Result<(), Self::Error> { - VarUint32::from(self.count).serialize(writer)?; - self.value_type.serialize(writer)?; - Ok(()) - } + fn serialize(self, writer: &mut W) -> Result<(), Self::Error> { + VarUint32::from(self.count).serialize(writer)?; + self.value_type.serialize(writer)?; + Ok(()) + } } /// Function body definition. #[derive(Debug, Clone)] pub struct FuncBody { - locals: Vec, - opcodes: Opcodes, + locals: Vec, + opcodes: Opcodes, } impl FuncBody { - /// New function body with given `locals` and `opcodes` - pub fn new(locals: Vec, opcodes: Opcodes) -> Self { - FuncBody { locals: locals, opcodes: opcodes } - } + /// New function body with given `locals` and `opcodes` + pub fn new(locals: Vec, opcodes: Opcodes) -> Self { + FuncBody { locals: locals, opcodes: opcodes } + } - /// List of individual opcodes - pub fn empty() -> Self { - FuncBody { locals: Vec::new(), opcodes: Opcodes::empty() } - } + /// List of individual opcodes + pub fn empty() -> Self { + FuncBody { locals: Vec::new(), opcodes: Opcodes::empty() } + } - /// Locals declared in function body. - pub fn locals(&self) -> &[Local] { &self.locals } + /// Locals declared in function body. + pub fn locals(&self) -> &[Local] { &self.locals } - /// Opcode sequence of the function body. Minimal opcode sequence - /// is just `&[Opcode::End]` - pub fn code(&self) -> &Opcodes { &self.opcodes } + /// Opcode sequence of the function body. Minimal opcode sequence + /// is just `&[Opcode::End]` + pub fn code(&self) -> &Opcodes { &self.opcodes } - /// Locals declared in function body (mutable). - pub fn locals_mut(&mut self) -> &mut Vec { &mut self.locals } + /// Locals declared in function body (mutable). + pub fn locals_mut(&mut self) -> &mut Vec { &mut self.locals } - /// Opcode sequence of the function body (mutable). - pub fn code_mut(&mut self) -> &mut Opcodes { &mut self.opcodes } + /// Opcode sequence of the function body (mutable). + pub fn code_mut(&mut self) -> &mut Opcodes { &mut self.opcodes } } impl Deserialize for FuncBody { - type Error = Error; + type Error = Error; - fn deserialize(reader: &mut R) -> Result { - // todo: maybe use reader.take(section_length) - let _body_size = VarUint32::deserialize(reader)?; - let locals: Vec = CountedList::deserialize(reader)?.into_inner(); - let opcodes = Opcodes::deserialize(reader)?; - Ok(FuncBody { locals: locals, opcodes: opcodes }) - } + fn deserialize(reader: &mut R) -> Result { + // todo: maybe use reader.take(section_length) + let _body_size = VarUint32::deserialize(reader)?; + let locals: Vec = CountedList::deserialize(reader)?.into_inner(); + let opcodes = Opcodes::deserialize(reader)?; + Ok(FuncBody { locals: locals, opcodes: opcodes }) + } } impl Serialize for FuncBody { - type Error = Error; + type Error = Error; - fn serialize(self, writer: &mut W) -> Result<(), Self::Error> { - let mut counted_writer = CountedWriter::new(writer); + fn serialize(self, writer: &mut W) -> Result<(), Self::Error> { + let mut counted_writer = CountedWriter::new(writer); - let data = self.locals; - let counted_list = CountedListWriter::( - data.len(), - data.into_iter().map(Into::into), - ); - counted_list.serialize(&mut counted_writer)?; + let data = self.locals; + let counted_list = CountedListWriter::( + data.len(), + data.into_iter().map(Into::into), + ); + counted_list.serialize(&mut counted_writer)?; - let code = self.opcodes; - code.serialize(&mut counted_writer)?; + let code = self.opcodes; + code.serialize(&mut counted_writer)?; - counted_writer.done()?; + counted_writer.done()?; - Ok(()) - } + Ok(()) + } } diff --git a/src/elements/global_entry.rs b/src/elements/global_entry.rs index c12ae31..9a7ec44 100644 --- a/src/elements/global_entry.rs +++ b/src/elements/global_entry.rs @@ -4,47 +4,47 @@ use super::{Deserialize, Serialize, Error, GlobalType, InitExpr}; /// Global entry in the module. #[derive(Clone, Debug)] pub struct GlobalEntry { - global_type: GlobalType, - init_expr: InitExpr, + global_type: GlobalType, + init_expr: InitExpr, } impl GlobalEntry { - /// New global entry - pub fn new(global_type: GlobalType, init_expr: InitExpr) -> Self { - GlobalEntry { - global_type: global_type, - init_expr: init_expr, - } - } - /// Global type. - pub fn global_type(&self) -> &GlobalType { &self.global_type } - /// Initialization expression (opcodes) for global. - pub fn init_expr(&self) -> &InitExpr { &self.init_expr } - /// Global type (mutable) - pub fn global_type_mut(&mut self) -> &mut GlobalType { &mut self.global_type } - /// Initialization expression (opcodes) for global (mutable) - pub fn init_expr_mut(&mut self) -> &mut InitExpr { &mut self.init_expr } + /// New global entry + pub fn new(global_type: GlobalType, init_expr: InitExpr) -> Self { + GlobalEntry { + global_type: global_type, + init_expr: init_expr, + } + } + /// Global type. + pub fn global_type(&self) -> &GlobalType { &self.global_type } + /// Initialization expression (opcodes) for global. + pub fn init_expr(&self) -> &InitExpr { &self.init_expr } + /// Global type (mutable) + pub fn global_type_mut(&mut self) -> &mut GlobalType { &mut self.global_type } + /// Initialization expression (opcodes) for global (mutable) + pub fn init_expr_mut(&mut self) -> &mut InitExpr { &mut self.init_expr } } impl Deserialize for GlobalEntry { - type Error = Error; + type Error = Error; - fn deserialize(reader: &mut R) -> Result { - let global_type = GlobalType::deserialize(reader)?; - let init_expr = InitExpr::deserialize(reader)?; + fn deserialize(reader: &mut R) -> Result { + let global_type = GlobalType::deserialize(reader)?; + let init_expr = InitExpr::deserialize(reader)?; - Ok(GlobalEntry { - global_type: global_type, - init_expr: init_expr, - }) - } + Ok(GlobalEntry { + global_type: global_type, + init_expr: init_expr, + }) + } } impl Serialize for GlobalEntry { - type Error = Error; + type Error = Error; - fn serialize(self, writer: &mut W) -> Result<(), Self::Error> { - self.global_type.serialize(writer)?; - self.init_expr.serialize(writer) - } + fn serialize(self, writer: &mut W) -> Result<(), Self::Error> { + self.global_type.serialize(writer)?; + self.init_expr.serialize(writer) + } } diff --git a/src/elements/import_entry.rs b/src/elements/import_entry.rs index 69b7e3d..94a09db 100644 --- a/src/elements/import_entry.rs +++ b/src/elements/import_entry.rs @@ -1,152 +1,152 @@ use std::io; use super::{ - Deserialize, Serialize, Error, VarUint7, VarInt7, VarUint32, VarUint1, - ValueType, TableElementType + Deserialize, Serialize, Error, VarUint7, VarInt7, VarUint32, VarUint1, + ValueType, TableElementType }; /// Global definition struct #[derive(Debug, Copy, Clone)] pub struct GlobalType { - content_type: ValueType, - is_mutable: bool, + content_type: ValueType, + is_mutable: bool, } impl GlobalType { - /// New global type - pub fn new(content_type: ValueType, is_mutable: bool) -> Self { - GlobalType { - content_type: content_type, - is_mutable: is_mutable, - } - } + /// New global type + pub fn new(content_type: ValueType, is_mutable: bool) -> Self { + GlobalType { + content_type: content_type, + is_mutable: is_mutable, + } + } - /// Type of the global entry - pub fn content_type(&self) -> ValueType { self.content_type } + /// Type of the global entry + pub fn content_type(&self) -> ValueType { self.content_type } - /// Is global entry is declared as mutable - pub fn is_mutable(&self) -> bool { self.is_mutable } + /// Is global entry is declared as mutable + pub fn is_mutable(&self) -> bool { self.is_mutable } } impl Deserialize for GlobalType { - type Error = Error; + type Error = Error; - fn deserialize(reader: &mut R) -> Result { - let content_type = ValueType::deserialize(reader)?; - let is_mutable = VarUint1::deserialize(reader)?; - Ok(GlobalType { - content_type: content_type, - is_mutable: is_mutable.into(), - }) - } + fn deserialize(reader: &mut R) -> Result { + let content_type = ValueType::deserialize(reader)?; + let is_mutable = VarUint1::deserialize(reader)?; + Ok(GlobalType { + content_type: content_type, + is_mutable: is_mutable.into(), + }) + } } impl Serialize for GlobalType { - type Error = Error; + type Error = Error; - fn serialize(self, writer: &mut W) -> Result<(), Self::Error> { - self.content_type.serialize(writer)?; - VarUint1::from(self.is_mutable).serialize(writer)?; - Ok(()) - } + fn serialize(self, writer: &mut W) -> Result<(), Self::Error> { + self.content_type.serialize(writer)?; + VarUint1::from(self.is_mutable).serialize(writer)?; + Ok(()) + } } /// Table entry #[derive(Debug, Copy, Clone)] pub struct TableType { - elem_type: TableElementType, - limits: ResizableLimits, + elem_type: TableElementType, + limits: ResizableLimits, } impl TableType { - /// New table definition - pub fn new(min: u32, max: Option) -> Self { - TableType { - elem_type: TableElementType::AnyFunc, - limits: ResizableLimits::new(min, max), - } - } + /// New table definition + pub fn new(min: u32, max: Option) -> Self { + TableType { + elem_type: TableElementType::AnyFunc, + limits: ResizableLimits::new(min, max), + } + } - /// Table memory specification - pub fn limits(&self) -> &ResizableLimits { &self.limits } + /// Table memory specification + pub fn limits(&self) -> &ResizableLimits { &self.limits } - /// Table element type - pub fn elem_type(&self) -> TableElementType { self.elem_type } + /// Table element type + pub fn elem_type(&self) -> TableElementType { self.elem_type } } impl Deserialize for TableType { - type Error = Error; + type Error = Error; - fn deserialize(reader: &mut R) -> Result { - let elem_type = TableElementType::deserialize(reader)?; - let limits = ResizableLimits::deserialize(reader)?; - Ok(TableType { - elem_type: elem_type, - limits: limits, - }) - } + fn deserialize(reader: &mut R) -> Result { + let elem_type = TableElementType::deserialize(reader)?; + let limits = ResizableLimits::deserialize(reader)?; + Ok(TableType { + elem_type: elem_type, + limits: limits, + }) + } } impl Serialize for TableType { - type Error = Error; + type Error = Error; - fn serialize(self, writer: &mut W) -> Result<(), Self::Error> { - self.elem_type.serialize(writer)?; - self.limits.serialize(writer) - } + fn serialize(self, writer: &mut W) -> Result<(), Self::Error> { + self.elem_type.serialize(writer)?; + self.limits.serialize(writer) + } } /// Memory limits #[derive(Debug, Copy, Clone)] pub struct ResizableLimits { - initial: u32, - maximum: Option, + initial: u32, + maximum: Option, } impl ResizableLimits { - /// New memory limits definition - pub fn new(min: u32, max: Option) -> Self { - ResizableLimits { - initial: min, - maximum: max, - } - } - /// Initial size - pub fn initial(&self) -> u32 { self.initial } - /// Maximum size - pub fn maximum(&self) -> Option { self.maximum } + /// New memory limits definition + pub fn new(min: u32, max: Option) -> Self { + ResizableLimits { + initial: min, + maximum: max, + } + } + /// Initial size + pub fn initial(&self) -> u32 { self.initial } + /// Maximum size + pub fn maximum(&self) -> Option { self.maximum } } impl Deserialize for ResizableLimits { - type Error = Error; + type Error = Error; - fn deserialize(reader: &mut R) -> Result { - let has_max = VarUint1::deserialize(reader)?; - let initial = VarUint32::deserialize(reader)?; - let maximum = if has_max.into() { - Some(VarUint32::deserialize(reader)?.into()) - } else { - None - }; + fn deserialize(reader: &mut R) -> Result { + let has_max = VarUint1::deserialize(reader)?; + let initial = VarUint32::deserialize(reader)?; + let maximum = if has_max.into() { + Some(VarUint32::deserialize(reader)?.into()) + } else { + None + }; - Ok(ResizableLimits { - initial: initial.into(), - maximum: maximum, - }) - } + Ok(ResizableLimits { + initial: initial.into(), + maximum: maximum, + }) + } } impl Serialize for ResizableLimits { - type Error = Error; + type Error = Error; - fn serialize(self, writer: &mut W) -> Result<(), Self::Error> { - let max = self.maximum; - VarUint1::from(max.is_some()).serialize(writer)?; - VarUint32::from(self.initial).serialize(writer)?; - if let Some(val) = max { - VarUint32::from(val).serialize(writer)?; - } - Ok(()) - } + fn serialize(self, writer: &mut W) -> Result<(), Self::Error> { + let max = self.maximum; + VarUint1::from(max.is_some()).serialize(writer)?; + VarUint32::from(self.initial).serialize(writer)?; + if let Some(val) = max { + VarUint32::from(val).serialize(writer)?; + } + Ok(()) + } } /// Memory entry. @@ -154,152 +154,152 @@ impl Serialize for ResizableLimits { pub struct MemoryType(ResizableLimits); impl MemoryType { - /// New memory definition - pub fn new(min: u32, max: Option) -> Self { - MemoryType(ResizableLimits::new(min, max)) - } - /// Limits of the memory entry. - pub fn limits(&self) -> &ResizableLimits { - &self.0 - } + /// New memory definition + pub fn new(min: u32, max: Option) -> Self { + MemoryType(ResizableLimits::new(min, max)) + } + /// Limits of the memory entry. + pub fn limits(&self) -> &ResizableLimits { + &self.0 + } } impl Deserialize for MemoryType { - type Error = Error; + type Error = Error; - fn deserialize(reader: &mut R) -> Result { - Ok(MemoryType(ResizableLimits::deserialize(reader)?)) - } + fn deserialize(reader: &mut R) -> Result { + Ok(MemoryType(ResizableLimits::deserialize(reader)?)) + } } impl Serialize for MemoryType { - type Error = Error; + type Error = Error; - fn serialize(self, writer: &mut W) -> Result<(), Self::Error> { - self.0.serialize(writer) - } + fn serialize(self, writer: &mut W) -> Result<(), Self::Error> { + self.0.serialize(writer) + } } /// External to local binding. #[derive(Debug, Copy, Clone)] pub enum External { - /// Binds to function with index. - Function(u32), - /// Describes local table definition to be imported as. - Table(TableType), - /// Describes local memory definition to be imported as. - Memory(MemoryType), - /// Describes local global entry to be imported as. - Global(GlobalType), + /// Binds to function with index. + Function(u32), + /// Describes local table definition to be imported as. + Table(TableType), + /// Describes local memory definition to be imported as. + Memory(MemoryType), + /// Describes local global entry to be imported as. + Global(GlobalType), } impl Deserialize for External { - type Error = Error; + type Error = Error; - fn deserialize(reader: &mut R) -> Result { - let kind = VarUint7::deserialize(reader)?; - match kind.into() { - 0x00 => Ok(External::Function(VarUint32::deserialize(reader)?.into())), - 0x01 => Ok(External::Table(TableType::deserialize(reader)?)), - 0x02 => Ok(External::Memory(MemoryType::deserialize(reader)?)), - 0x03 => Ok(External::Global(GlobalType::deserialize(reader)?)), - _ => Err(Error::UnknownExternalKind(kind.into())), - } - } + fn deserialize(reader: &mut R) -> Result { + let kind = VarUint7::deserialize(reader)?; + match kind.into() { + 0x00 => Ok(External::Function(VarUint32::deserialize(reader)?.into())), + 0x01 => Ok(External::Table(TableType::deserialize(reader)?)), + 0x02 => Ok(External::Memory(MemoryType::deserialize(reader)?)), + 0x03 => Ok(External::Global(GlobalType::deserialize(reader)?)), + _ => Err(Error::UnknownExternalKind(kind.into())), + } + } } impl Serialize for External { - type Error = Error; + type Error = Error; - fn serialize(self, writer: &mut W) -> Result<(), Self::Error> { - use self::External::*; + fn serialize(self, writer: &mut W) -> Result<(), Self::Error> { + use self::External::*; - match self { - Function(index) => { - VarUint7::from(0x00).serialize(writer)?; - VarUint32::from(index).serialize(writer)?; - }, - Table(tt) => { - VarInt7::from(0x01).serialize(writer)?; - tt.serialize(writer)?; - }, - Memory(mt) => { - VarInt7::from(0x02).serialize(writer)?; - mt.serialize(writer)?; - }, - Global(gt) => { - VarInt7::from(0x03).serialize(writer)?; - gt.serialize(writer)?; - }, - } + match self { + Function(index) => { + VarUint7::from(0x00).serialize(writer)?; + VarUint32::from(index).serialize(writer)?; + }, + Table(tt) => { + VarInt7::from(0x01).serialize(writer)?; + tt.serialize(writer)?; + }, + Memory(mt) => { + VarInt7::from(0x02).serialize(writer)?; + mt.serialize(writer)?; + }, + Global(gt) => { + VarInt7::from(0x03).serialize(writer)?; + gt.serialize(writer)?; + }, + } - Ok(()) - } + Ok(()) + } } /// Import entry. #[derive(Debug, Clone)] pub struct ImportEntry { - module_str: String, - field_str: String, - external: External, + module_str: String, + field_str: String, + external: External, } impl ImportEntry { - /// New import entry. - pub fn new(module_str: String, field_str: String, external: External) -> Self { - ImportEntry { - module_str: module_str, - field_str: field_str, - external: external, - } - } + /// New import entry. + pub fn new(module_str: String, field_str: String, external: External) -> Self { + ImportEntry { + module_str: module_str, + field_str: field_str, + external: external, + } + } - /// Module reference of the import entry. - pub fn module(&self) -> &str { &self.module_str } + /// Module reference of the import entry. + pub fn module(&self) -> &str { &self.module_str } - /// Module reference of the import entry (mutable). - pub fn module_mut(&mut self) -> &mut String { - &mut self.module_str - } + /// Module reference of the import entry (mutable). + pub fn module_mut(&mut self) -> &mut String { + &mut self.module_str + } - /// Field reference of the import entry. - pub fn field(&self) -> &str { &self.field_str } + /// Field reference of the import entry. + pub fn field(&self) -> &str { &self.field_str } - /// Field reference of the import entry (mutable) - pub fn field_mut(&mut self) -> &mut String { - &mut self.field_str - } + /// Field reference of the import entry (mutable) + pub fn field_mut(&mut self) -> &mut String { + &mut self.field_str + } - /// Local binidng of the import entry. - pub fn external(&self) -> &External { &self.external } + /// Local binidng of the import entry. + pub fn external(&self) -> &External { &self.external } - /// Local binidng of the import entry (mutable) - pub fn external_mut(&mut self) -> &mut External { &mut self.external } + /// Local binidng of the import entry (mutable) + pub fn external_mut(&mut self) -> &mut External { &mut self.external } } impl Deserialize for ImportEntry { - type Error = Error; + type Error = Error; - fn deserialize(reader: &mut R) -> Result { - let module_str = String::deserialize(reader)?; - let field_str = String::deserialize(reader)?; - let external = External::deserialize(reader)?; + fn deserialize(reader: &mut R) -> Result { + let module_str = String::deserialize(reader)?; + let field_str = String::deserialize(reader)?; + let external = External::deserialize(reader)?; - Ok(ImportEntry { - module_str: module_str, - field_str: field_str, - external: external, - }) - } + Ok(ImportEntry { + module_str: module_str, + field_str: field_str, + external: external, + }) + } } impl Serialize for ImportEntry { - type Error = Error; + type Error = Error; - fn serialize(self, writer: &mut W) -> Result<(), Self::Error> { - self.module_str.serialize(writer)?; - self.field_str.serialize(writer)?; - self.external.serialize(writer) - } + fn serialize(self, writer: &mut W) -> Result<(), Self::Error> { + self.module_str.serialize(writer)?; + self.field_str.serialize(writer)?; + self.external.serialize(writer) + } } diff --git a/src/elements/index_map.rs b/src/elements/index_map.rs index 0ad3b60..9dc9b3c 100644 --- a/src/elements/index_map.rs +++ b/src/elements/index_map.rs @@ -16,574 +16,574 @@ use super::{Deserialize, Error, Serialize, VarUint32}; /// deserializing mechanism which addressed this problem. #[derive(Debug, Default)] pub struct IndexMap { - /// The number of non-`None` entries in this map. - len: usize, + /// The number of non-`None` entries in this map. + len: usize, - /// A vector of entries. Missing entries are represented as `None`. - entries: Vec>, + /// A vector of entries. Missing entries are represented as `None`. + entries: Vec>, } impl IndexMap { - /// Create an empty `IndexMap`, preallocating enough space to store - /// `capacity` entries without needing to reallocate the underlying memory. - pub fn with_capacity(capacity: usize) -> IndexMap { - IndexMap { - len: 0, - entries: Vec::with_capacity(capacity), - } - } + /// Create an empty `IndexMap`, preallocating enough space to store + /// `capacity` entries without needing to reallocate the underlying memory. + pub fn with_capacity(capacity: usize) -> IndexMap { + IndexMap { + len: 0, + entries: Vec::with_capacity(capacity), + } + } - /// Clear the map. - pub fn clear(&mut self) { - self.entries.clear(); - self.len = 0; - } + /// Clear the map. + pub fn clear(&mut self) { + self.entries.clear(); + self.len = 0; + } - /// Return the name for the specified index, if it exists. - pub fn get(&self, idx: u32) -> Option<&T> { - match self.entries.get(idx as usize) { - Some(&Some(ref value)) => Some(value), - Some(&None) | None => None, - } - } + /// Return the name for the specified index, if it exists. + pub fn get(&self, idx: u32) -> Option<&T> { + match self.entries.get(idx as usize) { + Some(&Some(ref value)) => Some(value), + Some(&None) | None => None, + } + } - /// Does the map contain an entry for the specified index? - pub fn contains_key(&self, idx: u32) -> bool { - match self.entries.get(idx as usize) { - Some(&Some(_)) => true, - Some(&None) | None => false, - } - } + /// Does the map contain an entry for the specified index? + pub fn contains_key(&self, idx: u32) -> bool { + match self.entries.get(idx as usize) { + Some(&Some(_)) => true, + Some(&None) | None => false, + } + } - /// Insert a name into our map, returning the existing value if present. - /// - /// Note: This API is designed for reasonably dense indices based on valid - /// data. Inserting a huge `idx` will use up a lot of RAM, and this function - /// will not try to protect you against that. - pub fn insert(&mut self, idx: u32, value: T) -> Option { - let idx = idx as usize; - let result = if idx >= self.entries.len() { - // We need to grow the array, and add the new element at the end. - for _ in 0..(idx - self.entries.len()) { - // We can't use `extend(repeat(None)).take(n)`, because that - // would require `T` to implement `Clone`. - self.entries.push(None); - } - self.entries.push(Some(value)); - debug_assert_eq!(idx + 1, self.entries.len()); - self.len += 1; - None - } else { - // We're either replacing an existing element, or filling in a - // missing one. - let existing = self.entries[idx].take(); - if existing.is_none() { - self.len += 1; - } - self.entries[idx] = Some(value); - existing - }; - debug_assert!(self.entries.len() <= (::std::u32::MAX as usize) + 1); - #[cfg(debug_assertions)] - debug_assert_eq!(self.len, self.slow_len()); - result - } + /// Insert a name into our map, returning the existing value if present. + /// + /// Note: This API is designed for reasonably dense indices based on valid + /// data. Inserting a huge `idx` will use up a lot of RAM, and this function + /// will not try to protect you against that. + pub fn insert(&mut self, idx: u32, value: T) -> Option { + let idx = idx as usize; + let result = if idx >= self.entries.len() { + // We need to grow the array, and add the new element at the end. + for _ in 0..(idx - self.entries.len()) { + // We can't use `extend(repeat(None)).take(n)`, because that + // would require `T` to implement `Clone`. + self.entries.push(None); + } + self.entries.push(Some(value)); + debug_assert_eq!(idx + 1, self.entries.len()); + self.len += 1; + None + } else { + // We're either replacing an existing element, or filling in a + // missing one. + let existing = self.entries[idx].take(); + if existing.is_none() { + self.len += 1; + } + self.entries[idx] = Some(value); + existing + }; + debug_assert!(self.entries.len() <= (::std::u32::MAX as usize) + 1); + #[cfg(debug_assertions)] + debug_assert_eq!(self.len, self.slow_len()); + result + } - /// Remove an item if present and return it. - pub fn remove(&mut self, idx: u32) -> Option { - let result = match self.entries.get_mut(idx as usize) { - Some(value @ &mut Some(_)) => { - self.len -= 1; - value.take() - } - Some(&mut None) | None => None, - }; - #[cfg(debug_assertions)] - debug_assert_eq!(self.len, self.slow_len()); - result - } + /// Remove an item if present and return it. + pub fn remove(&mut self, idx: u32) -> Option { + let result = match self.entries.get_mut(idx as usize) { + Some(value @ &mut Some(_)) => { + self.len -= 1; + value.take() + } + Some(&mut None) | None => None, + }; + #[cfg(debug_assertions)] + debug_assert_eq!(self.len, self.slow_len()); + result + } - /// The number of items in this map. - pub fn len(&self) -> usize { - #[cfg(debug_assertions)] - debug_assert_eq!(self.len, self.slow_len()); - self.len - } + /// The number of items in this map. + pub fn len(&self) -> usize { + #[cfg(debug_assertions)] + debug_assert_eq!(self.len, self.slow_len()); + self.len + } - /// Is this map empty? - pub fn is_empty(&self) -> bool { - self.len == 0 - } + /// Is this map empty? + pub fn is_empty(&self) -> bool { + self.len == 0 + } - /// This function is only compiled when `-C debug-assertions` is enabled. - /// It computes the `len` value using a slow algorithm. - /// - /// WARNING: This turns a bunch of O(n) operations into O(n^2) operations. - /// We may want to remove it once the code is tested, or to put it behind - /// a feature flag named `slow_debug_checks`, or something like that. - #[cfg(debug_assertions)] - fn slow_len(&self) -> usize { - self.entries.iter().filter(|entry| entry.is_some()).count() - } + /// This function is only compiled when `-C debug-assertions` is enabled. + /// It computes the `len` value using a slow algorithm. + /// + /// WARNING: This turns a bunch of O(n) operations into O(n^2) operations. + /// We may want to remove it once the code is tested, or to put it behind + /// a feature flag named `slow_debug_checks`, or something like that. + #[cfg(debug_assertions)] + fn slow_len(&self) -> usize { + self.entries.iter().filter(|entry| entry.is_some()).count() + } - /// Create a non-consuming iterator over this `IndexMap`'s keys and values. - pub fn iter(&self) -> Iter { - // Note that this does the right thing because we use `&self`. - self.into_iter() - } + /// Create a non-consuming iterator over this `IndexMap`'s keys and values. + pub fn iter(&self) -> Iter { + // Note that this does the right thing because we use `&self`. + self.into_iter() + } - /// Custom deserialization routine. - /// - /// We will allocate an underlying array no larger than `max_entry_space` to - /// hold the data, so the maximum index must be less than `max_entry_space`. - /// This prevents mallicious *.wasm files from having a single entry with - /// the index `u32::MAX`, which would consume far too much memory. - /// - /// The `deserialize_value` function will be passed the index of the value - /// being deserialized, and must deserialize the value. - pub fn deserialize_with( - max_entry_space: usize, - deserialize_value: &F, - rdr: &mut R, - ) -> Result, Error> - where - R: Read, - F: Fn(u32, &mut R) -> Result, - { - let len: u32 = VarUint32::deserialize(rdr)?.into(); - let mut map = IndexMap::with_capacity(len as usize); - let mut prev_idx = None; - for _ in 0..len { - let idx: u32 = VarUint32::deserialize(rdr)?.into(); - if idx as usize >= max_entry_space { - return Err(Error::Other("index is larger than expected")); - } - match prev_idx { - Some(prev) if prev >= idx => { - // Supposedly these names must be "sorted by index", so - // let's try enforcing that and seeing what happens. - return Err(Error::Other("indices are out of order")); - } - _ => { - prev_idx = Some(idx); - } - } - let val = deserialize_value(idx, rdr)?; - map.insert(idx, val); - } - Ok(map) - } + /// Custom deserialization routine. + /// + /// We will allocate an underlying array no larger than `max_entry_space` to + /// hold the data, so the maximum index must be less than `max_entry_space`. + /// This prevents mallicious *.wasm files from having a single entry with + /// the index `u32::MAX`, which would consume far too much memory. + /// + /// The `deserialize_value` function will be passed the index of the value + /// being deserialized, and must deserialize the value. + pub fn deserialize_with( + max_entry_space: usize, + deserialize_value: &F, + rdr: &mut R, + ) -> Result, Error> + where + R: Read, + F: Fn(u32, &mut R) -> Result, + { + let len: u32 = VarUint32::deserialize(rdr)?.into(); + let mut map = IndexMap::with_capacity(len as usize); + let mut prev_idx = None; + for _ in 0..len { + let idx: u32 = VarUint32::deserialize(rdr)?.into(); + if idx as usize >= max_entry_space { + return Err(Error::Other("index is larger than expected")); + } + match prev_idx { + Some(prev) if prev >= idx => { + // Supposedly these names must be "sorted by index", so + // let's try enforcing that and seeing what happens. + return Err(Error::Other("indices are out of order")); + } + _ => { + prev_idx = Some(idx); + } + } + let val = deserialize_value(idx, rdr)?; + map.insert(idx, val); + } + Ok(map) + } } impl Clone for IndexMap { - fn clone(&self) -> IndexMap { - IndexMap { - len: self.len, - entries: self.entries.clone(), - } - } + fn clone(&self) -> IndexMap { + IndexMap { + len: self.len, + entries: self.entries.clone(), + } + } } impl PartialEq> for IndexMap { - fn eq(&self, other: &IndexMap) -> bool { - if self.len() != other.len() { - // If the number of non-`None` entries is different, we can't match. - false - } else { - // This is tricky, because one `Vec` might have a bunch of empty - // entries at the end which we want to ignore. - let smallest_len = min(self.entries.len(), other.entries.len()); - self.entries[0..smallest_len].eq(&other.entries[0..smallest_len]) - } - } + fn eq(&self, other: &IndexMap) -> bool { + if self.len() != other.len() { + // If the number of non-`None` entries is different, we can't match. + false + } else { + // This is tricky, because one `Vec` might have a bunch of empty + // entries at the end which we want to ignore. + let smallest_len = min(self.entries.len(), other.entries.len()); + self.entries[0..smallest_len].eq(&other.entries[0..smallest_len]) + } + } } impl Eq for IndexMap {} impl FromIterator<(u32, T)> for IndexMap { - /// Create an `IndexMap` from an iterator. - /// - /// Note: This API is designed for reasonably dense indices based on valid - /// data. Inserting a huge `idx` will use up a lot of RAM, and this function - /// will not try to protect you against that. - fn from_iter(iter: I) -> Self - where - I: IntoIterator, - { - let iter = iter.into_iter(); - let (lower, upper_opt) = iter.size_hint(); - let mut map = IndexMap::with_capacity(upper_opt.unwrap_or(lower)); - for (idx, value) in iter { - map.insert(idx, value); - } - map - } + /// Create an `IndexMap` from an iterator. + /// + /// Note: This API is designed for reasonably dense indices based on valid + /// data. Inserting a huge `idx` will use up a lot of RAM, and this function + /// will not try to protect you against that. + fn from_iter(iter: I) -> Self + where + I: IntoIterator, + { + let iter = iter.into_iter(); + let (lower, upper_opt) = iter.size_hint(); + let mut map = IndexMap::with_capacity(upper_opt.unwrap_or(lower)); + for (idx, value) in iter { + map.insert(idx, value); + } + map + } } /// An iterator over an `IndexMap` which takes ownership of it. pub struct IntoIter { - next_idx: u32, - remaining_len: usize, - iter: vec::IntoIter>, + next_idx: u32, + remaining_len: usize, + iter: vec::IntoIter>, } impl Iterator for IntoIter { - type Item = (u32, T); + type Item = (u32, T); - fn size_hint(&self) -> (usize, Option) { - (self.remaining_len, Some(self.remaining_len)) - } + fn size_hint(&self) -> (usize, Option) { + (self.remaining_len, Some(self.remaining_len)) + } - fn next(&mut self) -> Option { - // Bail early if we know there are no more items. This also keeps us - // from repeatedly calling `self.iter.next()` once it has been - // exhausted, which is not guaranteed to keep returning `None`. - if self.remaining_len == 0 { - return None; - } - while let Some(value_opt) = self.iter.next() { - let idx = self.next_idx; - self.next_idx += 1; - if let Some(value) = value_opt { - self.remaining_len -= 1; - return Some((idx, value)); - } - } - debug_assert_eq!(self.remaining_len, 0); - None - } + fn next(&mut self) -> Option { + // Bail early if we know there are no more items. This also keeps us + // from repeatedly calling `self.iter.next()` once it has been + // exhausted, which is not guaranteed to keep returning `None`. + if self.remaining_len == 0 { + return None; + } + while let Some(value_opt) = self.iter.next() { + let idx = self.next_idx; + self.next_idx += 1; + if let Some(value) = value_opt { + self.remaining_len -= 1; + return Some((idx, value)); + } + } + debug_assert_eq!(self.remaining_len, 0); + None + } } impl IntoIterator for IndexMap { - type Item = (u32, T); - type IntoIter = IntoIter; + type Item = (u32, T); + type IntoIter = IntoIter; - fn into_iter(self) -> IntoIter { - IntoIter { - next_idx: 0, - remaining_len: self.len, - iter: self.entries.into_iter(), - } - } + fn into_iter(self) -> IntoIter { + IntoIter { + next_idx: 0, + remaining_len: self.len, + iter: self.entries.into_iter(), + } + } } /// An iterator over a borrowed `IndexMap`. pub struct Iter<'a, T: 'static> { - next_idx: u32, - remaining_len: usize, - iter: slice::Iter<'a, Option>, + next_idx: u32, + remaining_len: usize, + iter: slice::Iter<'a, Option>, } impl<'a, T: 'static> Iterator for Iter<'a, T> { - type Item = (u32, &'a T); + type Item = (u32, &'a T); - fn size_hint(&self) -> (usize, Option) { - (self.remaining_len, Some(self.remaining_len)) - } + fn size_hint(&self) -> (usize, Option) { + (self.remaining_len, Some(self.remaining_len)) + } - fn next(&mut self) -> Option { - // Bail early if we know there are no more items. This also keeps us - // from repeatedly calling `self.iter.next()` once it has been - // exhausted, which is not guaranteed to keep returning `None`. - if self.remaining_len == 0 { - return None; - } - while let Some(value_opt) = self.iter.next() { - let idx = self.next_idx; - self.next_idx += 1; - if let &Some(ref value) = value_opt { - self.remaining_len -= 1; - return Some((idx, value)); - } - } - debug_assert_eq!(self.remaining_len, 0); - None - } + fn next(&mut self) -> Option { + // Bail early if we know there are no more items. This also keeps us + // from repeatedly calling `self.iter.next()` once it has been + // exhausted, which is not guaranteed to keep returning `None`. + if self.remaining_len == 0 { + return None; + } + while let Some(value_opt) = self.iter.next() { + let idx = self.next_idx; + self.next_idx += 1; + if let &Some(ref value) = value_opt { + self.remaining_len -= 1; + return Some((idx, value)); + } + } + debug_assert_eq!(self.remaining_len, 0); + None + } } impl<'a, T: 'static> IntoIterator for &'a IndexMap { - type Item = (u32, &'a T); - type IntoIter = Iter<'a, T>; + type Item = (u32, &'a T); + type IntoIter = Iter<'a, T>; - fn into_iter(self) -> Iter<'a, T> { - Iter { - next_idx: 0, - remaining_len: self.len, - iter: self.entries.iter(), - } - } + fn into_iter(self) -> Iter<'a, T> { + Iter { + next_idx: 0, + remaining_len: self.len, + iter: self.entries.iter(), + } + } } impl Serialize for IndexMap where - T: Serialize, - Error: From<::Error>, + T: Serialize, + Error: From<::Error>, { - type Error = Error; + type Error = Error; - fn serialize(self, wtr: &mut W) -> Result<(), Self::Error> { - VarUint32::from(self.len()).serialize(wtr)?; - for (idx, value) in self { - VarUint32::from(idx).serialize(wtr)?; - value.serialize(wtr)?; - } - Ok(()) - } + fn serialize(self, wtr: &mut W) -> Result<(), Self::Error> { + VarUint32::from(self.len()).serialize(wtr)?; + for (idx, value) in self { + VarUint32::from(idx).serialize(wtr)?; + value.serialize(wtr)?; + } + Ok(()) + } } impl IndexMap where - T: Deserialize, - Error: From<::Error>, + T: Deserialize, + Error: From<::Error>, { - /// Deserialize a map containing simple values that support `Deserialize`. - /// We will allocate an underlying array no larger than `max_entry_space` to - /// hold the data, so the maximum index must be less than `max_entry_space`. - pub fn deserialize( - max_entry_space: usize, - rdr: &mut R, - ) -> Result { - let deserialize_value: fn(u32, &mut R) -> Result = |_idx, rdr| { - T::deserialize(rdr).map_err(Error::from) - }; - Self::deserialize_with(max_entry_space, &deserialize_value, rdr) - } + /// Deserialize a map containing simple values that support `Deserialize`. + /// We will allocate an underlying array no larger than `max_entry_space` to + /// hold the data, so the maximum index must be less than `max_entry_space`. + pub fn deserialize( + max_entry_space: usize, + rdr: &mut R, + ) -> Result { + let deserialize_value: fn(u32, &mut R) -> Result = |_idx, rdr| { + T::deserialize(rdr).map_err(Error::from) + }; + Self::deserialize_with(max_entry_space, &deserialize_value, rdr) + } } #[cfg(test)] mod tests { - use std::io; - use super::*; + use std::io; + use super::*; - #[test] - fn default_is_empty_no_matter_how_we_look_at_it() { - let map = IndexMap::::default(); - assert_eq!(map.len(), 0); - assert!(map.is_empty()); - assert_eq!(map.iter().collect::>().len(), 0); - assert_eq!(map.into_iter().collect::>().len(), 0); - } + #[test] + fn default_is_empty_no_matter_how_we_look_at_it() { + let map = IndexMap::::default(); + assert_eq!(map.len(), 0); + assert!(map.is_empty()); + assert_eq!(map.iter().collect::>().len(), 0); + assert_eq!(map.into_iter().collect::>().len(), 0); + } - #[test] - fn with_capacity_creates_empty_map() { - let map = IndexMap::::with_capacity(10); - assert!(map.is_empty()); - } + #[test] + fn with_capacity_creates_empty_map() { + let map = IndexMap::::with_capacity(10); + assert!(map.is_empty()); + } - #[test] - fn clear_removes_all_values() { - let mut map = IndexMap::::default(); - map.insert(0, "sample value".to_string()); - assert_eq!(map.len(), 1); - map.clear(); - assert_eq!(map.len(), 0); - } + #[test] + fn clear_removes_all_values() { + let mut map = IndexMap::::default(); + map.insert(0, "sample value".to_string()); + assert_eq!(map.len(), 1); + map.clear(); + assert_eq!(map.len(), 0); + } - #[test] - fn get_returns_elements_that_are_there_but_nothing_else() { - let mut map = IndexMap::::default(); - map.insert(1, "sample value".to_string()); - assert_eq!(map.len(), 1); - assert_eq!(map.get(0), None); - assert_eq!(map.get(1), Some(&"sample value".to_string())); - assert_eq!(map.get(2), None); - } + #[test] + fn get_returns_elements_that_are_there_but_nothing_else() { + let mut map = IndexMap::::default(); + map.insert(1, "sample value".to_string()); + assert_eq!(map.len(), 1); + assert_eq!(map.get(0), None); + assert_eq!(map.get(1), Some(&"sample value".to_string())); + assert_eq!(map.get(2), None); + } - #[test] - fn contains_key_returns_true_when_a_key_is_present() { - let mut map = IndexMap::::default(); - map.insert(1, "sample value".to_string()); - assert!(!map.contains_key(0)); - assert!(map.contains_key(1)); - assert!(!map.contains_key(2)); - } + #[test] + fn contains_key_returns_true_when_a_key_is_present() { + let mut map = IndexMap::::default(); + map.insert(1, "sample value".to_string()); + assert!(!map.contains_key(0)); + assert!(map.contains_key(1)); + assert!(!map.contains_key(2)); + } - #[test] - fn insert_behaves_like_other_maps() { - let mut map = IndexMap::::default(); + #[test] + fn insert_behaves_like_other_maps() { + let mut map = IndexMap::::default(); - // Insert a key which requires extending our storage. - assert_eq!(map.insert(1, "val 1".to_string()), None); - assert_eq!(map.len(), 1); - assert!(map.contains_key(1)); + // Insert a key which requires extending our storage. + assert_eq!(map.insert(1, "val 1".to_string()), None); + assert_eq!(map.len(), 1); + assert!(map.contains_key(1)); - // Insert a key which requires filling in a hole. - assert_eq!(map.insert(0, "val 0".to_string()), None); - assert_eq!(map.len(), 2); - assert!(map.contains_key(0)); + // Insert a key which requires filling in a hole. + assert_eq!(map.insert(0, "val 0".to_string()), None); + assert_eq!(map.len(), 2); + assert!(map.contains_key(0)); - // Insert a key which replaces an existing key. - assert_eq!( - map.insert(1, "val 1.1".to_string()), - Some("val 1".to_string()) - ); - assert_eq!(map.len(), 2); - assert!(map.contains_key(1)); - assert_eq!(map.get(1), Some(&"val 1.1".to_string())); - } + // Insert a key which replaces an existing key. + assert_eq!( + map.insert(1, "val 1.1".to_string()), + Some("val 1".to_string()) + ); + assert_eq!(map.len(), 2); + assert!(map.contains_key(1)); + assert_eq!(map.get(1), Some(&"val 1.1".to_string())); + } - #[test] - fn remove_behaves_like_other_maps() { - let mut map = IndexMap::::default(); - assert_eq!(map.insert(1, "val 1".to_string()), None); + #[test] + fn remove_behaves_like_other_maps() { + let mut map = IndexMap::::default(); + assert_eq!(map.insert(1, "val 1".to_string()), None); - // Remove an out-of-bounds element. - assert_eq!(map.remove(2), None); - assert_eq!(map.len(), 1); + // Remove an out-of-bounds element. + assert_eq!(map.remove(2), None); + assert_eq!(map.len(), 1); - // Remove an in-bounds but missing element. - assert_eq!(map.remove(0), None); - assert_eq!(map.len(), 1); + // Remove an in-bounds but missing element. + assert_eq!(map.remove(0), None); + assert_eq!(map.len(), 1); - // Remove an existing element. - assert_eq!(map.remove(1), Some("val 1".to_string())); - assert_eq!(map.len(), 0); - } + // Remove an existing element. + assert_eq!(map.remove(1), Some("val 1".to_string())); + assert_eq!(map.len(), 0); + } - #[test] - fn partial_eq_works_as_expected_in_simple_cases() { - let mut map1 = IndexMap::::default(); - let mut map2 = IndexMap::::default(); - assert_eq!(map1, map2); + #[test] + fn partial_eq_works_as_expected_in_simple_cases() { + let mut map1 = IndexMap::::default(); + let mut map2 = IndexMap::::default(); + assert_eq!(map1, map2); - map1.insert(1, "a".to_string()); - map2.insert(1, "a".to_string()); - assert_eq!(map1, map2); + map1.insert(1, "a".to_string()); + map2.insert(1, "a".to_string()); + assert_eq!(map1, map2); - map1.insert(0, "b".to_string()); - assert_ne!(map1, map2); - map1.remove(0); - assert_eq!(map1, map2); + map1.insert(0, "b".to_string()); + assert_ne!(map1, map2); + map1.remove(0); + assert_eq!(map1, map2); - map1.insert(1, "not a".to_string()); - assert_ne!(map1, map2); - } + map1.insert(1, "not a".to_string()); + assert_ne!(map1, map2); + } - #[test] - fn partial_eq_is_smart_about_none_values_at_the_end() { - let mut map1 = IndexMap::::default(); - let mut map2 = IndexMap::::default(); + #[test] + fn partial_eq_is_smart_about_none_values_at_the_end() { + let mut map1 = IndexMap::::default(); + let mut map2 = IndexMap::::default(); - map1.insert(1, "a".to_string()); - map2.insert(1, "a".to_string()); + map1.insert(1, "a".to_string()); + map2.insert(1, "a".to_string()); - // Both maps have the same (idx, value) pairs, but map2 has extra space. - map2.insert(10, "b".to_string()); - map2.remove(10); - assert_eq!(map1, map2); + // Both maps have the same (idx, value) pairs, but map2 has extra space. + map2.insert(10, "b".to_string()); + map2.remove(10); + assert_eq!(map1, map2); - // Both maps have the same (idx, value) pairs, but map1 has extra space. - map1.insert(100, "b".to_string()); - map1.remove(100); - assert_eq!(map1, map2); + // Both maps have the same (idx, value) pairs, but map1 has extra space. + map1.insert(100, "b".to_string()); + map1.remove(100); + assert_eq!(map1, map2); - // Let's be paranoid. - map2.insert(1, "b".to_string()); - assert_ne!(map1, map2); - } + // Let's be paranoid. + map2.insert(1, "b".to_string()); + assert_ne!(map1, map2); + } - #[test] - fn from_iterator_builds_a_map() { - let data = &[ - // We support out-of-order values here! - (3, "val 3"), - (2, "val 2"), - (5, "val 5"), - ]; - let iter = data.iter().map(|&(idx, val)| (idx, val.to_string())); - let map = IndexMap::from_iter(iter); - assert_eq!(map.len(), 3); - assert_eq!(map.get(2), Some(&"val 2".to_string())); - assert_eq!(map.get(3), Some(&"val 3".to_string())); - assert_eq!(map.get(5), Some(&"val 5".to_string())); - } + #[test] + fn from_iterator_builds_a_map() { + let data = &[ + // We support out-of-order values here! + (3, "val 3"), + (2, "val 2"), + (5, "val 5"), + ]; + let iter = data.iter().map(|&(idx, val)| (idx, val.to_string())); + let map = IndexMap::from_iter(iter); + assert_eq!(map.len(), 3); + assert_eq!(map.get(2), Some(&"val 2".to_string())); + assert_eq!(map.get(3), Some(&"val 3".to_string())); + assert_eq!(map.get(5), Some(&"val 5".to_string())); + } - #[test] - fn iterators_are_well_behaved() { - // Create a map with reasonably complex internal structure, making - // sure that we have both internal missing elements, and a bunch of - // missing elements at the end. - let data = &[(3, "val 3"), (2, "val 2"), (5, "val 5")]; - let src_iter = data.iter().map(|&(idx, val)| (idx, val.to_string())); - let mut map = IndexMap::from_iter(src_iter); - map.remove(5); + #[test] + fn iterators_are_well_behaved() { + // Create a map with reasonably complex internal structure, making + // sure that we have both internal missing elements, and a bunch of + // missing elements at the end. + let data = &[(3, "val 3"), (2, "val 2"), (5, "val 5")]; + let src_iter = data.iter().map(|&(idx, val)| (idx, val.to_string())); + let mut map = IndexMap::from_iter(src_iter); + map.remove(5); - // Make sure `size_hint` and `next` behave as we expect at each step. - { - let mut iter1 = map.iter(); - assert_eq!(iter1.size_hint(), (2, Some(2))); - assert_eq!(iter1.next(), Some((2, &"val 2".to_string()))); - assert_eq!(iter1.size_hint(), (1, Some(1))); - assert_eq!(iter1.next(), Some((3, &"val 3".to_string()))); - assert_eq!(iter1.size_hint(), (0, Some(0))); - assert_eq!(iter1.next(), None); - assert_eq!(iter1.size_hint(), (0, Some(0))); - assert_eq!(iter1.next(), None); - assert_eq!(iter1.size_hint(), (0, Some(0))); - } + // Make sure `size_hint` and `next` behave as we expect at each step. + { + let mut iter1 = map.iter(); + assert_eq!(iter1.size_hint(), (2, Some(2))); + assert_eq!(iter1.next(), Some((2, &"val 2".to_string()))); + assert_eq!(iter1.size_hint(), (1, Some(1))); + assert_eq!(iter1.next(), Some((3, &"val 3".to_string()))); + assert_eq!(iter1.size_hint(), (0, Some(0))); + assert_eq!(iter1.next(), None); + assert_eq!(iter1.size_hint(), (0, Some(0))); + assert_eq!(iter1.next(), None); + assert_eq!(iter1.size_hint(), (0, Some(0))); + } - // Now do the same for a consuming iterator. - let mut iter2 = map.into_iter(); - assert_eq!(iter2.size_hint(), (2, Some(2))); - assert_eq!(iter2.next(), Some((2, "val 2".to_string()))); - assert_eq!(iter2.size_hint(), (1, Some(1))); - assert_eq!(iter2.next(), Some((3, "val 3".to_string()))); - assert_eq!(iter2.size_hint(), (0, Some(0))); - assert_eq!(iter2.next(), None); - assert_eq!(iter2.size_hint(), (0, Some(0))); - assert_eq!(iter2.next(), None); - assert_eq!(iter2.size_hint(), (0, Some(0))); - } + // Now do the same for a consuming iterator. + let mut iter2 = map.into_iter(); + assert_eq!(iter2.size_hint(), (2, Some(2))); + assert_eq!(iter2.next(), Some((2, "val 2".to_string()))); + assert_eq!(iter2.size_hint(), (1, Some(1))); + assert_eq!(iter2.next(), Some((3, "val 3".to_string()))); + assert_eq!(iter2.size_hint(), (0, Some(0))); + assert_eq!(iter2.next(), None); + assert_eq!(iter2.size_hint(), (0, Some(0))); + assert_eq!(iter2.next(), None); + assert_eq!(iter2.size_hint(), (0, Some(0))); + } - #[test] - fn serialize_and_deserialize() { - let mut map = IndexMap::::default(); - map.insert(1, "val 1".to_string()); + #[test] + fn serialize_and_deserialize() { + let mut map = IndexMap::::default(); + map.insert(1, "val 1".to_string()); - let mut output = vec![]; - map.clone() - .serialize(&mut output) - .expect("serialize failed"); + let mut output = vec![]; + map.clone() + .serialize(&mut output) + .expect("serialize failed"); - let mut input = io::Cursor::new(&output); - let deserialized = IndexMap::deserialize(2, &mut input).expect("deserialize failed"); + let mut input = io::Cursor::new(&output); + let deserialized = IndexMap::deserialize(2, &mut input).expect("deserialize failed"); - assert_eq!(deserialized, map); - } + assert_eq!(deserialized, map); + } - #[test] - fn deserialize_requires_elements_to_be_in_order() { - // Build a in-order example by hand. - let mut valid = vec![]; - VarUint32::from(2u32).serialize(&mut valid).unwrap(); - VarUint32::from(0u32).serialize(&mut valid).unwrap(); - "val 0".to_string().serialize(&mut valid).unwrap(); - VarUint32::from(1u32).serialize(&mut valid).unwrap(); - "val 1".to_string().serialize(&mut valid).unwrap(); - let map = IndexMap::::deserialize(2, &mut io::Cursor::new(valid)) - .expect("unexpected error deserializing"); - assert_eq!(map.len(), 2); + #[test] + fn deserialize_requires_elements_to_be_in_order() { + // Build a in-order example by hand. + let mut valid = vec![]; + VarUint32::from(2u32).serialize(&mut valid).unwrap(); + VarUint32::from(0u32).serialize(&mut valid).unwrap(); + "val 0".to_string().serialize(&mut valid).unwrap(); + VarUint32::from(1u32).serialize(&mut valid).unwrap(); + "val 1".to_string().serialize(&mut valid).unwrap(); + let map = IndexMap::::deserialize(2, &mut io::Cursor::new(valid)) + .expect("unexpected error deserializing"); + assert_eq!(map.len(), 2); - // Build an out-of-order example by hand. - let mut invalid = vec![]; - VarUint32::from(2u32).serialize(&mut invalid).unwrap(); - VarUint32::from(1u32).serialize(&mut invalid).unwrap(); - "val 1".to_string().serialize(&mut invalid).unwrap(); - VarUint32::from(0u32).serialize(&mut invalid).unwrap(); - "val 0".to_string().serialize(&mut invalid).unwrap(); - let res = IndexMap::::deserialize(2, &mut io::Cursor::new(invalid)); - assert!(res.is_err()); - } + // Build an out-of-order example by hand. + let mut invalid = vec![]; + VarUint32::from(2u32).serialize(&mut invalid).unwrap(); + VarUint32::from(1u32).serialize(&mut invalid).unwrap(); + "val 1".to_string().serialize(&mut invalid).unwrap(); + VarUint32::from(0u32).serialize(&mut invalid).unwrap(); + "val 0".to_string().serialize(&mut invalid).unwrap(); + let res = IndexMap::::deserialize(2, &mut io::Cursor::new(invalid)); + assert!(res.is_err()); + } - #[test] - fn deserialize_enforces_max_idx() { - // Build an example with an out-of-bounds index by hand. - let mut invalid = vec![]; - VarUint32::from(1u32).serialize(&mut invalid).unwrap(); - VarUint32::from(5u32).serialize(&mut invalid).unwrap(); - "val 5".to_string().serialize(&mut invalid).unwrap(); - let res = IndexMap::::deserialize(1, &mut io::Cursor::new(invalid)); - assert!(res.is_err()); - } + #[test] + fn deserialize_enforces_max_idx() { + // Build an example with an out-of-bounds index by hand. + let mut invalid = vec![]; + VarUint32::from(1u32).serialize(&mut invalid).unwrap(); + VarUint32::from(5u32).serialize(&mut invalid).unwrap(); + "val 5".to_string().serialize(&mut invalid).unwrap(); + let res = IndexMap::::deserialize(1, &mut io::Cursor::new(invalid)); + assert!(res.is_err()); + } } diff --git a/src/elements/mod.rs b/src/elements/mod.rs index 6303258..853ea8c 100644 --- a/src/elements/mod.rs +++ b/src/elements/mod.rs @@ -19,16 +19,16 @@ mod name_section; pub use self::module::{Module, peek_size, ImportCountType}; pub use self::section::{ - Section, FunctionSection, CodeSection, MemorySection, DataSection, - ImportSection, ExportSection, GlobalSection, TypeSection, ElementSection, - TableSection, CustomSection, + Section, FunctionSection, CodeSection, MemorySection, DataSection, + ImportSection, ExportSection, GlobalSection, TypeSection, ElementSection, + TableSection, CustomSection, }; pub use self::import_entry::{ImportEntry, ResizableLimits, MemoryType, TableType, GlobalType, External}; pub use self::export_entry::{ExportEntry, Internal}; pub use self::global_entry::GlobalEntry; pub use self::primitives::{ - VarUint32, VarUint7, Uint8, VarUint1, VarInt7, Uint32, VarInt32, VarInt64, - Uint64, VarUint64, CountedList, CountedWriter, CountedListWriter, + VarUint32, VarUint7, Uint8, VarUint1, VarInt7, Uint32, VarInt32, VarInt64, + Uint64, VarUint64, CountedList, CountedWriter, CountedListWriter, }; pub use self::types::{Type, ValueType, BlockType, FunctionType, TableElementType}; pub use self::ops::{Opcode, Opcodes, InitExpr}; @@ -36,164 +36,164 @@ pub use self::func::{Func, FuncBody, Local}; pub use self::segment::{ElementSegment, DataSegment}; pub use self::index_map::IndexMap; pub use self::name_section::{ - NameMap, NameSection, ModuleNameSection, FunctionNameSection, - LocalNameSection, + NameMap, NameSection, ModuleNameSection, FunctionNameSection, + LocalNameSection, }; /// Deserialization from serial i/o pub trait Deserialize : Sized { - /// Serialization error produced by deserialization routine. - type Error; - /// Deserialize type from serial i/o - fn deserialize(reader: &mut R) -> Result; + /// Serialization error produced by deserialization routine. + type Error; + /// Deserialize type from serial i/o + fn deserialize(reader: &mut R) -> Result; } /// Serialization to serial i/o pub trait Serialize { - /// Serialization error produced by serialization routine. - type Error; - /// Serialize type to serial i/o - fn serialize(self, writer: &mut W) -> Result<(), Self::Error>; + /// Serialization error produced by serialization routine. + type Error; + /// Serialize type to serial i/o + fn serialize(self, writer: &mut W) -> Result<(), Self::Error>; } /// Deserialization/serialization error #[derive(Debug, Clone)] pub enum Error { - /// Unexpected end of input - UnexpectedEof, - /// Invalid magic - InvalidMagic, - /// Unsupported version - UnsupportedVersion(u32), - /// Inconsistence between declared and actual length - InconsistentLength { - /// Expected length of the definition - expected: usize, - /// Actual length of the definition - actual: usize - }, - /// Other static error - Other(&'static str), - /// Other allocated error - HeapOther(String), - /// Invalid/unknown value type declaration - UnknownValueType(i8), - /// Invalid/unknown table element type declaration - UnknownTableElementType(i8), - /// Non-utf8 string - NonUtf8String, - /// Unknown external kind code - UnknownExternalKind(u8), - /// Unknown internal kind code - UnknownInternalKind(u8), - /// Unknown opcode encountered - UnknownOpcode(u8), - /// Invalid VarUint1 value - InvalidVarUint1(u8), - /// Invalid VarInt32 value - InvalidVarInt32, - /// Invalid VarInt64 value - InvalidVarInt64, + /// Unexpected end of input + UnexpectedEof, + /// Invalid magic + InvalidMagic, + /// Unsupported version + UnsupportedVersion(u32), + /// Inconsistence between declared and actual length + InconsistentLength { + /// Expected length of the definition + expected: usize, + /// Actual length of the definition + actual: usize + }, + /// Other static error + Other(&'static str), + /// Other allocated error + HeapOther(String), + /// Invalid/unknown value type declaration + UnknownValueType(i8), + /// Invalid/unknown table element type declaration + UnknownTableElementType(i8), + /// Non-utf8 string + NonUtf8String, + /// Unknown external kind code + UnknownExternalKind(u8), + /// Unknown internal kind code + UnknownInternalKind(u8), + /// Unknown opcode encountered + UnknownOpcode(u8), + /// Invalid VarUint1 value + InvalidVarUint1(u8), + /// Invalid VarInt32 value + InvalidVarInt32, + /// Invalid VarInt64 value + InvalidVarInt64, } impl fmt::Display for Error { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - match *self { - Error::UnexpectedEof => write!(f, "Unexpected end of input"), - Error::InvalidMagic => write!(f, "Invalid magic number at start of file"), - Error::UnsupportedVersion(v) => write!(f, "Unsupported wasm version {}", v), - Error::InconsistentLength { expected, actual } => { - write!(f, "Expected length {}, found {}", expected, actual) - } - Error::Other(msg) => write!(f, "{}", msg), - Error::HeapOther(ref msg) => write!(f, "{}", msg), - Error::UnknownValueType(ty) => write!(f, "Invalid or unknown value type {}", ty), - Error::UnknownTableElementType(ty) => write!(f, "Unknown table element type {}", ty), - Error::NonUtf8String => write!(f, "Non-UTF-8 string"), - Error::UnknownExternalKind(kind) => write!(f, "Unknown external kind {}", kind), - Error::UnknownInternalKind(kind) => write!(f, "Unknown internal kind {}", kind), - Error::UnknownOpcode(opcode) => write!(f, "Unknown opcode {}", opcode), - Error::InvalidVarUint1(val) => write!(f, "Not an unsigned 1-bit integer: {}", val), - Error::InvalidVarInt32 => write!(f, "Not a signed 32-bit integer"), - Error::InvalidVarInt64 => write!(f, "Not a signed 64-bit integer"), - } - } + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match *self { + Error::UnexpectedEof => write!(f, "Unexpected end of input"), + Error::InvalidMagic => write!(f, "Invalid magic number at start of file"), + Error::UnsupportedVersion(v) => write!(f, "Unsupported wasm version {}", v), + Error::InconsistentLength { expected, actual } => { + write!(f, "Expected length {}, found {}", expected, actual) + } + Error::Other(msg) => write!(f, "{}", msg), + Error::HeapOther(ref msg) => write!(f, "{}", msg), + Error::UnknownValueType(ty) => write!(f, "Invalid or unknown value type {}", ty), + Error::UnknownTableElementType(ty) => write!(f, "Unknown table element type {}", ty), + Error::NonUtf8String => write!(f, "Non-UTF-8 string"), + Error::UnknownExternalKind(kind) => write!(f, "Unknown external kind {}", kind), + Error::UnknownInternalKind(kind) => write!(f, "Unknown internal kind {}", kind), + Error::UnknownOpcode(opcode) => write!(f, "Unknown opcode {}", opcode), + Error::InvalidVarUint1(val) => write!(f, "Not an unsigned 1-bit integer: {}", val), + Error::InvalidVarInt32 => write!(f, "Not a signed 32-bit integer"), + Error::InvalidVarInt64 => write!(f, "Not a signed 64-bit integer"), + } + } } impl error::Error for Error { - fn description(&self) -> &str { - match *self { - Error::UnexpectedEof => "Unexpected end of input", - Error::InvalidMagic => "Invalid magic number at start of file", - Error::UnsupportedVersion(_) => "Unsupported wasm version", - Error::InconsistentLength { .. } => "Inconsistent length", - Error::Other(msg) => msg, - Error::HeapOther(ref msg) => &msg[..], - Error::UnknownValueType(_) => "Invalid or unknown value type", - Error::UnknownTableElementType(_) => "Unknown table element type", - Error::NonUtf8String => "Non-UTF-8 string", - Error::UnknownExternalKind(_) => "Unknown external kind", - Error::UnknownInternalKind(_) => "Unknown internal kind", - Error::UnknownOpcode(_) => "Unknown opcode", - Error::InvalidVarUint1(_) => "Not an unsigned 1-bit integer", - Error::InvalidVarInt32 => "Not a signed 32-bit integer", - Error::InvalidVarInt64 => "Not a signed 64-bit integer", - } - } + fn description(&self) -> &str { + match *self { + Error::UnexpectedEof => "Unexpected end of input", + Error::InvalidMagic => "Invalid magic number at start of file", + Error::UnsupportedVersion(_) => "Unsupported wasm version", + Error::InconsistentLength { .. } => "Inconsistent length", + Error::Other(msg) => msg, + Error::HeapOther(ref msg) => &msg[..], + Error::UnknownValueType(_) => "Invalid or unknown value type", + Error::UnknownTableElementType(_) => "Unknown table element type", + Error::NonUtf8String => "Non-UTF-8 string", + Error::UnknownExternalKind(_) => "Unknown external kind", + Error::UnknownInternalKind(_) => "Unknown internal kind", + Error::UnknownOpcode(_) => "Unknown opcode", + Error::InvalidVarUint1(_) => "Not an unsigned 1-bit integer", + Error::InvalidVarInt32 => "Not a signed 32-bit integer", + Error::InvalidVarInt64 => "Not a signed 64-bit integer", + } + } } impl From for Error { - fn from(err: io::Error) -> Self { - Error::HeapOther(format!("I/O Error: {}", err)) - } + fn from(err: io::Error) -> Self { + Error::HeapOther(format!("I/O Error: {}", err)) + } } /// Unparsed part of the module/section pub struct Unparsed(pub Vec); impl Deserialize for Unparsed { - type Error = Error; + type Error = Error; - fn deserialize(reader: &mut R) -> Result { - let len = VarUint32::deserialize(reader)?.into(); - let mut vec = vec![0u8; len]; - reader.read_exact(&mut vec[..])?; - Ok(Unparsed(vec)) - } + fn deserialize(reader: &mut R) -> Result { + let len = VarUint32::deserialize(reader)?.into(); + let mut vec = vec![0u8; len]; + reader.read_exact(&mut vec[..])?; + Ok(Unparsed(vec)) + } } impl From for Vec { - fn from(u: Unparsed) -> Vec { - u.0 - } + fn from(u: Unparsed) -> Vec { + u.0 + } } /// Deserialize module from file. pub fn deserialize_file>(p: P) -> Result { - use std::io::Read; + use std::io::Read; - let mut contents = Vec::new(); - ::std::fs::File::open(p)?.read_to_end(&mut contents)?; + let mut contents = Vec::new(); + ::std::fs::File::open(p)?.read_to_end(&mut contents)?; - deserialize_buffer(&contents) + deserialize_buffer(&contents) } /// Deserialize deserializable type from buffer. pub fn deserialize_buffer(contents: &[u8]) -> Result { - let mut reader = io::Cursor::new(contents); - T::deserialize(&mut reader) + let mut reader = io::Cursor::new(contents); + T::deserialize(&mut reader) } /// Create buffer with serialized value. pub fn serialize(val: T) -> Result, T::Error> { - let mut buf = Vec::new(); - val.serialize(&mut buf)?; - Ok(buf) + let mut buf = Vec::new(); + val.serialize(&mut buf)?; + Ok(buf) } /// Serialize module to the file pub fn serialize_to_file>(p: P, module: Module) -> Result<(), Error> { - let mut io = ::std::fs::File::create(p)?; - module.serialize(&mut io) + let mut io = ::std::fs::File::create(p)?; + module.serialize(&mut io) } diff --git a/src/elements/module.rs b/src/elements/module.rs index ab2796e..afb80fa 100644 --- a/src/elements/module.rs +++ b/src/elements/module.rs @@ -3,8 +3,8 @@ use byteorder::{LittleEndian, ByteOrder}; use super::{Deserialize, Serialize, Error, Uint32, External}; use super::section::{ - Section, CodeSection, TypeSection, ImportSection, ExportSection, FunctionSection, - GlobalSection, TableSection, ElementSection, DataSection, MemorySection + Section, CodeSection, TypeSection, ImportSection, ExportSection, FunctionSection, + GlobalSection, TableSection, ElementSection, DataSection, MemorySection }; use super::name_section::NameSection; @@ -13,494 +13,494 @@ const WASM_MAGIC_NUMBER: [u8; 4] = [0x00, 0x61, 0x73, 0x6d]; /// WebAssembly module #[derive(Debug, Clone)] pub struct Module { - magic: u32, - version: u32, - sections: Vec
, + magic: u32, + version: u32, + sections: Vec
, } #[derive(Debug, Clone, Copy)] /// Type of the import entry to count pub enum ImportCountType { - /// Count functions - Function, - /// Count globals - Global, + /// Count functions + Function, + /// Count globals + Global, } impl Default for Module { - fn default() -> Self { - Module { - magic: LittleEndian::read_u32(&WASM_MAGIC_NUMBER), - version: 1, - sections: Vec::with_capacity(16), - } - } + fn default() -> Self { + Module { + magic: LittleEndian::read_u32(&WASM_MAGIC_NUMBER), + version: 1, + sections: Vec::with_capacity(16), + } + } } impl Module { - /// New module with sections - pub fn new(sections: Vec
) -> Self { - Module { - sections: sections, ..Default::default() - } - } + /// New module with sections + pub fn new(sections: Vec
) -> Self { + Module { + sections: sections, ..Default::default() + } + } - /// Destructure the module, yielding sections - pub fn into_sections(self) -> Vec
{ - self.sections - } + /// Destructure the module, yielding sections + pub fn into_sections(self) -> Vec
{ + self.sections + } - /// Version of module. - pub fn version(&self) -> u32 { self.version } + /// Version of module. + pub fn version(&self) -> u32 { self.version } - /// Sections list. - /// Each known section is optional and may appear at most once. - pub fn sections(&self) -> &[Section] { - &self.sections - } + /// Sections list. + /// Each known section is optional and may appear at most once. + pub fn sections(&self) -> &[Section] { + &self.sections + } - /// Sections list (mutable) - /// Each known section is optional and may appear at most once. - pub fn sections_mut(&mut self) -> &mut Vec
{ - &mut self.sections - } + /// Sections list (mutable) + /// Each known section is optional and may appear at most once. + pub fn sections_mut(&mut self) -> &mut Vec
{ + &mut self.sections + } - /// Code section, if any. - pub fn code_section(&self) -> Option<&CodeSection> { - for section in self.sections() { - if let &Section::Code(ref code_section) = section { return Some(code_section); } - } - None - } + /// Code section, if any. + pub fn code_section(&self) -> Option<&CodeSection> { + for section in self.sections() { + if let &Section::Code(ref code_section) = section { return Some(code_section); } + } + None + } - /// Types section, if any. - pub fn type_section(&self) -> Option<&TypeSection> { - for section in self.sections() { - if let &Section::Type(ref type_section) = section { return Some(type_section); } - } - None - } + /// Types section, if any. + pub fn type_section(&self) -> Option<&TypeSection> { + for section in self.sections() { + if let &Section::Type(ref type_section) = section { return Some(type_section); } + } + None + } - /// Imports section, if any. - pub fn import_section(&self) -> Option<&ImportSection> { - for section in self.sections() { - if let &Section::Import(ref import_section) = section { return Some(import_section); } - } - None - } + /// Imports section, if any. + pub fn import_section(&self) -> Option<&ImportSection> { + for section in self.sections() { + if let &Section::Import(ref import_section) = section { return Some(import_section); } + } + None + } - /// Globals section, if any. - pub fn global_section(&self) -> Option<&GlobalSection> { - for section in self.sections() { - if let &Section::Global(ref section) = section { return Some(section); } - } - None - } + /// Globals section, if any. + pub fn global_section(&self) -> Option<&GlobalSection> { + for section in self.sections() { + if let &Section::Global(ref section) = section { return Some(section); } + } + None + } - /// Exports section, if any. - pub fn export_section(&self) -> Option<&ExportSection> { - for section in self.sections() { - if let &Section::Export(ref export_section) = section { return Some(export_section); } - } - None - } + /// Exports section, if any. + pub fn export_section(&self) -> Option<&ExportSection> { + for section in self.sections() { + if let &Section::Export(ref export_section) = section { return Some(export_section); } + } + None + } - /// Table section, if any. - pub fn table_section(&self) -> Option<&TableSection> { - for section in self.sections() { - if let &Section::Table(ref section) = section { return Some(section); } - } - None - } + /// Table section, if any. + pub fn table_section(&self) -> Option<&TableSection> { + for section in self.sections() { + if let &Section::Table(ref section) = section { return Some(section); } + } + None + } - /// Data section, if any. - pub fn data_section(&self) -> Option<&DataSection> { - for section in self.sections() { - if let &Section::Data(ref section) = section { return Some(section); } - } - None - } + /// Data section, if any. + pub fn data_section(&self) -> Option<&DataSection> { + for section in self.sections() { + if let &Section::Data(ref section) = section { return Some(section); } + } + None + } - /// Element section, if any. - pub fn elements_section(&self) -> Option<&ElementSection> { - for section in self.sections() { - if let &Section::Element(ref section) = section { return Some(section); } - } - None - } + /// Element section, if any. + pub fn elements_section(&self) -> Option<&ElementSection> { + for section in self.sections() { + if let &Section::Element(ref section) = section { return Some(section); } + } + None + } - /// Memory section, if any. - pub fn memory_section(&self) -> Option<&MemorySection> { - for section in self.sections() { - if let &Section::Memory(ref section) = section { return Some(section); } - } - None - } + /// Memory section, if any. + pub fn memory_section(&self) -> Option<&MemorySection> { + for section in self.sections() { + if let &Section::Memory(ref section) = section { return Some(section); } + } + None + } - /// Functions signatures section, if any. - pub fn function_section(&self) -> Option<&FunctionSection> { - for section in self.sections() { - if let &Section::Function(ref sect) = section { return Some(sect); } - } - None - } + /// Functions signatures section, if any. + pub fn function_section(&self) -> Option<&FunctionSection> { + for section in self.sections() { + if let &Section::Function(ref sect) = section { return Some(sect); } + } + None + } - /// Start section, if any. - pub fn start_section(&self) -> Option { - for section in self.sections() { - if let &Section::Start(sect) = section { return Some(sect); } - } - None - } + /// Start section, if any. + pub fn start_section(&self) -> Option { + for section in self.sections() { + if let &Section::Start(sect) = section { return Some(sect); } + } + None + } - /// Try to parse name section in place - /// Corresponding custom section with proper header will convert to name sections - /// If some of them will fail to be decoded, Err variant is returned with the list of - /// (index, Error) tuples of failed sections. - pub fn parse_names(mut self) -> Result, Self)> { - let mut parse_errors = Vec::new(); + /// Try to parse name section in place + /// Corresponding custom section with proper header will convert to name sections + /// If some of them will fail to be decoded, Err variant is returned with the list of + /// (index, Error) tuples of failed sections. + pub fn parse_names(mut self) -> Result, Self)> { + let mut parse_errors = Vec::new(); - for i in 0..self.sections.len() { - if let Some(name_section) = { - let section = self.sections.get(i).expect("cannot fail because i in range 0..len; qed"); - if let Section::Custom(ref custom) = *section { - if custom.name() == "name" { - let mut rdr = io::Cursor::new(custom.payload()); - let name_section = match NameSection::deserialize(&self, &mut rdr) { - Ok(ns) => ns, - Err(e) => { parse_errors.push((i, e)); continue; } - }; - Some(name_section) - } else { - None - } - } else { None } - } { - *self.sections.get_mut(i).expect("cannot fail because i in range 0..len; qed") = Section::Name(name_section); - } - } + for i in 0..self.sections.len() { + if let Some(name_section) = { + let section = self.sections.get(i).expect("cannot fail because i in range 0..len; qed"); + if let Section::Custom(ref custom) = *section { + if custom.name() == "name" { + let mut rdr = io::Cursor::new(custom.payload()); + let name_section = match NameSection::deserialize(&self, &mut rdr) { + Ok(ns) => ns, + Err(e) => { parse_errors.push((i, e)); continue; } + }; + Some(name_section) + } else { + None + } + } else { None } + } { + *self.sections.get_mut(i).expect("cannot fail because i in range 0..len; qed") = Section::Name(name_section); + } + } - if parse_errors.len() > 0 { - Err((parse_errors, self)) - } else { - Ok(self) - } - } + if parse_errors.len() > 0 { + Err((parse_errors, self)) + } else { + Ok(self) + } + } - /// Count imports by provided type - pub fn import_count(&self, count_type: ImportCountType) -> usize { - self.import_section() - .map(|is| - is.entries().iter().filter(|import| match (count_type, *import.external()) { - (ImportCountType::Function, External::Function(_)) => true, - (ImportCountType::Global, External::Global(_)) => true, - _ => false - }).count()) - .unwrap_or(0) - } + /// Count imports by provided type + pub fn import_count(&self, count_type: ImportCountType) -> usize { + self.import_section() + .map(|is| + is.entries().iter().filter(|import| match (count_type, *import.external()) { + (ImportCountType::Function, External::Function(_)) => true, + (ImportCountType::Global, External::Global(_)) => true, + _ => false + }).count()) + .unwrap_or(0) + } - /// Query functions space - pub fn functions_space(&self) -> usize { - self.import_count(ImportCountType::Function) + - self.function_section().map(|fs| fs.entries().len()).unwrap_or(0) - } + /// Query functions space + pub fn functions_space(&self) -> usize { + self.import_count(ImportCountType::Function) + + self.function_section().map(|fs| fs.entries().len()).unwrap_or(0) + } - /// Query globals space - pub fn globals_space(&self) -> usize { - self.import_count(ImportCountType::Global) + - self.global_section().map(|gs| gs.entries().len()).unwrap_or(0) - } + /// Query globals space + pub fn globals_space(&self) -> usize { + self.import_count(ImportCountType::Global) + + self.global_section().map(|gs| gs.entries().len()).unwrap_or(0) + } } impl Deserialize for Module { - type Error = super::Error; + type Error = super::Error; - fn deserialize(reader: &mut R) -> Result { - let mut sections = Vec::new(); + fn deserialize(reader: &mut R) -> Result { + let mut sections = Vec::new(); - let mut magic = [0u8; 4]; - reader.read(&mut magic)?; - if magic != WASM_MAGIC_NUMBER { - return Err(Error::InvalidMagic); - } + let mut magic = [0u8; 4]; + reader.read(&mut magic)?; + if magic != WASM_MAGIC_NUMBER { + return Err(Error::InvalidMagic); + } - let version: u32 = Uint32::deserialize(reader)?.into(); + let version: u32 = Uint32::deserialize(reader)?.into(); - if version != 1 { - return Err(Error::UnsupportedVersion(version)); - } + if version != 1 { + return Err(Error::UnsupportedVersion(version)); + } - loop { - match Section::deserialize(reader) { - Err(Error::UnexpectedEof) => { break; }, - Err(e) => { return Err(e) }, - Ok(section) => { sections.push(section); } - } - } + loop { + match Section::deserialize(reader) { + Err(Error::UnexpectedEof) => { break; }, + Err(e) => { return Err(e) }, + Ok(section) => { sections.push(section); } + } + } - Ok(Module { - magic: LittleEndian::read_u32(&magic), - version: version, - sections: sections, - }) - } + Ok(Module { + magic: LittleEndian::read_u32(&magic), + version: version, + sections: sections, + }) + } } impl Serialize for Module { - type Error = Error; + type Error = Error; - fn serialize(self, w: &mut W) -> Result<(), Self::Error> { - Uint32::from(self.magic).serialize(w)?; - Uint32::from(self.version).serialize(w)?; - for section in self.sections.into_iter() { - section.serialize(w)?; - } - Ok(()) - } + fn serialize(self, w: &mut W) -> Result<(), Self::Error> { + Uint32::from(self.magic).serialize(w)?; + Uint32::from(self.version).serialize(w)?; + for section in self.sections.into_iter() { + section.serialize(w)?; + } + Ok(()) + } } #[derive(Debug, Copy, Clone)] struct PeekSection<'a> { - cursor: usize, - region: &'a [u8], + cursor: usize, + region: &'a [u8], } impl<'a> io::Read for PeekSection<'a> { - fn read(&mut self, buf: &mut [u8]) -> ::std::io::Result { - let available = ::std::cmp::min(buf.len(), self.region.len() - self.cursor); - if available < buf.len() { - return Err(::std::io::Error::from(::std::io::ErrorKind::UnexpectedEof)); - } + fn read(&mut self, buf: &mut [u8]) -> ::std::io::Result { + let available = ::std::cmp::min(buf.len(), self.region.len() - self.cursor); + if available < buf.len() { + return Err(::std::io::Error::from(::std::io::ErrorKind::UnexpectedEof)); + } - let range = self.cursor..self.cursor + buf.len(); - buf.copy_from_slice(&self.region[range]); + let range = self.cursor..self.cursor + buf.len(); + buf.copy_from_slice(&self.region[range]); - self.cursor += available; - Ok(available) - } + self.cursor += available; + Ok(available) + } } /// Returns size of the module in the provided stream pub fn peek_size(source: &[u8]) -> usize { - if source.len() < 9 { - return 0; - } + if source.len() < 9 { + return 0; + } - let mut cursor = 8; - loop { - let (new_cursor, section_id, section_len) = { - let mut peek_section = PeekSection { cursor: 0, region: &source[cursor..] }; - let section_id: u8 = match super::VarUint7::deserialize(&mut peek_section) { - Ok(res) => res.into(), - Err(_) => { break; }, - }; - let section_len: u32 = match super::VarUint32::deserialize(&mut peek_section) { - Ok(res) => res.into(), - Err(_) => { break; }, - }; + let mut cursor = 8; + loop { + let (new_cursor, section_id, section_len) = { + let mut peek_section = PeekSection { cursor: 0, region: &source[cursor..] }; + let section_id: u8 = match super::VarUint7::deserialize(&mut peek_section) { + Ok(res) => res.into(), + Err(_) => { break; }, + }; + let section_len: u32 = match super::VarUint32::deserialize(&mut peek_section) { + Ok(res) => res.into(), + Err(_) => { break; }, + }; - (peek_section.cursor, section_id, section_len) - }; + (peek_section.cursor, section_id, section_len) + }; - if section_id <= 11 && section_len > 0 { - let next_cursor = cursor + new_cursor + section_len as usize; - if next_cursor >= source.len() { - break; - } - cursor = next_cursor; - } else { - break; - } - } + if section_id <= 11 && section_len > 0 { + let next_cursor = cursor + new_cursor + section_len as usize; + if next_cursor >= source.len() { + break; + } + cursor = next_cursor; + } else { + break; + } + } - cursor + cursor } #[cfg(test)] mod integration_tests { - use super::super::{deserialize_file, serialize, deserialize_buffer, Section}; - use super::Module; + use super::super::{deserialize_file, serialize, deserialize_buffer, Section}; + use super::Module; - #[test] - fn hello() { - let module = deserialize_file("./res/cases/v1/hello.wasm").expect("Should be deserialized"); + #[test] + fn hello() { + let module = deserialize_file("./res/cases/v1/hello.wasm").expect("Should be deserialized"); - assert_eq!(module.version(), 1); - assert_eq!(module.sections().len(), 8); - } + assert_eq!(module.version(), 1); + assert_eq!(module.sections().len(), 8); + } - #[test] - fn serde() { - let module = deserialize_file("./res/cases/v1/test5.wasm").expect("Should be deserialized"); - let buf = serialize(module).expect("serialization to succeed"); + #[test] + fn serde() { + let module = deserialize_file("./res/cases/v1/test5.wasm").expect("Should be deserialized"); + let buf = serialize(module).expect("serialization to succeed"); - let module_new: Module = deserialize_buffer(&buf).expect("deserialization to succeed"); - let module_old = deserialize_file("./res/cases/v1/test5.wasm").expect("Should be deserialized"); + let module_new: Module = deserialize_buffer(&buf).expect("deserialization to succeed"); + let module_old = deserialize_file("./res/cases/v1/test5.wasm").expect("Should be deserialized"); - assert_eq!(module_old.sections().len(), module_new.sections().len()); - } + assert_eq!(module_old.sections().len(), module_new.sections().len()); + } - #[test] - fn serde_type() { - let mut module = deserialize_file("./res/cases/v1/test5.wasm").expect("Should be deserialized"); - module.sections_mut().retain(|x| { - if let &Section::Type(_) = x { true } else { false } - }); + #[test] + fn serde_type() { + let mut module = deserialize_file("./res/cases/v1/test5.wasm").expect("Should be deserialized"); + module.sections_mut().retain(|x| { + if let &Section::Type(_) = x { true } else { false } + }); - let buf = serialize(module).expect("serialization to succeed"); + let buf = serialize(module).expect("serialization to succeed"); - let module_new: Module = deserialize_buffer(&buf).expect("deserialization to succeed"); - let module_old = deserialize_file("./res/cases/v1/test5.wasm").expect("Should be deserialized"); - assert_eq!( - module_old.type_section().expect("type section exists").types().len(), - module_new.type_section().expect("type section exists").types().len(), - "There should be equal amount of types before and after serialization" - ); - } + let module_new: Module = deserialize_buffer(&buf).expect("deserialization to succeed"); + let module_old = deserialize_file("./res/cases/v1/test5.wasm").expect("Should be deserialized"); + assert_eq!( + module_old.type_section().expect("type section exists").types().len(), + module_new.type_section().expect("type section exists").types().len(), + "There should be equal amount of types before and after serialization" + ); + } - #[test] - fn serde_import() { - let mut module = deserialize_file("./res/cases/v1/test5.wasm").expect("Should be deserialized"); - module.sections_mut().retain(|x| { - if let &Section::Import(_) = x { true } else { false } - }); + #[test] + fn serde_import() { + let mut module = deserialize_file("./res/cases/v1/test5.wasm").expect("Should be deserialized"); + module.sections_mut().retain(|x| { + if let &Section::Import(_) = x { true } else { false } + }); - let buf = serialize(module).expect("serialization to succeed"); + let buf = serialize(module).expect("serialization to succeed"); - let module_new: Module = deserialize_buffer(&buf).expect("deserialization to succeed"); - let module_old = deserialize_file("./res/cases/v1/test5.wasm").expect("Should be deserialized"); - assert_eq!( - module_old.import_section().expect("import section exists").entries().len(), - module_new.import_section().expect("import section exists").entries().len(), - "There should be equal amount of import entries before and after serialization" - ); - } + let module_new: Module = deserialize_buffer(&buf).expect("deserialization to succeed"); + let module_old = deserialize_file("./res/cases/v1/test5.wasm").expect("Should be deserialized"); + assert_eq!( + module_old.import_section().expect("import section exists").entries().len(), + module_new.import_section().expect("import section exists").entries().len(), + "There should be equal amount of import entries before and after serialization" + ); + } - #[test] - fn serde_code() { - let mut module = deserialize_file("./res/cases/v1/test5.wasm").expect("Should be deserialized"); - module.sections_mut().retain(|x| { - if let &Section::Code(_) = x { true } else { false } - }); + #[test] + fn serde_code() { + let mut module = deserialize_file("./res/cases/v1/test5.wasm").expect("Should be deserialized"); + module.sections_mut().retain(|x| { + if let &Section::Code(_) = x { true } else { false } + }); - let buf = serialize(module).expect("serialization to succeed"); + let buf = serialize(module).expect("serialization to succeed"); - let module_new: Module = deserialize_buffer(&buf).expect("deserialization to succeed"); - let module_old = deserialize_file("./res/cases/v1/test5.wasm").expect("Should be deserialized"); - assert_eq!( - module_old.code_section().expect("code section exists").bodies().len(), - module_new.code_section().expect("code section exists").bodies().len(), - "There should be equal amount of function bodies before and after serialization" - ); - } + let module_new: Module = deserialize_buffer(&buf).expect("deserialization to succeed"); + let module_old = deserialize_file("./res/cases/v1/test5.wasm").expect("Should be deserialized"); + assert_eq!( + module_old.code_section().expect("code section exists").bodies().len(), + module_new.code_section().expect("code section exists").bodies().len(), + "There should be equal amount of function bodies before and after serialization" + ); + } - #[test] - fn const_() { - use super::super::Opcode::*; + #[test] + fn const_() { + use super::super::Opcode::*; - let module = deserialize_file("./res/cases/v1/const.wasm").expect("Should be deserialized"); - let func = &module.code_section().expect("Code section to exist").bodies()[0]; - assert_eq!(func.code().elements().len(), 20); + let module = deserialize_file("./res/cases/v1/const.wasm").expect("Should be deserialized"); + let func = &module.code_section().expect("Code section to exist").bodies()[0]; + assert_eq!(func.code().elements().len(), 20); - assert_eq!(I64Const(9223372036854775807), func.code().elements()[0]); - assert_eq!(I64Const(-9223372036854775808), func.code().elements()[1]); - assert_eq!(I64Const(-1152894205662152753), func.code().elements()[2]); - assert_eq!(I64Const(-8192), func.code().elements()[3]); - assert_eq!(I32Const(1024), func.code().elements()[4]); - assert_eq!(I32Const(2048), func.code().elements()[5]); - assert_eq!(I32Const(4096), func.code().elements()[6]); - assert_eq!(I32Const(8192), func.code().elements()[7]); - assert_eq!(I32Const(16384), func.code().elements()[8]); - assert_eq!(I32Const(32767), func.code().elements()[9]); - assert_eq!(I32Const(-1024), func.code().elements()[10]); - assert_eq!(I32Const(-2048), func.code().elements()[11]); - assert_eq!(I32Const(-4096), func.code().elements()[12]); - assert_eq!(I32Const(-8192), func.code().elements()[13]); - assert_eq!(I32Const(-16384), func.code().elements()[14]); - assert_eq!(I32Const(-32768), func.code().elements()[15]); - assert_eq!(I32Const(-2147483648), func.code().elements()[16]); - assert_eq!(I32Const(2147483647), func.code().elements()[17]); - } + assert_eq!(I64Const(9223372036854775807), func.code().elements()[0]); + assert_eq!(I64Const(-9223372036854775808), func.code().elements()[1]); + assert_eq!(I64Const(-1152894205662152753), func.code().elements()[2]); + assert_eq!(I64Const(-8192), func.code().elements()[3]); + assert_eq!(I32Const(1024), func.code().elements()[4]); + assert_eq!(I32Const(2048), func.code().elements()[5]); + assert_eq!(I32Const(4096), func.code().elements()[6]); + assert_eq!(I32Const(8192), func.code().elements()[7]); + assert_eq!(I32Const(16384), func.code().elements()[8]); + assert_eq!(I32Const(32767), func.code().elements()[9]); + assert_eq!(I32Const(-1024), func.code().elements()[10]); + assert_eq!(I32Const(-2048), func.code().elements()[11]); + assert_eq!(I32Const(-4096), func.code().elements()[12]); + assert_eq!(I32Const(-8192), func.code().elements()[13]); + assert_eq!(I32Const(-16384), func.code().elements()[14]); + assert_eq!(I32Const(-32768), func.code().elements()[15]); + assert_eq!(I32Const(-2147483648), func.code().elements()[16]); + assert_eq!(I32Const(2147483647), func.code().elements()[17]); + } - #[test] - fn store() { - use super::super::Opcode::*; + #[test] + fn store() { + use super::super::Opcode::*; - let module = deserialize_file("./res/cases/v1/offset.wasm").expect("Should be deserialized"); - let func = &module.code_section().expect("Code section to exist").bodies()[0]; + let module = deserialize_file("./res/cases/v1/offset.wasm").expect("Should be deserialized"); + let func = &module.code_section().expect("Code section to exist").bodies()[0]; - assert_eq!(func.code().elements().len(), 5); - assert_eq!(I64Store(0, 32), func.code().elements()[2]); - } + assert_eq!(func.code().elements().len(), 5); + assert_eq!(I64Store(0, 32), func.code().elements()[2]); + } - #[test] - fn peek() { - use super::peek_size; + #[test] + fn peek() { + use super::peek_size; - let module = deserialize_file("./res/cases/v1/test5.wasm").expect("Should be deserialized"); - let mut buf = serialize(module).expect("serialization to succeed"); + let module = deserialize_file("./res/cases/v1/test5.wasm").expect("Should be deserialized"); + let mut buf = serialize(module).expect("serialization to succeed"); - buf.extend_from_slice(&[1, 5, 12, 17]); + buf.extend_from_slice(&[1, 5, 12, 17]); - assert_eq!(peek_size(&buf), buf.len() - 4); - } + assert_eq!(peek_size(&buf), buf.len() - 4); + } - #[test] - fn peek_2() { - use super::peek_size; + #[test] + fn peek_2() { + use super::peek_size; - let module = deserialize_file("./res/cases/v1/offset.wasm").expect("Should be deserialized"); - let mut buf = serialize(module).expect("serialization to succeed"); + let module = deserialize_file("./res/cases/v1/offset.wasm").expect("Should be deserialized"); + let mut buf = serialize(module).expect("serialization to succeed"); - buf.extend_from_slice(&[0, 0, 0, 0, 0, 1, 5, 12, 17]); + buf.extend_from_slice(&[0, 0, 0, 0, 0, 1, 5, 12, 17]); - assert_eq!(peek_size(&buf), buf.len() - 9); - } + assert_eq!(peek_size(&buf), buf.len() - 9); + } - #[test] - fn module_default_round_trip() { - let module1 = Module::default(); - let buf = serialize(module1).expect("Serialization should succeed"); + #[test] + fn module_default_round_trip() { + let module1 = Module::default(); + let buf = serialize(module1).expect("Serialization should succeed"); - let module2: Module = deserialize_buffer(&buf).expect("Deserialization should succeed"); - assert_eq!(Module::default().magic, module2.magic); - } + let module2: Module = deserialize_buffer(&buf).expect("Deserialization should succeed"); + assert_eq!(Module::default().magic, module2.magic); + } - #[test] - fn names() { - use super::super::name_section::NameSection; + #[test] + fn names() { + use super::super::name_section::NameSection; - let module = deserialize_file("./res/cases/v1/with_names.wasm") - .expect("Should be deserialized") - .parse_names() - .expect("Names to be parsed"); + let module = deserialize_file("./res/cases/v1/with_names.wasm") + .expect("Should be deserialized") + .parse_names() + .expect("Names to be parsed"); - let mut found_section = false; - for section in module.sections() { - match *section { - Section::Name(ref name_section) => { - match *name_section { - NameSection::Function(ref function_name_section) => { - assert_eq!( - function_name_section.names().get(0).expect("Should be entry #0"), - "elog" - ); - assert_eq!( - function_name_section.names().get(11).expect("Should be entry #0"), - "_ZN48_$LT$pwasm_token_contract..Endpoint$LT$T$GT$$GT$3new17hc3ace6dea0978cd9E" - ); + let mut found_section = false; + for section in module.sections() { + match *section { + Section::Name(ref name_section) => { + match *name_section { + NameSection::Function(ref function_name_section) => { + assert_eq!( + function_name_section.names().get(0).expect("Should be entry #0"), + "elog" + ); + assert_eq!( + function_name_section.names().get(11).expect("Should be entry #0"), + "_ZN48_$LT$pwasm_token_contract..Endpoint$LT$T$GT$$GT$3new17hc3ace6dea0978cd9E" + ); - found_section = true; - }, - _ => {}, - } - }, - _ => {}, - } - } + found_section = true; + }, + _ => {}, + } + }, + _ => {}, + } + } - assert!(found_section, "Name section should be present in dedicated example"); - } + assert!(found_section, "Name section should be present in dedicated example"); + } } diff --git a/src/elements/name_section.rs b/src/elements/name_section.rs index 350587e..d91f57b 100644 --- a/src/elements/name_section.rs +++ b/src/elements/name_section.rs @@ -10,218 +10,218 @@ const NAME_TYPE_LOCAL: u8 = 2; /// Debug name information. #[derive(Clone, Debug, PartialEq)] pub enum NameSection { - /// Module name section. - Module(ModuleNameSection), + /// Module name section. + Module(ModuleNameSection), - /// Function name section. - Function(FunctionNameSection), + /// Function name section. + Function(FunctionNameSection), - /// Local name section. - Local(LocalNameSection), + /// Local name section. + Local(LocalNameSection), - /// Name section is unparsed. - Unparsed { - /// The numeric identifier for this name section type. - name_type: u8, - /// The contents of this name section, unparsed. - name_payload: Vec, - }, + /// Name section is unparsed. + Unparsed { + /// The numeric identifier for this name section type. + name_type: u8, + /// The contents of this name section, unparsed. + name_payload: Vec, + }, } impl NameSection { - /// Deserialize a name section. - pub fn deserialize( - module: &Module, - rdr: &mut R, - ) -> Result { - let name_type: u8 = VarUint7::deserialize(rdr)?.into(); - let name_payload_len: u32 = VarUint32::deserialize(rdr)?.into(); - let name_section = match name_type { - NAME_TYPE_MODULE => NameSection::Module(ModuleNameSection::deserialize(rdr)?), - NAME_TYPE_FUNCTION => NameSection::Function(FunctionNameSection::deserialize(module, rdr)?), - NAME_TYPE_LOCAL => NameSection::Local(LocalNameSection::deserialize(module, rdr)?), - _ => { - let mut name_payload = vec![0u8; name_payload_len as usize]; - rdr.read_exact(&mut name_payload)?; - NameSection::Unparsed { - name_type, - name_payload, - } - } - }; - Ok(name_section) - } + /// Deserialize a name section. + pub fn deserialize( + module: &Module, + rdr: &mut R, + ) -> Result { + let name_type: u8 = VarUint7::deserialize(rdr)?.into(); + let name_payload_len: u32 = VarUint32::deserialize(rdr)?.into(); + let name_section = match name_type { + NAME_TYPE_MODULE => NameSection::Module(ModuleNameSection::deserialize(rdr)?), + NAME_TYPE_FUNCTION => NameSection::Function(FunctionNameSection::deserialize(module, rdr)?), + NAME_TYPE_LOCAL => NameSection::Local(LocalNameSection::deserialize(module, rdr)?), + _ => { + let mut name_payload = vec![0u8; name_payload_len as usize]; + rdr.read_exact(&mut name_payload)?; + NameSection::Unparsed { + name_type, + name_payload, + } + } + }; + Ok(name_section) + } } impl Serialize for NameSection { - type Error = Error; + type Error = Error; - fn serialize(self, wtr: &mut W) -> Result<(), Error> { - let (name_type, name_payload) = match self { - NameSection::Module(mod_name) => { - let mut buffer = vec![]; - mod_name.serialize(&mut buffer)?; - (NAME_TYPE_MODULE, buffer) - } - NameSection::Function(fn_names) => { - let mut buffer = vec![]; - fn_names.serialize(&mut buffer)?; - (NAME_TYPE_FUNCTION, buffer) - } - NameSection::Local(local_names) => { - let mut buffer = vec![]; - local_names.serialize(&mut buffer)?; - (NAME_TYPE_LOCAL, buffer) - } - NameSection::Unparsed { - name_type, - name_payload, - } => (name_type, name_payload), - }; - VarUint7::from(name_type).serialize(wtr)?; - VarUint32::from(name_payload.len()).serialize(wtr)?; - wtr.write_all(&name_payload)?; - Ok(()) - } + fn serialize(self, wtr: &mut W) -> Result<(), Error> { + let (name_type, name_payload) = match self { + NameSection::Module(mod_name) => { + let mut buffer = vec![]; + mod_name.serialize(&mut buffer)?; + (NAME_TYPE_MODULE, buffer) + } + NameSection::Function(fn_names) => { + let mut buffer = vec![]; + fn_names.serialize(&mut buffer)?; + (NAME_TYPE_FUNCTION, buffer) + } + NameSection::Local(local_names) => { + let mut buffer = vec![]; + local_names.serialize(&mut buffer)?; + (NAME_TYPE_LOCAL, buffer) + } + NameSection::Unparsed { + name_type, + name_payload, + } => (name_type, name_payload), + }; + VarUint7::from(name_type).serialize(wtr)?; + VarUint32::from(name_payload.len()).serialize(wtr)?; + wtr.write_all(&name_payload)?; + Ok(()) + } } /// The name of this module. #[derive(Clone, Debug, PartialEq)] pub struct ModuleNameSection { - name: String, + name: String, } impl ModuleNameSection { - /// Create a new module name section with the specified name. - pub fn new>(name: S) -> ModuleNameSection { - ModuleNameSection { name: name.into() } - } + /// Create a new module name section with the specified name. + pub fn new>(name: S) -> ModuleNameSection { + ModuleNameSection { name: name.into() } + } - /// The name of this module. - pub fn name(&self) -> &str { - &self.name - } + /// The name of this module. + pub fn name(&self) -> &str { + &self.name + } - /// The name of this module (mutable). - pub fn name_mut(&mut self) -> &mut String { - &mut self.name - } + /// The name of this module (mutable). + pub fn name_mut(&mut self) -> &mut String { + &mut self.name + } } impl Serialize for ModuleNameSection { - type Error = Error; + type Error = Error; - fn serialize(self, wtr: &mut W) -> Result<(), Error> { - self.name.serialize(wtr) - } + fn serialize(self, wtr: &mut W) -> Result<(), Error> { + self.name.serialize(wtr) + } } impl Deserialize for ModuleNameSection { - type Error = Error; + type Error = Error; - fn deserialize(rdr: &mut R) -> Result { - let name = String::deserialize(rdr)?; - Ok(ModuleNameSection { name }) - } + fn deserialize(rdr: &mut R) -> Result { + let name = String::deserialize(rdr)?; + Ok(ModuleNameSection { name }) + } } /// The names of the functions in this module. #[derive(Clone, Debug, Default, PartialEq)] pub struct FunctionNameSection { - names: NameMap, + names: NameMap, } impl FunctionNameSection { - /// A map from function indices to names. - pub fn names(&self) -> &NameMap { - &self.names - } + /// A map from function indices to names. + pub fn names(&self) -> &NameMap { + &self.names + } - /// A map from function indices to names (mutable). - pub fn names_mut(&mut self) -> &mut NameMap { - &mut self.names - } + /// A map from function indices to names (mutable). + pub fn names_mut(&mut self) -> &mut NameMap { + &mut self.names + } - /// Deserialize names, making sure that all names correspond to functions. - pub fn deserialize( - module: &Module, - rdr: &mut R, - ) -> Result { - let names = IndexMap::deserialize(module.functions_space(), rdr)?; - Ok(FunctionNameSection { names }) - } + /// Deserialize names, making sure that all names correspond to functions. + pub fn deserialize( + module: &Module, + rdr: &mut R, + ) -> Result { + let names = IndexMap::deserialize(module.functions_space(), rdr)?; + Ok(FunctionNameSection { names }) + } } impl Serialize for FunctionNameSection { - type Error = Error; + type Error = Error; - fn serialize(self, wtr: &mut W) -> Result<(), Error> { - self.names.serialize(wtr) - } + fn serialize(self, wtr: &mut W) -> Result<(), Error> { + self.names.serialize(wtr) + } } /// The names of the local variables in this module's functions. #[derive(Clone, Debug, Default, PartialEq)] pub struct LocalNameSection { - local_names: IndexMap, + local_names: IndexMap, } impl LocalNameSection { - /// A map from function indices to a map from variables indices to names. - pub fn local_names(&self) -> &IndexMap { - &self.local_names - } + /// A map from function indices to a map from variables indices to names. + pub fn local_names(&self) -> &IndexMap { + &self.local_names + } - /// A map from function indices to a map from variables indices to names - /// (mutable). - pub fn local_names_mut(&mut self) -> &mut IndexMap { - &mut self.local_names - } + /// A map from function indices to a map from variables indices to names + /// (mutable). + pub fn local_names_mut(&mut self) -> &mut IndexMap { + &mut self.local_names + } - /// Deserialize names, making sure that all names correspond to local - /// variables. - pub fn deserialize( - module: &Module, - rdr: &mut R, - ) -> Result { - let funcs = module.function_section().ok_or_else(|| { - Error::Other("cannot deserialize local names without a function section") - })?; - let max_entry_space = funcs.entries().len(); + /// Deserialize names, making sure that all names correspond to local + /// variables. + pub fn deserialize( + module: &Module, + rdr: &mut R, + ) -> Result { + let funcs = module.function_section().ok_or_else(|| { + Error::Other("cannot deserialize local names without a function section") + })?; + let max_entry_space = funcs.entries().len(); - let max_signature_args = module - .type_section() - .map(|ts| - ts.types() - .iter() - .map(|x| { let Type::Function(ref func) = *x; func.params().len() }) - .max() - .unwrap_or(0)) - .unwrap_or(0); + let max_signature_args = module + .type_section() + .map(|ts| + ts.types() + .iter() + .map(|x| { let Type::Function(ref func) = *x; func.params().len() }) + .max() + .unwrap_or(0)) + .unwrap_or(0); - let max_locals = module - .code_section() - .map(|cs| cs.bodies().iter().map(|f| f.locals().len()).max().unwrap_or(0)) - .unwrap_or(0); + let max_locals = module + .code_section() + .map(|cs| cs.bodies().iter().map(|f| f.locals().len()).max().unwrap_or(0)) + .unwrap_or(0); - let max_space = max_signature_args + max_locals; + let max_space = max_signature_args + max_locals; - let deserialize_locals = |_: u32, rdr: &mut R| IndexMap::deserialize(max_space, rdr); + let deserialize_locals = |_: u32, rdr: &mut R| IndexMap::deserialize(max_space, rdr); - let local_names = IndexMap::deserialize_with( - max_entry_space, - &deserialize_locals, - rdr, - )?; - Ok(LocalNameSection { local_names }) - }} + let local_names = IndexMap::deserialize_with( + max_entry_space, + &deserialize_locals, + rdr, + )?; + Ok(LocalNameSection { local_names }) + }} impl Serialize for LocalNameSection { - type Error = Error; + type Error = Error; - fn serialize(self, wtr: &mut W) -> Result<(), Error> { - self.local_names.serialize(wtr) - } + fn serialize(self, wtr: &mut W) -> Result<(), Error> { + self.local_names.serialize(wtr) + } } /// A map from indices to names. @@ -229,48 +229,48 @@ pub type NameMap = IndexMap; #[cfg(test)] mod tests { - use super::*; + use super::*; - // A helper funtion for the tests. Serialize a section, deserialize it, - // and make sure it matches the original. - fn serialize_test(original: NameSection) -> Vec { - let mut buffer = vec![]; - original - .serialize(&mut buffer) - .expect("serialize error"); - buffer - } + // A helper funtion for the tests. Serialize a section, deserialize it, + // and make sure it matches the original. + fn serialize_test(original: NameSection) -> Vec { + let mut buffer = vec![]; + original + .serialize(&mut buffer) + .expect("serialize error"); + buffer + } - #[test] - fn serialize_module_name() { - let original = NameSection::Module(ModuleNameSection::new("my_mod")); - serialize_test(original.clone()); - } + #[test] + fn serialize_module_name() { + let original = NameSection::Module(ModuleNameSection::new("my_mod")); + serialize_test(original.clone()); + } - #[test] - fn serialize_function_names() { - let mut sect = FunctionNameSection::default(); - sect.names_mut().insert(0, "hello_world".to_string()); - serialize_test(NameSection::Function(sect)); - } + #[test] + fn serialize_function_names() { + let mut sect = FunctionNameSection::default(); + sect.names_mut().insert(0, "hello_world".to_string()); + serialize_test(NameSection::Function(sect)); + } - #[test] - fn serialize_local_names() { - let mut sect = LocalNameSection::default(); - let mut locals = NameMap::default(); - locals.insert(0, "msg".to_string()); - sect.local_names_mut().insert(0, locals); - serialize_test(NameSection::Local(sect)); - } + #[test] + fn serialize_local_names() { + let mut sect = LocalNameSection::default(); + let mut locals = NameMap::default(); + locals.insert(0, "msg".to_string()); + sect.local_names_mut().insert(0, locals); + serialize_test(NameSection::Local(sect)); + } - #[test] - fn serialize_and_deserialize_unparsed() { - let original = NameSection::Unparsed { - // A made-up name section type which is unlikely to be allocated - // soon, in order to allow us to test `Unparsed`. - name_type: 120, - name_payload: vec![0u8, 1, 2], - }; - serialize_test(original.clone()); - } + #[test] + fn serialize_and_deserialize_unparsed() { + let original = NameSection::Unparsed { + // A made-up name section type which is unlikely to be allocated + // soon, in order to allow us to test `Unparsed`. + name_type: 120, + name_payload: vec![0u8, 1, 2], + }; + serialize_test(original.clone()); + } } diff --git a/src/elements/ops.rs b/src/elements/ops.rs index c0e1941..dbfbc67 100644 --- a/src/elements/ops.rs +++ b/src/elements/ops.rs @@ -1,9 +1,9 @@ use std::{io, fmt}; use super::{ - Serialize, Deserialize, Error, - Uint8, VarUint32, CountedList, BlockType, - Uint32, Uint64, CountedListWriter, - VarInt32, VarInt64, + Serialize, Deserialize, Error, + Uint8, VarUint32, CountedList, BlockType, + Uint32, Uint64, CountedListWriter, + VarInt32, VarInt64, }; /// Collection of opcodes (usually inside a block section). @@ -11,46 +11,46 @@ use super::{ pub struct Opcodes(Vec); impl Opcodes { - /// New list of opcodes from vector of opcodes. - pub fn new(elements: Vec) -> Self { - Opcodes(elements) - } + /// New list of opcodes from vector of opcodes. + pub fn new(elements: Vec) -> Self { + Opcodes(elements) + } - /// Empty expression with only `Opcode::End` opcode. - pub fn empty() -> Self { - Opcodes(vec![Opcode::End]) - } + /// Empty expression with only `Opcode::End` opcode. + pub fn empty() -> Self { + Opcodes(vec![Opcode::End]) + } - /// List of individual opcodes. - pub fn elements(&self) -> &[Opcode] { &self.0 } + /// List of individual opcodes. + pub fn elements(&self) -> &[Opcode] { &self.0 } - /// Individual opcodes, mutable. - pub fn elements_mut(&mut self) -> &mut Vec { &mut self.0 } + /// Individual opcodes, mutable. + pub fn elements_mut(&mut self) -> &mut Vec { &mut self.0 } } impl Deserialize for Opcodes { - type Error = Error; + type Error = Error; - fn deserialize(reader: &mut R) -> Result { - let mut opcodes = Vec::new(); - let mut block_count = 1usize; + fn deserialize(reader: &mut R) -> Result { + let mut opcodes = Vec::new(); + let mut block_count = 1usize; - loop { - let opcode = Opcode::deserialize(reader)?; - if opcode.is_terminal() { - block_count -= 1; - } else if opcode.is_block() { - block_count = block_count.checked_add(1).ok_or(Error::Other("too many opcodes"))?; - } + loop { + let opcode = Opcode::deserialize(reader)?; + if opcode.is_terminal() { + block_count -= 1; + } else if opcode.is_block() { + block_count = block_count.checked_add(1).ok_or(Error::Other("too many opcodes"))?; + } - opcodes.push(opcode); - if block_count == 0 { - break; - } - } + opcodes.push(opcode); + if block_count == 0 { + break; + } + } - Ok(Opcodes(opcodes)) - } + Ok(Opcodes(opcodes)) + } } /// Initialization expression. @@ -58,1173 +58,1173 @@ impl Deserialize for Opcodes { pub struct InitExpr(Vec); impl InitExpr { - /// New initialization expression from list of opcodes. - /// `code` must end with the `Opcode::End` opcode! - pub fn new(code: Vec) -> Self { - InitExpr(code) - } + /// New initialization expression from list of opcodes. + /// `code` must end with the `Opcode::End` opcode! + pub fn new(code: Vec) -> Self { + InitExpr(code) + } - /// Empty expression with only `Opcode::End` opcode - pub fn empty() -> Self { - InitExpr(vec![Opcode::End]) - } + /// Empty expression with only `Opcode::End` opcode + pub fn empty() -> Self { + InitExpr(vec![Opcode::End]) + } - /// List of opcodes used in the expression. - pub fn code(&self) -> &[Opcode] { - &self.0 - } + /// List of opcodes used in the expression. + pub fn code(&self) -> &[Opcode] { + &self.0 + } - /// List of opcodes used in the expression. - pub fn code_mut(&mut self) -> &mut Vec { - &mut self.0 - } + /// List of opcodes used in the expression. + pub fn code_mut(&mut self) -> &mut Vec { + &mut self.0 + } } // todo: check if kind of opcode sequence is valid as an expression impl Deserialize for InitExpr { - type Error = Error; + type Error = Error; - fn deserialize(reader: &mut R) -> Result { - let mut opcodes = Vec::new(); + fn deserialize(reader: &mut R) -> Result { + let mut opcodes = Vec::new(); - loop { - let opcode = Opcode::deserialize(reader)?; - let is_terminal = opcode.is_terminal(); - opcodes.push(opcode); - if is_terminal { - break; - } - } + loop { + let opcode = Opcode::deserialize(reader)?; + let is_terminal = opcode.is_terminal(); + opcodes.push(opcode); + if is_terminal { + break; + } + } - Ok(InitExpr(opcodes)) - } + Ok(InitExpr(opcodes)) + } } /// Opcode #[derive(Clone, Debug, PartialEq)] #[allow(missing_docs)] pub enum Opcode { - Unreachable, - Nop, - Block(BlockType), - Loop(BlockType), - If(BlockType), - Else, - End, - Br(u32), - BrIf(u32), - BrTable(Box<[u32]>, u32), - Return, + Unreachable, + Nop, + Block(BlockType), + Loop(BlockType), + If(BlockType), + Else, + End, + Br(u32), + BrIf(u32), + BrTable(Box<[u32]>, u32), + Return, - Call(u32), - CallIndirect(u32, u8), + Call(u32), + CallIndirect(u32, u8), - Drop, - Select, + Drop, + Select, - GetLocal(u32), - SetLocal(u32), - TeeLocal(u32), - GetGlobal(u32), - SetGlobal(u32), + GetLocal(u32), + SetLocal(u32), + TeeLocal(u32), + GetGlobal(u32), + SetGlobal(u32), - // All store/load opcodes operate with 'memory immediates' - // which represented here as (flag, offset) tuple - I32Load(u32, u32), - I64Load(u32, u32), - F32Load(u32, u32), - F64Load(u32, u32), - I32Load8S(u32, u32), - I32Load8U(u32, u32), - I32Load16S(u32, u32), - I32Load16U(u32, u32), - I64Load8S(u32, u32), - I64Load8U(u32, u32), - I64Load16S(u32, u32), - I64Load16U(u32, u32), - I64Load32S(u32, u32), - I64Load32U(u32, u32), - I32Store(u32, u32), - I64Store(u32, u32), - F32Store(u32, u32), - F64Store(u32, u32), - I32Store8(u32, u32), - I32Store16(u32, u32), - I64Store8(u32, u32), - I64Store16(u32, u32), - I64Store32(u32, u32), + // All store/load opcodes operate with 'memory immediates' + // which represented here as (flag, offset) tuple + I32Load(u32, u32), + I64Load(u32, u32), + F32Load(u32, u32), + F64Load(u32, u32), + I32Load8S(u32, u32), + I32Load8U(u32, u32), + I32Load16S(u32, u32), + I32Load16U(u32, u32), + I64Load8S(u32, u32), + I64Load8U(u32, u32), + I64Load16S(u32, u32), + I64Load16U(u32, u32), + I64Load32S(u32, u32), + I64Load32U(u32, u32), + I32Store(u32, u32), + I64Store(u32, u32), + F32Store(u32, u32), + F64Store(u32, u32), + I32Store8(u32, u32), + I32Store16(u32, u32), + I64Store8(u32, u32), + I64Store16(u32, u32), + I64Store32(u32, u32), - CurrentMemory(u8), - GrowMemory(u8), + CurrentMemory(u8), + GrowMemory(u8), - I32Const(i32), - I64Const(i64), - F32Const(u32), - F64Const(u64), + I32Const(i32), + I64Const(i64), + F32Const(u32), + F64Const(u64), - I32Eqz, - I32Eq, - I32Ne, - I32LtS, - I32LtU, - I32GtS, - I32GtU, - I32LeS, - I32LeU, - I32GeS, - I32GeU, + I32Eqz, + I32Eq, + I32Ne, + I32LtS, + I32LtU, + I32GtS, + I32GtU, + I32LeS, + I32LeU, + I32GeS, + I32GeU, - I64Eqz, - I64Eq, - I64Ne, - I64LtS, - I64LtU, - I64GtS, - I64GtU, - I64LeS, - I64LeU, - I64GeS, - I64GeU, + I64Eqz, + I64Eq, + I64Ne, + I64LtS, + I64LtU, + I64GtS, + I64GtU, + I64LeS, + I64LeU, + I64GeS, + I64GeU, - F32Eq, - F32Ne, - F32Lt, - F32Gt, - F32Le, - F32Ge, + F32Eq, + F32Ne, + F32Lt, + F32Gt, + F32Le, + F32Ge, - F64Eq, - F64Ne, - F64Lt, - F64Gt, - F64Le, - F64Ge, + F64Eq, + F64Ne, + F64Lt, + F64Gt, + F64Le, + F64Ge, - I32Clz, - I32Ctz, - I32Popcnt, - I32Add, - I32Sub, - I32Mul, - I32DivS, - I32DivU, - I32RemS, - I32RemU, - I32And, - I32Or, - I32Xor, - I32Shl, - I32ShrS, - I32ShrU, - I32Rotl, - I32Rotr, + I32Clz, + I32Ctz, + I32Popcnt, + I32Add, + I32Sub, + I32Mul, + I32DivS, + I32DivU, + I32RemS, + I32RemU, + I32And, + I32Or, + I32Xor, + I32Shl, + I32ShrS, + I32ShrU, + I32Rotl, + I32Rotr, - I64Clz, - I64Ctz, - I64Popcnt, - I64Add, - I64Sub, - I64Mul, - I64DivS, - I64DivU, - I64RemS, - I64RemU, - I64And, - I64Or, - I64Xor, - I64Shl, - I64ShrS, - I64ShrU, - I64Rotl, - I64Rotr, - F32Abs, - F32Neg, - F32Ceil, - F32Floor, - F32Trunc, - F32Nearest, - F32Sqrt, - F32Add, - F32Sub, - F32Mul, - F32Div, - F32Min, - F32Max, - F32Copysign, - F64Abs, - F64Neg, - F64Ceil, - F64Floor, - F64Trunc, - F64Nearest, - F64Sqrt, - F64Add, - F64Sub, - F64Mul, - F64Div, - F64Min, - F64Max, - F64Copysign, + I64Clz, + I64Ctz, + I64Popcnt, + I64Add, + I64Sub, + I64Mul, + I64DivS, + I64DivU, + I64RemS, + I64RemU, + I64And, + I64Or, + I64Xor, + I64Shl, + I64ShrS, + I64ShrU, + I64Rotl, + I64Rotr, + F32Abs, + F32Neg, + F32Ceil, + F32Floor, + F32Trunc, + F32Nearest, + F32Sqrt, + F32Add, + F32Sub, + F32Mul, + F32Div, + F32Min, + F32Max, + F32Copysign, + F64Abs, + F64Neg, + F64Ceil, + F64Floor, + F64Trunc, + F64Nearest, + F64Sqrt, + F64Add, + F64Sub, + F64Mul, + F64Div, + F64Min, + F64Max, + F64Copysign, - I32WrapI64, - I32TruncSF32, - I32TruncUF32, - I32TruncSF64, - I32TruncUF64, - I64ExtendSI32, - I64ExtendUI32, - I64TruncSF32, - I64TruncUF32, - I64TruncSF64, - I64TruncUF64, - F32ConvertSI32, - F32ConvertUI32, - F32ConvertSI64, - F32ConvertUI64, - F32DemoteF64, - F64ConvertSI32, - F64ConvertUI32, - F64ConvertSI64, - F64ConvertUI64, - F64PromoteF32, + I32WrapI64, + I32TruncSF32, + I32TruncUF32, + I32TruncSF64, + I32TruncUF64, + I64ExtendSI32, + I64ExtendUI32, + I64TruncSF32, + I64TruncUF32, + I64TruncSF64, + I64TruncUF64, + F32ConvertSI32, + F32ConvertUI32, + F32ConvertSI64, + F32ConvertUI64, + F32DemoteF64, + F64ConvertSI32, + F64ConvertUI32, + F64ConvertSI64, + F64ConvertUI64, + F64PromoteF32, - I32ReinterpretF32, - I64ReinterpretF64, - F32ReinterpretI32, - F64ReinterpretI64, + I32ReinterpretF32, + I64ReinterpretF64, + F32ReinterpretI32, + F64ReinterpretI64, } impl Opcode { - /// Is this opcode starts the new block (which should end with terminal opcode). - pub fn is_block(&self) -> bool { - match self { - &Opcode::Block(_) | &Opcode::Loop(_) | &Opcode::If(_) => true, - _ => false, - } - } + /// Is this opcode starts the new block (which should end with terminal opcode). + pub fn is_block(&self) -> bool { + match self { + &Opcode::Block(_) | &Opcode::Loop(_) | &Opcode::If(_) => true, + _ => false, + } + } - /// Is this opcode determines the termination of opcode sequence - /// `true` for `Opcode::End` - pub fn is_terminal(&self) -> bool { - match self { - &Opcode::End => true, - _ => false, - } - } + /// Is this opcode determines the termination of opcode sequence + /// `true` for `Opcode::End` + pub fn is_terminal(&self) -> bool { + match self { + &Opcode::End => true, + _ => false, + } + } } impl Deserialize for Opcode { - type Error = Error; + type Error = Error; - fn deserialize(reader: &mut R) -> Result { - use self::Opcode::*; + fn deserialize(reader: &mut R) -> Result { + use self::Opcode::*; - let val: u8 = Uint8::deserialize(reader)?.into(); + let val: u8 = Uint8::deserialize(reader)?.into(); - Ok( - match val { - 0x00 => Unreachable, - 0x01 => Nop, - 0x02 => Block(BlockType::deserialize(reader)?), - 0x03 => Loop(BlockType::deserialize(reader)?), - 0x04 => If(BlockType::deserialize(reader)?), - 0x05 => Else, - 0x0b => End, + Ok( + match val { + 0x00 => Unreachable, + 0x01 => Nop, + 0x02 => Block(BlockType::deserialize(reader)?), + 0x03 => Loop(BlockType::deserialize(reader)?), + 0x04 => If(BlockType::deserialize(reader)?), + 0x05 => Else, + 0x0b => End, - 0x0c => Br(VarUint32::deserialize(reader)?.into()), - 0x0d => BrIf(VarUint32::deserialize(reader)?.into()), - 0x0e => { - let t1: Vec = CountedList::::deserialize(reader)? - .into_inner() - .into_iter() - .map(Into::into) - .collect(); + 0x0c => Br(VarUint32::deserialize(reader)?.into()), + 0x0d => BrIf(VarUint32::deserialize(reader)?.into()), + 0x0e => { + let t1: Vec = CountedList::::deserialize(reader)? + .into_inner() + .into_iter() + .map(Into::into) + .collect(); - BrTable(t1.into_boxed_slice(), VarUint32::deserialize(reader)?.into()) - }, - 0x0f => Return, - 0x10 => Call(VarUint32::deserialize(reader)?.into()), - 0x11 => CallIndirect( - VarUint32::deserialize(reader)?.into(), - Uint8::deserialize(reader)?.into()), - 0x1a => Drop, - 0x1b => Select, + BrTable(t1.into_boxed_slice(), VarUint32::deserialize(reader)?.into()) + }, + 0x0f => Return, + 0x10 => Call(VarUint32::deserialize(reader)?.into()), + 0x11 => CallIndirect( + VarUint32::deserialize(reader)?.into(), + Uint8::deserialize(reader)?.into()), + 0x1a => Drop, + 0x1b => Select, - 0x20 => GetLocal(VarUint32::deserialize(reader)?.into()), - 0x21 => SetLocal(VarUint32::deserialize(reader)?.into()), - 0x22 => TeeLocal(VarUint32::deserialize(reader)?.into()), - 0x23 => GetGlobal(VarUint32::deserialize(reader)?.into()), - 0x24 => SetGlobal(VarUint32::deserialize(reader)?.into()), + 0x20 => GetLocal(VarUint32::deserialize(reader)?.into()), + 0x21 => SetLocal(VarUint32::deserialize(reader)?.into()), + 0x22 => TeeLocal(VarUint32::deserialize(reader)?.into()), + 0x23 => GetGlobal(VarUint32::deserialize(reader)?.into()), + 0x24 => SetGlobal(VarUint32::deserialize(reader)?.into()), - 0x28 => I32Load( - VarUint32::deserialize(reader)?.into(), - VarUint32::deserialize(reader)?.into()), + 0x28 => I32Load( + VarUint32::deserialize(reader)?.into(), + VarUint32::deserialize(reader)?.into()), - 0x29 => I64Load( - VarUint32::deserialize(reader)?.into(), - VarUint32::deserialize(reader)?.into()), + 0x29 => I64Load( + VarUint32::deserialize(reader)?.into(), + VarUint32::deserialize(reader)?.into()), - 0x2a => F32Load( - VarUint32::deserialize(reader)?.into(), - VarUint32::deserialize(reader)?.into()), + 0x2a => F32Load( + VarUint32::deserialize(reader)?.into(), + VarUint32::deserialize(reader)?.into()), - 0x2b => F64Load( - VarUint32::deserialize(reader)?.into(), - VarUint32::deserialize(reader)?.into()), + 0x2b => F64Load( + VarUint32::deserialize(reader)?.into(), + VarUint32::deserialize(reader)?.into()), - 0x2c => I32Load8S( - VarUint32::deserialize(reader)?.into(), - VarUint32::deserialize(reader)?.into()), + 0x2c => I32Load8S( + VarUint32::deserialize(reader)?.into(), + VarUint32::deserialize(reader)?.into()), - 0x2d => I32Load8U( - VarUint32::deserialize(reader)?.into(), - VarUint32::deserialize(reader)?.into()), + 0x2d => I32Load8U( + VarUint32::deserialize(reader)?.into(), + VarUint32::deserialize(reader)?.into()), - 0x2e => I32Load16S( - VarUint32::deserialize(reader)?.into(), - VarUint32::deserialize(reader)?.into()), + 0x2e => I32Load16S( + VarUint32::deserialize(reader)?.into(), + VarUint32::deserialize(reader)?.into()), - 0x2f => I32Load16U( - VarUint32::deserialize(reader)?.into(), - VarUint32::deserialize(reader)?.into()), + 0x2f => I32Load16U( + VarUint32::deserialize(reader)?.into(), + VarUint32::deserialize(reader)?.into()), - 0x30 => I64Load8S( - VarUint32::deserialize(reader)?.into(), - VarUint32::deserialize(reader)?.into()), + 0x30 => I64Load8S( + VarUint32::deserialize(reader)?.into(), + VarUint32::deserialize(reader)?.into()), - 0x31 => I64Load8U( - VarUint32::deserialize(reader)?.into(), - VarUint32::deserialize(reader)?.into()), + 0x31 => I64Load8U( + VarUint32::deserialize(reader)?.into(), + VarUint32::deserialize(reader)?.into()), - 0x32 => I64Load16S( - VarUint32::deserialize(reader)?.into(), - VarUint32::deserialize(reader)?.into()), + 0x32 => I64Load16S( + VarUint32::deserialize(reader)?.into(), + VarUint32::deserialize(reader)?.into()), - 0x33 => I64Load16U( - VarUint32::deserialize(reader)?.into(), - VarUint32::deserialize(reader)?.into()), + 0x33 => I64Load16U( + VarUint32::deserialize(reader)?.into(), + VarUint32::deserialize(reader)?.into()), - 0x34 => I64Load32S( - VarUint32::deserialize(reader)?.into(), - VarUint32::deserialize(reader)?.into()), + 0x34 => I64Load32S( + VarUint32::deserialize(reader)?.into(), + VarUint32::deserialize(reader)?.into()), - 0x35 => I64Load32U( - VarUint32::deserialize(reader)?.into(), - VarUint32::deserialize(reader)?.into()), + 0x35 => I64Load32U( + VarUint32::deserialize(reader)?.into(), + VarUint32::deserialize(reader)?.into()), - 0x36 => I32Store( - VarUint32::deserialize(reader)?.into(), - VarUint32::deserialize(reader)?.into()), + 0x36 => I32Store( + VarUint32::deserialize(reader)?.into(), + VarUint32::deserialize(reader)?.into()), - 0x37 => I64Store( - VarUint32::deserialize(reader)?.into(), - VarUint32::deserialize(reader)?.into()), + 0x37 => I64Store( + VarUint32::deserialize(reader)?.into(), + VarUint32::deserialize(reader)?.into()), - 0x38 => F32Store( - VarUint32::deserialize(reader)?.into(), - VarUint32::deserialize(reader)?.into()), + 0x38 => F32Store( + VarUint32::deserialize(reader)?.into(), + VarUint32::deserialize(reader)?.into()), - 0x39 => F64Store( - VarUint32::deserialize(reader)?.into(), - VarUint32::deserialize(reader)?.into()), + 0x39 => F64Store( + VarUint32::deserialize(reader)?.into(), + VarUint32::deserialize(reader)?.into()), - 0x3a => I32Store8( - VarUint32::deserialize(reader)?.into(), - VarUint32::deserialize(reader)?.into()), + 0x3a => I32Store8( + VarUint32::deserialize(reader)?.into(), + VarUint32::deserialize(reader)?.into()), - 0x3b => I32Store16( - VarUint32::deserialize(reader)?.into(), - VarUint32::deserialize(reader)?.into()), + 0x3b => I32Store16( + VarUint32::deserialize(reader)?.into(), + VarUint32::deserialize(reader)?.into()), - 0x3c => I64Store8( - VarUint32::deserialize(reader)?.into(), - VarUint32::deserialize(reader)?.into()), + 0x3c => I64Store8( + VarUint32::deserialize(reader)?.into(), + VarUint32::deserialize(reader)?.into()), - 0x3d => I64Store16( - VarUint32::deserialize(reader)?.into(), - VarUint32::deserialize(reader)?.into()), + 0x3d => I64Store16( + VarUint32::deserialize(reader)?.into(), + VarUint32::deserialize(reader)?.into()), - 0x3e => I64Store32( - VarUint32::deserialize(reader)?.into(), - VarUint32::deserialize(reader)?.into()), + 0x3e => I64Store32( + VarUint32::deserialize(reader)?.into(), + VarUint32::deserialize(reader)?.into()), - 0x3f => CurrentMemory(Uint8::deserialize(reader)?.into()), - 0x40 => GrowMemory(Uint8::deserialize(reader)?.into()), + 0x3f => CurrentMemory(Uint8::deserialize(reader)?.into()), + 0x40 => GrowMemory(Uint8::deserialize(reader)?.into()), - 0x41 => I32Const(VarInt32::deserialize(reader)?.into()), - 0x42 => I64Const(VarInt64::deserialize(reader)?.into()), - 0x43 => F32Const(Uint32::deserialize(reader)?.into()), - 0x44 => F64Const(Uint64::deserialize(reader)?.into()), - 0x45 => I32Eqz, - 0x46 => I32Eq, - 0x47 => I32Ne, - 0x48 => I32LtS, - 0x49 => I32LtU, - 0x4a => I32GtS, - 0x4b => I32GtU, - 0x4c => I32LeS, - 0x4d => I32LeU, - 0x4e => I32GeS, - 0x4f => I32GeU, + 0x41 => I32Const(VarInt32::deserialize(reader)?.into()), + 0x42 => I64Const(VarInt64::deserialize(reader)?.into()), + 0x43 => F32Const(Uint32::deserialize(reader)?.into()), + 0x44 => F64Const(Uint64::deserialize(reader)?.into()), + 0x45 => I32Eqz, + 0x46 => I32Eq, + 0x47 => I32Ne, + 0x48 => I32LtS, + 0x49 => I32LtU, + 0x4a => I32GtS, + 0x4b => I32GtU, + 0x4c => I32LeS, + 0x4d => I32LeU, + 0x4e => I32GeS, + 0x4f => I32GeU, - 0x50 => I64Eqz, - 0x51 => I64Eq, - 0x52 => I64Ne, - 0x53 => I64LtS, - 0x54 => I64LtU, - 0x55 => I64GtS, - 0x56 => I64GtU, - 0x57 => I64LeS, - 0x58 => I64LeU, - 0x59 => I64GeS, - 0x5a => I64GeU, + 0x50 => I64Eqz, + 0x51 => I64Eq, + 0x52 => I64Ne, + 0x53 => I64LtS, + 0x54 => I64LtU, + 0x55 => I64GtS, + 0x56 => I64GtU, + 0x57 => I64LeS, + 0x58 => I64LeU, + 0x59 => I64GeS, + 0x5a => I64GeU, - 0x5b => F32Eq, - 0x5c => F32Ne, - 0x5d => F32Lt, - 0x5e => F32Gt, - 0x5f => F32Le, - 0x60 => F32Ge, + 0x5b => F32Eq, + 0x5c => F32Ne, + 0x5d => F32Lt, + 0x5e => F32Gt, + 0x5f => F32Le, + 0x60 => F32Ge, - 0x61 => F64Eq, - 0x62 => F64Ne, - 0x63 => F64Lt, - 0x64 => F64Gt, - 0x65 => F64Le, - 0x66 => F64Ge, + 0x61 => F64Eq, + 0x62 => F64Ne, + 0x63 => F64Lt, + 0x64 => F64Gt, + 0x65 => F64Le, + 0x66 => F64Ge, - 0x67 => I32Clz, - 0x68 => I32Ctz, - 0x69 => I32Popcnt, - 0x6a => I32Add, - 0x6b => I32Sub, - 0x6c => I32Mul, - 0x6d => I32DivS, - 0x6e => I32DivU, - 0x6f => I32RemS, - 0x70 => I32RemU, - 0x71 => I32And, - 0x72 => I32Or, - 0x73 => I32Xor, - 0x74 => I32Shl, - 0x75 => I32ShrS, - 0x76 => I32ShrU, - 0x77 => I32Rotl, - 0x78 => I32Rotr, + 0x67 => I32Clz, + 0x68 => I32Ctz, + 0x69 => I32Popcnt, + 0x6a => I32Add, + 0x6b => I32Sub, + 0x6c => I32Mul, + 0x6d => I32DivS, + 0x6e => I32DivU, + 0x6f => I32RemS, + 0x70 => I32RemU, + 0x71 => I32And, + 0x72 => I32Or, + 0x73 => I32Xor, + 0x74 => I32Shl, + 0x75 => I32ShrS, + 0x76 => I32ShrU, + 0x77 => I32Rotl, + 0x78 => I32Rotr, - 0x79 => I64Clz, - 0x7a => I64Ctz, - 0x7b => I64Popcnt, - 0x7c => I64Add, - 0x7d => I64Sub, - 0x7e => I64Mul, - 0x7f => I64DivS, - 0x80 => I64DivU, - 0x81 => I64RemS, - 0x82 => I64RemU, - 0x83 => I64And, - 0x84 => I64Or, - 0x85 => I64Xor, - 0x86 => I64Shl, - 0x87 => I64ShrS, - 0x88 => I64ShrU, - 0x89 => I64Rotl, - 0x8a => I64Rotr, - 0x8b => F32Abs, - 0x8c => F32Neg, - 0x8d => F32Ceil, - 0x8e => F32Floor, - 0x8f => F32Trunc, - 0x90 => F32Nearest, - 0x91 => F32Sqrt, - 0x92 => F32Add, - 0x93 => F32Sub, - 0x94 => F32Mul, - 0x95 => F32Div, - 0x96 => F32Min, - 0x97 => F32Max, - 0x98 => F32Copysign, - 0x99 => F64Abs, - 0x9a => F64Neg, - 0x9b => F64Ceil, - 0x9c => F64Floor, - 0x9d => F64Trunc, - 0x9e => F64Nearest, - 0x9f => F64Sqrt, - 0xa0 => F64Add, - 0xa1 => F64Sub, - 0xa2 => F64Mul, - 0xa3 => F64Div, - 0xa4 => F64Min, - 0xa5 => F64Max, - 0xa6 => F64Copysign, + 0x79 => I64Clz, + 0x7a => I64Ctz, + 0x7b => I64Popcnt, + 0x7c => I64Add, + 0x7d => I64Sub, + 0x7e => I64Mul, + 0x7f => I64DivS, + 0x80 => I64DivU, + 0x81 => I64RemS, + 0x82 => I64RemU, + 0x83 => I64And, + 0x84 => I64Or, + 0x85 => I64Xor, + 0x86 => I64Shl, + 0x87 => I64ShrS, + 0x88 => I64ShrU, + 0x89 => I64Rotl, + 0x8a => I64Rotr, + 0x8b => F32Abs, + 0x8c => F32Neg, + 0x8d => F32Ceil, + 0x8e => F32Floor, + 0x8f => F32Trunc, + 0x90 => F32Nearest, + 0x91 => F32Sqrt, + 0x92 => F32Add, + 0x93 => F32Sub, + 0x94 => F32Mul, + 0x95 => F32Div, + 0x96 => F32Min, + 0x97 => F32Max, + 0x98 => F32Copysign, + 0x99 => F64Abs, + 0x9a => F64Neg, + 0x9b => F64Ceil, + 0x9c => F64Floor, + 0x9d => F64Trunc, + 0x9e => F64Nearest, + 0x9f => F64Sqrt, + 0xa0 => F64Add, + 0xa1 => F64Sub, + 0xa2 => F64Mul, + 0xa3 => F64Div, + 0xa4 => F64Min, + 0xa5 => F64Max, + 0xa6 => F64Copysign, - 0xa7 => I32WrapI64, - 0xa8 => I32TruncSF32, - 0xa9 => I32TruncUF32, - 0xaa => I32TruncSF64, - 0xab => I32TruncUF64, - 0xac => I64ExtendSI32, - 0xad => I64ExtendUI32, - 0xae => I64TruncSF32, - 0xaf => I64TruncUF32, - 0xb0 => I64TruncSF64, - 0xb1 => I64TruncUF64, - 0xb2 => F32ConvertSI32, - 0xb3 => F32ConvertUI32, - 0xb4 => F32ConvertSI64, - 0xb5 => F32ConvertUI64, - 0xb6 => F32DemoteF64, - 0xb7 => F64ConvertSI32, - 0xb8 => F64ConvertUI32, - 0xb9 => F64ConvertSI64, - 0xba => F64ConvertUI64, - 0xbb => F64PromoteF32, + 0xa7 => I32WrapI64, + 0xa8 => I32TruncSF32, + 0xa9 => I32TruncUF32, + 0xaa => I32TruncSF64, + 0xab => I32TruncUF64, + 0xac => I64ExtendSI32, + 0xad => I64ExtendUI32, + 0xae => I64TruncSF32, + 0xaf => I64TruncUF32, + 0xb0 => I64TruncSF64, + 0xb1 => I64TruncUF64, + 0xb2 => F32ConvertSI32, + 0xb3 => F32ConvertUI32, + 0xb4 => F32ConvertSI64, + 0xb5 => F32ConvertUI64, + 0xb6 => F32DemoteF64, + 0xb7 => F64ConvertSI32, + 0xb8 => F64ConvertUI32, + 0xb9 => F64ConvertSI64, + 0xba => F64ConvertUI64, + 0xbb => F64PromoteF32, - 0xbc => I32ReinterpretF32, - 0xbd => I64ReinterpretF64, - 0xbe => F32ReinterpretI32, - 0xbf => F64ReinterpretI64, + 0xbc => I32ReinterpretF32, + 0xbd => I64ReinterpretF64, + 0xbe => F32ReinterpretI32, + 0xbf => F64ReinterpretI64, - _ => { return Err(Error::UnknownOpcode(val)); } - } - ) - } + _ => { return Err(Error::UnknownOpcode(val)); } + } + ) + } } macro_rules! op { - ($writer: expr, $byte: expr) => ({ - let b: u8 = $byte; - $writer.write_all(&[b])?; - }); - ($writer: expr, $byte: expr, $s: block) => ({ - op!($writer, $byte); - $s; - }); + ($writer: expr, $byte: expr) => ({ + let b: u8 = $byte; + $writer.write_all(&[b])?; + }); + ($writer: expr, $byte: expr, $s: block) => ({ + op!($writer, $byte); + $s; + }); } impl Serialize for Opcode { - type Error = Error; + type Error = Error; - fn serialize(self, writer: &mut W) -> Result<(), Self::Error> { - use self::Opcode::*; + fn serialize(self, writer: &mut W) -> Result<(), Self::Error> { + use self::Opcode::*; - match self { - Unreachable => op!(writer, 0x00), - Nop => op!(writer, 0x01), - Block(block_type) => op!(writer, 0x02, { - block_type.serialize(writer)?; - }), - Loop(block_type) => op!(writer, 0x03, { - block_type.serialize(writer)?; - }), - If(block_type) => op!(writer, 0x04, { - block_type.serialize(writer)?; - }), - Else => op!(writer, 0x05), - End => op!(writer, 0x0b), - Br(idx) => op!(writer, 0x0c, { - VarUint32::from(idx).serialize(writer)?; - }), - BrIf(idx) => op!(writer, 0x0d, { - VarUint32::from(idx).serialize(writer)?; - }), - BrTable(table, default) => op!(writer, 0x0e, { - let list_writer = CountedListWriter::( - table.len(), - table.into_iter().map(|x| VarUint32::from(*x)), - ); - list_writer.serialize(writer)?; - VarUint32::from(default).serialize(writer)?; - }), - Return => op!(writer, 0x0f), - Call(index) => op!(writer, 0x10, { - VarUint32::from(index).serialize(writer)?; - }), - CallIndirect(index, reserved) => op!(writer, 0x11, { - VarUint32::from(index).serialize(writer)?; - Uint8::from(reserved).serialize(writer)?; - }), - Drop => op!(writer, 0x1a), - Select => op!(writer, 0x1b), - GetLocal(index) => op!(writer, 0x20, { - VarUint32::from(index).serialize(writer)?; - }), - SetLocal(index) => op!(writer, 0x21, { - VarUint32::from(index).serialize(writer)?; - }), - TeeLocal(index) => op!(writer, 0x22, { - VarUint32::from(index).serialize(writer)?; - }), - GetGlobal(index) => op!(writer, 0x23, { - VarUint32::from(index).serialize(writer)?; - }), - SetGlobal(index) => op!(writer, 0x24, { - VarUint32::from(index).serialize(writer)?; - }), - I32Load(flags, offset) => op!(writer, 0x28, { - VarUint32::from(flags).serialize(writer)?; - VarUint32::from(offset).serialize(writer)?; - }), - I64Load(flags, offset) => op!(writer, 0x29, { - VarUint32::from(flags).serialize(writer)?; - VarUint32::from(offset).serialize(writer)?; - }), - F32Load(flags, offset) => op!(writer, 0x2a, { - VarUint32::from(flags).serialize(writer)?; - VarUint32::from(offset).serialize(writer)?; - }), - F64Load(flags, offset) => op!(writer, 0x2b, { - VarUint32::from(flags).serialize(writer)?; - VarUint32::from(offset).serialize(writer)?; - }), - I32Load8S(flags, offset) => op!(writer, 0x2c, { - VarUint32::from(flags).serialize(writer)?; - VarUint32::from(offset).serialize(writer)?; - }), - I32Load8U(flags, offset) => op!(writer, 0x2d, { - VarUint32::from(flags).serialize(writer)?; - VarUint32::from(offset).serialize(writer)?; - }), - I32Load16S(flags, offset) => op!(writer, 0x2e, { - VarUint32::from(flags).serialize(writer)?; - VarUint32::from(offset).serialize(writer)?; - }), - I32Load16U(flags, offset) => op!(writer, 0x2f, { - VarUint32::from(flags).serialize(writer)?; - VarUint32::from(offset).serialize(writer)?; - }), - I64Load8S(flags, offset) => op!(writer, 0x30, { - VarUint32::from(flags).serialize(writer)?; - VarUint32::from(offset).serialize(writer)?; - }), - I64Load8U(flags, offset) => op!(writer, 0x31, { - VarUint32::from(flags).serialize(writer)?; - VarUint32::from(offset).serialize(writer)?; - }), - I64Load16S(flags, offset) => op!(writer, 0x32, { - VarUint32::from(flags).serialize(writer)?; - VarUint32::from(offset).serialize(writer)?; - }), - I64Load16U(flags, offset) => op!(writer, 0x33, { - VarUint32::from(flags).serialize(writer)?; - VarUint32::from(offset).serialize(writer)?; - }), - I64Load32S(flags, offset) => op!(writer, 0x34, { - VarUint32::from(flags).serialize(writer)?; - VarUint32::from(offset).serialize(writer)?; - }), - I64Load32U(flags, offset) => op!(writer, 0x35, { - VarUint32::from(flags).serialize(writer)?; - VarUint32::from(offset).serialize(writer)?; - }), - I32Store(flags, offset) => op!(writer, 0x36, { - VarUint32::from(flags).serialize(writer)?; - VarUint32::from(offset).serialize(writer)?; - }), - I64Store(flags, offset) => op!(writer, 0x37, { - VarUint32::from(flags).serialize(writer)?; - VarUint32::from(offset).serialize(writer)?; - }), - F32Store(flags, offset) => op!(writer, 0x38, { - VarUint32::from(flags).serialize(writer)?; - VarUint32::from(offset).serialize(writer)?; - }), - F64Store(flags, offset) => op!(writer, 0x39, { - VarUint32::from(flags).serialize(writer)?; - VarUint32::from(offset).serialize(writer)?; - }), - I32Store8(flags, offset) => op!(writer, 0x3a, { - VarUint32::from(flags).serialize(writer)?; - VarUint32::from(offset).serialize(writer)?; - }), - I32Store16(flags, offset) => op!(writer, 0x3b, { - VarUint32::from(flags).serialize(writer)?; - VarUint32::from(offset).serialize(writer)?; - }), - I64Store8(flags, offset) => op!(writer, 0x3c, { - VarUint32::from(flags).serialize(writer)?; - VarUint32::from(offset).serialize(writer)?; - }), - I64Store16(flags, offset) => op!(writer, 0x3d, { - VarUint32::from(flags).serialize(writer)?; - VarUint32::from(offset).serialize(writer)?; - }), - I64Store32(flags, offset) => op!(writer, 0x3e, { - VarUint32::from(flags).serialize(writer)?; - VarUint32::from(offset).serialize(writer)?; - }), - CurrentMemory(flag) => op!(writer, 0x3f, { - Uint8::from(flag).serialize(writer)?; - }), - GrowMemory(flag) => op!(writer, 0x40, { - Uint8::from(flag).serialize(writer)?; - }), - I32Const(def) => op!(writer, 0x41, { - VarInt32::from(def).serialize(writer)?; - }), - I64Const(def) => op!(writer, 0x42, { - VarInt64::from(def).serialize(writer)?; - }), - F32Const(def) => op!(writer, 0x43, { - Uint32::from(def).serialize(writer)?; - }), - F64Const(def) => op!(writer, 0x44, { - Uint64::from(def).serialize(writer)?; - }), - I32Eqz => op!(writer, 0x45), - I32Eq => op!(writer, 0x46), - I32Ne => op!(writer, 0x47), - I32LtS => op!(writer, 0x48), - I32LtU => op!(writer, 0x49), - I32GtS => op!(writer, 0x4a), - I32GtU => op!(writer, 0x4b), - I32LeS => op!(writer, 0x4c), - I32LeU => op!(writer, 0x4d), - I32GeS => op!(writer, 0x4e), - I32GeU => op!(writer, 0x4f), + match self { + Unreachable => op!(writer, 0x00), + Nop => op!(writer, 0x01), + Block(block_type) => op!(writer, 0x02, { + block_type.serialize(writer)?; + }), + Loop(block_type) => op!(writer, 0x03, { + block_type.serialize(writer)?; + }), + If(block_type) => op!(writer, 0x04, { + block_type.serialize(writer)?; + }), + Else => op!(writer, 0x05), + End => op!(writer, 0x0b), + Br(idx) => op!(writer, 0x0c, { + VarUint32::from(idx).serialize(writer)?; + }), + BrIf(idx) => op!(writer, 0x0d, { + VarUint32::from(idx).serialize(writer)?; + }), + BrTable(table, default) => op!(writer, 0x0e, { + let list_writer = CountedListWriter::( + table.len(), + table.into_iter().map(|x| VarUint32::from(*x)), + ); + list_writer.serialize(writer)?; + VarUint32::from(default).serialize(writer)?; + }), + Return => op!(writer, 0x0f), + Call(index) => op!(writer, 0x10, { + VarUint32::from(index).serialize(writer)?; + }), + CallIndirect(index, reserved) => op!(writer, 0x11, { + VarUint32::from(index).serialize(writer)?; + Uint8::from(reserved).serialize(writer)?; + }), + Drop => op!(writer, 0x1a), + Select => op!(writer, 0x1b), + GetLocal(index) => op!(writer, 0x20, { + VarUint32::from(index).serialize(writer)?; + }), + SetLocal(index) => op!(writer, 0x21, { + VarUint32::from(index).serialize(writer)?; + }), + TeeLocal(index) => op!(writer, 0x22, { + VarUint32::from(index).serialize(writer)?; + }), + GetGlobal(index) => op!(writer, 0x23, { + VarUint32::from(index).serialize(writer)?; + }), + SetGlobal(index) => op!(writer, 0x24, { + VarUint32::from(index).serialize(writer)?; + }), + I32Load(flags, offset) => op!(writer, 0x28, { + VarUint32::from(flags).serialize(writer)?; + VarUint32::from(offset).serialize(writer)?; + }), + I64Load(flags, offset) => op!(writer, 0x29, { + VarUint32::from(flags).serialize(writer)?; + VarUint32::from(offset).serialize(writer)?; + }), + F32Load(flags, offset) => op!(writer, 0x2a, { + VarUint32::from(flags).serialize(writer)?; + VarUint32::from(offset).serialize(writer)?; + }), + F64Load(flags, offset) => op!(writer, 0x2b, { + VarUint32::from(flags).serialize(writer)?; + VarUint32::from(offset).serialize(writer)?; + }), + I32Load8S(flags, offset) => op!(writer, 0x2c, { + VarUint32::from(flags).serialize(writer)?; + VarUint32::from(offset).serialize(writer)?; + }), + I32Load8U(flags, offset) => op!(writer, 0x2d, { + VarUint32::from(flags).serialize(writer)?; + VarUint32::from(offset).serialize(writer)?; + }), + I32Load16S(flags, offset) => op!(writer, 0x2e, { + VarUint32::from(flags).serialize(writer)?; + VarUint32::from(offset).serialize(writer)?; + }), + I32Load16U(flags, offset) => op!(writer, 0x2f, { + VarUint32::from(flags).serialize(writer)?; + VarUint32::from(offset).serialize(writer)?; + }), + I64Load8S(flags, offset) => op!(writer, 0x30, { + VarUint32::from(flags).serialize(writer)?; + VarUint32::from(offset).serialize(writer)?; + }), + I64Load8U(flags, offset) => op!(writer, 0x31, { + VarUint32::from(flags).serialize(writer)?; + VarUint32::from(offset).serialize(writer)?; + }), + I64Load16S(flags, offset) => op!(writer, 0x32, { + VarUint32::from(flags).serialize(writer)?; + VarUint32::from(offset).serialize(writer)?; + }), + I64Load16U(flags, offset) => op!(writer, 0x33, { + VarUint32::from(flags).serialize(writer)?; + VarUint32::from(offset).serialize(writer)?; + }), + I64Load32S(flags, offset) => op!(writer, 0x34, { + VarUint32::from(flags).serialize(writer)?; + VarUint32::from(offset).serialize(writer)?; + }), + I64Load32U(flags, offset) => op!(writer, 0x35, { + VarUint32::from(flags).serialize(writer)?; + VarUint32::from(offset).serialize(writer)?; + }), + I32Store(flags, offset) => op!(writer, 0x36, { + VarUint32::from(flags).serialize(writer)?; + VarUint32::from(offset).serialize(writer)?; + }), + I64Store(flags, offset) => op!(writer, 0x37, { + VarUint32::from(flags).serialize(writer)?; + VarUint32::from(offset).serialize(writer)?; + }), + F32Store(flags, offset) => op!(writer, 0x38, { + VarUint32::from(flags).serialize(writer)?; + VarUint32::from(offset).serialize(writer)?; + }), + F64Store(flags, offset) => op!(writer, 0x39, { + VarUint32::from(flags).serialize(writer)?; + VarUint32::from(offset).serialize(writer)?; + }), + I32Store8(flags, offset) => op!(writer, 0x3a, { + VarUint32::from(flags).serialize(writer)?; + VarUint32::from(offset).serialize(writer)?; + }), + I32Store16(flags, offset) => op!(writer, 0x3b, { + VarUint32::from(flags).serialize(writer)?; + VarUint32::from(offset).serialize(writer)?; + }), + I64Store8(flags, offset) => op!(writer, 0x3c, { + VarUint32::from(flags).serialize(writer)?; + VarUint32::from(offset).serialize(writer)?; + }), + I64Store16(flags, offset) => op!(writer, 0x3d, { + VarUint32::from(flags).serialize(writer)?; + VarUint32::from(offset).serialize(writer)?; + }), + I64Store32(flags, offset) => op!(writer, 0x3e, { + VarUint32::from(flags).serialize(writer)?; + VarUint32::from(offset).serialize(writer)?; + }), + CurrentMemory(flag) => op!(writer, 0x3f, { + Uint8::from(flag).serialize(writer)?; + }), + GrowMemory(flag) => op!(writer, 0x40, { + Uint8::from(flag).serialize(writer)?; + }), + I32Const(def) => op!(writer, 0x41, { + VarInt32::from(def).serialize(writer)?; + }), + I64Const(def) => op!(writer, 0x42, { + VarInt64::from(def).serialize(writer)?; + }), + F32Const(def) => op!(writer, 0x43, { + Uint32::from(def).serialize(writer)?; + }), + F64Const(def) => op!(writer, 0x44, { + Uint64::from(def).serialize(writer)?; + }), + I32Eqz => op!(writer, 0x45), + I32Eq => op!(writer, 0x46), + I32Ne => op!(writer, 0x47), + I32LtS => op!(writer, 0x48), + I32LtU => op!(writer, 0x49), + I32GtS => op!(writer, 0x4a), + I32GtU => op!(writer, 0x4b), + I32LeS => op!(writer, 0x4c), + I32LeU => op!(writer, 0x4d), + I32GeS => op!(writer, 0x4e), + I32GeU => op!(writer, 0x4f), - I64Eqz => op!(writer, 0x50), - I64Eq => op!(writer, 0x51), - I64Ne => op!(writer, 0x52), - I64LtS => op!(writer, 0x53), - I64LtU => op!(writer, 0x54), - I64GtS => op!(writer, 0x55), - I64GtU => op!(writer, 0x56), - I64LeS => op!(writer, 0x57), - I64LeU => op!(writer, 0x58), - I64GeS => op!(writer, 0x59), - I64GeU => op!(writer, 0x5a), + I64Eqz => op!(writer, 0x50), + I64Eq => op!(writer, 0x51), + I64Ne => op!(writer, 0x52), + I64LtS => op!(writer, 0x53), + I64LtU => op!(writer, 0x54), + I64GtS => op!(writer, 0x55), + I64GtU => op!(writer, 0x56), + I64LeS => op!(writer, 0x57), + I64LeU => op!(writer, 0x58), + I64GeS => op!(writer, 0x59), + I64GeU => op!(writer, 0x5a), - F32Eq => op!(writer, 0x5b), - F32Ne => op!(writer, 0x5c), - F32Lt => op!(writer, 0x5d), - F32Gt => op!(writer, 0x5e), - F32Le => op!(writer, 0x5f), - F32Ge => op!(writer, 0x60), + F32Eq => op!(writer, 0x5b), + F32Ne => op!(writer, 0x5c), + F32Lt => op!(writer, 0x5d), + F32Gt => op!(writer, 0x5e), + F32Le => op!(writer, 0x5f), + F32Ge => op!(writer, 0x60), - F64Eq => op!(writer, 0x61), - F64Ne => op!(writer, 0x62), - F64Lt => op!(writer, 0x63), - F64Gt => op!(writer, 0x64), - F64Le => op!(writer, 0x65), - F64Ge => op!(writer, 0x66), + F64Eq => op!(writer, 0x61), + F64Ne => op!(writer, 0x62), + F64Lt => op!(writer, 0x63), + F64Gt => op!(writer, 0x64), + F64Le => op!(writer, 0x65), + F64Ge => op!(writer, 0x66), - I32Clz => op!(writer, 0x67), - I32Ctz => op!(writer, 0x68), - I32Popcnt => op!(writer, 0x69), - I32Add => op!(writer, 0x6a), - I32Sub => op!(writer, 0x6b), - I32Mul => op!(writer, 0x6c), - I32DivS => op!(writer, 0x6d), - I32DivU => op!(writer, 0x6e), - I32RemS => op!(writer, 0x6f), - I32RemU => op!(writer, 0x70), - I32And => op!(writer, 0x71), - I32Or => op!(writer, 0x72), - I32Xor => op!(writer, 0x73), - I32Shl => op!(writer, 0x74), - I32ShrS => op!(writer, 0x75), - I32ShrU => op!(writer, 0x76), - I32Rotl => op!(writer, 0x77), - I32Rotr => op!(writer, 0x78), + I32Clz => op!(writer, 0x67), + I32Ctz => op!(writer, 0x68), + I32Popcnt => op!(writer, 0x69), + I32Add => op!(writer, 0x6a), + I32Sub => op!(writer, 0x6b), + I32Mul => op!(writer, 0x6c), + I32DivS => op!(writer, 0x6d), + I32DivU => op!(writer, 0x6e), + I32RemS => op!(writer, 0x6f), + I32RemU => op!(writer, 0x70), + I32And => op!(writer, 0x71), + I32Or => op!(writer, 0x72), + I32Xor => op!(writer, 0x73), + I32Shl => op!(writer, 0x74), + I32ShrS => op!(writer, 0x75), + I32ShrU => op!(writer, 0x76), + I32Rotl => op!(writer, 0x77), + I32Rotr => op!(writer, 0x78), - I64Clz => op!(writer, 0x79), - I64Ctz => op!(writer, 0x7a), - I64Popcnt => op!(writer, 0x7b), - I64Add => op!(writer, 0x7c), - I64Sub => op!(writer, 0x7d), - I64Mul => op!(writer, 0x7e), - I64DivS => op!(writer, 0x7f), - I64DivU => op!(writer, 0x80), - I64RemS => op!(writer, 0x81), - I64RemU => op!(writer, 0x82), - I64And => op!(writer, 0x83), - I64Or => op!(writer, 0x84), - I64Xor => op!(writer, 0x85), - I64Shl => op!(writer, 0x86), - I64ShrS => op!(writer, 0x87), - I64ShrU => op!(writer, 0x88), - I64Rotl => op!(writer, 0x89), - I64Rotr => op!(writer, 0x8a), - F32Abs => op!(writer, 0x8b), - F32Neg => op!(writer, 0x8c), - F32Ceil => op!(writer, 0x8d), - F32Floor => op!(writer, 0x8e), - F32Trunc => op!(writer, 0x8f), - F32Nearest => op!(writer, 0x90), - F32Sqrt => op!(writer, 0x91), - F32Add => op!(writer, 0x92), - F32Sub => op!(writer, 0x93), - F32Mul => op!(writer, 0x94), - F32Div => op!(writer, 0x95), - F32Min => op!(writer, 0x96), - F32Max => op!(writer, 0x97), - F32Copysign => op!(writer, 0x98), - F64Abs => op!(writer, 0x99), - F64Neg => op!(writer, 0x9a), - F64Ceil => op!(writer, 0x9b), - F64Floor => op!(writer, 0x9c), - F64Trunc => op!(writer, 0x9d), - F64Nearest => op!(writer, 0x9e), - F64Sqrt => op!(writer, 0x9f), - F64Add => op!(writer, 0xa0), - F64Sub => op!(writer, 0xa1), - F64Mul => op!(writer, 0xa2), - F64Div => op!(writer, 0xa3), - F64Min => op!(writer, 0xa4), - F64Max => op!(writer, 0xa5), - F64Copysign => op!(writer, 0xa6), + I64Clz => op!(writer, 0x79), + I64Ctz => op!(writer, 0x7a), + I64Popcnt => op!(writer, 0x7b), + I64Add => op!(writer, 0x7c), + I64Sub => op!(writer, 0x7d), + I64Mul => op!(writer, 0x7e), + I64DivS => op!(writer, 0x7f), + I64DivU => op!(writer, 0x80), + I64RemS => op!(writer, 0x81), + I64RemU => op!(writer, 0x82), + I64And => op!(writer, 0x83), + I64Or => op!(writer, 0x84), + I64Xor => op!(writer, 0x85), + I64Shl => op!(writer, 0x86), + I64ShrS => op!(writer, 0x87), + I64ShrU => op!(writer, 0x88), + I64Rotl => op!(writer, 0x89), + I64Rotr => op!(writer, 0x8a), + F32Abs => op!(writer, 0x8b), + F32Neg => op!(writer, 0x8c), + F32Ceil => op!(writer, 0x8d), + F32Floor => op!(writer, 0x8e), + F32Trunc => op!(writer, 0x8f), + F32Nearest => op!(writer, 0x90), + F32Sqrt => op!(writer, 0x91), + F32Add => op!(writer, 0x92), + F32Sub => op!(writer, 0x93), + F32Mul => op!(writer, 0x94), + F32Div => op!(writer, 0x95), + F32Min => op!(writer, 0x96), + F32Max => op!(writer, 0x97), + F32Copysign => op!(writer, 0x98), + F64Abs => op!(writer, 0x99), + F64Neg => op!(writer, 0x9a), + F64Ceil => op!(writer, 0x9b), + F64Floor => op!(writer, 0x9c), + F64Trunc => op!(writer, 0x9d), + F64Nearest => op!(writer, 0x9e), + F64Sqrt => op!(writer, 0x9f), + F64Add => op!(writer, 0xa0), + F64Sub => op!(writer, 0xa1), + F64Mul => op!(writer, 0xa2), + F64Div => op!(writer, 0xa3), + F64Min => op!(writer, 0xa4), + F64Max => op!(writer, 0xa5), + F64Copysign => op!(writer, 0xa6), - I32WrapI64 => op!(writer, 0xa7), - I32TruncSF32 => op!(writer, 0xa8), - I32TruncUF32 => op!(writer, 0xa9), - I32TruncSF64 => op!(writer, 0xaa), - I32TruncUF64 => op!(writer, 0xab), - I64ExtendSI32 => op!(writer, 0xac), - I64ExtendUI32 => op!(writer, 0xad), - I64TruncSF32 => op!(writer, 0xae), - I64TruncUF32 => op!(writer, 0xaf), - I64TruncSF64 => op!(writer, 0xb0), - I64TruncUF64 => op!(writer, 0xb1), - F32ConvertSI32 => op!(writer, 0xb2), - F32ConvertUI32 => op!(writer, 0xb3), - F32ConvertSI64 => op!(writer, 0xb4), - F32ConvertUI64 => op!(writer, 0xb5), - F32DemoteF64 => op!(writer, 0xb6), - F64ConvertSI32 => op!(writer, 0xb7), - F64ConvertUI32 => op!(writer, 0xb8), - F64ConvertSI64 => op!(writer, 0xb9), - F64ConvertUI64 => op!(writer, 0xba), - F64PromoteF32 => op!(writer, 0xbb), + I32WrapI64 => op!(writer, 0xa7), + I32TruncSF32 => op!(writer, 0xa8), + I32TruncUF32 => op!(writer, 0xa9), + I32TruncSF64 => op!(writer, 0xaa), + I32TruncUF64 => op!(writer, 0xab), + I64ExtendSI32 => op!(writer, 0xac), + I64ExtendUI32 => op!(writer, 0xad), + I64TruncSF32 => op!(writer, 0xae), + I64TruncUF32 => op!(writer, 0xaf), + I64TruncSF64 => op!(writer, 0xb0), + I64TruncUF64 => op!(writer, 0xb1), + F32ConvertSI32 => op!(writer, 0xb2), + F32ConvertUI32 => op!(writer, 0xb3), + F32ConvertSI64 => op!(writer, 0xb4), + F32ConvertUI64 => op!(writer, 0xb5), + F32DemoteF64 => op!(writer, 0xb6), + F64ConvertSI32 => op!(writer, 0xb7), + F64ConvertUI32 => op!(writer, 0xb8), + F64ConvertSI64 => op!(writer, 0xb9), + F64ConvertUI64 => op!(writer, 0xba), + F64PromoteF32 => op!(writer, 0xbb), - I32ReinterpretF32 => op!(writer, 0xbc), - I64ReinterpretF64 => op!(writer, 0xbd), - F32ReinterpretI32 => op!(writer, 0xbe), - F64ReinterpretI64 => op!(writer, 0xbf), - } + I32ReinterpretF32 => op!(writer, 0xbc), + I64ReinterpretF64 => op!(writer, 0xbd), + F32ReinterpretI32 => op!(writer, 0xbe), + F64ReinterpretI64 => op!(writer, 0xbf), + } - Ok(()) - } + Ok(()) + } } macro_rules! fmt_op { - ($f: expr, $mnemonic: expr) => ({ - write!($f, "{}", $mnemonic) - }); - ($f: expr, $mnemonic: expr, $immediate: expr) => ({ - write!($f, "{} {}", $mnemonic, $immediate) - }); - ($f: expr, $mnemonic: expr, $immediate1: expr, $immediate2: expr) => ({ - write!($f, "{} {} {}", $mnemonic, $immediate1, $immediate2) - }); + ($f: expr, $mnemonic: expr) => ({ + write!($f, "{}", $mnemonic) + }); + ($f: expr, $mnemonic: expr, $immediate: expr) => ({ + write!($f, "{} {}", $mnemonic, $immediate) + }); + ($f: expr, $mnemonic: expr, $immediate1: expr, $immediate2: expr) => ({ + write!($f, "{} {} {}", $mnemonic, $immediate1, $immediate2) + }); } impl fmt::Display for Opcode { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - use self::Opcode::*; - use super::BlockType; + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + use self::Opcode::*; + use super::BlockType; - match *self { - Unreachable => fmt_op!(f, "unreachable"), - Nop => fmt_op!(f, "nop"), - Block(BlockType::NoResult) => fmt_op!(f, "block"), - Block(BlockType::Value(value_type)) => fmt_op!(f, "block", value_type), - Loop(BlockType::NoResult) => fmt_op!(f, "loop"), - Loop(BlockType::Value(value_type)) => fmt_op!(f, "loop", value_type), - If(BlockType::NoResult) => fmt_op!(f, "if"), - If(BlockType::Value(value_type)) => fmt_op!(f, "if", value_type), - Else => fmt_op!(f, "else"), - End => fmt_op!(f, "end"), - Br(idx) => fmt_op!(f, "br", idx), - BrIf(idx) => fmt_op!(f, "br_if", idx), - BrTable(_, default) => fmt_op!(f, "br_table", default), - Return => fmt_op!(f, "return"), - Call(index) => fmt_op!(f, "call", index), - CallIndirect(index, _) => fmt_op!(f, "call_indirect", index), - Drop => fmt_op!(f, "drop"), - Select => fmt_op!(f, "select"), - GetLocal(index) => fmt_op!(f, "get_local", index), - SetLocal(index) => fmt_op!(f, "set_local", index), - TeeLocal(index) => fmt_op!(f, "tee_local", index), - GetGlobal(index) => fmt_op!(f, "get_global", index), - SetGlobal(index) => fmt_op!(f, "set_global", index), + match *self { + Unreachable => fmt_op!(f, "unreachable"), + Nop => fmt_op!(f, "nop"), + Block(BlockType::NoResult) => fmt_op!(f, "block"), + Block(BlockType::Value(value_type)) => fmt_op!(f, "block", value_type), + Loop(BlockType::NoResult) => fmt_op!(f, "loop"), + Loop(BlockType::Value(value_type)) => fmt_op!(f, "loop", value_type), + If(BlockType::NoResult) => fmt_op!(f, "if"), + If(BlockType::Value(value_type)) => fmt_op!(f, "if", value_type), + Else => fmt_op!(f, "else"), + End => fmt_op!(f, "end"), + Br(idx) => fmt_op!(f, "br", idx), + BrIf(idx) => fmt_op!(f, "br_if", idx), + BrTable(_, default) => fmt_op!(f, "br_table", default), + Return => fmt_op!(f, "return"), + Call(index) => fmt_op!(f, "call", index), + CallIndirect(index, _) => fmt_op!(f, "call_indirect", index), + Drop => fmt_op!(f, "drop"), + Select => fmt_op!(f, "select"), + GetLocal(index) => fmt_op!(f, "get_local", index), + SetLocal(index) => fmt_op!(f, "set_local", index), + TeeLocal(index) => fmt_op!(f, "tee_local", index), + GetGlobal(index) => fmt_op!(f, "get_global", index), + SetGlobal(index) => fmt_op!(f, "set_global", index), - I32Load(_, 0) => write!(f, "i32.load"), - I32Load(_, offset) => write!(f, "i32.load offset={}", offset), + I32Load(_, 0) => write!(f, "i32.load"), + I32Load(_, offset) => write!(f, "i32.load offset={}", offset), - I64Load(_, 0) => write!(f, "i64.load"), - I64Load(_, offset) => write!(f, "i64.load offset={}", offset), + I64Load(_, 0) => write!(f, "i64.load"), + I64Load(_, offset) => write!(f, "i64.load offset={}", offset), - F32Load(_, 0) => write!(f, "f32.load"), - F32Load(_, offset) => write!(f, "f32.load offset={}", offset), + F32Load(_, 0) => write!(f, "f32.load"), + F32Load(_, offset) => write!(f, "f32.load offset={}", offset), - F64Load(_, 0) => write!(f, "f64.load"), - F64Load(_, offset) => write!(f, "f64.load offset={}", offset), + F64Load(_, 0) => write!(f, "f64.load"), + F64Load(_, offset) => write!(f, "f64.load offset={}", offset), - I32Load8S(_, 0) => write!(f, "i32.load8_s"), - I32Load8S(_, offset) => write!(f, "i32.load8_s offset={}", offset), + I32Load8S(_, 0) => write!(f, "i32.load8_s"), + I32Load8S(_, offset) => write!(f, "i32.load8_s offset={}", offset), - I32Load8U(_, 0) => write!(f, "i32.load8_u"), - I32Load8U(_, offset) => write!(f, "i32.load8_u offset={}", offset), + I32Load8U(_, 0) => write!(f, "i32.load8_u"), + I32Load8U(_, offset) => write!(f, "i32.load8_u offset={}", offset), - I32Load16S(_, 0) => write!(f, "i32.load16_s"), - I32Load16S(_, offset) => write!(f, "i32.load16_s offset={}", offset), + I32Load16S(_, 0) => write!(f, "i32.load16_s"), + I32Load16S(_, offset) => write!(f, "i32.load16_s offset={}", offset), - I32Load16U(_, 0) => write!(f, "i32.load16_u"), - I32Load16U(_, offset) => write!(f, "i32.load16_u offset={}", offset), + I32Load16U(_, 0) => write!(f, "i32.load16_u"), + I32Load16U(_, offset) => write!(f, "i32.load16_u offset={}", offset), - I64Load8S(_, 0) => write!(f, "i64.load8_s"), - I64Load8S(_, offset) => write!(f, "i64.load8_s offset={}", offset), + I64Load8S(_, 0) => write!(f, "i64.load8_s"), + I64Load8S(_, offset) => write!(f, "i64.load8_s offset={}", offset), - I64Load8U(_, 0) => write!(f, "i64.load8_u"), - I64Load8U(_, offset) => write!(f, "i64.load8_u offset={}", offset), + I64Load8U(_, 0) => write!(f, "i64.load8_u"), + I64Load8U(_, offset) => write!(f, "i64.load8_u offset={}", offset), - I64Load16S(_, 0) => write!(f, "i64.load16_s"), - I64Load16S(_, offset) => write!(f, "i64.load16_s offset={}", offset), + I64Load16S(_, 0) => write!(f, "i64.load16_s"), + I64Load16S(_, offset) => write!(f, "i64.load16_s offset={}", offset), - I64Load16U(_, 0) => write!(f, "i64.load16_u"), - I64Load16U(_, offset) => write!(f, "i64.load16_u offset={}", offset), + I64Load16U(_, 0) => write!(f, "i64.load16_u"), + I64Load16U(_, offset) => write!(f, "i64.load16_u offset={}", offset), - I64Load32S(_, 0) => write!(f, "i64.load32_s"), - I64Load32S(_, offset) => write!(f, "i64.load32_s offset={}", offset), + I64Load32S(_, 0) => write!(f, "i64.load32_s"), + I64Load32S(_, offset) => write!(f, "i64.load32_s offset={}", offset), - I64Load32U(_, 0) => write!(f, "i64.load32_u"), - I64Load32U(_, offset) => write!(f, "i64.load32_u offset={}", offset), + I64Load32U(_, 0) => write!(f, "i64.load32_u"), + I64Load32U(_, offset) => write!(f, "i64.load32_u offset={}", offset), - I32Store(_, 0) => write!(f, "i32.store"), - I32Store(_, offset) => write!(f, "i32.store offset={}", offset), + I32Store(_, 0) => write!(f, "i32.store"), + I32Store(_, offset) => write!(f, "i32.store offset={}", offset), - I64Store(_, 0) => write!(f, "i64.store"), - I64Store(_, offset) => write!(f, "i64.store offset={}", offset), + I64Store(_, 0) => write!(f, "i64.store"), + I64Store(_, offset) => write!(f, "i64.store offset={}", offset), - F32Store(_, 0) => write!(f, "f32.store"), - F32Store(_, offset) => write!(f, "f32.store offset={}", offset), + F32Store(_, 0) => write!(f, "f32.store"), + F32Store(_, offset) => write!(f, "f32.store offset={}", offset), - F64Store(_, 0) => write!(f, "f64.store"), - F64Store(_, offset) => write!(f, "f64.store offset={}", offset), + F64Store(_, 0) => write!(f, "f64.store"), + F64Store(_, offset) => write!(f, "f64.store offset={}", offset), - I32Store8(_, 0) => write!(f, "i32.store8"), - I32Store8(_, offset) => write!(f, "i32.store8 offset={}", offset), + I32Store8(_, 0) => write!(f, "i32.store8"), + I32Store8(_, offset) => write!(f, "i32.store8 offset={}", offset), - I32Store16(_, 0) => write!(f, "i32.store16"), - I32Store16(_, offset) => write!(f, "i32.store16 offset={}", offset), + I32Store16(_, 0) => write!(f, "i32.store16"), + I32Store16(_, offset) => write!(f, "i32.store16 offset={}", offset), - I64Store8(_, 0) => write!(f, "i64.store8"), - I64Store8(_, offset) => write!(f, "i64.store8 offset={}", offset), + I64Store8(_, 0) => write!(f, "i64.store8"), + I64Store8(_, offset) => write!(f, "i64.store8 offset={}", offset), - I64Store16(_, 0) => write!(f, "i64.store16"), - I64Store16(_, offset) => write!(f, "i64.store16 offset={}", offset), + I64Store16(_, 0) => write!(f, "i64.store16"), + I64Store16(_, offset) => write!(f, "i64.store16 offset={}", offset), - I64Store32(_, 0) => write!(f, "i64.store32"), - I64Store32(_, offset) => write!(f, "i64.store32 offset={}", offset), + I64Store32(_, 0) => write!(f, "i64.store32"), + I64Store32(_, offset) => write!(f, "i64.store32 offset={}", offset), - CurrentMemory(_) => fmt_op!(f, "current_memory"), - GrowMemory(_) => fmt_op!(f, "grow_memory"), + CurrentMemory(_) => fmt_op!(f, "current_memory"), + GrowMemory(_) => fmt_op!(f, "grow_memory"), - I32Const(def) => fmt_op!(f, "i32.const", def), - I64Const(def) => fmt_op!(f, "i64.const", def), - F32Const(def) => fmt_op!(f, "f32.const", def), - F64Const(def) => fmt_op!(f, "f64.const", def), + I32Const(def) => fmt_op!(f, "i32.const", def), + I64Const(def) => fmt_op!(f, "i64.const", def), + F32Const(def) => fmt_op!(f, "f32.const", def), + F64Const(def) => fmt_op!(f, "f64.const", def), - I32Eq => write!(f, "i32.eq"), - I32Eqz => write!(f, "i32.eqz"), - I32Ne => write!(f, "i32.ne"), - I32LtS => write!(f, "i32.lt_s"), - I32LtU => write!(f, "i32.lt_u"), - I32GtS => write!(f, "i32.gt_s"), - I32GtU => write!(f, "i32.gt_u"), - I32LeS => write!(f, "i32.le_s"), - I32LeU => write!(f, "i32.le_u"), - I32GeS => write!(f, "i32.ge_s"), - I32GeU => write!(f, "i32.ge_u"), + I32Eq => write!(f, "i32.eq"), + I32Eqz => write!(f, "i32.eqz"), + I32Ne => write!(f, "i32.ne"), + I32LtS => write!(f, "i32.lt_s"), + I32LtU => write!(f, "i32.lt_u"), + I32GtS => write!(f, "i32.gt_s"), + I32GtU => write!(f, "i32.gt_u"), + I32LeS => write!(f, "i32.le_s"), + I32LeU => write!(f, "i32.le_u"), + I32GeS => write!(f, "i32.ge_s"), + I32GeU => write!(f, "i32.ge_u"), - I64Eq => write!(f, "i64.eq"), - I64Eqz => write!(f, "i64.eqz"), - I64Ne => write!(f, "i64.ne"), - I64LtS => write!(f, "i64.lt_s"), - I64LtU => write!(f, "i64.lt_u"), - I64GtS => write!(f, "i64.gt_s"), - I64GtU => write!(f, "i64.gt_u"), - I64LeS => write!(f, "i64.le_s"), - I64LeU => write!(f, "i64.le_u"), - I64GeS => write!(f, "i64.ge_s"), - I64GeU => write!(f, "i64.ge_u"), + I64Eq => write!(f, "i64.eq"), + I64Eqz => write!(f, "i64.eqz"), + I64Ne => write!(f, "i64.ne"), + I64LtS => write!(f, "i64.lt_s"), + I64LtU => write!(f, "i64.lt_u"), + I64GtS => write!(f, "i64.gt_s"), + I64GtU => write!(f, "i64.gt_u"), + I64LeS => write!(f, "i64.le_s"), + I64LeU => write!(f, "i64.le_u"), + I64GeS => write!(f, "i64.ge_s"), + I64GeU => write!(f, "i64.ge_u"), - F32Eq => write!(f, "f32.eq"), - F32Ne => write!(f, "f32.ne"), - F32Lt => write!(f, "f32.lt"), - F32Gt => write!(f, "f32.gt"), - F32Le => write!(f, "f32.le"), - F32Ge => write!(f, "f32.ge"), + F32Eq => write!(f, "f32.eq"), + F32Ne => write!(f, "f32.ne"), + F32Lt => write!(f, "f32.lt"), + F32Gt => write!(f, "f32.gt"), + F32Le => write!(f, "f32.le"), + F32Ge => write!(f, "f32.ge"), - F64Eq => write!(f, "f64.eq"), - F64Ne => write!(f, "f64.ne"), - F64Lt => write!(f, "f64.lt"), - F64Gt => write!(f, "f64.gt"), - F64Le => write!(f, "f64.le"), - F64Ge => write!(f, "f64.ge"), + F64Eq => write!(f, "f64.eq"), + F64Ne => write!(f, "f64.ne"), + F64Lt => write!(f, "f64.lt"), + F64Gt => write!(f, "f64.gt"), + F64Le => write!(f, "f64.le"), + F64Ge => write!(f, "f64.ge"), - I32Clz => write!(f, "i32.clz"), - I32Ctz => write!(f, "i32.ctz"), - I32Popcnt => write!(f, "i32.popcnt"), - I32Add => write!(f, "i32.add"), - I32Sub => write!(f, "i32.sub"), - I32Mul => write!(f, "i32.mul"), - I32DivS => write!(f, "i32.div_s"), - I32DivU => write!(f, "i32.div_u"), - I32RemS => write!(f, "i32.rem_s"), - I32RemU => write!(f, "i32.rem_u"), - I32And => write!(f, "i32.and"), - I32Or => write!(f, "i32.or"), - I32Xor => write!(f, "i32.xor"), - I32Shl => write!(f, "i32.shl"), - I32ShrS => write!(f, "i32.shr_s"), - I32ShrU => write!(f, "i32.shr_u"), - I32Rotl => write!(f, "i32.rotl"), - I32Rotr => write!(f, "i32.rotr"), + I32Clz => write!(f, "i32.clz"), + I32Ctz => write!(f, "i32.ctz"), + I32Popcnt => write!(f, "i32.popcnt"), + I32Add => write!(f, "i32.add"), + I32Sub => write!(f, "i32.sub"), + I32Mul => write!(f, "i32.mul"), + I32DivS => write!(f, "i32.div_s"), + I32DivU => write!(f, "i32.div_u"), + I32RemS => write!(f, "i32.rem_s"), + I32RemU => write!(f, "i32.rem_u"), + I32And => write!(f, "i32.and"), + I32Or => write!(f, "i32.or"), + I32Xor => write!(f, "i32.xor"), + I32Shl => write!(f, "i32.shl"), + I32ShrS => write!(f, "i32.shr_s"), + I32ShrU => write!(f, "i32.shr_u"), + I32Rotl => write!(f, "i32.rotl"), + I32Rotr => write!(f, "i32.rotr"), - I64Clz => write!(f, "i64.clz"), - I64Ctz => write!(f, "i64.ctz"), - I64Popcnt => write!(f, "i64.popcnt"), - I64Add => write!(f, "i64.add"), - I64Sub => write!(f, "i64.sub"), - I64Mul => write!(f, "i64.mul"), - I64DivS => write!(f, "i64.div_s"), - I64DivU => write!(f, "i64.div_u"), - I64RemS => write!(f, "i64.rem_s"), - I64RemU => write!(f, "i64.rem_u"), - I64And => write!(f, "i64.and"), - I64Or => write!(f, "i64.or"), - I64Xor => write!(f, "i64.xor"), - I64Shl => write!(f, "i64.shl"), - I64ShrS => write!(f, "i64.shr_s"), - I64ShrU => write!(f, "i64.shr_u"), - I64Rotl => write!(f, "i64.rotl"), - I64Rotr => write!(f, "i64.rotr"), + I64Clz => write!(f, "i64.clz"), + I64Ctz => write!(f, "i64.ctz"), + I64Popcnt => write!(f, "i64.popcnt"), + I64Add => write!(f, "i64.add"), + I64Sub => write!(f, "i64.sub"), + I64Mul => write!(f, "i64.mul"), + I64DivS => write!(f, "i64.div_s"), + I64DivU => write!(f, "i64.div_u"), + I64RemS => write!(f, "i64.rem_s"), + I64RemU => write!(f, "i64.rem_u"), + I64And => write!(f, "i64.and"), + I64Or => write!(f, "i64.or"), + I64Xor => write!(f, "i64.xor"), + I64Shl => write!(f, "i64.shl"), + I64ShrS => write!(f, "i64.shr_s"), + I64ShrU => write!(f, "i64.shr_u"), + I64Rotl => write!(f, "i64.rotl"), + I64Rotr => write!(f, "i64.rotr"), - F32Abs => write!(f, "f32.abs"), - F32Neg => write!(f, "f32.neg"), - F32Ceil => write!(f, "f32.ceil"), - F32Floor => write!(f, "f32.floor"), - F32Trunc => write!(f, "f32.trunc"), - F32Nearest => write!(f, "f32.nearest"), - F32Sqrt => write!(f, "f32.sqrt"), - F32Add => write!(f, "f32.add"), - F32Sub => write!(f, "f32.sub"), - F32Mul => write!(f, "f32.mul"), - F32Div => write!(f, "f32.div"), - F32Min => write!(f, "f32.min"), - F32Max => write!(f, "f32.max"), - F32Copysign => write!(f, "f32.copysign"), + F32Abs => write!(f, "f32.abs"), + F32Neg => write!(f, "f32.neg"), + F32Ceil => write!(f, "f32.ceil"), + F32Floor => write!(f, "f32.floor"), + F32Trunc => write!(f, "f32.trunc"), + F32Nearest => write!(f, "f32.nearest"), + F32Sqrt => write!(f, "f32.sqrt"), + F32Add => write!(f, "f32.add"), + F32Sub => write!(f, "f32.sub"), + F32Mul => write!(f, "f32.mul"), + F32Div => write!(f, "f32.div"), + F32Min => write!(f, "f32.min"), + F32Max => write!(f, "f32.max"), + F32Copysign => write!(f, "f32.copysign"), - F64Abs => write!(f, "f64.abs"), - F64Neg => write!(f, "f64.neg"), - F64Ceil => write!(f, "f64.ceil"), - F64Floor => write!(f, "f64.floor"), - F64Trunc => write!(f, "f64.trunc"), - F64Nearest => write!(f, "f64.nearest"), - F64Sqrt => write!(f, "f64.sqrt"), - F64Add => write!(f, "f64.add"), - F64Sub => write!(f, "f64.sub"), - F64Mul => write!(f, "f64.mul"), - F64Div => write!(f, "f64.div"), - F64Min => write!(f, "f64.min"), - F64Max => write!(f, "f64.max"), - F64Copysign => write!(f, "f64.copysign"), + F64Abs => write!(f, "f64.abs"), + F64Neg => write!(f, "f64.neg"), + F64Ceil => write!(f, "f64.ceil"), + F64Floor => write!(f, "f64.floor"), + F64Trunc => write!(f, "f64.trunc"), + F64Nearest => write!(f, "f64.nearest"), + F64Sqrt => write!(f, "f64.sqrt"), + F64Add => write!(f, "f64.add"), + F64Sub => write!(f, "f64.sub"), + F64Mul => write!(f, "f64.mul"), + F64Div => write!(f, "f64.div"), + F64Min => write!(f, "f64.min"), + F64Max => write!(f, "f64.max"), + F64Copysign => write!(f, "f64.copysign"), - I32WrapI64 => write!(f, "i32.wrap/i64"), - I32TruncSF32 => write!(f, "i32.trunc_s/f32"), - I32TruncUF32 => write!(f, "i32.trunc_u/f32"), - I32TruncSF64 => write!(f, "i32.trunc_s/f64"), - I32TruncUF64 => write!(f, "i32.trunc_u/f64"), + I32WrapI64 => write!(f, "i32.wrap/i64"), + I32TruncSF32 => write!(f, "i32.trunc_s/f32"), + I32TruncUF32 => write!(f, "i32.trunc_u/f32"), + I32TruncSF64 => write!(f, "i32.trunc_s/f64"), + I32TruncUF64 => write!(f, "i32.trunc_u/f64"), - I64ExtendSI32 => write!(f, "i64.extend_s/i32"), - I64ExtendUI32 => write!(f, "i64.extend_u/i32"), + I64ExtendSI32 => write!(f, "i64.extend_s/i32"), + I64ExtendUI32 => write!(f, "i64.extend_u/i32"), - I64TruncSF32 => write!(f, "i64.trunc_s/f32"), - I64TruncUF32 => write!(f, "i64.trunc_u/f32"), - I64TruncSF64 => write!(f, "i64.trunc_s/f64"), - I64TruncUF64 => write!(f, "i64.trunc_u/f64"), + I64TruncSF32 => write!(f, "i64.trunc_s/f32"), + I64TruncUF32 => write!(f, "i64.trunc_u/f32"), + I64TruncSF64 => write!(f, "i64.trunc_s/f64"), + I64TruncUF64 => write!(f, "i64.trunc_u/f64"), - F32ConvertSI32 => write!(f, "f32.convert_s/i32"), - F32ConvertUI32 => write!(f, "f32.convert_u/i32"), - F32ConvertSI64 => write!(f, "f32.convert_s/i64"), - F32ConvertUI64 => write!(f, "f32.convert_u/i64"), - F32DemoteF64 => write!(f, "f32.demote/f64"), + F32ConvertSI32 => write!(f, "f32.convert_s/i32"), + F32ConvertUI32 => write!(f, "f32.convert_u/i32"), + F32ConvertSI64 => write!(f, "f32.convert_s/i64"), + F32ConvertUI64 => write!(f, "f32.convert_u/i64"), + F32DemoteF64 => write!(f, "f32.demote/f64"), - F64ConvertSI32 => write!(f, "f64.convert_s/i32"), - F64ConvertUI32 => write!(f, "f64.convert_u/i32"), - F64ConvertSI64 => write!(f, "f64.convert_s/i64"), - F64ConvertUI64 => write!(f, "f64.convert_u/i64"), - F64PromoteF32 => write!(f, "f64.promote/f32"), + F64ConvertSI32 => write!(f, "f64.convert_s/i32"), + F64ConvertUI32 => write!(f, "f64.convert_u/i32"), + F64ConvertSI64 => write!(f, "f64.convert_s/i64"), + F64ConvertUI64 => write!(f, "f64.convert_u/i64"), + F64PromoteF32 => write!(f, "f64.promote/f32"), - I32ReinterpretF32 => write!(f, "i32.reinterpret/f32"), - I64ReinterpretF64 => write!(f, "i64.reinterpret/f64"), - F32ReinterpretI32 => write!(f, "f32.reinterpret/i32"), - F64ReinterpretI64 => write!(f, "f64.reinterpret/i64"), - } - } + I32ReinterpretF32 => write!(f, "i32.reinterpret/f32"), + I64ReinterpretF64 => write!(f, "i64.reinterpret/f64"), + F32ReinterpretI32 => write!(f, "f32.reinterpret/i32"), + F64ReinterpretI64 => write!(f, "f64.reinterpret/i64"), + } + } } impl Serialize for Opcodes { - type Error = Error; + type Error = Error; - fn serialize(self, writer: &mut W) -> Result<(), Self::Error> { - for op in self.0.into_iter() { - op.serialize(writer)?; - } + fn serialize(self, writer: &mut W) -> Result<(), Self::Error> { + for op in self.0.into_iter() { + op.serialize(writer)?; + } - Ok(()) - } + Ok(()) + } } impl Serialize for InitExpr { - type Error = Error; + type Error = Error; - fn serialize(self, writer: &mut W) -> Result<(), Self::Error> { - for op in self.0.into_iter() { - op.serialize(writer)?; - } + fn serialize(self, writer: &mut W) -> Result<(), Self::Error> { + for op in self.0.into_iter() { + op.serialize(writer)?; + } - Ok(()) - } + Ok(()) + } } #[test] fn ifelse() { - // see if-else.wast/if-else.wasm - let opcode = super::deserialize_buffer::(&[0x04, 0x7F, 0x41, 0x05, 0x05, 0x41, 0x07, 0x0B, 0x0B]) - .expect("valid hex of if instruction"); - let opcodes = opcode.elements(); - match &opcodes[0] { - &Opcode::If(_) => (), - _ => panic!("Should be deserialized as if opcode"), - } - let before_else = opcodes.iter().skip(1) - .take_while(|op| match **op { Opcode::Else => false, _ => true }).count(); - let after_else = opcodes.iter().skip(1) - .skip_while(|op| match **op { Opcode::Else => false, _ => true }) - .take_while(|op| match **op { Opcode::End => false, _ => true }) - .count() - - 1; // minus Opcode::Else itself - assert_eq!(before_else, after_else); + // see if-else.wast/if-else.wasm + let opcode = super::deserialize_buffer::(&[0x04, 0x7F, 0x41, 0x05, 0x05, 0x41, 0x07, 0x0B, 0x0B]) + .expect("valid hex of if instruction"); + let opcodes = opcode.elements(); + match &opcodes[0] { + &Opcode::If(_) => (), + _ => panic!("Should be deserialized as if opcode"), + } + let before_else = opcodes.iter().skip(1) + .take_while(|op| match **op { Opcode::Else => false, _ => true }).count(); + let after_else = opcodes.iter().skip(1) + .skip_while(|op| match **op { Opcode::Else => false, _ => true }) + .take_while(|op| match **op { Opcode::End => false, _ => true }) + .count() + - 1; // minus Opcode::Else itself + assert_eq!(before_else, after_else); } #[test] fn display() { - let opcode = Opcode::GetLocal(0); - assert_eq!("get_local 0", format!("{}", opcode)); + let opcode = Opcode::GetLocal(0); + assert_eq!("get_local 0", format!("{}", opcode)); - let opcode = Opcode::F64Store(0, 24); - assert_eq!("f64.store offset=24", format!("{}", opcode)); + let opcode = Opcode::F64Store(0, 24); + assert_eq!("f64.store offset=24", format!("{}", opcode)); - let opcode = Opcode::I64Store(0, 0); - assert_eq!("i64.store", format!("{}", opcode)); + let opcode = Opcode::I64Store(0, 0); + assert_eq!("i64.store", format!("{}", opcode)); } #[test] fn size_off() { - assert!(::std::mem::size_of::() <= 24); + assert!(::std::mem::size_of::() <= 24); } diff --git a/src/elements/primitives.rs b/src/elements/primitives.rs index 7233470..bb65ebe 100644 --- a/src/elements/primitives.rs +++ b/src/elements/primitives.rs @@ -8,68 +8,68 @@ use super::{Error, Deserialize, Serialize}; pub struct VarUint32(u32); impl From for usize { - fn from(var: VarUint32) -> usize { - var.0 as usize - } + fn from(var: VarUint32) -> usize { + var.0 as usize + } } impl From for u32 { - fn from(var: VarUint32) -> u32 { - var.0 - } + fn from(var: VarUint32) -> u32 { + var.0 + } } impl From for VarUint32 { - fn from(i: u32) -> VarUint32 { - VarUint32(i) - } + fn from(i: u32) -> VarUint32 { + VarUint32(i) + } } impl From for VarUint32 { - fn from(i: usize) -> VarUint32 { - assert!(i <= ::std::u32::MAX as usize); - VarUint32(i as u32) - } + fn from(i: usize) -> VarUint32 { + assert!(i <= ::std::u32::MAX as usize); + VarUint32(i as u32) + } } impl Deserialize for VarUint32 { - type Error = Error; + type Error = Error; - fn deserialize(reader: &mut R) -> Result { - let mut res = 0; - let mut shift = 0; - let mut u8buf = [0u8; 1]; - loop { - reader.read_exact(&mut u8buf)?; - let b = u8buf[0] as u32; - res |= (b & 0x7f) << shift; - shift += 7; - if (b >> 7) == 0 { - break; - } - } - Ok(VarUint32(res)) - } + fn deserialize(reader: &mut R) -> Result { + let mut res = 0; + let mut shift = 0; + let mut u8buf = [0u8; 1]; + loop { + reader.read_exact(&mut u8buf)?; + let b = u8buf[0] as u32; + res |= (b & 0x7f) << shift; + shift += 7; + if (b >> 7) == 0 { + break; + } + } + Ok(VarUint32(res)) + } } impl Serialize for VarUint32 { - type Error = Error; + type Error = Error; - fn serialize(self, writer: &mut W) -> Result<(), Self::Error> { - let mut buf = [0u8; 1]; - let mut v = self.0; - loop { - buf[0] = (v & 0b0111_1111) as u8; - v >>= 7; - if v > 0 { - buf[0] |= 0b1000_0000; - } - writer.write_all(&buf[..])?; - if v == 0 { break; } - } + fn serialize(self, writer: &mut W) -> Result<(), Self::Error> { + let mut buf = [0u8; 1]; + let mut v = self.0; + loop { + buf[0] = (v & 0b0111_1111) as u8; + v >>= 7; + if v > 0 { + buf[0] |= 0b1000_0000; + } + writer.write_all(&buf[..])?; + if v == 0 { break; } + } - Ok(()) - } + Ok(()) + } } /// Unsigned variable-length integer, limited to 64 bits, @@ -78,55 +78,55 @@ impl Serialize for VarUint32 { pub struct VarUint64(u64); impl From for u64 { - fn from(var: VarUint64) -> u64 { - var.0 - } + fn from(var: VarUint64) -> u64 { + var.0 + } } impl Deserialize for VarUint64 { - type Error = Error; + type Error = Error; - fn deserialize(reader: &mut R) -> Result { - let mut res = 0; - let mut shift = 0; - let mut u8buf = [0u8; 1]; - loop { - reader.read_exact(&mut u8buf)?; - let b = u8buf[0] as u64; - res |= (b & 0x7f) << shift; - shift += 7; - if (b >> 7) == 0 { - break; - } - } - Ok(VarUint64(res)) - } + fn deserialize(reader: &mut R) -> Result { + let mut res = 0; + let mut shift = 0; + let mut u8buf = [0u8; 1]; + loop { + reader.read_exact(&mut u8buf)?; + let b = u8buf[0] as u64; + res |= (b & 0x7f) << shift; + shift += 7; + if (b >> 7) == 0 { + break; + } + } + Ok(VarUint64(res)) + } } impl Serialize for VarUint64 { - type Error = Error; + type Error = Error; - fn serialize(self, writer: &mut W) -> Result<(), Self::Error> { - let mut buf = [0u8; 1]; - let mut v = self.0; - loop { - buf[0] = (v & 0b0111_1111) as u8; - v >>= 7; - if v > 0 { - buf[0] |= 0b1000_0000; - } - writer.write_all(&buf[..])?; - if v == 0 { break; } - } + fn serialize(self, writer: &mut W) -> Result<(), Self::Error> { + let mut buf = [0u8; 1]; + let mut v = self.0; + loop { + buf[0] = (v & 0b0111_1111) as u8; + v >>= 7; + if v > 0 { + buf[0] |= 0b1000_0000; + } + writer.write_all(&buf[..])?; + if v == 0 { break; } + } - Ok(()) - } + Ok(()) + } } impl From for VarUint64 { - fn from(u: u64) -> VarUint64 { - VarUint64(u) - } + fn from(u: u64) -> VarUint64 { + VarUint64(u) + } } /// 7-bit unsigned integer, encoded in LEB128 (always 1 byte length) @@ -134,35 +134,35 @@ impl From for VarUint64 { pub struct VarUint7(u8); impl From for u8 { - fn from(v: VarUint7) -> u8 { - v.0 - } + fn from(v: VarUint7) -> u8 { + v.0 + } } impl From for VarUint7 { - fn from(v: u8) -> Self { - VarUint7(v) - } + fn from(v: u8) -> Self { + VarUint7(v) + } } impl Deserialize for VarUint7 { - type Error = Error; + type Error = Error; - fn deserialize(reader: &mut R) -> Result { - let mut u8buf = [0u8; 1]; - reader.read_exact(&mut u8buf)?; - Ok(VarUint7(u8buf[0])) - } + fn deserialize(reader: &mut R) -> Result { + let mut u8buf = [0u8; 1]; + reader.read_exact(&mut u8buf)?; + Ok(VarUint7(u8buf[0])) + } } impl Serialize for VarUint7 { - type Error = Error; + type Error = Error; - fn serialize(self, writer: &mut W) -> Result<(), Self::Error> { - // todo check range? - writer.write_all(&[self.0])?; - Ok(()) - } + fn serialize(self, writer: &mut W) -> Result<(), Self::Error> { + // todo check range? + writer.write_all(&[self.0])?; + Ok(()) + } } /// 7-bit signed integer, encoded in LEB128 (always 1 byte length) @@ -170,40 +170,40 @@ impl Serialize for VarUint7 { pub struct VarInt7(i8); impl From for i8 { - fn from(v: VarInt7) -> i8 { - v.0 - } + fn from(v: VarInt7) -> i8 { + v.0 + } } impl From for VarInt7 { - fn from(v: i8) -> VarInt7 { - VarInt7(v) - } + fn from(v: i8) -> VarInt7 { + VarInt7(v) + } } impl Deserialize for VarInt7 { - type Error = Error; + type Error = Error; - fn deserialize(reader: &mut R) -> Result { - let mut u8buf = [0u8; 1]; - reader.read_exact(&mut u8buf)?; - // expand sign - if u8buf[0] & 0b0100_0000 == 0b0100_0000 { u8buf[0] |= 0b1000_0000 } - // todo check range - Ok(VarInt7(u8buf[0] as i8)) - } + fn deserialize(reader: &mut R) -> Result { + let mut u8buf = [0u8; 1]; + reader.read_exact(&mut u8buf)?; + // expand sign + if u8buf[0] & 0b0100_0000 == 0b0100_0000 { u8buf[0] |= 0b1000_0000 } + // todo check range + Ok(VarInt7(u8buf[0] as i8)) + } } impl Serialize for VarInt7 { - type Error = Error; + type Error = Error; - fn serialize(self, writer: &mut W) -> Result<(), Self::Error> { - // todo check range? - let mut b: u8 = self.0 as u8; - if self.0 < 0 { b |= 0b0100_0000; b &= 0b0111_1111; } - writer.write_all(&[b])?; - Ok(()) - } + fn serialize(self, writer: &mut W) -> Result<(), Self::Error> { + // todo check range? + let mut b: u8 = self.0 as u8; + if self.0 < 0 { b |= 0b0100_0000; b &= 0b0111_1111; } + writer.write_all(&[b])?; + Ok(()) + } } /// 8-bit unsigned integer, NOT encoded in LEB128; @@ -212,34 +212,34 @@ impl Serialize for VarInt7 { pub struct Uint8(u8); impl From for u8 { - fn from(v: Uint8) -> u8 { - v.0 - } + fn from(v: Uint8) -> u8 { + v.0 + } } impl From for Uint8 { - fn from(v: u8) -> Self { - Uint8(v) - } + fn from(v: u8) -> Self { + Uint8(v) + } } impl Deserialize for Uint8 { - type Error = Error; + type Error = Error; - fn deserialize(reader: &mut R) -> Result { - let mut u8buf = [0u8; 1]; - reader.read_exact(&mut u8buf)?; - Ok(Uint8(u8buf[0])) - } + fn deserialize(reader: &mut R) -> Result { + let mut u8buf = [0u8; 1]; + reader.read_exact(&mut u8buf)?; + Ok(Uint8(u8buf[0])) + } } impl Serialize for Uint8 { - type Error = Error; + type Error = Error; - fn serialize(self, writer: &mut W) -> Result<(), Self::Error> { - writer.write_all(&[self.0])?; - Ok(()) - } + fn serialize(self, writer: &mut W) -> Result<(), Self::Error> { + writer.write_all(&[self.0])?; + Ok(()) + } } @@ -248,63 +248,63 @@ impl Serialize for Uint8 { pub struct VarInt32(i32); impl From for i32 { - fn from(v: VarInt32) -> i32 { - v.0 - } + fn from(v: VarInt32) -> i32 { + v.0 + } } impl From for VarInt32 { - fn from(v: i32) -> VarInt32 { - VarInt32(v) - } + fn from(v: i32) -> VarInt32 { + VarInt32(v) + } } impl Deserialize for VarInt32 { - type Error = Error; + type Error = Error; - fn deserialize(reader: &mut R) -> Result { - let mut res = 0; - let mut shift = 0; - let mut u8buf = [0u8; 1]; - loop { - if shift > 31 { return Err(Error::InvalidVarInt32); } - reader.read_exact(&mut u8buf)?; - let b = u8buf[0]; + fn deserialize(reader: &mut R) -> Result { + let mut res = 0; + let mut shift = 0; + let mut u8buf = [0u8; 1]; + loop { + if shift > 31 { return Err(Error::InvalidVarInt32); } + reader.read_exact(&mut u8buf)?; + let b = u8buf[0]; - res |= ((b & 0x7f) as i32) << shift; - shift += 7; - if (b >> 7) == 0 { - if shift < 32 && b & 0b0100_0000 == 0b0100_0000 { - res |= (1i32 << shift).wrapping_neg(); - } - break; - } - } - Ok(VarInt32(res)) - } + res |= ((b & 0x7f) as i32) << shift; + shift += 7; + if (b >> 7) == 0 { + if shift < 32 && b & 0b0100_0000 == 0b0100_0000 { + res |= (1i32 << shift).wrapping_neg(); + } + break; + } + } + Ok(VarInt32(res)) + } } impl Serialize for VarInt32 { - type Error = Error; + type Error = Error; - fn serialize(self, writer: &mut W) -> Result<(), Self::Error> { - let mut buf = [0u8; 1]; - let mut v = self.0; - let mut more = true; - while more { - buf[0] = (v & 0b0111_1111) as u8; - v >>= 7; - if (v == 0 && buf[0] & 0b0100_0000 == 0) || (v == -1 && buf[0] & 0b0100_0000 == 0b0100_0000) { - more = false - } else { - buf[0] |= 0b1000_0000 - } + fn serialize(self, writer: &mut W) -> Result<(), Self::Error> { + let mut buf = [0u8; 1]; + let mut v = self.0; + let mut more = true; + while more { + buf[0] = (v & 0b0111_1111) as u8; + v >>= 7; + if (v == 0 && buf[0] & 0b0100_0000 == 0) || (v == -1 && buf[0] & 0b0100_0000 == 0b0100_0000) { + more = false + } else { + buf[0] |= 0b1000_0000 + } - writer.write_all(&buf[..])?; - } + writer.write_all(&buf[..])?; + } - Ok(()) - } + Ok(()) + } } /// 64-bit signed integer, encoded in LEB128 (can be 1-9 bytes length) @@ -312,63 +312,63 @@ impl Serialize for VarInt32 { pub struct VarInt64(i64); impl From for i64 { - fn from(v: VarInt64) -> i64 { - v.0 - } + fn from(v: VarInt64) -> i64 { + v.0 + } } impl From for VarInt64 { - fn from(v: i64) -> VarInt64 { - VarInt64(v) - } + fn from(v: i64) -> VarInt64 { + VarInt64(v) + } } impl Deserialize for VarInt64 { - type Error = Error; + type Error = Error; - fn deserialize(reader: &mut R) -> Result { - let mut res = 0i64; - let mut shift = 0; - let mut u8buf = [0u8; 1]; - loop { - if shift > 63 { return Err(Error::InvalidVarInt64); } - reader.read_exact(&mut u8buf)?; - let b = u8buf[0]; + fn deserialize(reader: &mut R) -> Result { + let mut res = 0i64; + let mut shift = 0; + let mut u8buf = [0u8; 1]; + loop { + if shift > 63 { return Err(Error::InvalidVarInt64); } + reader.read_exact(&mut u8buf)?; + let b = u8buf[0]; - res |= ((b & 0x7f) as i64) << shift; - shift += 7; - if (b >> 7) == 0 { - if shift < 64 && b & 0b0100_0000 == 0b0100_0000 { - res |= (1i64 << shift).wrapping_neg(); - } - break; - } - } - Ok(VarInt64(res)) - } + res |= ((b & 0x7f) as i64) << shift; + shift += 7; + if (b >> 7) == 0 { + if shift < 64 && b & 0b0100_0000 == 0b0100_0000 { + res |= (1i64 << shift).wrapping_neg(); + } + break; + } + } + Ok(VarInt64(res)) + } } impl Serialize for VarInt64 { - type Error = Error; + type Error = Error; - fn serialize(self, writer: &mut W) -> Result<(), Self::Error> { - let mut buf = [0u8; 1]; - let mut v = self.0; - let mut more = true; - while more { - buf[0] = (v & 0b0111_1111) as u8; - v >>= 7; - if (v == 0 && buf[0] & 0b0100_0000 == 0) || (v == -1 && buf[0] & 0b0100_0000 == 0b0100_0000) { - more = false - } else { - buf[0] |= 0b1000_0000 - } + fn serialize(self, writer: &mut W) -> Result<(), Self::Error> { + let mut buf = [0u8; 1]; + let mut v = self.0; + let mut more = true; + while more { + buf[0] = (v & 0b0111_1111) as u8; + v >>= 7; + if (v == 0 && buf[0] & 0b0100_0000 == 0) || (v == -1 && buf[0] & 0b0100_0000 == 0b0100_0000) { + more = false + } else { + buf[0] |= 0b1000_0000 + } - writer.write_all(&buf[..])?; - } + writer.write_all(&buf[..])?; + } - Ok(()) - } + Ok(()) + } } /// 32-bit unsigned integer, encoded in little endian @@ -376,35 +376,35 @@ impl Serialize for VarInt64 { pub struct Uint32(u32); impl Deserialize for Uint32 { - type Error = Error; + type Error = Error; - fn deserialize(reader: &mut R) -> Result { - let mut buf = [0u8; 4]; - reader.read_exact(&mut buf)?; - // todo check range - Ok(Uint32(LittleEndian::read_u32(&buf))) - } + fn deserialize(reader: &mut R) -> Result { + let mut buf = [0u8; 4]; + reader.read_exact(&mut buf)?; + // todo check range + Ok(Uint32(LittleEndian::read_u32(&buf))) + } } impl From for u32 { - fn from(var: Uint32) -> u32 { - var.0 - } + fn from(var: Uint32) -> u32 { + var.0 + } } impl Serialize for Uint32 { - type Error = Error; + type Error = Error; - fn serialize(self, writer: &mut W) -> Result<(), Self::Error> { - let mut buf = [0u8; 4]; - LittleEndian::write_u32(&mut buf, self.0); - writer.write_all(&buf)?; - Ok(()) - } + fn serialize(self, writer: &mut W) -> Result<(), Self::Error> { + let mut buf = [0u8; 4]; + LittleEndian::write_u32(&mut buf, self.0); + writer.write_all(&buf)?; + Ok(()) + } } impl From for Uint32 { - fn from(u: u32) -> Self { Uint32(u) } + fn from(u: u32) -> Self { Uint32(u) } } /// 64-bit unsigned integer, encoded in little endian @@ -412,35 +412,35 @@ impl From for Uint32 { pub struct Uint64(u64); impl Deserialize for Uint64 { - type Error = Error; + type Error = Error; - fn deserialize(reader: &mut R) -> Result { - let mut buf = [0u8; 8]; - reader.read_exact(&mut buf)?; - // todo check range - Ok(Uint64(LittleEndian::read_u64(&buf))) - } + fn deserialize(reader: &mut R) -> Result { + let mut buf = [0u8; 8]; + reader.read_exact(&mut buf)?; + // todo check range + Ok(Uint64(LittleEndian::read_u64(&buf))) + } } impl Serialize for Uint64 { - type Error = Error; + type Error = Error; - fn serialize(self, writer: &mut W) -> Result<(), Self::Error> { - let mut buf = [0u8; 8]; - LittleEndian::write_u64(&mut buf, self.0); - writer.write_all(&buf)?; - Ok(()) - } + fn serialize(self, writer: &mut W) -> Result<(), Self::Error> { + let mut buf = [0u8; 8]; + LittleEndian::write_u64(&mut buf, self.0); + writer.write_all(&buf)?; + Ok(()) + } } impl From for Uint64 { - fn from(u: u64) -> Self { Uint64(u) } + fn from(u: u64) -> Self { Uint64(u) } } impl From for u64 { - fn from(var: Uint64) -> u64 { - var.0 - } + fn from(var: Uint64) -> u64 { + var.0 + } } @@ -449,66 +449,66 @@ impl From for u64 { pub struct VarUint1(bool); impl From for bool { - fn from(v: VarUint1) -> bool { - v.0 - } + fn from(v: VarUint1) -> bool { + v.0 + } } impl From for VarUint1 { - fn from(b: bool) -> Self { - VarUint1(b) - } + fn from(b: bool) -> Self { + VarUint1(b) + } } impl Deserialize for VarUint1 { - type Error = Error; + type Error = Error; - fn deserialize(reader: &mut R) -> Result { - let mut u8buf = [0u8; 1]; - reader.read_exact(&mut u8buf)?; - match u8buf[0] { - 0 => Ok(VarUint1(false)), - 1 => Ok(VarUint1(true)), - v @ _ => Err(Error::InvalidVarUint1(v)), - } - } + fn deserialize(reader: &mut R) -> Result { + let mut u8buf = [0u8; 1]; + reader.read_exact(&mut u8buf)?; + match u8buf[0] { + 0 => Ok(VarUint1(false)), + 1 => Ok(VarUint1(true)), + v @ _ => Err(Error::InvalidVarUint1(v)), + } + } } impl Serialize for VarUint1 { - type Error = Error; + type Error = Error; - fn serialize(self, writer: &mut W) -> Result<(), Self::Error> { - writer.write_all(&[ - if self.0 { 1u8 } else { 0u8 } - ])?; - Ok(()) - } + fn serialize(self, writer: &mut W) -> Result<(), Self::Error> { + writer.write_all(&[ + if self.0 { 1u8 } else { 0u8 } + ])?; + Ok(()) + } } impl Deserialize for String { - type Error = Error; + type Error = Error; - fn deserialize(reader: &mut R) -> Result { - let length = VarUint32::deserialize(reader)?.into(); - if length > 0 { - let mut buf = vec![0u8; length]; - reader.read_exact(&mut buf)?; - String::from_utf8(buf).map_err(|_| Error::NonUtf8String) - } - else { - Ok(String::new()) - } - } + fn deserialize(reader: &mut R) -> Result { + let length = VarUint32::deserialize(reader)?.into(); + if length > 0 { + let mut buf = vec![0u8; length]; + reader.read_exact(&mut buf)?; + String::from_utf8(buf).map_err(|_| Error::NonUtf8String) + } + else { + Ok(String::new()) + } + } } impl Serialize for String { - type Error = Error; + type Error = Error; - fn serialize(self, writer: &mut W) -> Result<(), Error> { - VarUint32::from(self.len()).serialize(writer)?; - writer.write_all(&self.into_bytes()[..])?; - Ok(()) - } + fn serialize(self, writer: &mut W) -> Result<(), Error> { + VarUint32::from(self.len()).serialize(writer)?; + writer.write_all(&self.into_bytes()[..])?; + Ok(()) + } } /// List for reading sequence of elements typed `T`, given @@ -517,65 +517,65 @@ impl Serialize for String { pub struct CountedList(Vec); impl CountedList { - /// Destroy counted list returing inner vector. - pub fn into_inner(self) -> Vec { self.0 } + /// Destroy counted list returing inner vector. + pub fn into_inner(self) -> Vec { self.0 } } impl Deserialize for CountedList where T::Error: From { - type Error = T::Error; + type Error = T::Error; - fn deserialize(reader: &mut R) -> Result { - let count: usize = VarUint32::deserialize(reader)?.into(); - let mut result = Vec::new(); - for _ in 0..count { result.push(T::deserialize(reader)?); } - Ok(CountedList(result)) - } + fn deserialize(reader: &mut R) -> Result { + let count: usize = VarUint32::deserialize(reader)?.into(); + let mut result = Vec::new(); + for _ in 0..count { result.push(T::deserialize(reader)?); } + Ok(CountedList(result)) + } } /// Helper struct to write payload which is preceded by /// it's own length in bytes. #[derive(Debug)] pub struct CountedWriter<'a, W: 'a + io::Write> { - writer: &'a mut W, - data: Vec, + writer: &'a mut W, + data: Vec, } impl<'a, W: 'a + io::Write> CountedWriter<'a, W> { - /// New counted writer on top of the given serial writer - pub fn new(writer: &'a mut W) -> Self { - CountedWriter { - writer: writer, - data: Vec::new(), - } - } + /// New counted writer on top of the given serial writer + pub fn new(writer: &'a mut W) -> Self { + CountedWriter { + writer: writer, + data: Vec::new(), + } + } - /// Finish counted writer routing, which writes accumulated length - /// and actual payload. - pub fn done(self) -> io::Result<()> { - let writer = self.writer; - let data = self.data; - VarUint32::from(data.len()) - .serialize(writer) - .map_err( - |_| io::Error::new( - io::ErrorKind::Other, - "Length serialization error", - ) - )?; - writer.write_all(&data[..])?; - Ok(()) - } + /// Finish counted writer routing, which writes accumulated length + /// and actual payload. + pub fn done(self) -> io::Result<()> { + let writer = self.writer; + let data = self.data; + VarUint32::from(data.len()) + .serialize(writer) + .map_err( + |_| io::Error::new( + io::ErrorKind::Other, + "Length serialization error", + ) + )?; + writer.write_all(&data[..])?; + Ok(()) + } } impl<'a, W: 'a + io::Write> io::Write for CountedWriter<'a, W> { - fn write(&mut self, buf: &[u8]) -> io::Result { - self.data.extend(buf.to_vec()); - Ok(buf.len()) - } + fn write(&mut self, buf: &[u8]) -> io::Result { + self.data.extend(buf.to_vec()); + Ok(buf.len()) + } - fn flush(&mut self) -> io::Result<()> { - Ok(()) - } + fn flush(&mut self) -> io::Result<()> { + Ok(()) + } } /// Helper struct to write series of `T` preceded by the length of the sequence @@ -584,204 +584,204 @@ impl<'a, W: 'a + io::Write> io::Write for CountedWriter<'a, W> { pub struct CountedListWriter, T: IntoIterator>(pub usize, pub T); impl, T: IntoIterator> Serialize for CountedListWriter { - type Error = Error; + type Error = Error; - fn serialize(self, writer: &mut W) -> Result<(), Self::Error> { - let len_us = self.0; - let data = self.1; - let len: VarUint32 = len_us.into(); - len.serialize(writer)?; - for data_element in data { data_element.serialize(writer)? } + fn serialize(self, writer: &mut W) -> Result<(), Self::Error> { + let len_us = self.0; + let data = self.1; + let len: VarUint32 = len_us.into(); + len.serialize(writer)?; + for data_element in data { data_element.serialize(writer)? } - Ok(()) - } + Ok(()) + } } #[cfg(test)] mod tests { - use super::super::{deserialize_buffer, Serialize}; - use super::{CountedList, VarInt7, VarUint32, VarInt32, VarInt64, VarUint64}; + use super::super::{deserialize_buffer, Serialize}; + use super::{CountedList, VarInt7, VarUint32, VarInt32, VarInt64, VarUint64}; - fn varuint32_ser_test(val: u32, expected: Vec) { - let mut buf = Vec::new(); - let v1: VarUint32 = val.into(); - v1.serialize(&mut buf).expect("to be serialized ok"); - assert_eq!(expected, buf); - } + fn varuint32_ser_test(val: u32, expected: Vec) { + let mut buf = Vec::new(); + let v1: VarUint32 = val.into(); + v1.serialize(&mut buf).expect("to be serialized ok"); + assert_eq!(expected, buf); + } - fn varuint32_de_test(dt: Vec, expected: u32) { - let val: VarUint32 = super::super::deserialize_buffer(&dt).expect("buf to be serialized"); - assert_eq!(expected, val.into()); - } + fn varuint32_de_test(dt: Vec, expected: u32) { + let val: VarUint32 = super::super::deserialize_buffer(&dt).expect("buf to be serialized"); + assert_eq!(expected, val.into()); + } - fn varuint32_serde_test(dt: Vec, val: u32) { - varuint32_de_test(dt.clone(), val); - varuint32_ser_test(val, dt); - } + fn varuint32_serde_test(dt: Vec, val: u32) { + varuint32_de_test(dt.clone(), val); + varuint32_ser_test(val, dt); + } - fn varint32_ser_test(val: i32, expected: Vec) { - let mut buf = Vec::new(); - let v1: VarInt32 = val.into(); - v1.serialize(&mut buf).expect("to be serialized ok"); - assert_eq!(expected, buf); - } + fn varint32_ser_test(val: i32, expected: Vec) { + let mut buf = Vec::new(); + let v1: VarInt32 = val.into(); + v1.serialize(&mut buf).expect("to be serialized ok"); + assert_eq!(expected, buf); + } - fn varint32_de_test(dt: Vec, expected: i32) { - let val: VarInt32 = super::super::deserialize_buffer(&dt).expect("buf to be serialized"); - assert_eq!(expected, val.into()); - } + fn varint32_de_test(dt: Vec, expected: i32) { + let val: VarInt32 = super::super::deserialize_buffer(&dt).expect("buf to be serialized"); + assert_eq!(expected, val.into()); + } - fn varint32_serde_test(dt: Vec, val: i32) { - varint32_de_test(dt.clone(), val); - varint32_ser_test(val, dt); - } + fn varint32_serde_test(dt: Vec, val: i32) { + varint32_de_test(dt.clone(), val); + varint32_ser_test(val, dt); + } - fn varuint64_ser_test(val: u64, expected: Vec) { - let mut buf = Vec::new(); - let v1: VarUint64 = val.into(); - v1.serialize(&mut buf).expect("to be serialized ok"); - assert_eq!(expected, buf); - } + fn varuint64_ser_test(val: u64, expected: Vec) { + let mut buf = Vec::new(); + let v1: VarUint64 = val.into(); + v1.serialize(&mut buf).expect("to be serialized ok"); + assert_eq!(expected, buf); + } - fn varuint64_de_test(dt: Vec, expected: u64) { - let val: VarUint64 = super::super::deserialize_buffer(&dt).expect("buf to be serialized"); - assert_eq!(expected, val.into()); - } + fn varuint64_de_test(dt: Vec, expected: u64) { + let val: VarUint64 = super::super::deserialize_buffer(&dt).expect("buf to be serialized"); + assert_eq!(expected, val.into()); + } - fn varuint64_serde_test(dt: Vec, val: u64) { - varuint64_de_test(dt.clone(), val); - varuint64_ser_test(val, dt); - } + fn varuint64_serde_test(dt: Vec, val: u64) { + varuint64_de_test(dt.clone(), val); + varuint64_ser_test(val, dt); + } - fn varint64_ser_test(val: i64, expected: Vec) { - let mut buf = Vec::new(); - let v1: VarInt64 = val.into(); - v1.serialize(&mut buf).expect("to be serialized ok"); - assert_eq!(expected, buf); - } + fn varint64_ser_test(val: i64, expected: Vec) { + let mut buf = Vec::new(); + let v1: VarInt64 = val.into(); + v1.serialize(&mut buf).expect("to be serialized ok"); + assert_eq!(expected, buf); + } - fn varint64_de_test(dt: Vec, expected: i64) { - let val: VarInt64 = super::super::deserialize_buffer(&dt).expect("buf to be serialized"); - assert_eq!(expected, val.into()); - } + fn varint64_de_test(dt: Vec, expected: i64) { + let val: VarInt64 = super::super::deserialize_buffer(&dt).expect("buf to be serialized"); + assert_eq!(expected, val.into()); + } - fn varint64_serde_test(dt: Vec, val: i64) { - varint64_de_test(dt.clone(), val); - varint64_ser_test(val, dt); - } + fn varint64_serde_test(dt: Vec, val: i64) { + varint64_de_test(dt.clone(), val); + varint64_ser_test(val, dt); + } - #[test] - fn varuint32_0() { - varuint32_serde_test(vec![0u8; 1], 0); - } + #[test] + fn varuint32_0() { + varuint32_serde_test(vec![0u8; 1], 0); + } - #[test] - fn varuint32_1() { - varuint32_serde_test(vec![1u8; 1], 1); - } + #[test] + fn varuint32_1() { + varuint32_serde_test(vec![1u8; 1], 1); + } - #[test] - fn varuint32_135() { - varuint32_serde_test(vec![135u8, 0x01], 135); - } + #[test] + fn varuint32_135() { + varuint32_serde_test(vec![135u8, 0x01], 135); + } - #[test] - fn varuint32_8192() { - varuint32_serde_test(vec![0x80, 0x40], 8192); - } + #[test] + fn varuint32_8192() { + varuint32_serde_test(vec![0x80, 0x40], 8192); + } - #[test] - fn varint32_8192() { - varint32_serde_test(vec![0x80, 0xc0, 0x00], 8192); - } + #[test] + fn varint32_8192() { + varint32_serde_test(vec![0x80, 0xc0, 0x00], 8192); + } - #[test] - fn varint32_neg_8192() { - varint32_serde_test(vec![0x80, 0x40], -8192); - } + #[test] + fn varint32_neg_8192() { + varint32_serde_test(vec![0x80, 0x40], -8192); + } - #[test] - fn varuint64_0() { - varuint64_serde_test(vec![0u8; 1], 0); - } + #[test] + fn varuint64_0() { + varuint64_serde_test(vec![0u8; 1], 0); + } - #[test] - fn varuint64_1() { - varuint64_serde_test(vec![1u8; 1], 1); - } + #[test] + fn varuint64_1() { + varuint64_serde_test(vec![1u8; 1], 1); + } - #[test] - fn varuint64_135() { - varuint64_serde_test(vec![135u8, 0x01], 135); - } + #[test] + fn varuint64_135() { + varuint64_serde_test(vec![135u8, 0x01], 135); + } - #[test] - fn varuint64_8192() { - varuint64_serde_test(vec![0x80, 0x40], 8192); - } + #[test] + fn varuint64_8192() { + varuint64_serde_test(vec![0x80, 0x40], 8192); + } - #[test] - fn varint64_8192() { - varint64_serde_test(vec![0x80, 0xc0, 0x00], 8192); - } + #[test] + fn varint64_8192() { + varint64_serde_test(vec![0x80, 0xc0, 0x00], 8192); + } - #[test] - fn varint64_neg_8192() { - varint64_serde_test(vec![0x80, 0x40], -8192); - } + #[test] + fn varint64_neg_8192() { + varint64_serde_test(vec![0x80, 0x40], -8192); + } - #[test] - fn varint64_min() { - varint64_serde_test( - vec![0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x7f], - -9223372036854775808, - ); - } + #[test] + fn varint64_min() { + varint64_serde_test( + vec![0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x7f], + -9223372036854775808, + ); + } - #[test] - fn varint64_max() { - varint64_serde_test( - vec![0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00], - 9223372036854775807, - ); - } + #[test] + fn varint64_max() { + varint64_serde_test( + vec![0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00], + 9223372036854775807, + ); + } - #[test] - fn varint32_min() { - varint32_serde_test( - vec![0x80, 0x80, 0x80, 0x80, 0x78], - -2147483648, - ); - } + #[test] + fn varint32_min() { + varint32_serde_test( + vec![0x80, 0x80, 0x80, 0x80, 0x78], + -2147483648, + ); + } - #[test] - fn varint32_max() { - varint32_serde_test( - vec![0xff, 0xff, 0xff, 0xff, 0x07], - 2147483647, - ); - } + #[test] + fn varint32_max() { + varint32_serde_test( + vec![0xff, 0xff, 0xff, 0xff, 0x07], + 2147483647, + ); + } - #[test] - fn counted_list() { - let payload = [ - 133u8, //(128+5), length is 5 - 0x80, 0x80, 0x80, 0x0, // padding - 0x01, - 0x7d, - 0x05, - 0x07, - 0x09, - ]; + #[test] + fn counted_list() { + let payload = [ + 133u8, //(128+5), length is 5 + 0x80, 0x80, 0x80, 0x0, // padding + 0x01, + 0x7d, + 0x05, + 0x07, + 0x09, + ]; - let list: CountedList = - deserialize_buffer(&payload).expect("type_section be deserialized"); + let list: CountedList = + deserialize_buffer(&payload).expect("type_section be deserialized"); - let vars = list.into_inner(); - assert_eq!(5, vars.len()); - let v3: i8 = (*vars.get(1).unwrap()).into(); - assert_eq!(-0x03i8, v3); - } + let vars = list.into_inner(); + assert_eq!(5, vars.len()); + let v3: i8 = (*vars.get(1).unwrap()).into(); + assert_eq!(-0x03i8, v3); + } } diff --git a/src/elements/section.rs b/src/elements/section.rs index f6c84e1..b8952f6 100644 --- a/src/elements/section.rs +++ b/src/elements/section.rs @@ -1,25 +1,25 @@ use std::io; use super::{ - Serialize, - Deserialize, - Unparsed, - Error, - VarUint7, - VarUint32, - CountedList, - ImportEntry, - MemoryType, - TableType, - ExportEntry, - GlobalEntry, - Func, - FuncBody, - ElementSegment, - DataSegment, - CountedWriter, - CountedListWriter, - External, - serialize, + Serialize, + Deserialize, + Unparsed, + Error, + VarUint7, + VarUint32, + CountedList, + ImportEntry, + MemoryType, + TableType, + ExportEntry, + GlobalEntry, + Func, + FuncBody, + ElementSegment, + DataSegment, + CountedWriter, + CountedListWriter, + External, + serialize, }; use super::types::Type; @@ -28,228 +28,228 @@ use super::name_section::NameSection; /// Section in the WebAssembly module. #[derive(Debug, Clone)] pub enum Section { - /// Section is unparsed. - Unparsed { - /// id of the unparsed section - id: u8, - /// raw bytes of the unparsed section - payload: Vec, - }, - /// Custom section (`id=0`) - Custom(CustomSection), - /// Types section - Type(TypeSection), - /// Import section - Import(ImportSection), - /// Function signatures section - Function(FunctionSection), - /// Table definition section - Table(TableSection), - /// Memory definition section - Memory(MemorySection), - /// Global entries section - Global(GlobalSection), - /// Export definitions - Export(ExportSection), - /// Entry reference of the module - Start(u32), - /// Elements section - Element(ElementSection), - /// Function bodies section - Code(CodeSection), - /// Data definition section - Data(DataSection), - /// Name section - Name(NameSection), + /// Section is unparsed. + Unparsed { + /// id of the unparsed section + id: u8, + /// raw bytes of the unparsed section + payload: Vec, + }, + /// Custom section (`id=0`) + Custom(CustomSection), + /// Types section + Type(TypeSection), + /// Import section + Import(ImportSection), + /// Function signatures section + Function(FunctionSection), + /// Table definition section + Table(TableSection), + /// Memory definition section + Memory(MemorySection), + /// Global entries section + Global(GlobalSection), + /// Export definitions + Export(ExportSection), + /// Entry reference of the module + Start(u32), + /// Elements section + Element(ElementSection), + /// Function bodies section + Code(CodeSection), + /// Data definition section + Data(DataSection), + /// Name section + Name(NameSection), } impl Deserialize for Section { - type Error = Error; + type Error = Error; - fn deserialize(reader: &mut R) -> Result { - let id = match VarUint7::deserialize(reader) { - // todo: be more selective detecting no more section - Err(_) => { return Err(Error::UnexpectedEof); }, - Ok(id) => id, - }; + fn deserialize(reader: &mut R) -> Result { + let id = match VarUint7::deserialize(reader) { + // todo: be more selective detecting no more section + Err(_) => { return Err(Error::UnexpectedEof); }, + Ok(id) => id, + }; - Ok( - match id.into() { - 0 => { - Section::Custom(CustomSection::deserialize(reader)?.into()) - }, - 1 => { - Section::Type(TypeSection::deserialize(reader)?) - }, - 2 => { - Section::Import(ImportSection::deserialize(reader)?) - }, - 3 => { - Section::Function(FunctionSection::deserialize(reader)?) - }, - 4 => { - Section::Table(TableSection::deserialize(reader)?) - }, - 5 => { - Section::Memory(MemorySection::deserialize(reader)?) - }, - 6 => { - Section::Global(GlobalSection::deserialize(reader)?) - }, - 7 => { - Section::Export(ExportSection::deserialize(reader)?) - }, - 8 => { - let _section_length = VarUint32::deserialize(reader)?; - Section::Start(VarUint32::deserialize(reader)?.into()) - }, - 9 => { - Section::Element(ElementSection::deserialize(reader)?) - }, - 10 => { - Section::Code(CodeSection::deserialize(reader)?) - }, - 11 => { - Section::Data(DataSection::deserialize(reader)?) - }, - _ => { - Section::Unparsed { id: id.into(), payload: Unparsed::deserialize(reader)?.into() } - } - } - ) - } + Ok( + match id.into() { + 0 => { + Section::Custom(CustomSection::deserialize(reader)?.into()) + }, + 1 => { + Section::Type(TypeSection::deserialize(reader)?) + }, + 2 => { + Section::Import(ImportSection::deserialize(reader)?) + }, + 3 => { + Section::Function(FunctionSection::deserialize(reader)?) + }, + 4 => { + Section::Table(TableSection::deserialize(reader)?) + }, + 5 => { + Section::Memory(MemorySection::deserialize(reader)?) + }, + 6 => { + Section::Global(GlobalSection::deserialize(reader)?) + }, + 7 => { + Section::Export(ExportSection::deserialize(reader)?) + }, + 8 => { + let _section_length = VarUint32::deserialize(reader)?; + Section::Start(VarUint32::deserialize(reader)?.into()) + }, + 9 => { + Section::Element(ElementSection::deserialize(reader)?) + }, + 10 => { + Section::Code(CodeSection::deserialize(reader)?) + }, + 11 => { + Section::Data(DataSection::deserialize(reader)?) + }, + _ => { + Section::Unparsed { id: id.into(), payload: Unparsed::deserialize(reader)?.into() } + } + } + ) + } } impl Serialize for Section { - type Error = Error; + type Error = Error; - fn serialize(self, writer: &mut W) -> Result<(), Self::Error> { - match self { - Section::Custom(custom_section) => { - VarUint7::from(0x00).serialize(writer)?; - custom_section.serialize(writer)?; - }, - Section::Unparsed { id, payload } => { - VarUint7::from(id).serialize(writer)?; - writer.write_all(&payload[..])?; - }, - Section::Type(type_section) => { - VarUint7::from(0x01).serialize(writer)?; - type_section.serialize(writer)?; - }, - Section::Import(import_section) => { - VarUint7::from(0x02).serialize(writer)?; - import_section.serialize(writer)?; - }, - Section::Function(function_section) => { - VarUint7::from(0x03).serialize(writer)?; - function_section.serialize(writer)?; - }, - Section::Table(table_section) => { - VarUint7::from(0x04).serialize(writer)?; - table_section.serialize(writer)?; - }, - Section::Memory(memory_section) => { - VarUint7::from(0x05).serialize(writer)?; - memory_section.serialize(writer)?; - }, - Section::Global(global_section) => { - VarUint7::from(0x06).serialize(writer)?; - global_section.serialize(writer)?; - }, - Section::Export(export_section) => { - VarUint7::from(0x07).serialize(writer)?; - export_section.serialize(writer)?; - }, - Section::Start(index) => { - VarUint7::from(0x08).serialize(writer)?; - let mut counted_writer = CountedWriter::new(writer); - VarUint32::from(index).serialize(&mut counted_writer)?; - counted_writer.done()?; - }, - Section::Element(element_section) => { - VarUint7::from(0x09).serialize(writer)?; - element_section.serialize(writer)?; - }, - Section::Code(code_section) => { - VarUint7::from(0x0a).serialize(writer)?; - code_section.serialize(writer)?; - }, - Section::Data(data_section) => { - VarUint7::from(0x0b).serialize(writer)?; - data_section.serialize(writer)?; - }, - Section::Name(name_section) => { - VarUint7::from(0x00).serialize(writer)?; - let custom = CustomSection { - name: "name".to_owned(), - payload: serialize(name_section)?, - }; - custom.serialize(writer)?; - } - } - Ok(()) - } + fn serialize(self, writer: &mut W) -> Result<(), Self::Error> { + match self { + Section::Custom(custom_section) => { + VarUint7::from(0x00).serialize(writer)?; + custom_section.serialize(writer)?; + }, + Section::Unparsed { id, payload } => { + VarUint7::from(id).serialize(writer)?; + writer.write_all(&payload[..])?; + }, + Section::Type(type_section) => { + VarUint7::from(0x01).serialize(writer)?; + type_section.serialize(writer)?; + }, + Section::Import(import_section) => { + VarUint7::from(0x02).serialize(writer)?; + import_section.serialize(writer)?; + }, + Section::Function(function_section) => { + VarUint7::from(0x03).serialize(writer)?; + function_section.serialize(writer)?; + }, + Section::Table(table_section) => { + VarUint7::from(0x04).serialize(writer)?; + table_section.serialize(writer)?; + }, + Section::Memory(memory_section) => { + VarUint7::from(0x05).serialize(writer)?; + memory_section.serialize(writer)?; + }, + Section::Global(global_section) => { + VarUint7::from(0x06).serialize(writer)?; + global_section.serialize(writer)?; + }, + Section::Export(export_section) => { + VarUint7::from(0x07).serialize(writer)?; + export_section.serialize(writer)?; + }, + Section::Start(index) => { + VarUint7::from(0x08).serialize(writer)?; + let mut counted_writer = CountedWriter::new(writer); + VarUint32::from(index).serialize(&mut counted_writer)?; + counted_writer.done()?; + }, + Section::Element(element_section) => { + VarUint7::from(0x09).serialize(writer)?; + element_section.serialize(writer)?; + }, + Section::Code(code_section) => { + VarUint7::from(0x0a).serialize(writer)?; + code_section.serialize(writer)?; + }, + Section::Data(data_section) => { + VarUint7::from(0x0b).serialize(writer)?; + data_section.serialize(writer)?; + }, + Section::Name(name_section) => { + VarUint7::from(0x00).serialize(writer)?; + let custom = CustomSection { + name: "name".to_owned(), + payload: serialize(name_section)?, + }; + custom.serialize(writer)?; + } + } + Ok(()) + } } /// Custom section #[derive(Debug, Clone)] pub struct CustomSection { - name: String, - payload: Vec, + name: String, + payload: Vec, } impl CustomSection { - /// Name of the custom section - pub fn name(&self) -> &str { - &self.name - } + /// Name of the custom section + pub fn name(&self) -> &str { + &self.name + } - /// Payload of the custom secion - pub fn payload(&self) -> &[u8] { - &self.payload - } + /// Payload of the custom secion + pub fn payload(&self) -> &[u8] { + &self.payload + } - /// Name of the custom section (mutable) - pub fn name_mut(&mut self) -> &mut String { - &mut self.name - } + /// Name of the custom section (mutable) + pub fn name_mut(&mut self) -> &mut String { + &mut self.name + } - /// Payload of the custom section (mutable) - pub fn payload_mut(&mut self) -> &mut Vec { - &mut self.payload - } + /// Payload of the custom section (mutable) + pub fn payload_mut(&mut self) -> &mut Vec { + &mut self.payload + } } impl Deserialize for CustomSection { - type Error = Error; + type Error = Error; - fn deserialize(reader: &mut R) -> Result { - // todo: maybe use reader.take(section_length) - let section_length: u32 = VarUint32::deserialize(reader)?.into(); + fn deserialize(reader: &mut R) -> Result { + // todo: maybe use reader.take(section_length) + let section_length: u32 = VarUint32::deserialize(reader)?.into(); - let name = String::deserialize(reader)?; - let payload_left = section_length - (name.len() as u32 + name.len() as u32 / 128 + 1); - let mut payload = vec![0u8; payload_left as usize]; - reader.read_exact(&mut payload[..])?; + let name = String::deserialize(reader)?; + let payload_left = section_length - (name.len() as u32 + name.len() as u32 / 128 + 1); + let mut payload = vec![0u8; payload_left as usize]; + reader.read_exact(&mut payload[..])?; - Ok(CustomSection { name: name, payload: payload }) - } + Ok(CustomSection { name: name, payload: payload }) + } } impl Serialize for CustomSection { - type Error = Error; + type Error = Error; - fn serialize(self, writer: &mut W) -> Result<(), Self::Error> { - use std::io::Write; + fn serialize(self, writer: &mut W) -> Result<(), Self::Error> { + use std::io::Write; - let mut counted_writer = CountedWriter::new(writer); - self.name.serialize(&mut counted_writer)?; - counted_writer.write_all(&self.payload[..])?; - counted_writer.done()?; - Ok(()) - } + let mut counted_writer = CountedWriter::new(writer); + self.name.serialize(&mut counted_writer)?; + counted_writer.write_all(&self.payload[..])?; + counted_writer.done()?; + Ok(()) + } } /// Section with type declarations @@ -257,47 +257,47 @@ impl Serialize for CustomSection { pub struct TypeSection(Vec); impl TypeSection { - /// New type section with provided types - pub fn with_types(types: Vec) -> Self { - TypeSection(types) - } + /// New type section with provided types + pub fn with_types(types: Vec) -> Self { + TypeSection(types) + } - /// List of type declarations - pub fn types(&self) -> &[Type] { - &self.0 - } + /// List of type declarations + pub fn types(&self) -> &[Type] { + &self.0 + } - /// List of type declarations (mutable) - pub fn types_mut(&mut self) -> &mut Vec { - &mut self.0 - } + /// List of type declarations (mutable) + pub fn types_mut(&mut self) -> &mut Vec { + &mut self.0 + } } impl Deserialize for TypeSection { - type Error = Error; + type Error = Error; - fn deserialize(reader: &mut R) -> Result { - // todo: maybe use reader.take(section_length) - let _section_length = VarUint32::deserialize(reader)?; - let types: Vec = CountedList::deserialize(reader)?.into_inner(); - Ok(TypeSection(types)) - } + fn deserialize(reader: &mut R) -> Result { + // todo: maybe use reader.take(section_length) + let _section_length = VarUint32::deserialize(reader)?; + let types: Vec = CountedList::deserialize(reader)?.into_inner(); + Ok(TypeSection(types)) + } } impl Serialize for TypeSection { - type Error = Error; + type Error = Error; - fn serialize(self, writer: &mut W) -> Result<(), Self::Error> { - let mut counted_writer = CountedWriter::new(writer); - let data = self.0; - let counted_list = CountedListWriter::( - data.len(), - data.into_iter().map(Into::into), - ); - counted_list.serialize(&mut counted_writer)?; - counted_writer.done()?; - Ok(()) - } + fn serialize(self, writer: &mut W) -> Result<(), Self::Error> { + let mut counted_writer = CountedWriter::new(writer); + let data = self.0; + let counted_list = CountedListWriter::( + data.len(), + data.into_iter().map(Into::into), + ); + counted_list.serialize(&mut counted_writer)?; + counted_writer.done()?; + Ok(()) + } } /// Section of the imports definition. @@ -305,61 +305,61 @@ impl Serialize for TypeSection { pub struct ImportSection(Vec); impl ImportSection { - /// New import section with provided types - pub fn with_entries(entries: Vec) -> Self { - ImportSection(entries) - } + /// New import section with provided types + pub fn with_entries(entries: Vec) -> Self { + ImportSection(entries) + } - /// List of import entries. - pub fn entries(&self) -> &[ImportEntry] { - &self.0 - } + /// List of import entries. + pub fn entries(&self) -> &[ImportEntry] { + &self.0 + } - /// List of import entries (mutable). - pub fn entries_mut(&mut self) -> &mut Vec { - &mut self.0 - } + /// List of import entries (mutable). + pub fn entries_mut(&mut self) -> &mut Vec { + &mut self.0 + } - /// Returns number of functions - pub fn functions(&self) -> usize { - self.0.iter() - .filter(|entry| match entry.external() { &External::Function(_) => true, _ => false }) - .count() - } + /// Returns number of functions + pub fn functions(&self) -> usize { + self.0.iter() + .filter(|entry| match entry.external() { &External::Function(_) => true, _ => false }) + .count() + } - /// Returns number of globals - pub fn globals(&self) -> usize { - self.0.iter() - .filter(|entry| match entry.external() { &External::Global(_) => true, _ => false }) - .count() - } + /// Returns number of globals + pub fn globals(&self) -> usize { + self.0.iter() + .filter(|entry| match entry.external() { &External::Global(_) => true, _ => false }) + .count() + } } impl Deserialize for ImportSection { - type Error = Error; + type Error = Error; - fn deserialize(reader: &mut R) -> Result { - // todo: maybe use reader.take(section_length) - let _section_length = VarUint32::deserialize(reader)?; - let entries: Vec = CountedList::deserialize(reader)?.into_inner(); - Ok(ImportSection(entries)) - } + fn deserialize(reader: &mut R) -> Result { + // todo: maybe use reader.take(section_length) + let _section_length = VarUint32::deserialize(reader)?; + let entries: Vec = CountedList::deserialize(reader)?.into_inner(); + Ok(ImportSection(entries)) + } } impl Serialize for ImportSection { - type Error = Error; + type Error = Error; - fn serialize(self, writer: &mut W) -> Result<(), Self::Error> { - let mut counted_writer = CountedWriter::new(writer); - let data = self.0; - let counted_list = CountedListWriter::( - data.len(), - data.into_iter().map(Into::into), - ); - counted_list.serialize(&mut counted_writer)?; - counted_writer.done()?; - Ok(()) - } + fn serialize(self, writer: &mut W) -> Result<(), Self::Error> { + let mut counted_writer = CountedWriter::new(writer); + let data = self.0; + let counted_list = CountedListWriter::( + data.len(), + data.into_iter().map(Into::into), + ); + counted_list.serialize(&mut counted_writer)?; + counted_writer.done()?; + Ok(()) + } } /// Section with function signatures definition. @@ -367,51 +367,51 @@ impl Serialize for ImportSection { pub struct FunctionSection(Vec); impl FunctionSection { - /// New function signatures section with provided entries - pub fn with_entries(entries: Vec) -> Self { - FunctionSection(entries) - } + /// New function signatures section with provided entries + pub fn with_entries(entries: Vec) -> Self { + FunctionSection(entries) + } - /// List of all functions in the section, mutable - pub fn entries_mut(&mut self) -> &mut Vec { - &mut self.0 - } + /// List of all functions in the section, mutable + pub fn entries_mut(&mut self) -> &mut Vec { + &mut self.0 + } - /// List of all functions in the section - pub fn entries(&self) -> &[Func] { - &self.0 - } + /// List of all functions in the section + pub fn entries(&self) -> &[Func] { + &self.0 + } } impl Deserialize for FunctionSection { - type Error = Error; + type Error = Error; - fn deserialize(reader: &mut R) -> Result { - // todo: maybe use reader.take(section_length) - let _section_length = VarUint32::deserialize(reader)?; - let funcs: Vec = CountedList::::deserialize(reader)? - .into_inner() - .into_iter() - .map(|f| Func::new(f.into())) - .collect(); - Ok(FunctionSection(funcs)) - } + fn deserialize(reader: &mut R) -> Result { + // todo: maybe use reader.take(section_length) + let _section_length = VarUint32::deserialize(reader)?; + let funcs: Vec = CountedList::::deserialize(reader)? + .into_inner() + .into_iter() + .map(|f| Func::new(f.into())) + .collect(); + Ok(FunctionSection(funcs)) + } } impl Serialize for FunctionSection { - type Error = Error; + type Error = Error; - fn serialize(self, writer: &mut W) -> Result<(), Self::Error> { - let mut counted_writer = CountedWriter::new(writer); - let data = self.0; - let counted_list = CountedListWriter::( - data.len(), - data.into_iter().map(|func| func.type_ref().into()) - ); - counted_list.serialize(&mut counted_writer)?; - counted_writer.done()?; - Ok(()) - } + fn serialize(self, writer: &mut W) -> Result<(), Self::Error> { + let mut counted_writer = CountedWriter::new(writer); + let data = self.0; + let counted_list = CountedListWriter::( + data.len(), + data.into_iter().map(|func| func.type_ref().into()) + ); + counted_list.serialize(&mut counted_writer)?; + counted_writer.done()?; + Ok(()) + } } /// Section with table definition (currently only one is allowed). @@ -419,47 +419,47 @@ impl Serialize for FunctionSection { pub struct TableSection(Vec); impl TableSection { - /// Table entries. - pub fn entries(&self) -> &[TableType] { - &self.0 - } + /// Table entries. + pub fn entries(&self) -> &[TableType] { + &self.0 + } - /// New table section with provided table entries - pub fn with_entries(entries: Vec) -> Self { - TableSection(entries) - } + /// New table section with provided table entries + pub fn with_entries(entries: Vec) -> Self { + TableSection(entries) + } - /// Mutable table entries. - pub fn entries_mut(&mut self) -> &mut Vec { - &mut self.0 - } + /// Mutable table entries. + pub fn entries_mut(&mut self) -> &mut Vec { + &mut self.0 + } } impl Deserialize for TableSection { - type Error = Error; + type Error = Error; - fn deserialize(reader: &mut R) -> Result { - // todo: maybe use reader.take(section_length) - let _section_length = VarUint32::deserialize(reader)?; - let entries: Vec = CountedList::deserialize(reader)?.into_inner(); - Ok(TableSection(entries)) - } + fn deserialize(reader: &mut R) -> Result { + // todo: maybe use reader.take(section_length) + let _section_length = VarUint32::deserialize(reader)?; + let entries: Vec = CountedList::deserialize(reader)?.into_inner(); + Ok(TableSection(entries)) + } } impl Serialize for TableSection { - type Error = Error; + type Error = Error; - fn serialize(self, writer: &mut W) -> Result<(), Self::Error> { - let mut counted_writer = CountedWriter::new(writer); - let data = self.0; - let counted_list = CountedListWriter::( - data.len(), - data.into_iter().map(Into::into), - ); - counted_list.serialize(&mut counted_writer)?; - counted_writer.done()?; - Ok(()) - } + fn serialize(self, writer: &mut W) -> Result<(), Self::Error> { + let mut counted_writer = CountedWriter::new(writer); + let data = self.0; + let counted_list = CountedListWriter::( + data.len(), + data.into_iter().map(Into::into), + ); + counted_list.serialize(&mut counted_writer)?; + counted_writer.done()?; + Ok(()) + } } /// Section with table definition (currently only one entry is allowed). @@ -467,47 +467,47 @@ impl Serialize for TableSection { pub struct MemorySection(Vec); impl MemorySection { - /// List of all memory entries in the section - pub fn entries(&self) -> &[MemoryType] { - &self.0 - } + /// List of all memory entries in the section + pub fn entries(&self) -> &[MemoryType] { + &self.0 + } - /// New memory section with memory types - pub fn with_entries(entries: Vec) -> Self { - MemorySection(entries) - } + /// New memory section with memory types + pub fn with_entries(entries: Vec) -> Self { + MemorySection(entries) + } - /// Mutable list of all memory entries in the section - pub fn entries_mut(&mut self) -> &mut Vec { - &mut self.0 - } + /// Mutable list of all memory entries in the section + pub fn entries_mut(&mut self) -> &mut Vec { + &mut self.0 + } } impl Deserialize for MemorySection { - type Error = Error; + type Error = Error; - fn deserialize(reader: &mut R) -> Result { - // todo: maybe use reader.take(section_length) - let _section_length = VarUint32::deserialize(reader)?; - let entries: Vec = CountedList::deserialize(reader)?.into_inner(); - Ok(MemorySection(entries)) - } + fn deserialize(reader: &mut R) -> Result { + // todo: maybe use reader.take(section_length) + let _section_length = VarUint32::deserialize(reader)?; + let entries: Vec = CountedList::deserialize(reader)?.into_inner(); + Ok(MemorySection(entries)) + } } impl Serialize for MemorySection { - type Error = Error; + type Error = Error; - fn serialize(self, writer: &mut W) -> Result<(), Self::Error> { - let mut counted_writer = CountedWriter::new(writer); - let data = self.0; - let counted_list = CountedListWriter::( - data.len(), - data.into_iter().map(Into::into), - ); - counted_list.serialize(&mut counted_writer)?; - counted_writer.done()?; - Ok(()) - } + fn serialize(self, writer: &mut W) -> Result<(), Self::Error> { + let mut counted_writer = CountedWriter::new(writer); + let data = self.0; + let counted_list = CountedListWriter::( + data.len(), + data.into_iter().map(Into::into), + ); + counted_list.serialize(&mut counted_writer)?; + counted_writer.done()?; + Ok(()) + } } /// Globals definition section. @@ -515,47 +515,47 @@ impl Serialize for MemorySection { pub struct GlobalSection(Vec); impl GlobalSection { - /// List of all global entries in the section - pub fn entries(&self) -> &[GlobalEntry] { - &self.0 - } + /// List of all global entries in the section + pub fn entries(&self) -> &[GlobalEntry] { + &self.0 + } - /// New global section from list of global entries - pub fn with_entries(entries: Vec) -> Self { - GlobalSection(entries) - } + /// New global section from list of global entries + pub fn with_entries(entries: Vec) -> Self { + GlobalSection(entries) + } - /// List of all global entries in the section (mutable) - pub fn entries_mut(&mut self) -> &mut Vec { - &mut self.0 - } + /// List of all global entries in the section (mutable) + pub fn entries_mut(&mut self) -> &mut Vec { + &mut self.0 + } } impl Deserialize for GlobalSection { - type Error = Error; + type Error = Error; - fn deserialize(reader: &mut R) -> Result { - // todo: maybe use reader.take(section_length) - let _section_length = VarUint32::deserialize(reader)?; - let entries: Vec = CountedList::deserialize(reader)?.into_inner(); - Ok(GlobalSection(entries)) - } + fn deserialize(reader: &mut R) -> Result { + // todo: maybe use reader.take(section_length) + let _section_length = VarUint32::deserialize(reader)?; + let entries: Vec = CountedList::deserialize(reader)?.into_inner(); + Ok(GlobalSection(entries)) + } } impl Serialize for GlobalSection { - type Error = Error; + type Error = Error; - fn serialize(self, writer: &mut W) -> Result<(), Self::Error> { - let mut counted_writer = CountedWriter::new(writer); - let data = self.0; - let counted_list = CountedListWriter::( - data.len(), - data.into_iter().map(Into::into), - ); - counted_list.serialize(&mut counted_writer)?; - counted_writer.done()?; - Ok(()) - } + fn serialize(self, writer: &mut W) -> Result<(), Self::Error> { + let mut counted_writer = CountedWriter::new(writer); + let data = self.0; + let counted_list = CountedListWriter::( + data.len(), + data.into_iter().map(Into::into), + ); + counted_list.serialize(&mut counted_writer)?; + counted_writer.done()?; + Ok(()) + } } /// List of exports definition. @@ -563,47 +563,47 @@ impl Serialize for GlobalSection { pub struct ExportSection(Vec); impl ExportSection { - /// List of all export entries in the section - pub fn entries(&self) -> &[ExportEntry] { - &self.0 - } + /// List of all export entries in the section + pub fn entries(&self) -> &[ExportEntry] { + &self.0 + } - /// New export section from list of export entries - pub fn with_entries(entries: Vec) -> Self { - ExportSection(entries) - } + /// New export section from list of export entries + pub fn with_entries(entries: Vec) -> Self { + ExportSection(entries) + } - /// List of all export entries in the section (mutable) - pub fn entries_mut(&mut self) -> &mut Vec { - &mut self.0 - } + /// List of all export entries in the section (mutable) + pub fn entries_mut(&mut self) -> &mut Vec { + &mut self.0 + } } impl Deserialize for ExportSection { - type Error = Error; + type Error = Error; - fn deserialize(reader: &mut R) -> Result { - // todo: maybe use reader.take(section_length) - let _section_length = VarUint32::deserialize(reader)?; - let entries: Vec = CountedList::deserialize(reader)?.into_inner(); - Ok(ExportSection(entries)) - } + fn deserialize(reader: &mut R) -> Result { + // todo: maybe use reader.take(section_length) + let _section_length = VarUint32::deserialize(reader)?; + let entries: Vec = CountedList::deserialize(reader)?.into_inner(); + Ok(ExportSection(entries)) + } } impl Serialize for ExportSection { - type Error = Error; + type Error = Error; - fn serialize(self, writer: &mut W) -> Result<(), Self::Error> { - let mut counted_writer = CountedWriter::new(writer); - let data = self.0; - let counted_list = CountedListWriter::( - data.len(), - data.into_iter().map(Into::into), - ); - counted_list.serialize(&mut counted_writer)?; - counted_writer.done()?; - Ok(()) - } + fn serialize(self, writer: &mut W) -> Result<(), Self::Error> { + let mut counted_writer = CountedWriter::new(writer); + let data = self.0; + let counted_list = CountedListWriter::( + data.len(), + data.into_iter().map(Into::into), + ); + counted_list.serialize(&mut counted_writer)?; + counted_writer.done()?; + Ok(()) + } } /// Section with function bodies of the module. @@ -611,47 +611,47 @@ impl Serialize for ExportSection { pub struct CodeSection(Vec); impl CodeSection { - /// New code section with specified function bodies - pub fn with_bodies(bodies: Vec) -> Self { - CodeSection(bodies) - } + /// New code section with specified function bodies + pub fn with_bodies(bodies: Vec) -> Self { + CodeSection(bodies) + } - /// All function bodies in the section. - pub fn bodies(&self) -> &[FuncBody] { - &self.0 - } + /// All function bodies in the section. + pub fn bodies(&self) -> &[FuncBody] { + &self.0 + } - /// All function bodies in the section, mutable. - pub fn bodies_mut(&mut self) -> &mut Vec { - &mut self.0 - } + /// All function bodies in the section, mutable. + pub fn bodies_mut(&mut self) -> &mut Vec { + &mut self.0 + } } impl Deserialize for CodeSection { - type Error = Error; + type Error = Error; - fn deserialize(reader: &mut R) -> Result { - // todo: maybe use reader.take(section_length) - let _section_length = VarUint32::deserialize(reader)?; - let entries: Vec = CountedList::deserialize(reader)?.into_inner(); - Ok(CodeSection(entries)) - } + fn deserialize(reader: &mut R) -> Result { + // todo: maybe use reader.take(section_length) + let _section_length = VarUint32::deserialize(reader)?; + let entries: Vec = CountedList::deserialize(reader)?.into_inner(); + Ok(CodeSection(entries)) + } } impl Serialize for CodeSection { - type Error = Error; + type Error = Error; - fn serialize(self, writer: &mut W) -> Result<(), Self::Error> { - let mut counted_writer = CountedWriter::new(writer); - let data = self.0; - let counted_list = CountedListWriter::( - data.len(), - data.into_iter().map(Into::into), - ); - counted_list.serialize(&mut counted_writer)?; - counted_writer.done()?; - Ok(()) - } + fn serialize(self, writer: &mut W) -> Result<(), Self::Error> { + let mut counted_writer = CountedWriter::new(writer); + let data = self.0; + let counted_list = CountedListWriter::( + data.len(), + data.into_iter().map(Into::into), + ); + counted_list.serialize(&mut counted_writer)?; + counted_writer.done()?; + Ok(()) + } } /// Element entries section. @@ -659,47 +659,47 @@ impl Serialize for CodeSection { pub struct ElementSection(Vec); impl ElementSection { - /// New elements section - pub fn with_entries(entries: Vec) -> Self { - ElementSection(entries) - } + /// New elements section + pub fn with_entries(entries: Vec) -> Self { + ElementSection(entries) + } - /// New elements entries in the section - pub fn entries(&self) -> &[ElementSegment] { - &self.0 - } + /// New elements entries in the section + pub fn entries(&self) -> &[ElementSegment] { + &self.0 + } - /// List of all data entries in the section (mutable) - pub fn entries_mut(&mut self) -> &mut Vec { - &mut self.0 - } + /// List of all data entries in the section (mutable) + pub fn entries_mut(&mut self) -> &mut Vec { + &mut self.0 + } } impl Deserialize for ElementSection { - type Error = Error; + type Error = Error; - fn deserialize(reader: &mut R) -> Result { - // todo: maybe use reader.take(section_length) - let _section_length = VarUint32::deserialize(reader)?; - let entries: Vec = CountedList::deserialize(reader)?.into_inner(); - Ok(ElementSection(entries)) - } + fn deserialize(reader: &mut R) -> Result { + // todo: maybe use reader.take(section_length) + let _section_length = VarUint32::deserialize(reader)?; + let entries: Vec = CountedList::deserialize(reader)?.into_inner(); + Ok(ElementSection(entries)) + } } impl Serialize for ElementSection { - type Error = Error; + type Error = Error; - fn serialize(self, writer: &mut W) -> Result<(), Self::Error> { - let mut counted_writer = CountedWriter::new(writer); - let data = self.0; - let counted_list = CountedListWriter::( - data.len(), - data.into_iter().map(Into::into), - ); - counted_list.serialize(&mut counted_writer)?; - counted_writer.done()?; - Ok(()) - } + fn serialize(self, writer: &mut W) -> Result<(), Self::Error> { + let mut counted_writer = CountedWriter::new(writer); + let data = self.0; + let counted_list = CountedListWriter::( + data.len(), + data.into_iter().map(Into::into), + ); + counted_list.serialize(&mut counted_writer)?; + counted_writer.done()?; + Ok(()) + } } /// Data entries definitions. @@ -707,379 +707,379 @@ impl Serialize for ElementSection { pub struct DataSection(Vec); impl DataSection { - /// New data section - pub fn with_entries(entries: Vec) -> Self { - DataSection(entries) - } + /// New data section + pub fn with_entries(entries: Vec) -> Self { + DataSection(entries) + } - /// List of all data entries in the section - pub fn entries(&self) -> &[DataSegment] { - &self.0 - } + /// List of all data entries in the section + pub fn entries(&self) -> &[DataSegment] { + &self.0 + } - /// List of all data entries in the section (mutable) - pub fn entries_mut(&mut self) -> &mut Vec { - &mut self.0 - } + /// List of all data entries in the section (mutable) + pub fn entries_mut(&mut self) -> &mut Vec { + &mut self.0 + } } impl Deserialize for DataSection { - type Error = Error; + type Error = Error; - fn deserialize(reader: &mut R) -> Result { - // todo: maybe use reader.take(section_length) - let _section_length = VarUint32::deserialize(reader)?; - let entries: Vec = CountedList::deserialize(reader)?.into_inner(); - Ok(DataSection(entries)) - } + fn deserialize(reader: &mut R) -> Result { + // todo: maybe use reader.take(section_length) + let _section_length = VarUint32::deserialize(reader)?; + let entries: Vec = CountedList::deserialize(reader)?.into_inner(); + Ok(DataSection(entries)) + } } impl Serialize for DataSection { - type Error = Error; + type Error = Error; - fn serialize(self, writer: &mut W) -> Result<(), Self::Error> { - let mut counted_writer = CountedWriter::new(writer); - let data = self.0; - let counted_list = CountedListWriter::( - data.len(), - data.into_iter().map(Into::into), - ); - counted_list.serialize(&mut counted_writer)?; - counted_writer.done()?; - Ok(()) - } + fn serialize(self, writer: &mut W) -> Result<(), Self::Error> { + let mut counted_writer = CountedWriter::new(writer); + let data = self.0; + let counted_list = CountedListWriter::( + data.len(), + data.into_iter().map(Into::into), + ); + counted_list.serialize(&mut counted_writer)?; + counted_writer.done()?; + Ok(()) + } } #[cfg(test)] mod tests { - use super::super::{ - deserialize_buffer, deserialize_file, ValueType, InitExpr, DataSegment, - serialize, ElementSegment, Opcodes, BlockType, Local, FuncBody, - }; - use super::{Section, TypeSection, Type, DataSection, ElementSection, CodeSection}; + use super::super::{ + deserialize_buffer, deserialize_file, ValueType, InitExpr, DataSegment, + serialize, ElementSegment, Opcodes, BlockType, Local, FuncBody, + }; + use super::{Section, TypeSection, Type, DataSection, ElementSection, CodeSection}; - #[test] - fn import_section() { - let module = deserialize_file("./res/cases/v1/test5.wasm").expect("Should be deserialized"); - let mut found = false; - for section in module.sections() { - match section { - &Section::Import(ref import_section) => { - assert_eq!(25, import_section.entries().len()); - found = true - }, - _ => { } - } - } - assert!(found, "There should be import section in test5.wasm"); - } + #[test] + fn import_section() { + let module = deserialize_file("./res/cases/v1/test5.wasm").expect("Should be deserialized"); + let mut found = false; + for section in module.sections() { + match section { + &Section::Import(ref import_section) => { + assert_eq!(25, import_section.entries().len()); + found = true + }, + _ => { } + } + } + assert!(found, "There should be import section in test5.wasm"); + } - fn functions_test_payload() -> &'static [u8] { - &[ - // functions section id - 0x03u8, - // functions section length - 0x87, 0x80, 0x80, 0x80, 0x0, - // number of functions - 0x04, - // type reference 1 - 0x01, - // type reference 2 - 0x86, 0x80, 0x00, - // type reference 3 - 0x09, - // type reference 4 - 0x33 - ] - } + fn functions_test_payload() -> &'static [u8] { + &[ + // functions section id + 0x03u8, + // functions section length + 0x87, 0x80, 0x80, 0x80, 0x0, + // number of functions + 0x04, + // type reference 1 + 0x01, + // type reference 2 + 0x86, 0x80, 0x00, + // type reference 3 + 0x09, + // type reference 4 + 0x33 + ] + } - #[test] - fn fn_section_detect() { - let section: Section = - deserialize_buffer(functions_test_payload()).expect("section to be deserialized"); + #[test] + fn fn_section_detect() { + let section: Section = + deserialize_buffer(functions_test_payload()).expect("section to be deserialized"); - match section { - Section::Function(_) => {}, - _ => { - panic!("Payload should be recognized as functions section") - } - } - } + match section { + Section::Function(_) => {}, + _ => { + panic!("Payload should be recognized as functions section") + } + } + } - #[test] - fn fn_section_number() { - let section: Section = - deserialize_buffer(functions_test_payload()).expect("section to be deserialized"); + #[test] + fn fn_section_number() { + let section: Section = + deserialize_buffer(functions_test_payload()).expect("section to be deserialized"); - match section { - Section::Function(fn_section) => { - assert_eq!(4, fn_section.entries().len(), "There should be 4 functions total"); - }, - _ => { - // will be catched by dedicated test - } - } - } + match section { + Section::Function(fn_section) => { + assert_eq!(4, fn_section.entries().len(), "There should be 4 functions total"); + }, + _ => { + // will be catched by dedicated test + } + } + } - #[test] - fn fn_section_ref() { - let section: Section = - deserialize_buffer(functions_test_payload()).expect("section to be deserialized"); + #[test] + fn fn_section_ref() { + let section: Section = + deserialize_buffer(functions_test_payload()).expect("section to be deserialized"); - match section { - Section::Function(fn_section) => { - assert_eq!(6, fn_section.entries()[1].type_ref()); - }, - _ => { - // will be catched by dedicated test - } - } - } + match section { + Section::Function(fn_section) => { + assert_eq!(6, fn_section.entries()[1].type_ref()); + }, + _ => { + // will be catched by dedicated test + } + } + } - fn types_test_payload() -> &'static [u8] { - &[ - // section length - 148u8, 0x80, 0x80, 0x80, 0x0, + fn types_test_payload() -> &'static [u8] { + &[ + // section length + 148u8, 0x80, 0x80, 0x80, 0x0, - // 2 functions - 130u8, 0x80, 0x80, 0x80, 0x0, - // func 1, form =1 - 0x01, - // param_count=1 - 129u8, 0x80, 0x80, 0x80, 0x0, - // first param - 0x7e, // i64 - // no return params - 0x00, + // 2 functions + 130u8, 0x80, 0x80, 0x80, 0x0, + // func 1, form =1 + 0x01, + // param_count=1 + 129u8, 0x80, 0x80, 0x80, 0x0, + // first param + 0x7e, // i64 + // no return params + 0x00, - // func 2, form=1 - 0x01, - // param_count=1 - 130u8, 0x80, 0x80, 0x80, 0x0, - // first param - 0x7e, - // second param - 0x7d, - // return param (is_present, param_type) - 0x01, 0x7e - ] - } + // func 2, form=1 + 0x01, + // param_count=1 + 130u8, 0x80, 0x80, 0x80, 0x0, + // first param + 0x7e, + // second param + 0x7d, + // return param (is_present, param_type) + 0x01, 0x7e + ] + } - #[test] - fn type_section_len() { - let type_section: TypeSection = - deserialize_buffer(types_test_payload()).expect("type_section be deserialized"); + #[test] + fn type_section_len() { + let type_section: TypeSection = + deserialize_buffer(types_test_payload()).expect("type_section be deserialized"); - assert_eq!(type_section.types().len(), 2); - } + assert_eq!(type_section.types().len(), 2); + } - #[test] - fn type_section_infer() { - let type_section: TypeSection = - deserialize_buffer(types_test_payload()).expect("type_section be deserialized"); + #[test] + fn type_section_infer() { + let type_section: TypeSection = + deserialize_buffer(types_test_payload()).expect("type_section be deserialized"); - let t1 = match &type_section.types()[1] { - &Type::Function(ref func_type) => func_type - }; + let t1 = match &type_section.types()[1] { + &Type::Function(ref func_type) => func_type + }; - assert_eq!(Some(ValueType::I64), t1.return_type()); - assert_eq!(2, t1.params().len()); - } + assert_eq!(Some(ValueType::I64), t1.return_type()); + assert_eq!(2, t1.params().len()); + } - fn export_payload() -> &'static [u8] { - &[ - // section id - 0x07, - // section length - 148u8, 0x80, 0x80, 0x80, 0x0, - // 6 entries - 134u8, 0x80, 0x80, 0x80, 0x0, - // func "A", index 6 - // [name_len(1-5 bytes), name_bytes(name_len, internal_kind(1byte), internal_index(1-5 bytes)]) - 0x01, 0x41, 0x01, 0x86, 0x80, 0x00, - // func "B", index 8 - 0x01, 0x42, 0x01, 0x86, 0x00, - // func "C", index 7 - 0x01, 0x43, 0x01, 0x07, - // memory "D", index 0 - 0x01, 0x44, 0x02, 0x00, - // func "E", index 1 - 0x01, 0x45, 0x01, 0x01, - // func "F", index 2 - 0x01, 0x46, 0x01, 0x02 - ] - } + fn export_payload() -> &'static [u8] { + &[ + // section id + 0x07, + // section length + 148u8, 0x80, 0x80, 0x80, 0x0, + // 6 entries + 134u8, 0x80, 0x80, 0x80, 0x0, + // func "A", index 6 + // [name_len(1-5 bytes), name_bytes(name_len, internal_kind(1byte), internal_index(1-5 bytes)]) + 0x01, 0x41, 0x01, 0x86, 0x80, 0x00, + // func "B", index 8 + 0x01, 0x42, 0x01, 0x86, 0x00, + // func "C", index 7 + 0x01, 0x43, 0x01, 0x07, + // memory "D", index 0 + 0x01, 0x44, 0x02, 0x00, + // func "E", index 1 + 0x01, 0x45, 0x01, 0x01, + // func "F", index 2 + 0x01, 0x46, 0x01, 0x02 + ] + } - #[test] - fn export_detect() { - let section: Section = - deserialize_buffer(export_payload()).expect("section to be deserialized"); + #[test] + fn export_detect() { + let section: Section = + deserialize_buffer(export_payload()).expect("section to be deserialized"); - match section { - Section::Export(_) => {}, - _ => { - panic!("Payload should be recognized as export section") - } - } - } + match section { + Section::Export(_) => {}, + _ => { + panic!("Payload should be recognized as export section") + } + } + } - fn code_payload() -> &'static [u8] { - &[ - // sectionid - 0x0Au8, - // section length, 32 - 0x20, - // body count - 0x01, - // body 1, length 30 - 0x1E, - 0x01, 0x01, 0x7F, // local i32 (one collection of length one of type i32) - 0x02, 0x7F, // block i32 - 0x23, 0x00, // get_global 0 - 0x21, 0x01, // set_local 1 - 0x23, 0x00, // get_global 0 - 0x20, 0x00, // get_local 0 - 0x6A, // i32.add - 0x24, 0x00, // set_global 0 - 0x23, 0x00, // get_global 0 - 0x41, 0x0F, // i32.const 15 - 0x6A, // i32.add - 0x41, 0x70, // i32.const -16 - 0x71, // i32.and - 0x24, 0x00, // set_global 0 - 0x20, 0x01, // get_local 1 - 0x0B, - 0x0B, - ] - } + fn code_payload() -> &'static [u8] { + &[ + // sectionid + 0x0Au8, + // section length, 32 + 0x20, + // body count + 0x01, + // body 1, length 30 + 0x1E, + 0x01, 0x01, 0x7F, // local i32 (one collection of length one of type i32) + 0x02, 0x7F, // block i32 + 0x23, 0x00, // get_global 0 + 0x21, 0x01, // set_local 1 + 0x23, 0x00, // get_global 0 + 0x20, 0x00, // get_local 0 + 0x6A, // i32.add + 0x24, 0x00, // set_global 0 + 0x23, 0x00, // get_global 0 + 0x41, 0x0F, // i32.const 15 + 0x6A, // i32.add + 0x41, 0x70, // i32.const -16 + 0x71, // i32.and + 0x24, 0x00, // set_global 0 + 0x20, 0x01, // get_local 1 + 0x0B, + 0x0B, + ] + } - #[test] - fn code_detect() { + #[test] + fn code_detect() { - let section: Section = - deserialize_buffer(code_payload()).expect("section to be deserialized"); + let section: Section = + deserialize_buffer(code_payload()).expect("section to be deserialized"); - match section { - Section::Code(_) => {}, - _ => { - panic!("Payload should be recognized as a code section") - } - } - } + match section { + Section::Code(_) => {}, + _ => { + panic!("Payload should be recognized as a code section") + } + } + } - fn data_payload() -> &'static [u8] { - &[ - 0x0bu8, // section id - 19, // 19 bytes overall - 0x01, // number of segments - 0x00, // index - 0x0b, // just `end` op - // 16x 0x00 - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00 - ] - } + fn data_payload() -> &'static [u8] { + &[ + 0x0bu8, // section id + 19, // 19 bytes overall + 0x01, // number of segments + 0x00, // index + 0x0b, // just `end` op + // 16x 0x00 + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00 + ] + } - #[test] - fn data_section_ser() { - let data_section = DataSection::with_entries( - vec![DataSegment::new(0u32, InitExpr::empty(), vec![0u8; 16])] - ); + #[test] + fn data_section_ser() { + let data_section = DataSection::with_entries( + vec![DataSegment::new(0u32, InitExpr::empty(), vec![0u8; 16])] + ); - let buf = serialize(data_section).expect("Data section to be serialized"); + let buf = serialize(data_section).expect("Data section to be serialized"); - assert_eq!(buf, vec![ - 20u8, // 19 bytes overall - 0x01, // number of segments - 0x00, // index - 0x0b, // just `end` op - 16, // value of length 16 - 0x00, 0x00, 0x00, 0x00, // 16x 0x00 as in initialization - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00 - ]); - } + assert_eq!(buf, vec![ + 20u8, // 19 bytes overall + 0x01, // number of segments + 0x00, // index + 0x0b, // just `end` op + 16, // value of length 16 + 0x00, 0x00, 0x00, 0x00, // 16x 0x00 as in initialization + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00 + ]); + } - #[test] - fn data_section_detect() { - let section: Section = - deserialize_buffer(data_payload()).expect("section to be deserialized"); + #[test] + fn data_section_detect() { + let section: Section = + deserialize_buffer(data_payload()).expect("section to be deserialized"); - match section { - Section::Data(_) => {}, - _ => { - panic!("Payload should be recognized as a data section") - } - } - } + match section { + Section::Data(_) => {}, + _ => { + panic!("Payload should be recognized as a data section") + } + } + } - #[test] - fn element_section_ser() { - let element_section = ElementSection::with_entries( - vec![ElementSegment::new(0u32, InitExpr::empty(), vec![0u32; 4])] - ); + #[test] + fn element_section_ser() { + let element_section = ElementSection::with_entries( + vec![ElementSegment::new(0u32, InitExpr::empty(), vec![0u32; 4])] + ); - let buf = serialize(element_section).expect("Element section to be serialized"); + let buf = serialize(element_section).expect("Element section to be serialized"); - assert_eq!(buf, vec![ - 08u8, // 8 bytes overall - 0x01, // number of segments - 0x00, // index - 0x0b, // just `end` op - 0x04, // 4 elements - 0x00, 0x00, 0x00, 0x00 // 4x 0x00 as in initialization - ]); - } + assert_eq!(buf, vec![ + 08u8, // 8 bytes overall + 0x01, // number of segments + 0x00, // index + 0x0b, // just `end` op + 0x04, // 4 elements + 0x00, 0x00, 0x00, 0x00 // 4x 0x00 as in initialization + ]); + } - #[test] - fn code_section_ser() { - use super::super::Opcode::*; + #[test] + fn code_section_ser() { + use super::super::Opcode::*; - let code_section = CodeSection::with_bodies( - vec![ - FuncBody::new( - vec![Local::new(1, ValueType::I32)], - Opcodes::new(vec![ - Block(BlockType::Value(ValueType::I32)), - GetGlobal(0), - End, - End, - ]) - ) - ]); + let code_section = CodeSection::with_bodies( + vec![ + FuncBody::new( + vec![Local::new(1, ValueType::I32)], + Opcodes::new(vec![ + Block(BlockType::Value(ValueType::I32)), + GetGlobal(0), + End, + End, + ]) + ) + ]); - let buf = serialize(code_section).expect("Code section to be serialized"); + let buf = serialize(code_section).expect("Code section to be serialized"); - assert_eq!(buf, vec![ - 11u8, // 11 bytes total section size - 0x01, // 1 function - 9, // function #1 total code size - 1, // 1 local variable declaration - 1, // amount of variables - 0x7f, // type of variable (7-bit, -0x01), negative - 0x02, // block - 0x7f, // block return type (7-bit, -0x01), negative - 0x23, 0x00, // get_global(0) - 0x0b, // block end - 0x0b, // function end - ]); - } + assert_eq!(buf, vec![ + 11u8, // 11 bytes total section size + 0x01, // 1 function + 9, // function #1 total code size + 1, // 1 local variable declaration + 1, // amount of variables + 0x7f, // type of variable (7-bit, -0x01), negative + 0x02, // block + 0x7f, // block return type (7-bit, -0x01), negative + 0x23, 0x00, // get_global(0) + 0x0b, // block end + 0x0b, // function end + ]); + } - #[test] - fn start_section() { - let section: Section = deserialize_buffer(&[08u8, 01u8, 00u8]).expect("Start section to deserialize"); - if let Section::Start(_) = section { - } else { - panic!("Payload should be a start section"); - } + #[test] + fn start_section() { + let section: Section = deserialize_buffer(&[08u8, 01u8, 00u8]).expect("Start section to deserialize"); + if let Section::Start(_) = section { + } else { + panic!("Payload should be a start section"); + } - let serialized = serialize(section).expect("Start section to successfully serializen"); + let serialized = serialize(section).expect("Start section to successfully serializen"); - assert_eq!(serialized, vec![08u8, 01u8, 00u8]); - } + assert_eq!(serialized, vec![08u8, 01u8, 00u8]); + } } diff --git a/src/elements/segment.rs b/src/elements/segment.rs index 98d1e37..e77a6d0 100644 --- a/src/elements/segment.rs +++ b/src/elements/segment.rs @@ -4,132 +4,132 @@ use super::{Deserialize, Serialize, Error, VarUint32, CountedList, InitExpr, Cou /// Entry in the element section. #[derive(Debug, Clone)] pub struct ElementSegment { - index: u32, - offset: InitExpr, - members: Vec, + index: u32, + offset: InitExpr, + members: Vec, } impl ElementSegment { - /// New element segment. - pub fn new(index: u32, offset: InitExpr, members: Vec) -> Self { - ElementSegment { index: index, offset: offset, members: members } - } + /// New element segment. + pub fn new(index: u32, offset: InitExpr, members: Vec) -> Self { + ElementSegment { index: index, offset: offset, members: members } + } - /// Sequence of function indices. - pub fn members(&self) -> &[u32] { &self.members } + /// Sequence of function indices. + pub fn members(&self) -> &[u32] { &self.members } - /// Sequence of function indices (mutable) - pub fn members_mut(&mut self) -> &mut Vec { &mut self.members } + /// Sequence of function indices (mutable) + pub fn members_mut(&mut self) -> &mut Vec { &mut self.members } - /// Table index (currently valid only value of `0`) - pub fn index(&self) -> u32 { self.index } + /// Table index (currently valid only value of `0`) + pub fn index(&self) -> u32 { self.index } - /// An i32 initializer expression that computes the offset at which to place the elements. - pub fn offset(&self) -> &InitExpr { &self.offset } + /// An i32 initializer expression that computes the offset at which to place the elements. + pub fn offset(&self) -> &InitExpr { &self.offset } - /// An i32 initializer expression that computes the offset at which to place the elements (mutable) - pub fn offset_mut(&mut self) -> &mut InitExpr { &mut self.offset } + /// An i32 initializer expression that computes the offset at which to place the elements (mutable) + pub fn offset_mut(&mut self) -> &mut InitExpr { &mut self.offset } } impl Deserialize for ElementSegment { - type Error = Error; + type Error = Error; - fn deserialize(reader: &mut R) -> Result { - let index = VarUint32::deserialize(reader)?; - let offset = InitExpr::deserialize(reader)?; - let funcs: Vec = CountedList::::deserialize(reader)? - .into_inner() - .into_iter() - .map(Into::into) - .collect(); + fn deserialize(reader: &mut R) -> Result { + let index = VarUint32::deserialize(reader)?; + let offset = InitExpr::deserialize(reader)?; + let funcs: Vec = CountedList::::deserialize(reader)? + .into_inner() + .into_iter() + .map(Into::into) + .collect(); - Ok(ElementSegment { - index: index.into(), - offset: offset, - members: funcs, - }) - } + Ok(ElementSegment { + index: index.into(), + offset: offset, + members: funcs, + }) + } } impl Serialize for ElementSegment { - type Error = Error; + type Error = Error; - fn serialize(self, writer: &mut W) -> Result<(), Self::Error> { - VarUint32::from(self.index).serialize(writer)?; - self.offset.serialize(writer)?; - let data = self.members; - let counted_list = CountedListWriter::( - data.len(), - data.into_iter().map(Into::into), - ); - counted_list.serialize(writer)?; - Ok(()) - } + fn serialize(self, writer: &mut W) -> Result<(), Self::Error> { + VarUint32::from(self.index).serialize(writer)?; + self.offset.serialize(writer)?; + let data = self.members; + let counted_list = CountedListWriter::( + data.len(), + data.into_iter().map(Into::into), + ); + counted_list.serialize(writer)?; + Ok(()) + } } /// Data segment definition. #[derive(Clone, Debug)] pub struct DataSegment { - index: u32, - offset: InitExpr, - value: Vec, + index: u32, + offset: InitExpr, + value: Vec, } impl DataSegment { - /// New data segments. - pub fn new(index: u32, offset: InitExpr, value: Vec) -> Self { - DataSegment { - index: index, - offset: offset, - value: value, - } - } + /// New data segments. + pub fn new(index: u32, offset: InitExpr, value: Vec) -> Self { + DataSegment { + index: index, + offset: offset, + value: value, + } + } - /// Linear memory index (currently the only valid value is `0`). - pub fn index(&self) -> u32 { self.index } + /// Linear memory index (currently the only valid value is `0`). + pub fn index(&self) -> u32 { self.index } - /// An i32 initializer expression that computes the offset at which to place the data. - pub fn offset(&self) -> &InitExpr { &self.offset } + /// An i32 initializer expression that computes the offset at which to place the data. + pub fn offset(&self) -> &InitExpr { &self.offset } - /// An i32 initializer expression that computes the offset at which to place the data (mutable) - pub fn offset_mut(&mut self) -> &mut InitExpr { &mut self.offset } + /// An i32 initializer expression that computes the offset at which to place the data (mutable) + pub fn offset_mut(&mut self) -> &mut InitExpr { &mut self.offset } - /// Initial value of the data segment. - pub fn value(&self) -> &[u8] { &self.value } + /// Initial value of the data segment. + pub fn value(&self) -> &[u8] { &self.value } - /// Initial value of the data segment (mutable). - pub fn value_mut(&mut self) -> &mut Vec { &mut self.value } + /// Initial value of the data segment (mutable). + pub fn value_mut(&mut self) -> &mut Vec { &mut self.value } } impl Deserialize for DataSegment { - type Error = Error; + type Error = Error; - fn deserialize(reader: &mut R) -> Result { - let index = VarUint32::deserialize(reader)?; - let offset = InitExpr::deserialize(reader)?; - let value_len = VarUint32::deserialize(reader)?; + fn deserialize(reader: &mut R) -> Result { + let index = VarUint32::deserialize(reader)?; + let offset = InitExpr::deserialize(reader)?; + let value_len = VarUint32::deserialize(reader)?; - let mut value_buf = vec![0u8; value_len.into()]; - reader.read_exact(&mut value_buf[..])?; + let mut value_buf = vec![0u8; value_len.into()]; + reader.read_exact(&mut value_buf[..])?; - Ok(DataSegment { - index: index.into(), - offset: offset, - value: value_buf, - }) - } + Ok(DataSegment { + index: index.into(), + offset: offset, + value: value_buf, + }) + } } impl Serialize for DataSegment { - type Error = Error; + type Error = Error; - fn serialize(self, writer: &mut W) -> Result<(), Self::Error> { - VarUint32::from(self.index).serialize(writer)?; - self.offset.serialize(writer)?; + fn serialize(self, writer: &mut W) -> Result<(), Self::Error> { + VarUint32::from(self.index).serialize(writer)?; + self.offset.serialize(writer)?; - let value = self.value; - VarUint32::from(value.len()).serialize(writer)?; - writer.write_all(&value[..])?; - Ok(()) - } + let value = self.value; + VarUint32::from(value.len()).serialize(writer)?; + writer.write_all(&value[..])?; + Ok(()) + } } diff --git a/src/elements/types.rs b/src/elements/types.rs index 44e2bed..9e82767 100644 --- a/src/elements/types.rs +++ b/src/elements/types.rs @@ -1,245 +1,245 @@ use std::{io, fmt}; use super::{ - Deserialize, Serialize, Error, VarUint7, VarInt7, VarUint1, CountedList, - CountedListWriter + Deserialize, Serialize, Error, VarUint7, VarInt7, VarUint1, CountedList, + CountedListWriter }; /// Type definition in types section. Currently can be only of the function type. #[derive(Debug, PartialEq, Clone)] pub enum Type { - /// Function type. - Function(FunctionType), + /// Function type. + Function(FunctionType), } impl Deserialize for Type { - type Error = Error; + type Error = Error; - fn deserialize(reader: &mut R) -> Result { - Ok(Type::Function(FunctionType::deserialize(reader)?)) - } + fn deserialize(reader: &mut R) -> Result { + Ok(Type::Function(FunctionType::deserialize(reader)?)) + } } impl Serialize for Type { - type Error = Error; + type Error = Error; - fn serialize(self, writer: &mut W) -> Result<(), Self::Error> { - match self { - Type::Function(fn_type) => fn_type.serialize(writer) - } - } + fn serialize(self, writer: &mut W) -> Result<(), Self::Error> { + match self { + Type::Function(fn_type) => fn_type.serialize(writer) + } + } } /// Value type. #[derive(Clone, Copy, PartialEq, Debug)] pub enum ValueType { - /// 32-bit signed integer - I32, - /// 64-bit signed integer - I64, - /// 32-bit float - F32, - /// 64-bit float - F64, + /// 32-bit signed integer + I32, + /// 64-bit signed integer + I64, + /// 32-bit float + F32, + /// 64-bit float + F64, } impl Deserialize for ValueType { - type Error = Error; + type Error = Error; - fn deserialize(reader: &mut R) -> Result { - let val = VarInt7::deserialize(reader)?; + fn deserialize(reader: &mut R) -> Result { + let val = VarInt7::deserialize(reader)?; - match val.into() { - -0x01 => Ok(ValueType::I32), - -0x02 => Ok(ValueType::I64), - -0x03 => Ok(ValueType::F32), - -0x04 => Ok(ValueType::F64), - _ => Err(Error::UnknownValueType(val.into())), - } - } + match val.into() { + -0x01 => Ok(ValueType::I32), + -0x02 => Ok(ValueType::I64), + -0x03 => Ok(ValueType::F32), + -0x04 => Ok(ValueType::F64), + _ => Err(Error::UnknownValueType(val.into())), + } + } } impl Serialize for ValueType { - type Error = Error; + type Error = Error; - fn serialize(self, writer: &mut W) -> Result<(), Self::Error> { - let val: VarInt7 = match self { - ValueType::I32 => -0x01, - ValueType::I64 => -0x02, - ValueType::F32 => -0x03, - ValueType::F64 => -0x04, - }.into(); - val.serialize(writer)?; - Ok(()) - } + fn serialize(self, writer: &mut W) -> Result<(), Self::Error> { + let val: VarInt7 = match self { + ValueType::I32 => -0x01, + ValueType::I64 => -0x02, + ValueType::F32 => -0x03, + ValueType::F64 => -0x04, + }.into(); + val.serialize(writer)?; + Ok(()) + } } impl fmt::Display for ValueType { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - match *self { - ValueType::I32 => write!(f, "i32"), - ValueType::I64 => write!(f, "i64"), - ValueType::F32 => write!(f, "f32"), - ValueType::F64 => write!(f, "f64"), - } - } + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match *self { + ValueType::I32 => write!(f, "i32"), + ValueType::I64 => write!(f, "i64"), + ValueType::F32 => write!(f, "f32"), + ValueType::F64 => write!(f, "f64"), + } + } } /// Block type which is basically `ValueType` + NoResult (to define blocks that have no return type) #[derive(Clone, Copy, PartialEq, Debug)] pub enum BlockType { - /// Value-type specified block type - Value(ValueType), - /// No specified block type - NoResult, + /// Value-type specified block type + Value(ValueType), + /// No specified block type + NoResult, } impl Deserialize for BlockType { - type Error = Error; + type Error = Error; - fn deserialize(reader: &mut R) -> Result { - let val = VarInt7::deserialize(reader)?; + fn deserialize(reader: &mut R) -> Result { + let val = VarInt7::deserialize(reader)?; - match val.into() { - -0x01 => Ok(BlockType::Value(ValueType::I32)), - -0x02 => Ok(BlockType::Value(ValueType::I64)), - -0x03 => Ok(BlockType::Value(ValueType::F32)), - -0x04 => Ok(BlockType::Value(ValueType::F64)), - -0x40 => Ok(BlockType::NoResult), - _ => Err(Error::UnknownValueType(val.into())), - } - } + match val.into() { + -0x01 => Ok(BlockType::Value(ValueType::I32)), + -0x02 => Ok(BlockType::Value(ValueType::I64)), + -0x03 => Ok(BlockType::Value(ValueType::F32)), + -0x04 => Ok(BlockType::Value(ValueType::F64)), + -0x40 => Ok(BlockType::NoResult), + _ => Err(Error::UnknownValueType(val.into())), + } + } } impl Serialize for BlockType { - type Error = Error; + type Error = Error; - fn serialize(self, writer: &mut W) -> Result<(), Self::Error> { - let val: VarInt7 = match self { - BlockType::NoResult => -0x40i8, - BlockType::Value(ValueType::I32) => -0x01, - BlockType::Value(ValueType::I64) => -0x02, - BlockType::Value(ValueType::F32) => -0x03, - BlockType::Value(ValueType::F64) => -0x04, - }.into(); - val.serialize(writer)?; - Ok(()) - } + fn serialize(self, writer: &mut W) -> Result<(), Self::Error> { + let val: VarInt7 = match self { + BlockType::NoResult => -0x40i8, + BlockType::Value(ValueType::I32) => -0x01, + BlockType::Value(ValueType::I64) => -0x02, + BlockType::Value(ValueType::F32) => -0x03, + BlockType::Value(ValueType::F64) => -0x04, + }.into(); + val.serialize(writer)?; + Ok(()) + } } /// Function signature type. #[derive(Debug, Clone, PartialEq)] pub struct FunctionType { - form: u8, - params: Vec, - return_type: Option, + form: u8, + params: Vec, + return_type: Option, } impl Default for FunctionType { - fn default() -> Self { - FunctionType { - form: 0x60, - params: Vec::new(), - return_type: None, - } - } + fn default() -> Self { + FunctionType { + form: 0x60, + params: Vec::new(), + return_type: None, + } + } } impl FunctionType { - /// New function type given the signature in-params(`params`) and return type (`return_type`) - pub fn new(params: Vec, return_type: Option) -> Self { - FunctionType { - params: params, - return_type: return_type, - ..Default::default() - } - } - /// Function form (currently only valid value is `0x60`) - pub fn form(&self) -> u8 { self.form } - /// Parameters in the function signature. - pub fn params(&self) -> &[ValueType] { &self.params } - /// Mutable parameters in the function signature. - pub fn params_mut(&mut self) -> &mut Vec { &mut self.params } - /// Return type in the function signature, if any. - pub fn return_type(&self) -> Option { self.return_type } - /// Mutable type in the function signature, if any. - pub fn return_type_mut(&mut self) -> &mut Option { &mut self.return_type } + /// New function type given the signature in-params(`params`) and return type (`return_type`) + pub fn new(params: Vec, return_type: Option) -> Self { + FunctionType { + params: params, + return_type: return_type, + ..Default::default() + } + } + /// Function form (currently only valid value is `0x60`) + pub fn form(&self) -> u8 { self.form } + /// Parameters in the function signature. + pub fn params(&self) -> &[ValueType] { &self.params } + /// Mutable parameters in the function signature. + pub fn params_mut(&mut self) -> &mut Vec { &mut self.params } + /// Return type in the function signature, if any. + pub fn return_type(&self) -> Option { self.return_type } + /// Mutable type in the function signature, if any. + pub fn return_type_mut(&mut self) -> &mut Option { &mut self.return_type } } impl Deserialize for FunctionType { - type Error = Error; + type Error = Error; - fn deserialize(reader: &mut R) -> Result { - let form: u8 = VarUint7::deserialize(reader)?.into(); + fn deserialize(reader: &mut R) -> Result { + let form: u8 = VarUint7::deserialize(reader)?.into(); - let params: Vec = CountedList::deserialize(reader)?.into_inner(); + let params: Vec = CountedList::deserialize(reader)?.into_inner(); - let has_return_type = VarUint1::deserialize(reader)?; - let return_type = if has_return_type.into() { - Some(ValueType::deserialize(reader)?) - } else { - None - }; + let has_return_type = VarUint1::deserialize(reader)?; + let return_type = if has_return_type.into() { + Some(ValueType::deserialize(reader)?) + } else { + None + }; - Ok(FunctionType { - form: form, - params: params, - return_type: return_type, - }) - } + Ok(FunctionType { + form: form, + params: params, + return_type: return_type, + }) + } } impl Serialize for FunctionType { - type Error = Error; + type Error = Error; - fn serialize(self, writer: &mut W) -> Result<(), Self::Error> { - VarUint7::from(self.form).serialize(writer)?; + fn serialize(self, writer: &mut W) -> Result<(), Self::Error> { + VarUint7::from(self.form).serialize(writer)?; - let data = self.params; - let counted_list = CountedListWriter::( - data.len(), - data.into_iter().map(Into::into), - ); - counted_list.serialize(writer)?; + let data = self.params; + let counted_list = CountedListWriter::( + data.len(), + data.into_iter().map(Into::into), + ); + counted_list.serialize(writer)?; - if let Some(return_type) = self.return_type { - VarUint1::from(true).serialize(writer)?; - return_type.serialize(writer)?; - } else { - VarUint1::from(false).serialize(writer)?; - } + if let Some(return_type) = self.return_type { + VarUint1::from(true).serialize(writer)?; + return_type.serialize(writer)?; + } else { + VarUint1::from(false).serialize(writer)?; + } - Ok(()) - } + Ok(()) + } } /// Table element type. #[derive(Clone, Copy, PartialEq, Debug)] pub enum TableElementType { - /// A reference to a function with any signature. - AnyFunc, + /// A reference to a function with any signature. + AnyFunc, } impl Deserialize for TableElementType { - type Error = Error; + type Error = Error; - fn deserialize(reader: &mut R) -> Result { - let val = VarInt7::deserialize(reader)?; + fn deserialize(reader: &mut R) -> Result { + let val = VarInt7::deserialize(reader)?; - match val.into() { - -0x10 => Ok(TableElementType::AnyFunc), - _ => Err(Error::UnknownTableElementType(val.into())), - } - } + match val.into() { + -0x10 => Ok(TableElementType::AnyFunc), + _ => Err(Error::UnknownTableElementType(val.into())), + } + } } impl Serialize for TableElementType { - type Error = Error; + type Error = Error; - fn serialize(self, writer: &mut W) -> Result<(), Self::Error> { - let val: VarInt7 = match self { - TableElementType::AnyFunc => 0x70, - }.into(); - val.serialize(writer)?; - Ok(()) - } + fn serialize(self, writer: &mut W) -> Result<(), Self::Error> { + let val: VarInt7 = match self { + TableElementType::AnyFunc => 0x70, + }.into(); + val.serialize(writer)?; + Ok(()) + } } diff --git a/src/lib.rs b/src/lib.rs index 3e370a5..b829b3c 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -14,18 +14,18 @@ mod validation; mod common; pub use elements::{ - Error as SerializationError, - deserialize_buffer, - deserialize_file, - serialize, - serialize_to_file, - peek_size, + Error as SerializationError, + deserialize_buffer, + deserialize_file, + serialize, + serialize_to_file, + peek_size, }; #[allow(deprecated)] pub use interpreter::{ - ProgramInstance, - ModuleInstance, - ModuleInstanceInterface, - RuntimeValue, + ProgramInstance, + ModuleInstance, + ModuleInstanceInterface, + RuntimeValue, };