[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:
parent
ad14e656f6
commit
d927320719
1
Cargo.lock
generated
1
Cargo.lock
generated
@ -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",
|
||||||
|
@ -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,
|
||||||
|
@ -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" }
|
||||||
|
@ -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],
|
||||||
|
@ -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;
|
||||||
|
@ -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)
|
||||||
},
|
},
|
||||||
|
Loading…
Reference in New Issue
Block a user