Getting rid of RequiredMem enum
This commit is contained in:
parent
c8d94c981b
commit
342c4e736d
@ -243,15 +243,10 @@ impl<'a> CodeReader<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
enum RequiredMem {
|
|
||||||
Mem(U256),
|
|
||||||
OutOfMemory
|
|
||||||
}
|
|
||||||
|
|
||||||
enum InstructionCost {
|
enum InstructionCost {
|
||||||
Gas(U256),
|
Gas(U256),
|
||||||
GasMem(U256, RequiredMem),
|
GasMem(U256, U256),
|
||||||
GasMemCopy(U256, RequiredMem, U256)
|
GasMemCopy(U256, U256, U256)
|
||||||
}
|
}
|
||||||
|
|
||||||
enum InstructionResult {
|
enum InstructionResult {
|
||||||
@ -381,31 +376,31 @@ impl Interpreter {
|
|||||||
InstructionCost::Gas(U256::from(schedule.sload_gas))
|
InstructionCost::Gas(U256::from(schedule.sload_gas))
|
||||||
},
|
},
|
||||||
instructions::MSTORE => {
|
instructions::MSTORE => {
|
||||||
InstructionCost::GasMem(default_gas, self.mem_needed_const(stack.peek(0), 32))
|
InstructionCost::GasMem(default_gas, try!(self.mem_needed_const(stack.peek(0), 32)))
|
||||||
},
|
},
|
||||||
instructions::MLOAD => {
|
instructions::MLOAD => {
|
||||||
InstructionCost::GasMem(default_gas, self.mem_needed_const(stack.peek(0), 32))
|
InstructionCost::GasMem(default_gas, try!(self.mem_needed_const(stack.peek(0), 32)))
|
||||||
},
|
},
|
||||||
instructions::MSTORE8 => {
|
instructions::MSTORE8 => {
|
||||||
InstructionCost::GasMem(default_gas, self.mem_needed_const(stack.peek(0), 1))
|
InstructionCost::GasMem(default_gas, try!(self.mem_needed_const(stack.peek(0), 1)))
|
||||||
},
|
},
|
||||||
instructions::RETURN => {
|
instructions::RETURN => {
|
||||||
InstructionCost::GasMem(default_gas, self.mem_needed(stack.peek(0), stack.peek(1)))
|
InstructionCost::GasMem(default_gas, try!(self.mem_needed(stack.peek(0), stack.peek(1))))
|
||||||
},
|
},
|
||||||
instructions::SHA3 => {
|
instructions::SHA3 => {
|
||||||
let w = overflowing!(add_u256_usize(stack.peek(1), 31));
|
let w = overflowing!(add_u256_usize(stack.peek(1), 31));
|
||||||
let words = w >> 5;
|
let words = w >> 5;
|
||||||
let gas = U256::from(schedule.sha3_gas) + (U256::from(schedule.sha3_word_gas) * words);
|
let gas = U256::from(schedule.sha3_gas) + (U256::from(schedule.sha3_word_gas) * words);
|
||||||
InstructionCost::GasMem(gas, self.mem_needed(stack.peek(0), stack.peek(1)))
|
InstructionCost::GasMem(gas, try!(self.mem_needed(stack.peek(0), stack.peek(1))))
|
||||||
},
|
},
|
||||||
instructions::CALLDATACOPY => {
|
instructions::CALLDATACOPY => {
|
||||||
InstructionCost::GasMemCopy(default_gas, self.mem_needed(stack.peek(0), stack.peek(2)), stack.peek(2).clone())
|
InstructionCost::GasMemCopy(default_gas, try!(self.mem_needed(stack.peek(0), stack.peek(2))), stack.peek(2).clone())
|
||||||
},
|
},
|
||||||
instructions::CODECOPY => {
|
instructions::CODECOPY => {
|
||||||
InstructionCost::GasMemCopy(default_gas, self.mem_needed(stack.peek(0), stack.peek(2)), stack.peek(2).clone())
|
InstructionCost::GasMemCopy(default_gas, try!(self.mem_needed(stack.peek(0), stack.peek(2))), stack.peek(2).clone())
|
||||||
},
|
},
|
||||||
instructions::EXTCODECOPY => {
|
instructions::EXTCODECOPY => {
|
||||||
InstructionCost::GasMemCopy(default_gas, self.mem_needed(stack.peek(1), stack.peek(3)), stack.peek(3).clone())
|
InstructionCost::GasMemCopy(default_gas, try!(self.mem_needed(stack.peek(1), stack.peek(3))), stack.peek(3).clone())
|
||||||
},
|
},
|
||||||
instructions::JUMPDEST => {
|
instructions::JUMPDEST => {
|
||||||
InstructionCost::Gas(U256::one())
|
InstructionCost::Gas(U256::one())
|
||||||
@ -416,13 +411,13 @@ impl Interpreter {
|
|||||||
|
|
||||||
let data_gas = overflowing!(stack.peek(1).overflowing_mul(U256::from(schedule.log_data_gas)));
|
let data_gas = overflowing!(stack.peek(1).overflowing_mul(U256::from(schedule.log_data_gas)));
|
||||||
let gas = overflowing!(data_gas.overflowing_add(U256::from(log_gas)));
|
let gas = overflowing!(data_gas.overflowing_add(U256::from(log_gas)));
|
||||||
InstructionCost::GasMem(gas, self.mem_needed(stack.peek(0), stack.peek(1)))
|
InstructionCost::GasMem(gas, try!(self.mem_needed(stack.peek(0), stack.peek(1))))
|
||||||
},
|
},
|
||||||
instructions::CALL | instructions::CALLCODE => {
|
instructions::CALL | instructions::CALLCODE => {
|
||||||
let mut gas = overflowing!(add_u256_usize(stack.peek(0), schedule.call_gas));
|
let mut gas = overflowing!(add_u256_usize(stack.peek(0), schedule.call_gas));
|
||||||
let mem = self.mem_max(
|
let mem = cmp::max(
|
||||||
self.mem_needed(stack.peek(5), stack.peek(6)),
|
try!(self.mem_needed(stack.peek(5), stack.peek(6))),
|
||||||
self.mem_needed(stack.peek(3), stack.peek(4))
|
try!(self.mem_needed(stack.peek(3), stack.peek(4)))
|
||||||
);
|
);
|
||||||
|
|
||||||
let address = u256_to_address(stack.peek(1));
|
let address = u256_to_address(stack.peek(1));
|
||||||
@ -439,15 +434,15 @@ impl Interpreter {
|
|||||||
},
|
},
|
||||||
instructions::DELEGATECALL => {
|
instructions::DELEGATECALL => {
|
||||||
let gas = overflowing!(add_u256_usize(stack.peek(0), schedule.call_gas));
|
let gas = overflowing!(add_u256_usize(stack.peek(0), schedule.call_gas));
|
||||||
let mem = self.mem_max(
|
let mem = cmp::max(
|
||||||
self.mem_needed(stack.peek(4), stack.peek(5)),
|
try!(self.mem_needed(stack.peek(4), stack.peek(5))),
|
||||||
self.mem_needed(stack.peek(2), stack.peek(3))
|
try!(self.mem_needed(stack.peek(2), stack.peek(3)))
|
||||||
);
|
);
|
||||||
InstructionCost::GasMem(gas, mem)
|
InstructionCost::GasMem(gas, mem)
|
||||||
},
|
},
|
||||||
instructions::CREATE => {
|
instructions::CREATE => {
|
||||||
let gas = U256::from(schedule.create_gas);
|
let gas = U256::from(schedule.create_gas);
|
||||||
let mem = self.mem_needed(stack.peek(1), stack.peek(2));
|
let mem = try!(self.mem_needed(stack.peek(1), stack.peek(2)));
|
||||||
InstructionCost::GasMem(gas, mem)
|
InstructionCost::GasMem(gas, mem)
|
||||||
},
|
},
|
||||||
instructions::EXP => {
|
instructions::EXP => {
|
||||||
@ -463,24 +458,18 @@ impl Interpreter {
|
|||||||
InstructionCost::Gas(gas) => {
|
InstructionCost::Gas(gas) => {
|
||||||
Ok((gas, 0))
|
Ok((gas, 0))
|
||||||
},
|
},
|
||||||
InstructionCost::GasMem(gas, mem_size) => match mem_size {
|
InstructionCost::GasMem(gas, mem_size) => {
|
||||||
RequiredMem::Mem(mem_size) => {
|
let (mem_gas, new_mem_size) = try!(self.mem_gas_cost(schedule, mem.size(), &mem_size));
|
||||||
let (mem_gas, new_mem_size) = try!(self.mem_gas_cost(schedule, mem.size(), &mem_size));
|
let gas = overflowing!(gas.overflowing_add(mem_gas));
|
||||||
let gas = overflowing!(gas.overflowing_add(mem_gas));
|
Ok((gas, new_mem_size))
|
||||||
Ok((gas, new_mem_size))
|
|
||||||
},
|
|
||||||
RequiredMem::OutOfMemory => Err(evm::Error::OutOfGas)
|
|
||||||
},
|
},
|
||||||
InstructionCost::GasMemCopy(gas, mem_size, copy) => match mem_size {
|
InstructionCost::GasMemCopy(gas, mem_size, copy) => {
|
||||||
RequiredMem::Mem(mem_size) => {
|
let (mem_gas, new_mem_size) = try!(self.mem_gas_cost(schedule, mem.size(), &mem_size));
|
||||||
let (mem_gas, new_mem_size) = try!(self.mem_gas_cost(schedule, mem.size(), &mem_size));
|
let copy = overflowing!(add_u256_usize(©, 31));
|
||||||
let copy = overflowing!(add_u256_usize(©, 31));
|
let copy_gas = U256::from(schedule.copy_gas) * (copy / U256::from(32));
|
||||||
let copy_gas = U256::from(schedule.copy_gas) * (copy / U256::from(32));
|
let gas = overflowing!(gas.overflowing_add(copy_gas));
|
||||||
let gas = overflowing!(gas.overflowing_add(copy_gas));
|
let gas = overflowing!(gas.overflowing_add(mem_gas));
|
||||||
let gas = overflowing!(gas.overflowing_add(mem_gas));
|
Ok((gas, new_mem_size))
|
||||||
Ok((gas, new_mem_size))
|
|
||||||
},
|
|
||||||
RequiredMem::OutOfMemory => Err(evm::Error::OutOfGas)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -510,35 +499,16 @@ impl Interpreter {
|
|||||||
}, req_mem_size_rounded.low_u64() as usize))
|
}, req_mem_size_rounded.low_u64() as usize))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn mem_max(&self, m_a: RequiredMem, m_b: RequiredMem) -> RequiredMem {
|
fn mem_needed_const(&self, mem: &U256, add: usize) -> Result<U256, evm::Error> {
|
||||||
match (m_a, m_b) {
|
Ok(overflowing!(mem.overflowing_add(U256::from(add))))
|
||||||
(RequiredMem::Mem(a), RequiredMem::Mem(b)) => {
|
|
||||||
RequiredMem::Mem(cmp::max(a, b))
|
|
||||||
},
|
|
||||||
(RequiredMem::OutOfMemory, _) | (_, RequiredMem::OutOfMemory) => {
|
|
||||||
RequiredMem::OutOfMemory
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn mem_needed_const(&self, mem: &U256, add: usize) -> RequiredMem {
|
fn mem_needed(&self, offset: &U256, size: &U256) -> Result<U256, ::evm::Error> {
|
||||||
match mem.overflowing_add(U256::from(add)) {
|
|
||||||
(_, true) => RequiredMem::OutOfMemory,
|
|
||||||
(mem, false) => RequiredMem::Mem(mem)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn mem_needed(&self, offset: &U256, size: &U256) -> RequiredMem {
|
|
||||||
if self.is_zero(size) {
|
if self.is_zero(size) {
|
||||||
return RequiredMem::Mem(U256::zero());
|
return Ok(U256::zero());
|
||||||
}
|
}
|
||||||
|
|
||||||
match offset.clone().overflowing_add(size.clone()) {
|
Ok(overflowing!(offset.overflowing_add(size.clone())))
|
||||||
(_result, true) => RequiredMem::OutOfMemory,
|
|
||||||
(result, false) => {
|
|
||||||
RequiredMem::Mem(result)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn exec_instruction(&self,
|
fn exec_instruction(&self,
|
||||||
|
Loading…
Reference in New Issue
Block a user