Skip to content
This repository has been archived by the owner on Nov 6, 2020. It is now read-only.

Commit

Permalink
update wasmi, parity-wasm, wasm-utils to latest version
Browse files Browse the repository at this point in the history
  • Loading branch information
NikVolf committed Feb 21, 2018
1 parent 01d9bff commit bace1ff
Show file tree
Hide file tree
Showing 6 changed files with 102 additions and 71 deletions.
21 changes: 14 additions & 7 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion ethcore/wasm/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ authors = ["Parity Technologies <[email protected]>"]
byteorder = "1.0"
ethereum-types = "0.2"
log = "0.3"
parity-wasm = "0.23"
parity-wasm = "0.27"
libc = "0.2"
wasm-utils = { git = "https://github.com/paritytech/wasm-utils" }
vm = { path = "../vm" }
Expand Down
14 changes: 10 additions & 4 deletions ethcore/wasm/src/env.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
use std::cell::RefCell;
use wasmi::{
self, Signature, Error, FuncRef, FuncInstance, MemoryDescriptor,
MemoryRef, MemoryInstance,
MemoryRef, MemoryInstance, memory_units,
};

/// Internal ids all functions runtime supports. This is just a glue for wasmi interpreter
Expand Down Expand Up @@ -219,7 +219,10 @@ impl ImportResolver {
let mut mem_ref = self.memory.borrow_mut();
if mem_ref.is_none() {
*mem_ref = Some(
MemoryInstance::alloc(0, Some(0)).expect("Memory allocation (0, 0) should not fail; qed")
MemoryInstance::alloc(
memory_units::Pages(0),
Some(memory_units::Pages(0)),
).expect("Memory allocation (0, 0) should not fail; qed")
);
}
}
Expand All @@ -229,7 +232,7 @@ impl ImportResolver {

/// Returns memory size module initially requested
pub fn memory_size(&self) -> Result<u32, Error> {
Ok(self.memory_ref().size())
Ok(self.memory_ref().current_size().0 as u32)
}
}

