Merge pull request #133 from gavofyork/evm_stack_fix
Single array for logs output.
This commit is contained in:
commit
1d53d806b2
@ -516,6 +516,8 @@ pub const LOG2: Instruction = 0xa2;
|
|||||||
pub const LOG3: Instruction = 0xa3;
|
pub const LOG3: Instruction = 0xa3;
|
||||||
/// Makes a log entry; 4 topics.
|
/// Makes a log entry; 4 topics.
|
||||||
pub const LOG4: Instruction = 0xa4;
|
pub const LOG4: Instruction = 0xa4;
|
||||||
|
/// Maximal number of topics for log instructions
|
||||||
|
pub const MAX_NO_OF_TOPICS : usize = 4;
|
||||||
|
|
||||||
/// create a new account with associated code
|
/// create a new account with associated code
|
||||||
pub const CREATE: Instruction = 0xf0;
|
pub const CREATE: Instruction = 0xf0;
|
||||||
|
@ -5,6 +5,7 @@ use evm;
|
|||||||
use super::instructions as instructions;
|
use super::instructions as instructions;
|
||||||
use super::instructions::Instruction;
|
use super::instructions::Instruction;
|
||||||
use std::num::wrapping::OverflowingOps;
|
use std::num::wrapping::OverflowingOps;
|
||||||
|
use std::marker::Copy;
|
||||||
|
|
||||||
#[cfg(feature = "evm_debug")]
|
#[cfg(feature = "evm_debug")]
|
||||||
macro_rules! evm_debug {
|
macro_rules! evm_debug {
|
||||||
@ -39,30 +40,44 @@ trait Stack<T> {
|
|||||||
fn has(&self, no_of_elems: usize) -> bool;
|
fn has(&self, no_of_elems: usize) -> bool;
|
||||||
/// Get element from top and remove it from Stack. Panics if stack is empty.
|
/// Get element from top and remove it from Stack. Panics if stack is empty.
|
||||||
fn pop_back(&mut self) -> T;
|
fn pop_back(&mut self) -> T;
|
||||||
/// Get elements from top and remove them from Stack. Panics if stack is empty.
|
/// Get (up to `instructions::MAX_NO_OF_TOPICS`) elements from top and remove them from Stack. Panics if stack is empty.
|
||||||
fn pop_n(&mut self, no_of_elems: usize) -> Vec<T>;
|
fn pop_n(&mut self, no_of_elems: usize) -> &[T];
|
||||||
/// Add element on top of the Stack
|
/// Add element on top of the Stack
|
||||||
fn push(&mut self, elem: T);
|
fn push(&mut self, elem: T);
|
||||||
/// Get number of elements on Stack
|
/// Get number of elements on Stack
|
||||||
fn size(&self) -> usize;
|
fn size(&self) -> usize;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S : fmt::Display> Stack<S> for Vec<S> {
|
struct VecStack<S> {
|
||||||
|
stack: Vec<S>,
|
||||||
|
logs: [S; instructions::MAX_NO_OF_TOPICS]
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<S : Copy> VecStack<S> {
|
||||||
|
fn with_capacity(capacity: usize, zero: S) -> Self {
|
||||||
|
VecStack {
|
||||||
|
stack: Vec::with_capacity(capacity),
|
||||||
|
logs: [zero; instructions::MAX_NO_OF_TOPICS]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<S : fmt::Display> Stack<S> for VecStack<S> {
|
||||||
fn peek(&self, no_from_top: usize) -> &S {
|
fn peek(&self, no_from_top: usize) -> &S {
|
||||||
return &self[self.len() - no_from_top - 1];
|
return &self.stack[self.stack.len() - no_from_top - 1];
|
||||||
}
|
}
|
||||||
|
|
||||||
fn swap_with_top(&mut self, no_from_top: usize) {
|
fn swap_with_top(&mut self, no_from_top: usize) {
|
||||||
let len = self.len();
|
let len = self.stack.len();
|
||||||
self.swap(len - no_from_top - 1, len - 1);
|
self.stack.swap(len - no_from_top - 1, len - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn has(&self, no_of_elems: usize) -> bool {
|
fn has(&self, no_of_elems: usize) -> bool {
|
||||||
self.len() >= no_of_elems
|
self.stack.len() >= no_of_elems
|
||||||
}
|
}
|
||||||
|
|
||||||
fn pop_back(&mut self) -> S {
|
fn pop_back(&mut self) -> S {
|
||||||
let val = self.pop();
|
let val = self.stack.pop();
|
||||||
match val {
|
match val {
|
||||||
Some(x) => {
|
Some(x) => {
|
||||||
evm_debug!({
|
evm_debug!({
|
||||||
@ -74,24 +89,24 @@ impl<S : fmt::Display> Stack<S> for Vec<S> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn pop_n(&mut self, no_of_elems: usize) -> Vec<S> {
|
fn pop_n(&mut self, no_of_elems: usize) -> &[S] {
|
||||||
let mut vec = Vec::new();
|
assert!(no_of_elems <= instructions::MAX_NO_OF_TOPICS);
|
||||||
|
|
||||||
for _i in 1..no_of_elems+1 {
|
for i in 0..no_of_elems {
|
||||||
vec.push(self.pop_back());
|
self.logs[i] = self.pop_back();
|
||||||
}
|
}
|
||||||
vec
|
&self.logs[0..no_of_elems]
|
||||||
}
|
}
|
||||||
|
|
||||||
fn push(&mut self, elem: S) {
|
fn push(&mut self, elem: S) {
|
||||||
evm_debug!({
|
evm_debug!({
|
||||||
format!(" PUSH: {}", elem)
|
format!(" PUSH: {}", elem)
|
||||||
});
|
});
|
||||||
self.push(elem);
|
self.stack.push(elem);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn size(&self) -> usize {
|
fn size(&self) -> usize {
|
||||||
self.len()
|
self.stack.len()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -246,7 +261,7 @@ impl evm::Evm for Interpreter {
|
|||||||
let valid_jump_destinations = self.find_jump_destinations(&code);
|
let valid_jump_destinations = self.find_jump_destinations(&code);
|
||||||
|
|
||||||
let mut current_gas = params.gas.clone();
|
let mut current_gas = params.gas.clone();
|
||||||
let mut stack = Vec::with_capacity(ext.schedule().stack_limit);
|
let mut stack = VecStack::with_capacity(ext.schedule().stack_limit, U256::zero());
|
||||||
let mut mem = vec![];
|
let mut mem = vec![];
|
||||||
let mut reader = CodeReader {
|
let mut reader = CodeReader {
|
||||||
position: 0,
|
position: 0,
|
||||||
|
Loading…
Reference in New Issue
Block a user