mirror of
https://github.com/fluencelabs/wasm-utils
synced 2025-05-16 17:21:23 +00:00
convert to tabs
This commit is contained in:
parent
b81573d2b8
commit
a2922a6fb0
@ -12,154 +12,154 @@ pub struct StorageValue([u8; 32]);
|
||||
struct ErrorStorage;
|
||||
|
||||
impl StorageKey {
|
||||
// todo: deal with memory views
|
||||
fn from_mem(vec: Vec<u8>) -> Result<Self, ErrorStorage> {
|
||||
if vec.len() != 32 { return Err(ErrorStorage); }
|
||||
let mut result = StorageKey([0u8; 32]);
|
||||
result.0.copy_from_slice(&vec[0..32]);
|
||||
Ok(result)
|
||||
}
|
||||
// todo: deal with memory views
|
||||
fn from_mem(vec: Vec<u8>) -> Result<Self, ErrorStorage> {
|
||||
if vec.len() != 32 { return Err(ErrorStorage); }
|
||||
let mut result = StorageKey([0u8; 32]);
|
||||
result.0.copy_from_slice(&vec[0..32]);
|
||||
Ok(result)
|
||||
}
|
||||
}
|
||||
|
||||
impl StorageValue {
|
||||
// todo: deal with memory views
|
||||
// todo: deal with variable-length values when it comes
|
||||
fn from_mem(vec: Vec<u8>) -> Result<Self, ErrorStorage> {
|
||||
if vec.len() != 32 { return Err(ErrorStorage); }
|
||||
let mut result = StorageValue([0u8; 32]);
|
||||
result.0.copy_from_slice(&vec[0..32]);
|
||||
Ok(result)
|
||||
}
|
||||
// todo: deal with memory views
|
||||
// todo: deal with variable-length values when it comes
|
||||
fn from_mem(vec: Vec<u8>) -> Result<Self, ErrorStorage> {
|
||||
if vec.len() != 32 { return Err(ErrorStorage); }
|
||||
let mut result = StorageValue([0u8; 32]);
|
||||
result.0.copy_from_slice(&vec[0..32]);
|
||||
Ok(result)
|
||||
}
|
||||
|
||||
fn as_slice(&self) -> &[u8] {
|
||||
&self.0
|
||||
}
|
||||
fn as_slice(&self) -> &[u8] {
|
||||
&self.0
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Runtime {
|
||||
gas_counter: u64,
|
||||
gas_limit: u64,
|
||||
dynamic_top: u32,
|
||||
storage: HashMap<StorageKey, StorageValue>,
|
||||
memory: Arc<interpreter::MemoryInstance>,
|
||||
gas_counter: u64,
|
||||
gas_limit: u64,
|
||||
dynamic_top: u32,
|
||||
storage: HashMap<StorageKey, StorageValue>,
|
||||
memory: Arc<interpreter::MemoryInstance>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct ErrorAlloc;
|
||||
|
||||
impl Runtime {
|
||||
pub fn with_params(memory: Arc<interpreter::MemoryInstance>, stack_space: u32, gas_limit: u64) -> Runtime {
|
||||
Runtime {
|
||||
gas_counter: 0,
|
||||
gas_limit: gas_limit,
|
||||
dynamic_top: stack_space,
|
||||
storage: HashMap::new(),
|
||||
memory: memory,
|
||||
}
|
||||
}
|
||||
pub fn with_params(memory: Arc<interpreter::MemoryInstance>, stack_space: u32, gas_limit: u64) -> Runtime {
|
||||
Runtime {
|
||||
gas_counter: 0,
|
||||
gas_limit: gas_limit,
|
||||
dynamic_top: stack_space,
|
||||
storage: HashMap::new(),
|
||||
memory: memory,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn storage_write(&mut self, context: interpreter::CallerContext)
|
||||
-> Result<Option<interpreter::RuntimeValue>, interpreter::Error>
|
||||
{
|
||||
let val_ptr = context.value_stack.pop_as::<i32>()?;
|
||||
let key_ptr = context.value_stack.pop_as::<i32>()?;
|
||||
pub fn storage_write(&mut self, context: interpreter::CallerContext)
|
||||
-> Result<Option<interpreter::RuntimeValue>, interpreter::Error>
|
||||
{
|
||||
let val_ptr = context.value_stack.pop_as::<i32>()?;
|
||||
let key_ptr = context.value_stack.pop_as::<i32>()?;
|
||||
|
||||
let key = StorageKey::from_mem(self.memory.get(key_ptr as u32, 32)?)
|
||||
.map_err(|_| interpreter::Error::Trap("Memory access violation".to_owned()))?;
|
||||
let val = StorageValue::from_mem(self.memory.get(val_ptr as u32, 32)?)
|
||||
.map_err(|_| interpreter::Error::Trap("Memory access violation".to_owned()))?;
|
||||
let key = StorageKey::from_mem(self.memory.get(key_ptr as u32, 32)?)
|
||||
.map_err(|_| interpreter::Error::Trap("Memory access violation".to_owned()))?;
|
||||
let val = StorageValue::from_mem(self.memory.get(val_ptr as u32, 32)?)
|
||||
.map_err(|_| interpreter::Error::Trap("Memory access violation".to_owned()))?;
|
||||
|
||||
println!("write storage {:?} = {:?}", key, val);
|
||||
println!("write storage {:?} = {:?}", key, val);
|
||||
|
||||
self.storage.insert(key, val);
|
||||
self.storage.insert(key, val);
|
||||
|
||||
Ok(Some(0i32.into()))
|
||||
}
|
||||
Ok(Some(0i32.into()))
|
||||
}
|
||||
|
||||
pub fn storage_read(&mut self, context: interpreter::CallerContext)
|
||||
-> Result<Option<interpreter::RuntimeValue>, interpreter::Error>
|
||||
{
|
||||
// arguments passed are in backward order (since it is stack)
|
||||
let val_ptr = context.value_stack.pop_as::<i32>()?;
|
||||
let key_ptr = context.value_stack.pop_as::<i32>()?;
|
||||
pub fn storage_read(&mut self, context: interpreter::CallerContext)
|
||||
-> Result<Option<interpreter::RuntimeValue>, interpreter::Error>
|
||||
{
|
||||
// arguments passed are in backward order (since it is stack)
|
||||
let val_ptr = context.value_stack.pop_as::<i32>()?;
|
||||
let key_ptr = context.value_stack.pop_as::<i32>()?;
|
||||
|
||||
let key = StorageKey::from_mem(self.memory.get(key_ptr as u32, 32)?)
|
||||
.map_err(|_| interpreter::Error::Trap("Memory access violation".to_owned()))?;
|
||||
let empty = StorageValue([0u8; 32]);
|
||||
let val = self.storage.get(&key).unwrap_or(&empty);
|
||||
let key = StorageKey::from_mem(self.memory.get(key_ptr as u32, 32)?)
|
||||
.map_err(|_| interpreter::Error::Trap("Memory access violation".to_owned()))?;
|
||||
let empty = StorageValue([0u8; 32]);
|
||||
let val = self.storage.get(&key).unwrap_or(&empty);
|
||||
|
||||
self.memory.set(val_ptr as u32, val.as_slice())?;
|
||||
self.memory.set(val_ptr as u32, val.as_slice())?;
|
||||
|
||||
println!("read storage {:?} (evaluated as {:?})", key, val);
|
||||
println!("read storage {:?} (evaluated as {:?})", key, val);
|
||||
|
||||
Ok(Some(0.into()))
|
||||
}
|
||||
Ok(Some(0.into()))
|
||||
}
|
||||
|
||||
pub fn malloc(&mut self, context: interpreter::CallerContext)
|
||||
-> Result<Option<interpreter::RuntimeValue>, interpreter::Error>
|
||||
{
|
||||
let amount = context.value_stack.pop_as::<i32>()? as u32;
|
||||
let previous_top = self.dynamic_top;
|
||||
self.dynamic_top = previous_top + amount;
|
||||
Ok(Some((previous_top as i32).into()))
|
||||
}
|
||||
pub fn malloc(&mut self, context: interpreter::CallerContext)
|
||||
-> Result<Option<interpreter::RuntimeValue>, interpreter::Error>
|
||||
{
|
||||
let amount = context.value_stack.pop_as::<i32>()? as u32;
|
||||
let previous_top = self.dynamic_top;
|
||||
self.dynamic_top = previous_top + amount;
|
||||
Ok(Some((previous_top as i32).into()))
|
||||
}
|
||||
|
||||
pub fn alloc(&mut self, amount: u32) -> Result<u32, ErrorAlloc> {
|
||||
let previous_top = self.dynamic_top;
|
||||
self.dynamic_top = previous_top + amount;
|
||||
Ok(previous_top.into())
|
||||
}
|
||||
pub fn alloc(&mut self, amount: u32) -> Result<u32, ErrorAlloc> {
|
||||
let previous_top = self.dynamic_top;
|
||||
self.dynamic_top = previous_top + amount;
|
||||
Ok(previous_top.into())
|
||||
}
|
||||
|
||||
fn gas(&mut self, context: interpreter::CallerContext)
|
||||
-> Result<Option<interpreter::RuntimeValue>, interpreter::Error>
|
||||
{
|
||||
let prev = self.gas_counter;
|
||||
let update = context.value_stack.pop_as::<i32>()? as u64;
|
||||
if prev + update > self.gas_limit {
|
||||
// exceeds gas
|
||||
Err(interpreter::Error::Trap(format!("Gas exceeds limits of {}", self.gas_limit)))
|
||||
} else {
|
||||
self.gas_counter = prev + update;
|
||||
Ok(None)
|
||||
}
|
||||
}
|
||||
fn gas(&mut self, context: interpreter::CallerContext)
|
||||
-> Result<Option<interpreter::RuntimeValue>, interpreter::Error>
|
||||
{
|
||||
let prev = self.gas_counter;
|
||||
let update = context.value_stack.pop_as::<i32>()? as u64;
|
||||
if prev + update > self.gas_limit {
|
||||
// exceeds gas
|
||||
Err(interpreter::Error::Trap(format!("Gas exceeds limits of {}", self.gas_limit)))
|
||||
} else {
|
||||
self.gas_counter = prev + update;
|
||||
Ok(None)
|
||||
}
|
||||
}
|
||||
|
||||
fn user_trap(&mut self, _context: interpreter::CallerContext)
|
||||
-> Result<Option<interpreter::RuntimeValue>, interpreter::Error>
|
||||
{
|
||||
Err(interpreter::Error::Trap("unknown trap".to_owned()))
|
||||
}
|
||||
fn user_trap(&mut self, _context: interpreter::CallerContext)
|
||||
-> Result<Option<interpreter::RuntimeValue>, interpreter::Error>
|
||||
{
|
||||
Err(interpreter::Error::Trap("unknown trap".to_owned()))
|
||||
}
|
||||
|
||||
fn user_noop(&mut self,
|
||||
_context: interpreter::CallerContext
|
||||
) -> Result<Option<interpreter::RuntimeValue>, interpreter::Error> {
|
||||
Ok(None)
|
||||
}
|
||||
fn user_noop(&mut self,
|
||||
_context: interpreter::CallerContext
|
||||
) -> Result<Option<interpreter::RuntimeValue>, interpreter::Error> {
|
||||
Ok(None)
|
||||
}
|
||||
}
|
||||
|
||||
impl interpreter::UserFunctionExecutor for Runtime {
|
||||
fn execute(&mut self, name: &str, context: interpreter::CallerContext)
|
||||
-> Result<Option<interpreter::RuntimeValue>, interpreter::Error>
|
||||
{
|
||||
match name {
|
||||
"_malloc" => {
|
||||
self.malloc(context)
|
||||
},
|
||||
"_free" => {
|
||||
self.user_noop(context)
|
||||
},
|
||||
"_storage_read" => {
|
||||
self.storage_read(context)
|
||||
},
|
||||
"_storage_write" => {
|
||||
self.storage_write(context)
|
||||
},
|
||||
"gas" => {
|
||||
self.gas(context)
|
||||
},
|
||||
_ => {
|
||||
self.user_trap(context)
|
||||
}
|
||||
}
|
||||
}
|
||||
fn execute(&mut self, name: &str, context: interpreter::CallerContext)
|
||||
-> Result<Option<interpreter::RuntimeValue>, interpreter::Error>
|
||||
{
|
||||
match name {
|
||||
"_malloc" => {
|
||||
self.malloc(context)
|
||||
},
|
||||
"_free" => {
|
||||
self.user_noop(context)
|
||||
},
|
||||
"_storage_read" => {
|
||||
self.storage_read(context)
|
||||
},
|
||||
"_storage_write" => {
|
||||
self.storage_write(context)
|
||||
},
|
||||
"gas" => {
|
||||
self.gas(context)
|
||||
},
|
||||
_ => {
|
||||
self.user_trap(context)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user