From 0c4c1b4e9ba4410da136a3b4ea747bb513140c27 Mon Sep 17 00:00:00 2001 From: fro Date: Thu, 11 Jan 2018 20:39:42 +0300 Subject: [PATCH 1/3] mem_cmp added to the Wasm runtime --- Cargo.lock | 1 + ethcore/vm/src/schedule.rs | 3 +++ ethcore/wasm/Cargo.toml | 1 + ethcore/wasm/src/env.rs | 5 +++++ ethcore/wasm/src/lib.rs | 1 + ethcore/wasm/src/runtime.rs | 26 ++++++++++++++++++++++++++ 6 files changed, 37 insertions(+) diff --git a/Cargo.lock b/Cargo.lock index adf79b076b8..adbb306fa93 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3480,6 +3480,7 @@ dependencies = [ "byteorder 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "ethcore-logger 1.9.0", "ethereum-types 0.1.3 (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)", "parity-wasm 0.15.3 (registry+https://github.com/rust-lang/crates.io-index)", "vm 0.1.0", diff --git a/ethcore/vm/src/schedule.rs b/ethcore/vm/src/schedule.rs index e250bfa1cec..53e585d3770 100644 --- a/ethcore/vm/src/schedule.rs +++ b/ethcore/vm/src/schedule.rs @@ -128,6 +128,8 @@ pub struct WasmCosts { /// Memory (load/store) operations multiplier. pub mem: u32, /// Memory copy operation, per byte. + pub mem_cmp: u32, + /// Memory copy operation, per byte. pub mem_copy: u32, /// Memory move operation, per byte. pub mem_move: u32, @@ -148,6 +150,7 @@ impl Default for WasmCosts { div: 16, mul: 4, mem: 2, + mem_cmp: 1, mem_copy: 1, mem_move: 1, mem_set: 1, diff --git a/ethcore/wasm/Cargo.toml b/ethcore/wasm/Cargo.toml index 19f6ebc0dae..2b790e0991c 100644 --- a/ethcore/wasm/Cargo.toml +++ b/ethcore/wasm/Cargo.toml @@ -8,6 +8,7 @@ byteorder = "1.0" ethereum-types = "0.1" log = "0.3" parity-wasm = "0.15" +libc = "0.2" wasm-utils = { git = "https://github.com/paritytech/wasm-utils" } vm = { path = "../vm" } ethcore-logger = { path = "../../logger" } diff --git a/ethcore/wasm/src/env.rs b/ethcore/wasm/src/env.rs index cae6738582a..27c7c93a946 100644 --- a/ethcore/wasm/src/env.rs +++ b/ethcore/wasm/src/env.rs @@ -92,6 +92,11 @@ pub const SIGNATURES: &'static [UserFunctionDescriptor] = &[ &[I32; 3], Some(I32), ), + Static( + "_ext_memcmp", + &[I32; 3], + Some(I32), + ), Static( "_ext_memcpy", &[I32; 3], diff --git a/ethcore/wasm/src/lib.rs b/ethcore/wasm/src/lib.rs index bd56dd298dd..241004c6a58 100644 --- a/ethcore/wasm/src/lib.rs +++ b/ethcore/wasm/src/lib.rs @@ -22,6 +22,7 @@ extern crate ethereum_types; extern crate ethcore_logger; extern crate byteorder; extern crate parity_wasm; +extern crate libc; extern crate wasm_utils; mod runtime; diff --git a/ethcore/wasm/src/runtime.rs b/ethcore/wasm/src/runtime.rs index 7071f994429..0ccdb1d98c5 100644 --- a/ethcore/wasm/src/runtime.rs +++ b/ethcore/wasm/src/runtime.rs @@ -19,6 +19,7 @@ use std::sync::Arc; use byteorder::{LittleEndian, ByteOrder}; +use libc::{memcmp, c_void}; use vm; use panic_payload; @@ -567,6 +568,28 @@ impl<'a, 'b> Runtime<'a, 'b> { &*self.memory } + fn mem_cmp(&mut self, context: InterpreterCallerContext) + -> Result, InterpreterError> + { + // + // method signature: + // fn memcmp(cx: *const c_void, ct: *const c_void, n: usize) -> i32; + // + + let len = context.value_stack.pop_as::()? as u32; + let cx = context.value_stack.pop_as::()? as u32; + let ct = context.value_stack.pop_as::()? as u32; + + self.charge(|schedule| schedule.wasm.mem_copy as u64 * len as u64)?; // TODO: charge cmp + + 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) -> Result, InterpreterError> { @@ -890,6 +913,9 @@ impl<'a, 'b> interpreter::UserFunctionExecutor for Runtime<'a, 'b> { "_emscripten_memcpy_big" => { self.mem_copy(context) }, + "_ext_memcmp" => { + self.mem_cmp(context) + }, "_ext_memcpy" => { self.mem_copy(context) }, From ae6bb909e0c2a204eb98845d2e9ed933c11f3a4f Mon Sep 17 00:00:00 2001 From: fro Date: Fri, 12 Jan 2018 15:08:42 +0300 Subject: [PATCH 2/3] schedule.wasm.mem_copy to schedule.wasm.mem_cmp for mem_cmp --- ethcore/wasm/src/runtime.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ethcore/wasm/src/runtime.rs b/ethcore/wasm/src/runtime.rs index 0ccdb1d98c5..f72b47cf913 100644 --- a/ethcore/wasm/src/runtime.rs +++ b/ethcore/wasm/src/runtime.rs @@ -580,7 +580,7 @@ impl<'a, 'b> Runtime<'a, 'b> { let cx = context.value_stack.pop_as::()? as u32; let ct = context.value_stack.pop_as::()? as u32; - self.charge(|schedule| schedule.wasm.mem_copy as u64 * len as u64)?; // TODO: charge cmp + 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)?; From 7bbddf67910a62eaa5ea97e105f0d639d2f504ab Mon Sep 17 00:00:00 2001 From: fro Date: Mon, 15 Jan 2018 17:14:50 +0300 Subject: [PATCH 3/3] Cargo.lock conflict fix, fix comment --- Cargo.lock | 1 + ethcore/wasm/src/runtime.rs | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/Cargo.lock b/Cargo.lock index 461dbd5f494..d568f38bff5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3514,6 +3514,7 @@ dependencies = [ "byteorder 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "ethcore-logger 1.9.0", "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)", "parity-wasm 0.15.3 (registry+https://github.com/rust-lang/crates.io-index)", "vm 0.1.0", diff --git a/ethcore/wasm/src/runtime.rs b/ethcore/wasm/src/runtime.rs index f72b47cf913..5b968953750 100644 --- a/ethcore/wasm/src/runtime.rs +++ b/ethcore/wasm/src/runtime.rs @@ -573,7 +573,7 @@ impl<'a, 'b> Runtime<'a, 'b> { { // // method signature: - // fn memcmp(cx: *const c_void, ct: *const c_void, n: usize) -> i32; + // fn memcmp(cx: *const u8, ct: *const u8, n: usize) -> i32; // let len = context.value_stack.pop_as::()? as u32;