convert to tabs

This commit is contained in:
NikVolf 2017-05-19 20:21:16 +03:00
parent b81573d2b8
commit a2922a6fb0

View File

@ -12,154 +12,154 @@ pub struct StorageValue([u8; 32]);
struct ErrorStorage; struct ErrorStorage;
impl StorageKey { impl StorageKey {
// todo: deal with memory views // todo: deal with memory views
fn from_mem(vec: Vec<u8>) -> Result<Self, ErrorStorage> { fn from_mem(vec: Vec<u8>) -> Result<Self, ErrorStorage> {
if vec.len() != 32 { return Err(ErrorStorage); } if vec.len() != 32 { return Err(ErrorStorage); }
let mut result = StorageKey([0u8; 32]); let mut result = StorageKey([0u8; 32]);
result.0.copy_from_slice(&vec[0..32]); result.0.copy_from_slice(&vec[0..32]);
Ok(result) Ok(result)
} }
} }
impl StorageValue { impl StorageValue {
// todo: deal with memory views // todo: deal with memory views
// todo: deal with variable-length values when it comes // todo: deal with variable-length values when it comes
fn from_mem(vec: Vec<u8>) -> Result<Self, ErrorStorage> { fn from_mem(vec: Vec<u8>) -> Result<Self, ErrorStorage> {
if vec.len() != 32 { return Err(ErrorStorage); } if vec.len() != 32 { return Err(ErrorStorage); }
let mut result = StorageValue([0u8; 32]); let mut result = StorageValue([0u8; 32]);
result.0.copy_from_slice(&vec[0..32]); result.0.copy_from_slice(&vec[0..32]);
Ok(result) Ok(result)
} }
fn as_slice(&self) -> &[u8] { fn as_slice(&self) -> &[u8] {
&self.0 &self.0
} }
} }
pub struct Runtime { pub struct Runtime {
gas_counter: u64, gas_counter: u64,
gas_limit: u64, gas_limit: u64,
dynamic_top: u32, dynamic_top: u32,
storage: HashMap<StorageKey, StorageValue>, storage: HashMap<StorageKey, StorageValue>,
memory: Arc<interpreter::MemoryInstance>, memory: Arc<interpreter::MemoryInstance>,
} }
#[derive(Debug)] #[derive(Debug)]
pub struct ErrorAlloc; pub struct ErrorAlloc;
impl Runtime { impl Runtime {
pub fn with_params(memory: Arc<interpreter::MemoryInstance>, stack_space: u32, gas_limit: u64) -> Runtime { pub fn with_params(memory: Arc<interpreter::MemoryInstance>, stack_space: u32, gas_limit: u64) -> Runtime {
Runtime { Runtime {
gas_counter: 0, gas_counter: 0,
gas_limit: gas_limit, gas_limit: gas_limit,
dynamic_top: stack_space, dynamic_top: stack_space,
storage: HashMap::new(), storage: HashMap::new(),
memory: memory, memory: memory,
} }
} }
pub fn storage_write(&mut self, context: interpreter::CallerContext) pub fn storage_write(&mut self, context: interpreter::CallerContext)
-> Result<Option<interpreter::RuntimeValue>, interpreter::Error> -> Result<Option<interpreter::RuntimeValue>, interpreter::Error>
{ {
let val_ptr = context.value_stack.pop_as::<i32>()?; let val_ptr = context.value_stack.pop_as::<i32>()?;
let key_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)?) let key = StorageKey::from_mem(self.memory.get(key_ptr as u32, 32)?)
.map_err(|_| interpreter::Error::Trap("Memory access violation".to_owned()))?; .map_err(|_| interpreter::Error::Trap("Memory access violation".to_owned()))?;
let val = StorageValue::from_mem(self.memory.get(val_ptr as u32, 32)?) let val = StorageValue::from_mem(self.memory.get(val_ptr as u32, 32)?)
.map_err(|_| interpreter::Error::Trap("Memory access violation".to_owned()))?; .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) pub fn storage_read(&mut self, context: interpreter::CallerContext)
-> Result<Option<interpreter::RuntimeValue>, interpreter::Error> -> Result<Option<interpreter::RuntimeValue>, interpreter::Error>
{ {
// arguments passed are in backward order (since it is stack) // arguments passed are in backward order (since it is stack)
let val_ptr = context.value_stack.pop_as::<i32>()?; let val_ptr = context.value_stack.pop_as::<i32>()?;
let key_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)?) let key = StorageKey::from_mem(self.memory.get(key_ptr as u32, 32)?)
.map_err(|_| interpreter::Error::Trap("Memory access violation".to_owned()))?; .map_err(|_| interpreter::Error::Trap("Memory access violation".to_owned()))?;
let empty = StorageValue([0u8; 32]); let empty = StorageValue([0u8; 32]);
let val = self.storage.get(&key).unwrap_or(&empty); 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) pub fn malloc(&mut self, context: interpreter::CallerContext)
-> Result<Option<interpreter::RuntimeValue>, interpreter::Error> -> Result<Option<interpreter::RuntimeValue>, interpreter::Error>
{ {
let amount = context.value_stack.pop_as::<i32>()? as u32; let amount = context.value_stack.pop_as::<i32>()? as u32;
let previous_top = self.dynamic_top; let previous_top = self.dynamic_top;
self.dynamic_top = previous_top + amount; self.dynamic_top = previous_top + amount;
Ok(Some((previous_top as i32).into())) Ok(Some((previous_top as i32).into()))
} }
pub fn alloc(&mut self, amount: u32) -> Result<u32, ErrorAlloc> { pub fn alloc(&mut self, amount: u32) -> Result<u32, ErrorAlloc> {
let previous_top = self.dynamic_top; let previous_top = self.dynamic_top;
self.dynamic_top = previous_top + amount; self.dynamic_top = previous_top + amount;
Ok(previous_top.into()) Ok(previous_top.into())
} }
fn gas(&mut self, context: interpreter::CallerContext) fn gas(&mut self, context: interpreter::CallerContext)
-> Result<Option<interpreter::RuntimeValue>, interpreter::Error> -> Result<Option<interpreter::RuntimeValue>, interpreter::Error>
{ {
let prev = self.gas_counter; let prev = self.gas_counter;
let update = context.value_stack.pop_as::<i32>()? as u64; let update = context.value_stack.pop_as::<i32>()? as u64;
if prev + update > self.gas_limit { if prev + update > self.gas_limit {
// exceeds gas // exceeds gas
Err(interpreter::Error::Trap(format!("Gas exceeds limits of {}", self.gas_limit))) Err(interpreter::Error::Trap(format!("Gas exceeds limits of {}", self.gas_limit)))
} else { } else {
self.gas_counter = prev + update; self.gas_counter = prev + update;
Ok(None) Ok(None)
} }
} }
fn user_trap(&mut self, _context: interpreter::CallerContext) fn user_trap(&mut self, _context: interpreter::CallerContext)
-> Result<Option<interpreter::RuntimeValue>, interpreter::Error> -> Result<Option<interpreter::RuntimeValue>, interpreter::Error>
{ {
Err(interpreter::Error::Trap("unknown trap".to_owned())) Err(interpreter::Error::Trap("unknown trap".to_owned()))
} }
fn user_noop(&mut self, fn user_noop(&mut self,
_context: interpreter::CallerContext _context: interpreter::CallerContext
) -> Result<Option<interpreter::RuntimeValue>, interpreter::Error> { ) -> Result<Option<interpreter::RuntimeValue>, interpreter::Error> {
Ok(None) Ok(None)
} }
} }
impl interpreter::UserFunctionExecutor for Runtime { impl interpreter::UserFunctionExecutor for Runtime {
fn execute(&mut self, name: &str, context: interpreter::CallerContext) fn execute(&mut self, name: &str, context: interpreter::CallerContext)
-> Result<Option<interpreter::RuntimeValue>, interpreter::Error> -> Result<Option<interpreter::RuntimeValue>, interpreter::Error>
{ {
match name { match name {
"_malloc" => { "_malloc" => {
self.malloc(context) self.malloc(context)
}, },
"_free" => { "_free" => {
self.user_noop(context) self.user_noop(context)
}, },
"_storage_read" => { "_storage_read" => {
self.storage_read(context) self.storage_read(context)
}, },
"_storage_write" => { "_storage_write" => {
self.storage_write(context) self.storage_write(context)
}, },
"gas" => { "gas" => {
self.gas(context) self.gas(context)
}, },
_ => { _ => {
self.user_trap(context) self.user_trap(context)
} }
} }
} }
} }