Fixing memory allocation

This commit is contained in:
Tomusdrw 2016-01-15 23:32:16 +01:00
parent f49afe1b6a
commit 9e7fea94bf
2 changed files with 58 additions and 21 deletions

View File

@ -45,7 +45,7 @@ impl<S : fmt::Display> Stack<S> for Vec<S> {
let val = self.pop(); let val = self.pop();
match val { match val {
Some(x) => { Some(x) => {
// println!("Poping from stack: {}", x); println!("Poping from stack: {}", x);
x x
}, },
None => panic!("Tried to pop from empty stack.") None => panic!("Tried to pop from empty stack.")
@ -62,7 +62,7 @@ impl<S : fmt::Display> Stack<S> for Vec<S> {
} }
fn push(&mut self, elem: S) { fn push(&mut self, elem: S) {
// println!("Pushing to stack: {}", elem); println!("Pushing to stack: {}", elem);
self.push(elem); self.push(elem);
} }
@ -216,14 +216,17 @@ impl evm::Evm for Interpreter {
reader.position += 1; reader.position += 1;
// Calculate gas cost // Calculate gas cost
let gas_cost = try!(self.get_gas_cost_and_expand_mem(ext, instruction, &mut mem, &stack)); let (gas_cost, mem_size) = try!(self.get_gas_cost_mem(ext, instruction, &mut mem, &stack));
try!(self.verify_gas(&current_gas, &gas_cost)); try!(self.verify_gas(&current_gas, &gas_cost));
mem.expand(mem_size);
current_gas = current_gas - gas_cost; current_gas = current_gas - gas_cost;
// println!("Executing: {} (0x{:x}) [Gas Cost: {} (Left: {})]",
// instructions::get_info(instruction).name, instruction, println!("Executing: {} (0x{:x}) [Gas Cost: {} (Left: {})]",
// gas_cost, instructions::get_info(instruction).name, instruction,
// current_gas gas_cost,
// ); current_gas
);
// Execute instruction // Execute instruction
let result = try!(self.exec_instruction( let result = try!(self.exec_instruction(
current_gas, params, ext, instruction, &mut reader, &mut mem, &mut stack current_gas, params, ext, instruction, &mut reader, &mut mem, &mut stack
@ -254,12 +257,12 @@ impl evm::Evm for Interpreter {
impl Interpreter { impl Interpreter {
fn get_gas_cost_and_expand_mem(&self, fn get_gas_cost_mem(&self,
ext: &evm::Ext, ext: &evm::Ext,
instruction: Instruction, instruction: Instruction,
mem: &mut Memory, mem: &mut Memory,
stack: &Stack<U256> stack: &Stack<U256>
) -> evm::Result { ) -> Result<(U256, usize), evm::Error> {
let schedule = ext.schedule(); let schedule = ext.schedule();
let info = instructions::get_info(instruction); let info = instructions::get_info(instruction);
@ -367,14 +370,13 @@ impl Interpreter {
match cost { match cost {
InstructionCost::Gas(gas) => { InstructionCost::Gas(gas) => {
Ok(gas) Ok((gas, 0))
}, },
InstructionCost::GasMem(gas, mem_size) => match mem_size { InstructionCost::GasMem(gas, mem_size) => match mem_size {
RequiredMem::Mem(mem_size) => { RequiredMem::Mem(mem_size) => {
let (mem_gas, new_mem_size) = self.mem_gas_cost(schedule, mem.size(), &mem_size); let (mem_gas, new_mem_size) = self.mem_gas_cost(schedule, mem.size(), &mem_size);
// Expand after calculating the cost let gas = try!(self.gas_add(gas, mem_gas));
mem.expand(new_mem_size); Ok((gas, new_mem_size))
self.gas_add(gas, mem_gas)
}, },
RequiredMem::OutOfMemory => Err(evm::Error::OutOfGas) RequiredMem::OutOfMemory => Err(evm::Error::OutOfGas)
}, },
@ -382,9 +384,8 @@ impl Interpreter {
RequiredMem::Mem(mem_size) => { RequiredMem::Mem(mem_size) => {
let (mem_gas, new_mem_size) = self.mem_gas_cost(schedule, mem.size(), &mem_size); let (mem_gas, new_mem_size) = self.mem_gas_cost(schedule, mem.size(), &mem_size);
let copy_gas = U256::from(schedule.copy_gas) * (add_u256_usize(&copy, 31) / U256::from(32)); let copy_gas = U256::from(schedule.copy_gas) * (add_u256_usize(&copy, 31) / U256::from(32));
// Expand after calculating the cost let gas = try!(self.gas_add(try!(self.gas_add(gas, copy_gas)), mem_gas));
mem.expand(new_mem_size); Ok((gas, new_mem_size))
self.gas_add(try!(self.gas_add(gas, copy_gas)), mem_gas)
}, },
RequiredMem::OutOfMemory => Err(evm::Error::OutOfGas) RequiredMem::OutOfMemory => Err(evm::Error::OutOfGas)
} }

View File

@ -763,4 +763,40 @@ mod tests {
_ => assert!(false, "Expected not enough cash error. {:?}", res) _ => assert!(false, "Expected not enough cash error. {:?}", res)
} }
} }
evm_test!{test_sha3: test_sha3_jit, test_sha3_int}
fn test_sha3(factory: Factory) {
let code = "6064640fffffffff20600055".from_hex().unwrap();
let sender = Address::from_str("0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6").unwrap();
let address = contract_address(&sender, &U256::zero());
// TODO: add tests for 'callcreate'
//let next_address = contract_address(&address, &U256::zero());
let mut params = ActionParams::new();
params.address = address.clone();
params.sender = sender.clone();
params.origin = sender.clone();
params.gas = U256::from(0x0186a0);
params.code = code.clone();
params.value = U256::from_str("0de0b6b3a7640000").unwrap();
let mut state = State::new_temp();
state.add_balance(&sender, &U256::from_str("152d02c7e14af6800000").unwrap());
let info = EnvInfo::new();
let engine = TestEngine::new(0, factory);
let mut substate = Substate::new();
let result = {
let mut ex = Executive::new(&mut state, &info, &engine);
ex.create(&params, &mut substate)
};
match result {
Err(_) => {
},
_ => {
panic!("Expected OutOfGas");
}
}
}
} }