[WASM] mem_cmp added to the Wasm runtime (#7539)

* mem_cmp added to the Wasm runtime

* schedule.wasm.mem_copy to schedule.wasm.mem_cmp for mem_cmp
This commit is contained in:
Alexey 2018-01-15 17:24:24 +03:00 committed by Nikolay Volf
parent ad14e656f6
commit d927320719
6 changed files with 37 additions and 0 deletions

1
Cargo.lock generated
View File

@ -3514,6 +3514,7 @@ dependencies = [
"byteorder 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "byteorder 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"ethcore-logger 1.9.0", "ethcore-logger 1.9.0",
"ethereum-types 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", "ethereum-types 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.31 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
"parity-wasm 0.15.3 (registry+https://github.com/rust-lang/crates.io-index)", "parity-wasm 0.15.3 (registry+https://github.com/rust-lang/crates.io-index)",
"vm 0.1.0", "vm 0.1.0",

View File

@ -128,6 +128,8 @@ pub struct WasmCosts {
/// Memory (load/store) operations multiplier. /// Memory (load/store) operations multiplier.
pub mem: u32, pub mem: u32,
/// Memory copy operation, per byte. /// Memory copy operation, per byte.
pub mem_cmp: u32,
/// Memory copy operation, per byte.
pub mem_copy: u32, pub mem_copy: u32,
/// Memory move operation, per byte. /// Memory move operation, per byte.
pub mem_move: u32, pub mem_move: u32,
@ -148,6 +150,7 @@ impl Default for WasmCosts {
div: 16, div: 16,
mul: 4, mul: 4,
mem: 2, mem: 2,
mem_cmp: 1,
mem_copy: 1, mem_copy: 1,
mem_move: 1, mem_move: 1,
mem_set: 1, mem_set: 1,

View File

@ -8,6 +8,7 @@ byteorder = "1.0"
ethereum-types = "0.1" ethereum-types = "0.1"
log = "0.3" log = "0.3"
parity-wasm = "0.15" parity-wasm = "0.15"
libc = "0.2"
wasm-utils = { git = "https://github.com/paritytech/wasm-utils" } wasm-utils = { git = "https://github.com/paritytech/wasm-utils" }
vm = { path = "../vm" } vm = { path = "../vm" }
ethcore-logger = { path = "../../logger" } ethcore-logger = { path = "../../logger" }

View File

@ -92,6 +92,11 @@ pub const SIGNATURES: &'static [UserFunctionDescriptor] = &[
&[I32; 3], &[I32; 3],
Some(I32), Some(I32),
), ),
Static(
"_ext_memcmp",
&[I32; 3],
Some(I32),
),
Static( Static(
"_ext_memcpy", "_ext_memcpy",
&[I32; 3], &[I32; 3],

View File

@ -22,6 +22,7 @@ extern crate ethereum_types;
extern crate ethcore_logger; extern crate ethcore_logger;
extern crate byteorder; extern crate byteorder;
extern crate parity_wasm; extern crate parity_wasm;
extern crate libc;
extern crate wasm_utils; extern crate wasm_utils;
mod runtime; mod runtime;

View File

@ -19,6 +19,7 @@
use std::sync::Arc; use std::sync::Arc;
use byteorder::{LittleEndian, ByteOrder}; use byteorder::{LittleEndian, ByteOrder};
use libc::{memcmp, c_void};
use vm; use vm;
use panic_payload; use panic_payload;
@ -567,6 +568,28 @@ impl<'a, 'b> Runtime<'a, 'b> {
&*self.memory &*self.memory
} }
fn mem_cmp(&mut self, context: InterpreterCallerContext)
-> Result<Option<interpreter::RuntimeValue>, InterpreterError>
{
//
// method signature:
// fn memcmp(cx: *const u8, ct: *const u8, n: usize) -> i32;
//
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;
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 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)))
}
fn mem_copy(&mut self, context: InterpreterCallerContext) fn mem_copy(&mut self, context: InterpreterCallerContext)
-> Result<Option<interpreter::RuntimeValue>, InterpreterError> -> Result<Option<interpreter::RuntimeValue>, InterpreterError>
{ {
@ -890,6 +913,9 @@ impl<'a, 'b> interpreter::UserFunctionExecutor<UserTrap> for Runtime<'a, 'b> {
"_emscripten_memcpy_big" => { "_emscripten_memcpy_big" => {
self.mem_copy(context) self.mem_copy(context)
}, },
"_ext_memcmp" => {
self.mem_cmp(context)
},
"_ext_memcpy" => { "_ext_memcpy" => {
self.mem_copy(context) self.mem_copy(context)
}, },