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

[Wasm] memcmp fix and test added #7590

Merged
merged 2 commits into from
Jan 17, 2018
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion ethcore/res/wasm-tests
6 changes: 4 additions & 2 deletions ethcore/wasm/src/runtime.rs
Original file line number Diff line number Diff line change
@@ -577,16 +577,18 @@ impl<'a, 'b> Runtime<'a, 'b> {
//

let len = context.value_stack.pop_as::<i32>()? as u32;
let cx = context.value_stack.pop_as::<i32>()? as u32;
let ct = context.value_stack.pop_as::<i32>()? as u32;
let cx = context.value_stack.pop_as::<i32>()? as u32;

self.charge(|schedule| schedule.wasm.mem_cmp as u64 * len as u64)?;

let cx = self.memory.get(cx, len as usize)?;
let ct = self.memory.get(ct, len as usize)?;
let cx = self.memory.get(cx, len as usize)?;

let result = unsafe {
memcmp(cx.as_ptr() as *const c_void, ct.as_ptr() as *const c_void, len as usize)
};

Ok(Some(Into::into(result)))
}

86 changes: 58 additions & 28 deletions ethcore/wasm/src/tests.rs
Original file line number Diff line number Diff line change
@@ -29,6 +29,34 @@ macro_rules! load_sample {
}
}

macro_rules! reqrep_test {
($name: expr, $input: expr) => {
reqrep_test!($name, $input, vm::EnvInfo::default(), HashMap::new())
};
($name: expr, $input: expr, $info: expr, $block_hashes: expr) => {
{
::ethcore_logger::init_log();
let code = load_sample!($name);

let mut params = ActionParams::default();
params.gas = U256::from(100_000);
params.code = Some(Arc::new(code));
params.data = Some($input);

let mut fake_ext = FakeExt::new();
fake_ext.info = $info;
fake_ext.blockhashes = $block_hashes;

let mut interpreter = wasm_interpreter();
interpreter.exec(params, &mut fake_ext)
.map(|result| match result {
GasLeft::Known(_) => { panic!("Test is expected to return payload to check"); },
GasLeft::NeedsReturn { gas_left: gas, data: result, apply_state: _apply } => (gas, result.to_vec()),
})
}
};
}

fn test_finalize(res: Result<GasLeft, vm::Error>) -> Result<U256, vm::Error> {
match res {
Ok(GasLeft::Known(gas)) => Ok(gas),
@@ -491,6 +519,36 @@ fn keccak() {
assert_eq!(gas_left, U256::from(81_067));
}

// memcmp test.
#[test]
fn memcmp() {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

reqrep_test! macro is more suitable for this kind of tests

::ethcore_logger::init_log();

let (gas_left, result) = reqrep_test! {
"memcmp.wasm",
vec![1u8, 1, 1]
}.expect("Interpreter to execute without any errors");

assert_eq!(0i32, LittleEndian::read_i32(&result));
assert_eq!(gas_left, U256::from(96610));

let (gas_left, result) = reqrep_test! {
"memcmp.wasm",
vec![1u8, 1, 3, 1]
}.expect("Interpreter to execute without any errors");

assert_eq!(2i32, LittleEndian::read_i32(&result));
assert_eq!(gas_left, U256::from(96610));

let (gas_left, result) = reqrep_test! {
"memcmp.wasm",
vec![1u8, 1, 0]
}.expect("Interpreter to execute without any errors");

assert_eq!(-1i32, LittleEndian::read_i32(&result));
assert_eq!(gas_left, U256::from(96610));
}

// memcpy test.
#[test]
fn memcpy() {
@@ -580,34 +638,6 @@ fn memset() {
assert_eq!(gas_left, U256::from(71_921));
}

macro_rules! reqrep_test {
($name: expr, $input: expr) => {
reqrep_test!($name, $input, vm::EnvInfo::default(), HashMap::new())
};
($name: expr, $input: expr, $info: expr, $block_hashes: expr) => {
{
::ethcore_logger::init_log();
let code = load_sample!($name);

let mut params = ActionParams::default();
params.gas = U256::from(100_000);
params.code = Some(Arc::new(code));
params.data = Some($input);

let mut fake_ext = FakeExt::new();
fake_ext.info = $info;
fake_ext.blockhashes = $block_hashes;

let mut interpreter = wasm_interpreter();
interpreter.exec(params, &mut fake_ext)
.map(|result| match result {
GasLeft::Known(_) => { panic!("Test is expected to return payload to check"); },
GasLeft::NeedsReturn { gas_left: gas, data: result, apply_state: _apply } => (gas, result.to_vec()),
})
}
};
}

// math_* tests check the ability of wasm contract to perform big integer operations
// - addition
// - multiplication