import inject example

This commit is contained in:
NikVolf
2017-04-10 13:58:14 +03:00
parent d09a59c6bc
commit 3b949e1c7e
4 changed files with 61 additions and 21 deletions

View File

@ -3,6 +3,7 @@ extern crate parity_wasm;
use std::env; use std::env;
use parity_wasm::elements; use parity_wasm::elements;
use parity_wasm::builder;
pub fn inject_nop(opcodes: &mut elements::Opcodes) { pub fn inject_nop(opcodes: &mut elements::Opcodes) {
use parity_wasm::elements::Opcode::*; use parity_wasm::elements::Opcode::*;
@ -38,5 +39,19 @@ fn main() {
} }
} }
parity_wasm::serialize_to_file(&args[2], module).unwrap(); 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();
} }

View File

@ -12,6 +12,12 @@ pub struct SignatureBuilder<F=Identity> {
signature: elements::FunctionType, signature: elements::FunctionType,
} }
impl SignatureBuilder {
pub fn new() -> Self {
SignatureBuilder::with_callback(Identity)
}
}
impl<F> SignatureBuilder<F> where F: Invoke<elements::FunctionType> { impl<F> SignatureBuilder<F> where F: Invoke<elements::FunctionType> {
pub fn with_callback(callback: F) -> Self { pub fn with_callback(callback: F) -> Self {
SignatureBuilder { SignatureBuilder {
@ -50,6 +56,10 @@ impl<F> SignatureBuilder<F> where F: Invoke<elements::FunctionType> {
pub fn build(self) -> F::Result { pub fn build(self) -> F::Result {
self.callback.invoke(self.signature) self.callback.invoke(self.signature)
} }
pub fn build_sig(self) -> Signature {
Signature::Inline(self.signature)
}
} }
impl<F> Invoke<Vec<elements::ValueType>> for SignatureBuilder<F> impl<F> Invoke<Vec<elements::ValueType>> for SignatureBuilder<F>
@ -298,6 +308,11 @@ pub fn signatures() -> SignaturesBuilder {
SignaturesBuilder::new() SignaturesBuilder::new()
} }
/// New signature builder
pub fn signature() -> SignatureBuilder {
SignatureBuilder::new()
}
/// New builder of function (signature & body) /// New builder of function (signature & body)
pub fn function() -> FunctionBuilder { pub fn function() -> FunctionBuilder {
FunctionBuilder::new() FunctionBuilder::new()

View File

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

View File

@ -123,22 +123,13 @@ impl<F> ModuleBuilder<F> where F: Invoke<elements::Module> {
pub fn push_function(&mut self, func: code::FunctionDefinition) -> CodeLocation { pub fn push_function(&mut self, func: code::FunctionDefinition) -> CodeLocation {
let signature = func.signature; let signature = func.signature;
let body = func.code; let body = func.code;
let module = &mut self.module;
let type_ref = match signature { let type_ref = self.resolve_type_ref(signature);
code::Signature::Inline(func_type) => {
module.types.types_mut().push(elements::Type::Function(func_type));
module.types.types().len() as u32 - 1
}
code::Signature::TypeReference(type_ref) => {
type_ref
}
};
module.functions.entries_mut().push(elements::Func::new(type_ref)); self.module.functions.entries_mut().push(elements::Func::new(type_ref));
let signature_index = module.functions.entries_mut().len() as u32 - 1; let signature_index = self.module.functions.entries_mut().len() as u32 - 1;
module.code.bodies_mut().push(body); self.module.code.bodies_mut().push(body);
let body_index = module.code.bodies_mut().len() as u32 - 1; let body_index = self.module.code.bodies_mut().len() as u32 - 1;
CodeLocation { CodeLocation {
signature: signature_index, signature: signature_index,
@ -146,17 +137,36 @@ impl<F> ModuleBuilder<F> where F: Invoke<elements::Module> {
} }
} }
fn resolve_type_ref(&mut self, signature: code::Signature) -> u32 {
match signature {
code::Signature::Inline(func_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 {
let type_ref = self.resolve_type_ref(signature);
self.module.functions.entries_mut().push(elements::Func::new(type_ref));
self.module.functions.entries_mut().len() as u32 - 1
}
/// Push signatures in the module, returning corresponding indices of pushed signatures /// Push signatures in the module, returning corresponding indices of pushed signatures
pub fn push_signatures(&mut self, signatures: code::SignatureBindings) -> Vec<u32> { pub fn push_signatures(&mut self, signatures: code::SignatureBindings) -> Vec<u32> {
let module = &mut self.module;
let mut result = Vec::new(); let mut result = Vec::new();
// todo: maybe reuse existing types with the equal signatures // todo: maybe reuse existing types with the equal signatures
let raw_functions: Vec<u32> = signatures.into_iter().map(|binding| let raw_functions: Vec<u32> = signatures.into_iter().map(|binding|
match binding { match binding {
code::Signature::Inline(func_type) => { code::Signature::Inline(func_type) => {
module.types.types_mut().push(elements::Type::Function(func_type)); self.module.types.types_mut().push(elements::Type::Function(func_type));
module.types.types().len() as u32 - 1 self.module.types.types().len() as u32 - 1
} }
code::Signature::TypeReference(type_ref) => { code::Signature::TypeReference(type_ref) => {
type_ref type_ref
@ -165,8 +175,8 @@ impl<F> ModuleBuilder<F> where F: Invoke<elements::Module> {
).collect(); ).collect();
for function in raw_functions { for function in raw_functions {
module.functions.entries_mut().push(elements::Func::new(function)); self.module.functions.entries_mut().push(elements::Func::new(function));
result.push(module.functions.entries_mut().len() as u32 - 1); result.push(self.module.functions.entries_mut().len() as u32 - 1);
} }
result result