[Wasm] memcmp fix and test added (#7590)

* [Wasm] memcmp fix and test added

* [Wasm] use reqrep_test! macro for memcmp test
This commit is contained in:
Alexey 2018-01-17 12:13:17 +03:00 committed by Nikolay Volf
parent c7aed335ce
commit 534692cdae
3 changed files with 63 additions and 31 deletions

@ -1 +1 @@
Subproject commit d9d6133c1bc5dca4c74c9eb758a39546a0d46b45 Subproject commit f25e60e300ade96aba2adffb3ebca8e5b4965720

View File

@ -577,16 +577,18 @@ impl<'a, 'b> Runtime<'a, 'b> {
// //
let len = context.value_stack.pop_as::<i32>()? as u32; 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 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)?; 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 ct = self.memory.get(ct, len as usize)?;
let cx = self.memory.get(cx, len as usize)?;
let result = unsafe { let result = unsafe {
memcmp(cx.as_ptr() as *const c_void, ct.as_ptr() as *const c_void, len as usize) memcmp(cx.as_ptr() as *const c_void, ct.as_ptr() as *const c_void, len as usize)
}; };
Ok(Some(Into::into(result))) Ok(Some(Into::into(result)))
} }

View File

@ -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> { fn test_finalize(res: Result<GasLeft, vm::Error>) -> Result<U256, vm::Error> {
match res { match res {
Ok(GasLeft::Known(gas)) => Ok(gas), Ok(GasLeft::Known(gas)) => Ok(gas),
@ -491,6 +519,36 @@ fn keccak() {
assert_eq!(gas_left, U256::from(81_067)); assert_eq!(gas_left, U256::from(81_067));
} }
// memcmp test.
#[test]
fn memcmp() {
::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. // memcpy test.
#[test] #[test]
fn memcpy() { fn memcpy() {
@ -580,34 +638,6 @@ fn memset() {
assert_eq!(gas_left, U256::from(71_921)); 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 // math_* tests check the ability of wasm contract to perform big integer operations
// - addition // - addition
// - multiplication // - multiplication