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

WASM tests update #7018

Merged
merged 1 commit into from
Nov 12, 2017
Merged
Show file tree
Hide file tree
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
8 changes: 4 additions & 4 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion ethcore/res/wasm-tests
14 changes: 7 additions & 7 deletions ethcore/vm/src/schedule.rs
Original file line number Diff line number Diff line change
Expand Up @@ -127,12 +127,14 @@ pub struct WasmCosts {
pub mul: u32,
/// Memory (load/store) operations multiplier.
pub mem: u32,
/// Memory copy operation.
/// Memory copy operation, per byte.
pub mem_copy: u32,
/// Memory move operation, per byte.
pub mem_move: u32,
/// Memory set operation, per byte.
pub mem_set: u32,
/// Static region charge, per byte.
pub static_region: u32,
/// General static query of u64 value from env-info
pub static_u64: u32,
/// General static query of U256 value from env-info
pub static_u256: u32,
/// General static query of Address value from env-info
Expand All @@ -147,11 +149,9 @@ impl Default for WasmCosts {
mul: 4,
mem: 2,
mem_copy: 1,
mem_move: 1,
mem_set: 1,
static_region: 1,

// due to runtime issues, this can be slow
static_u64: 32,

static_u256: 64,
static_address: 40,
}
Expand Down
29 changes: 22 additions & 7 deletions ethcore/wasm/src/env.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,12 +38,12 @@ pub const SIGNATURES: &'static [UserFunctionDescriptor] = &[
None,
),
Static(
"_malloc",
"_ext_malloc",
&[I32],
Some(I32),
),
Static(
"_free",
"_ext_free",
&[I32],
None,
),
Expand Down Expand Up @@ -92,14 +92,29 @@ pub const SIGNATURES: &'static [UserFunctionDescriptor] = &[
&[I32; 3],
Some(I32),
),
Static(
"_ext_memcpy",
&[I32; 3],
Some(I32),
),
Static(
"_ext_memset",
&[I32; 3],
Some(I32),
),
Static(
"_ext_memmove",
&[I32; 3],
Some(I32),
),
Static(
"_panic",
&[I32; 2],
None,
),
Static(
"_blockhash",
&[I32; 3],
&[I64, I32],
Some(I32),
),
Static(
Expand Down Expand Up @@ -130,12 +145,12 @@ pub const SIGNATURES: &'static [UserFunctionDescriptor] = &[
Static(
"_timestamp",
&[],
Some(I32),
Some(I64),
),
Static(
"_blocknumber",
&[],
Some(I32),
Some(I64),
),
Static(
"_difficulty",
Expand All @@ -162,8 +177,8 @@ pub const SIGNATURES: &'static [UserFunctionDescriptor] = &[

Static(
"_llvm_bswap_i64",
&[I32; 2],
Some(I32)
&[I64],
Some(I64)
),
];

Expand Down
102 changes: 62 additions & 40 deletions ethcore/wasm/src/runtime.rs
Original file line number Diff line number Diff line change
Expand Up @@ -560,32 +560,67 @@ impl<'a, 'b> Runtime<'a, 'b> {
fn mem_copy(&mut self, context: InterpreterCallerContext)
-> Result<Option<interpreter::RuntimeValue>, InterpreterError>
{
//
// method signature:
// fn memcpy(dest: *const u8, src: *const u8, len: u32) -> *mut u8;
//

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

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

let mem = self.memory().get(src, len as usize)?;
self.memory().set(dst, &mem)?;
self.memory().copy_nonoverlapping(src as usize, dst as usize, len as usize)?;

Ok(Some(0i32.into()))
Ok(Some(Into::into(dst as i32)))
}

fn bswap_32(x: u32) -> u32 {
x >> 24 | x >> 8 & 0xff00 | x << 8 & 0xff0000 | x << 24
fn mem_move(&mut self, context: InterpreterCallerContext)
-> Result<Option<interpreter::RuntimeValue>, InterpreterError>
{
//
// method signature:
// fn memmove(dest: *const u8, src: *const u8, len: u32) -> *mut u8;
//

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

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

self.memory().copy(src as usize, dst as usize, len as usize)?;

Ok(Some(Into::into(dst as i32)))
}

fn bitswap_i64(&mut self, context: InterpreterCallerContext)
fn mem_set(&mut self, context: InterpreterCallerContext)
-> Result<Option<interpreter::RuntimeValue>, InterpreterError>
{
let x1 = context.value_stack.pop_as::<i32>()?;
let x2 = context.value_stack.pop_as::<i32>()?;
//
// method signature:
// fn memset(dest: *const u8, c: u32, len: u32) -> *mut u8;
//

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

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

self.memory().clear(dst as usize, c as u8, len as usize)?;

let result = ((Runtime::bswap_32(x2 as u32) as u64) << 32
| Runtime::bswap_32(x1 as u32) as u64) as i64;
Ok(Some(Into::into(dst as i32)))
}

fn bitswap_i64(&mut self, context: InterpreterCallerContext)
-> Result<Option<interpreter::RuntimeValue>, InterpreterError>
{
let x = context.value_stack.pop_as::<i64>()?;
let result = x.swap_bytes();

self.return_i64(result)
Ok(Some(result.into()))
}

fn user_panic(&mut self, context: InterpreterCallerContext)
Expand All @@ -606,13 +641,10 @@ impl<'a, 'b> Runtime<'a, 'b> {
-> Result<Option<interpreter::RuntimeValue>, InterpreterError>
{
let return_ptr = context.value_stack.pop_as::<i32>()? as u32;
let block_hi = context.value_stack.pop_as::<i32>()? as u32;
let block_lo = context.value_stack.pop_as::<i32>()? as u32;
let block_num = context.value_stack.pop_as::<i64>()? as u64;

self.charge(|schedule| schedule.blockhash_gas as u64)?;

let block_num = (block_hi as u64) << 32 | block_lo as u64;

trace!("Requesting block hash for block #{}", block_num);
let hash = self.ext.blockhash(&U256::from(block_num));

Expand Down Expand Up @@ -694,14 +726,14 @@ impl<'a, 'b> Runtime<'a, 'b> {
-> Result<Option<interpreter::RuntimeValue>, InterpreterError>
{
let timestamp = self.ext.env_info().timestamp as i64;
self.return_i64(timestamp)
Ok(Some(timestamp.into()))
}

fn block_number(&mut self, _context: InterpreterCallerContext)
-> Result<Option<interpreter::RuntimeValue>, InterpreterError>
{
let block_number: u64 = self.ext.env_info().number.into();
self.return_i64(block_number as i64)
let block_number = self.ext.env_info().number as i64;
Ok(Some(block_number.into()))
}

fn difficulty(&mut self, context: InterpreterCallerContext)
Expand All @@ -726,25 +758,6 @@ impl<'a, 'b> Runtime<'a, 'b> {
Ok(None)
}

fn return_i64(&mut self, val: i64) -> Result<Option<interpreter::RuntimeValue>, InterpreterError> {
self.charge(|schedule| schedule.wasm.static_u64 as u64)?;

let uval = val as u64;
let hi = (uval >> 32) as i32;
let lo = (uval << 32 >> 32) as i32;

let target = self.instance.module("contract").ok_or(UserTrap::Other)?;
target.execute_export(
"setTempRet0",
self.execution_params().add_argument(
interpreter::RuntimeValue::I32(hi).into()
),
)?;
Ok(Some(
(lo).into()
))
}

pub fn execution_params(&mut self) -> interpreter::ExecutionParams<UserTrap> {
use super::env;

Expand Down Expand Up @@ -812,10 +825,10 @@ impl<'a, 'b> interpreter::UserFunctionExecutor<UserTrap> for Runtime<'a, 'b> {
-> Result<Option<interpreter::RuntimeValue>, InterpreterError>
{
match name {
"_malloc" => {
"_ext_malloc" => {
self.malloc(context)
},
"_free" => {
"_ext_free" => {
// Since it is arena allocator, free does nothing
// todo: update if changed
self.user_noop(context)
Expand Down Expand Up @@ -853,6 +866,15 @@ impl<'a, 'b> interpreter::UserFunctionExecutor<UserTrap> for Runtime<'a, 'b> {
"_emscripten_memcpy_big" => {
self.mem_copy(context)
},
"_ext_memcpy" => {
self.mem_copy(context)
},
"_ext_memmove" => {
self.mem_move(context)
},
"_ext_memset" => {
self.mem_set(context)
},
"_llvm_bswap_i64" => {
self.bitswap_i64(context)
},
Expand Down
Loading