mirror of
https://github.com/pezkuwichain/wasm-instrument.git
synced 2026-06-12 08:51:05 +00:00
tabify all
This commit is contained in:
+13
-13
@@ -2,26 +2,26 @@ use parity_wasm::interpreter::{self, ModuleInstance};
|
||||
use runtime::Runtime;
|
||||
|
||||
pub struct Arena {
|
||||
pub runtime: Runtime,
|
||||
pub runtime: Runtime,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Error;
|
||||
|
||||
impl Arena {
|
||||
pub fn alloc(&self, size: u32) -> Result<u32, Error> {
|
||||
// todo: maybe use unsafe cell since it has nothing to do with threads
|
||||
let previous_top = self.runtime.env().dynamic_top.get();
|
||||
self.runtime.env().dynamic_top.set(previous_top + size);
|
||||
Ok(previous_top)
|
||||
}
|
||||
pub fn alloc(&self, size: u32) -> Result<u32, Error> {
|
||||
// todo: maybe use unsafe cell since it has nothing to do with threads
|
||||
let previous_top = self.runtime.env().dynamic_top.get();
|
||||
self.runtime.env().dynamic_top.set(previous_top + size);
|
||||
Ok(previous_top)
|
||||
}
|
||||
}
|
||||
|
||||
impl interpreter::UserFunctionInterface for Arena {
|
||||
fn call(&mut self, _module: &ModuleInstance, context: interpreter::CallerContext) -> Result<Option<interpreter::RuntimeValue>, interpreter::Error> {
|
||||
let amount = context.value_stack.pop_as::<i32>()?;
|
||||
self.alloc(amount as u32)
|
||||
.map(|val| Some((val as i32).into()))
|
||||
.map_err(|e| interpreter::Error::Trap(format!("Allocator failure: {}", "todo: format arg")))
|
||||
}
|
||||
fn call(&mut self, _module: &ModuleInstance, context: interpreter::CallerContext) -> Result<Option<interpreter::RuntimeValue>, interpreter::Error> {
|
||||
let amount = context.value_stack.pop_as::<i32>()?;
|
||||
self.alloc(amount as u32)
|
||||
.map(|val| Some((val as i32).into()))
|
||||
.map_err(|e| interpreter::Error::Trap(format!("Allocator failure: {}", "todo: format arg")))
|
||||
}
|
||||
}
|
||||
@@ -4,66 +4,66 @@ use runtime;
|
||||
use WasmMemoryPtr;
|
||||
|
||||
fn write_u32(dst: &mut [u8], val: u32) {
|
||||
dst[0] = (val & 0x000000ff) as u8;
|
||||
dst[1] = ((val & 0x0000ff00) >> 8) as u8;
|
||||
dst[2] = ((val & 0x00ff0000) >> 16) as u8;
|
||||
dst[3] = ((val & 0xff000000) >> 24) as u8;
|
||||
dst[0] = (val & 0x000000ff) as u8;
|
||||
dst[1] = ((val & 0x0000ff00) >> 8) as u8;
|
||||
dst[2] = ((val & 0x00ff0000) >> 16) as u8;
|
||||
dst[3] = ((val & 0xff000000) >> 24) as u8;
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum Error {
|
||||
Allocator(runtime::ErrorAlloc),
|
||||
Interpreter(interpreter::Error),
|
||||
Allocator(runtime::ErrorAlloc),
|
||||
Interpreter(interpreter::Error),
|
||||
}
|
||||
|
||||
impl From<runtime::ErrorAlloc> for Error {
|
||||
fn from(err: runtime::ErrorAlloc) -> Self {
|
||||
Error::Allocator(err)
|
||||
}
|
||||
fn from(err: runtime::ErrorAlloc) -> Self {
|
||||
Error::Allocator(err)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<interpreter::Error> for Error {
|
||||
fn from(err: interpreter::Error) -> Self {
|
||||
Error::Interpreter(err)
|
||||
}
|
||||
fn from(err: interpreter::Error) -> Self {
|
||||
Error::Interpreter(err)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn init(
|
||||
memory: &interpreter::MemoryInstance,
|
||||
runtime: &mut runtime::Runtime,
|
||||
input: &[u8],
|
||||
memory: &interpreter::MemoryInstance,
|
||||
runtime: &mut runtime::Runtime,
|
||||
input: &[u8],
|
||||
) -> Result<WasmMemoryPtr, Error> {
|
||||
let mut input_ptr_slc = [0u8; 4];
|
||||
let mut input_length = [0u8; 4];
|
||||
let mut input_ptr_slc = [0u8; 4];
|
||||
let mut input_length = [0u8; 4];
|
||||
|
||||
let descriptor_ptr = runtime.alloc(16)?;
|
||||
let descriptor_ptr = runtime.alloc(16)?;
|
||||
|
||||
println!("descriptor_ptr: {}", descriptor_ptr);
|
||||
println!("descriptor_ptr: {}", descriptor_ptr);
|
||||
|
||||
if input.len() > 0 {
|
||||
let input_ptr = runtime.alloc(input.len() as u32)?;
|
||||
write_u32(&mut input_ptr_slc, input_ptr);
|
||||
write_u32(&mut input_length, input.len() as u32);
|
||||
memory.set(input_ptr, input)?;
|
||||
println!("input_ptr: {}", input_ptr);
|
||||
} else {
|
||||
write_u32(&mut input_ptr_slc, 0);
|
||||
write_u32(&mut input_length, 0);
|
||||
}
|
||||
if input.len() > 0 {
|
||||
let input_ptr = runtime.alloc(input.len() as u32)?;
|
||||
write_u32(&mut input_ptr_slc, input_ptr);
|
||||
write_u32(&mut input_length, input.len() as u32);
|
||||
memory.set(input_ptr, input)?;
|
||||
println!("input_ptr: {}", input_ptr);
|
||||
} else {
|
||||
write_u32(&mut input_ptr_slc, 0);
|
||||
write_u32(&mut input_length, 0);
|
||||
}
|
||||
|
||||
memory.set(descriptor_ptr, &input_ptr_slc)?;
|
||||
memory.set(descriptor_ptr+4, &input_length)?;
|
||||
memory.set(descriptor_ptr, &input_ptr_slc)?;
|
||||
memory.set(descriptor_ptr+4, &input_length)?;
|
||||
|
||||
// zero result ptr/len
|
||||
memory.set(descriptor_ptr+8, &[0u8; 4])?;
|
||||
memory.set(descriptor_ptr+12, &[0u8; 4])?;
|
||||
// zero result ptr/len
|
||||
memory.set(descriptor_ptr+8, &[0u8; 4])?;
|
||||
memory.set(descriptor_ptr+12, &[0u8; 4])?;
|
||||
|
||||
println!("descriptor: {:?}", memory.get(descriptor_ptr, 16));
|
||||
println!("descriptor: {:?}", memory.get(descriptor_ptr, 16));
|
||||
|
||||
Ok(descriptor_ptr as i32)
|
||||
Ok(descriptor_ptr as i32)
|
||||
}
|
||||
|
||||
fn _read_u32(slc: &[u8]) -> u32 {
|
||||
use std::ops::Shl;
|
||||
(slc[0] as u32) + (slc[1] as u32).shl(8) + (slc[2] as u32).shl(16) + (slc[3] as u32).shl(24)
|
||||
use std::ops::Shl;
|
||||
(slc[0] as u32) + (slc[1] as u32).shl(8) + (slc[2] as u32).shl(16) + (slc[3] as u32).shl(24)
|
||||
}
|
||||
+59
-59
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
|
||||
Rust contract demo runner
|
||||
Rust contract demo runner
|
||||
|
||||
*/
|
||||
|
||||
@@ -19,81 +19,81 @@ pub const DEFAULT_MEMORY_INDEX: interpreter::ItemIndex = interpreter::ItemIndex:
|
||||
pub type WasmMemoryPtr = i32;
|
||||
|
||||
fn main() {
|
||||
// First, load wasm contract as a module
|
||||
wasm_utils::init_log();
|
||||
// First, load wasm contract as a module
|
||||
wasm_utils::init_log();
|
||||
|
||||
let args = env::args().collect::<Vec<_>>();
|
||||
if args.len() != 2 {
|
||||
println!("Usage: {} contract.wasm", args[0]);
|
||||
return;
|
||||
}
|
||||
let args = env::args().collect::<Vec<_>>();
|
||||
if args.len() != 2 {
|
||||
println!("Usage: {} contract.wasm", args[0]);
|
||||
return;
|
||||
}
|
||||
|
||||
let module = parity_wasm::deserialize_file(&args[1]).expect("Module deserialization to succeed");
|
||||
let module = parity_wasm::deserialize_file(&args[1]).expect("Module deserialization to succeed");
|
||||
|
||||
let program = parity_wasm::interpreter::ProgramInstance::new()
|
||||
.expect("Program instance to be created");
|
||||
let program = parity_wasm::interpreter::ProgramInstance::new()
|
||||
.expect("Program instance to be created");
|
||||
|
||||
// Add module to the programm
|
||||
let module_instance = program.add_module("contract", module).expect("Module to be added successfully");
|
||||
// Add module to the programm
|
||||
let module_instance = program.add_module("contract", module).expect("Module to be added successfully");
|
||||
|
||||
{
|
||||
let env_instance = program.module("env").expect("env module to exist");
|
||||
let env_memory = env_instance.memory(interpreter::ItemIndex::Internal(0))
|
||||
.expect("liner memory to exist");
|
||||
let env_instance = program.module("env").expect("env module to exist");
|
||||
let env_memory = env_instance.memory(interpreter::ItemIndex::Internal(0))
|
||||
.expect("liner memory to exist");
|
||||
|
||||
// Second, create runtime and program instance
|
||||
let mut runtime = runtime::Runtime::with_params(
|
||||
env_memory.clone(), // memory shared ptr
|
||||
5*1024*1024, // default stack space
|
||||
65536, // runner arbitrary gas limit
|
||||
);
|
||||
// Second, create runtime and program instance
|
||||
let mut runtime = runtime::Runtime::with_params(
|
||||
env_memory.clone(), // memory shared ptr
|
||||
5*1024*1024, // default stack space
|
||||
65536, // runner arbitrary gas limit
|
||||
);
|
||||
|
||||
// Initialize call descriptor
|
||||
let descriptor = call_args::init(
|
||||
&*env_memory,
|
||||
&mut runtime,
|
||||
&[3u8; 128],
|
||||
).expect("call descriptor initialization to succeed");
|
||||
// Initialize call descriptor
|
||||
let descriptor = call_args::init(
|
||||
&*env_memory,
|
||||
&mut runtime,
|
||||
&[3u8; 128],
|
||||
).expect("call descriptor initialization to succeed");
|
||||
|
||||
// create native env module with native add && sub implementations
|
||||
let functions = interpreter::UserFunctions {
|
||||
executor: &mut runtime,
|
||||
functions: vec![
|
||||
interpreter::UserFunction {
|
||||
name: "_storage_read".to_owned(),
|
||||
params: vec![elements::ValueType::I32, elements::ValueType::I32],
|
||||
result: Some(elements::ValueType::I32),
|
||||
},
|
||||
interpreter::UserFunction {
|
||||
name: "_storage_write".to_owned(),
|
||||
params: vec![elements::ValueType::I32, elements::ValueType::I32],
|
||||
result: Some(elements::ValueType::I32),
|
||||
},
|
||||
interpreter::UserFunction {
|
||||
name: "_malloc".to_owned(),
|
||||
params: vec![elements::ValueType::I32],
|
||||
result: Some(elements::ValueType::I32),
|
||||
},
|
||||
interpreter::UserFunction {
|
||||
name: "gas".to_owned(),
|
||||
params: vec![elements::ValueType::I32],
|
||||
result: None,
|
||||
},
|
||||
interpreter::UserFunction {
|
||||
name: "_free".to_owned(),
|
||||
params: vec![elements::ValueType::I32],
|
||||
result: None,
|
||||
},
|
||||
interpreter::UserFunction {
|
||||
name: "_storage_read".to_owned(),
|
||||
params: vec![elements::ValueType::I32, elements::ValueType::I32],
|
||||
result: Some(elements::ValueType::I32),
|
||||
},
|
||||
interpreter::UserFunction {
|
||||
name: "_storage_write".to_owned(),
|
||||
params: vec![elements::ValueType::I32, elements::ValueType::I32],
|
||||
result: Some(elements::ValueType::I32),
|
||||
},
|
||||
interpreter::UserFunction {
|
||||
name: "_malloc".to_owned(),
|
||||
params: vec![elements::ValueType::I32],
|
||||
result: Some(elements::ValueType::I32),
|
||||
},
|
||||
interpreter::UserFunction {
|
||||
name: "gas".to_owned(),
|
||||
params: vec![elements::ValueType::I32],
|
||||
result: None,
|
||||
},
|
||||
interpreter::UserFunction {
|
||||
name: "_free".to_owned(),
|
||||
params: vec![elements::ValueType::I32],
|
||||
result: None,
|
||||
},
|
||||
],
|
||||
};
|
||||
let native_env_instance = Arc::new(interpreter::env_native_module(env_instance, functions).unwrap());
|
||||
|
||||
// Form ExecutionParams (payload + env link)
|
||||
// Form ExecutionParams (payload + env link)
|
||||
let params = interpreter::ExecutionParams::with_external("env".into(), native_env_instance)
|
||||
.add_argument(interpreter::RuntimeValue::I32(descriptor));
|
||||
.add_argument(interpreter::RuntimeValue::I32(descriptor));
|
||||
|
||||
module_instance.execute_export("_call", params)
|
||||
.expect("_call to execute successfully")
|
||||
.expect("_call function to return result ptr");
|
||||
}
|
||||
module_instance.execute_export("_call", params)
|
||||
.expect("_call to execute successfully")
|
||||
.expect("_call function to return result ptr");
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user