Expand Down Expand Up @@ -281,7 +284,10 @@ impl wasmi::ModuleImportResolver for ImportResolver {
{
Err(Error::Instantiation("Module requested too much memory".to_owned()))
} else {
let mem = MemoryInstance::alloc(descriptor.initial(), descriptor.maximum())?;
let mem = MemoryInstance::alloc(
memory_units::Pages(descriptor.initial() as usize),
descriptor.maximum().map(|x| memory_units::Pages(x as usize)),
)?;
*self.memory.borrow_mut() = Some(mem.clone());
Ok(mem)
}
Expand Down
22 changes: 14 additions & 8 deletions ethcore/wasm/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,25 +34,31 @@ mod panic_payload;
mod parser;

use vm::{GasLeft, ReturnData, ActionParams};
use wasmi::Error as InterpreterError;
use wasmi::{Error as InterpreterError, Trap};

use runtime::{Runtime, RuntimeContext};

use ethereum_types::U256;

/// Wrapped interpreter error
#[derive(Debug)]
pub struct Error(InterpreterError);
pub enum Error {
Interpreter(InterpreterError),
Trap(Trap),
}

impl From<InterpreterError> for Error {
fn from(e: InterpreterError) -> Self {
Error(e)
Error::Interpreter(e)
}
}

impl From<Error> for vm::Error {
fn from(e: Error) -> Self {
vm::Error::Wasm(format!("Wasm runtime error: {:?}", e.0))
match e {
Error::Interpreter(e) => vm::Error::Wasm(format!("Wasm runtime error: {:?}", e)),
Error::Trap(e) => vm::Error::Wasm(format!("Wasm contract trap: {:?}", e)),
}
}
}

Expand All @@ -70,14 +76,14 @@ impl vm::Vm for WasmInterpreter {
fn exec(&mut self, params: ActionParams, ext: &mut vm::Ext) -> vm::Result<GasLeft> {
let (module, data) = parser::payload(&params, ext.schedule().wasm())?;

let loaded_module = wasmi::Module::from_parity_wasm_module(module).map_err(Error)?;
let loaded_module = wasmi::Module::from_parity_wasm_module(module).map_err(Error::Interpreter)?;

let instantiation_resolover = env::ImportResolver::with_limit(16);

let module_instance = wasmi::ModuleInstance::new(
&loaded_module,
&wasmi::ImportsBuilder::new().with_resolver("env", &instantiation_resolover)
).map_err(Error)?;
).map_err(Error::Interpreter)?;

let adjusted_gas = params.gas * U256::from(ext.schedule().wasm().opcodes_div) /
U256::from(ext.schedule().wasm().opcodes_mul);
Expand All @@ -87,7 +93,7 @@ impl vm::Vm for WasmInterpreter {
return Err(vm::Error::Wasm("Wasm interpreter cannot run contracts with gas (wasm adjusted) >= 2^64".to_owned()));
}

let initial_memory = instantiation_resolover.memory_size().map_err(Error)?;
let initial_memory = instantiation_resolover.memory_size().map_err(Error::Interpreter)?;
trace!(target: "wasm", "Contract requested {:?} pages of initial memory", initial_memory);

let (gas_left, result) = {
Expand All @@ -114,7 +120,7 @@ impl vm::Vm for WasmInterpreter {
assert!(runtime.schedule().wasm().initial_mem < 1 << 16);
runtime.charge(|s| initial_memory as u64 * s.wasm().initial_mem as u64)?;

let module_instance = module_instance.run_start(&mut runtime).map_err(Error)?;
let module_instance = module_instance.run_start(&mut runtime).map_err(Error::Trap)?;

match module_instance.invoke_export("call", &[], &mut runtime) {
Ok(_) => { },
Expand Down
24 changes: 15 additions & 9 deletions ethcore/wasm/src/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,18 @@ use parity_wasm::elements::{self, Deserialize};
use parity_wasm::peek_size;

fn gas_rules(wasm_costs: &vm::WasmCosts) -> rules::Set {
rules::Set::new({
let mut vals = ::std::collections::HashMap::with_capacity(4);
vals.insert(rules::InstructionType::Load, wasm_costs.mem as u32);
vals.insert(rules::InstructionType::Store, wasm_costs.mem as u32);
vals.insert(rules::InstructionType::Div, wasm_costs.div as u32);
vals.insert(rules::InstructionType::Mul, wasm_costs.mul as u32);
vals
}).with_grow_cost(wasm_costs.grow_mem)
rules::Set::new(
1,
{
let mut vals = ::std::collections::HashMap::with_capacity(8);
vals.insert(rules::InstructionType::Load, rules::Metering::Fixed(wasm_costs.mem as u32));
vals.insert(rules::InstructionType::Store, rules::Metering::Fixed(wasm_costs.mem as u32));
vals.insert(rules::InstructionType::Div, rules::Metering::Fixed(wasm_costs.div as u32));
vals.insert(rules::InstructionType::Mul, rules::Metering::Fixed(wasm_costs.mul as u32));
vals
})
.with_grow_cost(wasm_costs.grow_mem)
.with_forbidden_floats()
}

/// Splits payload to code and data according to params.params_type, also
Expand Down Expand Up @@ -71,7 +75,9 @@ pub fn payload<'a>(params: &'a vm::ActionParams, wasm_costs: &vm::WasmCosts)
let contract_module = wasm_utils::inject_gas_counter(
deserialized_module,
&gas_rules(wasm_costs),
);
).map_err(|_| vm::Error::Wasm(format!("Wasm contract error: bytecode invalid")))?;

::parity_wasm::elements::serialize_to_file("./debug.wasm", contract_module.clone());

let data = match params.params_type {
vm::ParamsType::Embedded => {
Expand Down
Loading

0 comments on commit bace1ff

Please sign in to comment.