inject example, some fixes

This commit is contained in:
NikVolf
2017-04-10 13:11:34 +03:00
parent 56d315f6c5
commit d09a59c6bc
7 changed files with 105 additions and 13 deletions

42
examples/inject.rs Normal file
View File

@ -0,0 +1,42 @@
extern crate parity_wasm;
use std::env;
use parity_wasm::elements;
pub fn inject_nop(opcodes: &mut elements::Opcodes) {
use parity_wasm::elements::Opcode::*;
for opcode in opcodes.elements_mut().iter_mut() {
match opcode {
&mut Block(_, ref mut block) | &mut If(_, ref mut block) => {
inject_nop(block)
},
_ => { }
}
}
opcodes.elements_mut().insert(0, Nop);
}
fn main() {
let args = env::args().collect::<Vec<_>>();
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();
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());
}
},
_ => { }
}
}
parity_wasm::serialize_to_file(&args[2], module).unwrap();
}

View File

@ -179,34 +179,37 @@ impl<F> SignaturesBuilder<F> where F: Invoke<SignatureBindings> {
pub struct FuncBodyBuilder<F=Identity> {
callback: F,
locals: Vec<elements::Local>,
opcodes: elements::Opcodes,
body: elements::FuncBody,
}
impl<F> FuncBodyBuilder<F> {
pub fn with_callback(callback: F) -> Self {
FuncBodyBuilder {
callback: callback,
locals: Vec::new(),
opcodes: elements::Opcodes::empty(),
body: elements::FuncBody::new(Vec::new(), elements::Opcodes::empty()),
}
}
}
impl<F> FuncBodyBuilder<F> where F: Invoke<elements::FuncBody> {
pub fn with_func(mut self, func: elements::FuncBody) -> Self {
self.body = func;
self
}
pub fn with_locals(mut self, locals: Vec<elements::Local>) -> Self {
self.locals.extend(locals);
self.body.locals_mut().extend(locals);
self
}
pub fn with_opcodes(mut self, opcodes: elements::Opcodes) -> Self {
self.opcodes = opcodes;
*self.body.code_mut() = opcodes;
self
}
pub fn build(self) -> F::Result {
self.callback.invoke(elements::FuncBody::new(self.locals, self.opcodes))
self.callback.invoke(self.body)
}
}

View File

@ -6,6 +6,6 @@ mod code;
mod misc;
mod import;
pub use self::module::{module, ModuleBuilder};
pub use self::module::{module, from_module, ModuleBuilder};
pub use self::code::{signatures, function};
pub use self::import::import;

View File

@ -1,5 +1,6 @@
use super::invoke::{Invoke, Identity};
use super::code::{self, SignaturesBuilder};
use super::import;
use elements;
/// Module builder
@ -90,6 +91,12 @@ impl<F> ModuleBuilder<F> where F: Invoke<elements::Module> {
}
}
/// 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<I>(mut self, sections: I) -> Self
where I: IntoIterator<Item=elements::Section>
@ -170,6 +177,17 @@ impl<F> ModuleBuilder<F> where F: Invoke<elements::Module> {
SignaturesBuilder::with_callback(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
pub fn import(self) -> import::ImportBuilder<Self> {
import::ImportBuilder::with_callback(self)
}
/// Build module (final step)
pub fn build(self) -> F::Result {
self.callback.invoke(self.module.into())
@ -196,11 +214,26 @@ impl<F> Invoke<code::SignatureBindings> for ModuleBuilder<F>
}
}
impl<F> Invoke<elements::ImportEntry> for ModuleBuilder<F>
where F: Invoke<elements::Module>
{
type Result = Self;
fn invoke(self, entry: elements::ImportEntry) -> Self::Result {
self.with_import(entry)
}
}
/// Start new module builder
pub fn module() -> ModuleBuilder {
ModuleBuilder::new()
}
/// Start builder to extend existing module
pub fn from_module(module: elements::Module) -> ModuleBuilder {
ModuleBuilder::new().with_module(module)
}
#[cfg(test)]
mod tests {

View File

@ -79,6 +79,12 @@ impl FuncBody {
/// 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<Local> { &mut self.locals }
/// Opcode sequence of the function body (mutable).
pub fn code_mut(&mut self) -> &mut Opcodes { &mut self.opcodes }
}
impl Deserialize for FuncBody {

View File

@ -10,18 +10,21 @@ use super::{
pub struct Opcodes(Vec<Opcode>);
impl Opcodes {
/// New list of opcodes from vector of opcodes
/// New list of opcodes from vector of opcodes.
pub fn new(elements: Vec<Opcode>) -> Self {
Opcodes(elements)
}
/// Empty expression with only `Opcode::End` opcode
/// Empty expression with only `Opcode::End` opcode.
pub fn empty() -> Self {
Opcodes(vec![Opcode::End])
}
/// List of individual opcodes
/// List of individual opcodes.
pub fn elements(&self) -> &[Opcode] { &self.0 }
/// Individual opcodes, mutable.
pub fn elements_mut(&mut self) -> &mut Vec<Opcode> { &mut self.0 }
}
impl Deserialize for Opcodes {

View File

@ -228,6 +228,11 @@ impl ImportSection {
pub fn entries(&self) -> &[ImportEntry] {
&self.0
}
/// List of import entries (mutable).
pub fn entries_mut(&mut self) -> &mut Vec<ImportEntry> {
&mut self.0
}
}
impl Deserialize for ImportSection {
@ -903,9 +908,9 @@ mod tests {
9, // function #1 total code size
1, // 1 local variable declaration
1, // amount of variables
0xff, // type of variable (-0x01), negative
0x7f, // type of variable (7-bit, -0x01), negative
0x02, // block
0xff, // block return type (-0x01), negative
0x7f, // block return type (7-bit, -0x01), negative
0x23, 0x00, // get_global(0)
0x0b, // block end
0x0b, // function end