mirror of
https://github.com/fluencelabs/wasm-utils
synced 2025-07-01 15:31:44 +00:00
test for pack added
This commit is contained in:
@ -26,10 +26,6 @@ path = "ext/src/main.rs"
|
|||||||
name = "wasm-gas"
|
name = "wasm-gas"
|
||||||
path = "gas/src/main.rs"
|
path = "gas/src/main.rs"
|
||||||
|
|
||||||
[[bin]]
|
|
||||||
name = "wasm-pack"
|
|
||||||
path = "pack/src/main.rs"
|
|
||||||
|
|
||||||
[[bin]]
|
[[bin]]
|
||||||
name = "wasm-build"
|
name = "wasm-build"
|
||||||
path = "build/src/main.rs"
|
path = "build/src/main.rs"
|
||||||
|
@ -12,8 +12,7 @@ use std::path::PathBuf;
|
|||||||
use clap::{App, Arg};
|
use clap::{App, Arg};
|
||||||
use parity_wasm::elements;
|
use parity_wasm::elements;
|
||||||
|
|
||||||
use wasm_utils::CREATE_SYMBOL;
|
use wasm_utils::{CREATE_SYMBOL, CALL_SYMBOL, SET_TEMP_RET_SYMBOL};
|
||||||
use wasm_utils::CALL_SYMBOL;
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum Error {
|
pub enum Error {
|
||||||
@ -65,7 +64,7 @@ pub fn process_output(target_dir: &str, bin_name: &str) -> Result<(), Error> {
|
|||||||
|
|
||||||
fn has_ctor(module: &elements::Module) -> bool {
|
fn has_ctor(module: &elements::Module) -> bool {
|
||||||
if let Some(ref section) = module.export_section() {
|
if let Some(ref section) = module.export_section() {
|
||||||
section.entries().iter().any(|e| CALL_SYMBOL == e.field())
|
section.entries().iter().any(|e| CREATE_SYMBOL == e.field())
|
||||||
} else {
|
} else {
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
@ -128,7 +127,7 @@ fn main() {
|
|||||||
let mut ctor_module = module.clone();
|
let mut ctor_module = module.clone();
|
||||||
|
|
||||||
if !matches.is_present("skip_optimization") {
|
if !matches.is_present("skip_optimization") {
|
||||||
wasm_utils::optimize(&mut module, vec![CALL_SYMBOL, "setTempRet0"]).expect("Optimizer to finish without errors");
|
wasm_utils::optimize(&mut module, vec![CALL_SYMBOL, SET_TEMP_RET_SYMBOL]).expect("Optimizer to finish without errors");
|
||||||
}
|
}
|
||||||
|
|
||||||
let raw_module = parity_wasm::serialize(module).expect("Failed to serialize module");
|
let raw_module = parity_wasm::serialize(module).expect("Failed to serialize module");
|
||||||
@ -138,7 +137,7 @@ fn main() {
|
|||||||
// Otherwise it will just save an optimised raw_module
|
// Otherwise it will just save an optimised raw_module
|
||||||
if has_ctor(&ctor_module) {
|
if has_ctor(&ctor_module) {
|
||||||
if !matches.is_present("skip_optimization") {
|
if !matches.is_present("skip_optimization") {
|
||||||
wasm_utils::optimize(&mut ctor_module, vec![CREATE_SYMBOL, "setTempRet0"]).expect("Optimizer to finish without errors");
|
wasm_utils::optimize(&mut ctor_module, vec![CREATE_SYMBOL, SET_TEMP_RET_SYMBOL]).expect("Optimizer to finish without errors");
|
||||||
}
|
}
|
||||||
wasm_utils::pack_instance(raw_module, &mut ctor_module);
|
wasm_utils::pack_instance(raw_module, &mut ctor_module);
|
||||||
parity_wasm::serialize_to_file(&path, ctor_module).expect("Failed to serialize to file");
|
parity_wasm::serialize_to_file(&path, ctor_module).expect("Failed to serialize to file");
|
||||||
|
@ -6,6 +6,7 @@ extern crate byteorder;
|
|||||||
|
|
||||||
pub static CREATE_SYMBOL: &'static str = "_create";
|
pub static CREATE_SYMBOL: &'static str = "_create";
|
||||||
pub static CALL_SYMBOL: &'static str = "_call";
|
pub static CALL_SYMBOL: &'static str = "_call";
|
||||||
|
pub static SET_TEMP_RET_SYMBOL: &'static str = "setTempRet0";
|
||||||
|
|
||||||
pub mod rules;
|
pub mod rules;
|
||||||
|
|
||||||
|
85
src/pack.rs
85
src/pack.rs
@ -1,8 +1,7 @@
|
|||||||
use parity_wasm::{serialize,elements, builder, deserialize_buffer};
|
use parity_wasm::{serialize,elements, builder, deserialize_buffer};
|
||||||
use self::elements::{ External, Section, ResizableLimits, Opcode, DataSegment, InitExpr, Internal };
|
use self::elements::{ External, Section, ResizableLimits, Opcode, DataSegment, InitExpr, Internal };
|
||||||
|
|
||||||
use super::CREATE_SYMBOL;
|
use super::{CREATE_SYMBOL, CALL_SYMBOL};
|
||||||
use super::CALL_SYMBOL;
|
|
||||||
|
|
||||||
/// If module has an exported "_create" function we want to pack it into "constructor".
|
/// If module has an exported "_create" function we want to pack it into "constructor".
|
||||||
/// `raw_module` is the actual contract code
|
/// `raw_module` is the actual contract code
|
||||||
@ -35,8 +34,10 @@ pub fn pack_instance(raw_module: Vec<u8>, ctor_module: &mut elements::Module) {
|
|||||||
|
|
||||||
// Code data address is an address where we put the contract's code (raw_module)
|
// Code data address is an address where we put the contract's code (raw_module)
|
||||||
let mut code_data_address = 0i32;
|
let mut code_data_address = 0i32;
|
||||||
|
|
||||||
for section in ctor_module.sections_mut() {
|
for section in ctor_module.sections_mut() {
|
||||||
match section {
|
match section {
|
||||||
|
// TODO: add data section is there no one
|
||||||
&mut Section::Data(ref mut data_section) => {
|
&mut Section::Data(ref mut data_section) => {
|
||||||
let (index, offset) = if let Some(ref entry) = data_section.entries().iter().last() {
|
let (index, offset) = if let Some(ref entry) = data_section.entries().iter().last() {
|
||||||
if let Opcode::I32Const(offst) = entry.offset().code()[0] {
|
if let Opcode::I32Const(offst) = entry.offset().code()[0] {
|
||||||
@ -89,3 +90,83 @@ pub fn pack_instance(raw_module: Vec<u8>, ctor_module: &mut elements::Module) {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod test {
|
||||||
|
extern crate parity_wasm;
|
||||||
|
use parity_wasm::interpreter;
|
||||||
|
use parity_wasm::ModuleInstanceInterface;
|
||||||
|
use super::*;
|
||||||
|
use super::super::optimize;
|
||||||
|
use super::super::SET_TEMP_RET_SYMBOL;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn call_returns_code() {
|
||||||
|
let mut module = builder::module()
|
||||||
|
.import()
|
||||||
|
.module("env")
|
||||||
|
.field("memory")
|
||||||
|
.external()
|
||||||
|
.memory(1 as u32, Some(1 as u32))
|
||||||
|
.build()
|
||||||
|
.data()
|
||||||
|
.offset(elements::Opcode::I32Const(16))
|
||||||
|
.value(vec![0u8])
|
||||||
|
.build()
|
||||||
|
.function()
|
||||||
|
.signature().param().i32().build()
|
||||||
|
.body()
|
||||||
|
.with_opcodes(elements::Opcodes::new(
|
||||||
|
vec![
|
||||||
|
elements::Opcode::End
|
||||||
|
]
|
||||||
|
))
|
||||||
|
.build()
|
||||||
|
.build()
|
||||||
|
.function()
|
||||||
|
.signature().param().i32().build()
|
||||||
|
.body()
|
||||||
|
.with_opcodes(elements::Opcodes::new(
|
||||||
|
vec![
|
||||||
|
elements::Opcode::End
|
||||||
|
]
|
||||||
|
))
|
||||||
|
.build()
|
||||||
|
.build()
|
||||||
|
.export()
|
||||||
|
.field("_call")
|
||||||
|
.internal().func(0)
|
||||||
|
.build()
|
||||||
|
.export()
|
||||||
|
.field("_create")
|
||||||
|
.internal().func(1)
|
||||||
|
.build()
|
||||||
|
.build();
|
||||||
|
let mut ctor_module = module.clone();
|
||||||
|
optimize(&mut module, vec![CALL_SYMBOL, SET_TEMP_RET_SYMBOL]).expect("Optimizer to finish without errors");
|
||||||
|
optimize(&mut ctor_module, vec![CREATE_SYMBOL, SET_TEMP_RET_SYMBOL]).expect("Optimizer to finish without errors");
|
||||||
|
|
||||||
|
let raw_module = parity_wasm::serialize(module).unwrap();
|
||||||
|
let raw_module_len = raw_module.len();
|
||||||
|
pack_instance(raw_module, &mut ctor_module);
|
||||||
|
|
||||||
|
let program = parity_wasm::DefaultProgramInstance::new().expect("Program instance to load");
|
||||||
|
let env_instance = program.module("env").expect("Wasm program to contain env module");
|
||||||
|
let env_memory = env_instance.memory(interpreter::ItemIndex::Internal(0)).expect("Linear memory to exist in wasm runtime");
|
||||||
|
|
||||||
|
let execution_params = interpreter::ExecutionParams::default();
|
||||||
|
let module = program.add_module("contract", ctor_module, None).expect("Failed to initialize module");
|
||||||
|
|
||||||
|
let _ = module.execute_export("_call", execution_params);
|
||||||
|
|
||||||
|
let result_code = env_memory.get(20, raw_module_len).expect("Failed to get code");
|
||||||
|
|
||||||
|
let result_module: elements::Module = parity_wasm::deserialize_buffer(result_code).expect("Result module is not valid");
|
||||||
|
|
||||||
|
let program = parity_wasm::DefaultProgramInstance::new().expect("Program2 instance to load");
|
||||||
|
let module = program.add_module("contract", result_module, None).expect("Failed to initialize module");
|
||||||
|
let execution_params = interpreter::ExecutionParams::default();
|
||||||
|
|
||||||
|
let _ = module.execute_export("_call", execution_params);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Reference in New Issue
Block a user