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

Commit

Permalink
pwasm-std update (#7018)
Browse files Browse the repository at this point in the history
  • Loading branch information
pepyakin authored and debris committed Nov 13, 2017
1 parent 6ad5d55 commit 561e843
Show file tree
Hide file tree
Showing 6 changed files with 212 additions and 85 deletions.
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

0 comments on commit 561e843

Please sign in to comment.