Change the return type of step_inner function. (#10940)
* Change the return type of step_inner function. * Fix indention.
This commit is contained in:
parent
6c7d0fef4e
commit
8e0c522931
@ -109,8 +109,6 @@ enum InstructionResult<Gas> {
|
|||||||
Trap(TrapKind),
|
Trap(TrapKind),
|
||||||
}
|
}
|
||||||
|
|
||||||
enum Never {}
|
|
||||||
|
|
||||||
/// ActionParams without code, so that it can be feed into CodeReader.
|
/// ActionParams without code, so that it can be feed into CodeReader.
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
struct InterpreterParams {
|
struct InterpreterParams {
|
||||||
@ -171,12 +169,6 @@ pub enum InterpreterResult {
|
|||||||
Trap(TrapKind),
|
Trap(TrapKind),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<vm::Error> for InterpreterResult {
|
|
||||||
fn from(error: vm::Error) -> InterpreterResult {
|
|
||||||
InterpreterResult::Done(Err(error))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Intepreter EVM implementation
|
/// Intepreter EVM implementation
|
||||||
pub struct Interpreter<Cost: CostType> {
|
pub struct Interpreter<Cost: CostType> {
|
||||||
mem: Vec<u8>,
|
mem: Vec<u8>,
|
||||||
@ -309,7 +301,7 @@ impl<Cost: CostType> Interpreter<Cost> {
|
|||||||
} else if self.reader.len() == 0 {
|
} else if self.reader.len() == 0 {
|
||||||
InterpreterResult::Done(Ok(GasLeft::Known(self.gasometer.as_ref().expect("Gasometer None case is checked above; qed").current_gas.as_u256())))
|
InterpreterResult::Done(Ok(GasLeft::Known(self.gasometer.as_ref().expect("Gasometer None case is checked above; qed").current_gas.as_u256())))
|
||||||
} else {
|
} else {
|
||||||
self.step_inner(ext).err().expect("step_inner never returns Ok(()); qed")
|
self.step_inner(ext)
|
||||||
};
|
};
|
||||||
|
|
||||||
if let &InterpreterResult::Done(_) = &result {
|
if let &InterpreterResult::Done(_) = &result {
|
||||||
@ -321,7 +313,7 @@ impl<Cost: CostType> Interpreter<Cost> {
|
|||||||
|
|
||||||
/// Inner helper function for step.
|
/// Inner helper function for step.
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn step_inner(&mut self, ext: &mut dyn vm::Ext) -> Result<Never, InterpreterResult> {
|
fn step_inner(&mut self, ext: &mut dyn vm::Ext) -> InterpreterResult {
|
||||||
let result = match self.resume_result.take() {
|
let result = match self.resume_result.take() {
|
||||||
Some(result) => result,
|
Some(result) => result,
|
||||||
None => {
|
None => {
|
||||||
@ -336,22 +328,28 @@ impl<Cost: CostType> Interpreter<Cost> {
|
|||||||
|
|
||||||
let instruction = match instruction {
|
let instruction = match instruction {
|
||||||
Some(i) => i,
|
Some(i) => i,
|
||||||
None => return Err(InterpreterResult::Done(Err(vm::Error::BadInstruction {
|
None => return InterpreterResult::Done(Err(vm::Error::BadInstruction {
|
||||||
instruction: opcode
|
instruction: opcode
|
||||||
}))),
|
})),
|
||||||
};
|
};
|
||||||
|
|
||||||
let info = instruction.info();
|
let info = instruction.info();
|
||||||
self.last_stack_ret_len = info.ret;
|
self.last_stack_ret_len = info.ret;
|
||||||
self.verify_instruction(ext, instruction, info)?;
|
if let Err(e) = self.verify_instruction(ext, instruction, info) {
|
||||||
|
return InterpreterResult::Done(Err(e));
|
||||||
|
};
|
||||||
|
|
||||||
// Calculate gas cost
|
// Calculate gas cost
|
||||||
let requirements = self.gasometer.as_mut().expect(GASOMETER_PROOF).requirements(ext, instruction, info, &self.stack, self.mem.size())?;
|
let requirements = match self.gasometer.as_mut().expect(GASOMETER_PROOF).requirements(ext, instruction, info, &self.stack, self.mem.size()) {
|
||||||
|
Ok(t) => t,
|
||||||
|
Err(e) => return InterpreterResult::Done(Err(e)),
|
||||||
|
};
|
||||||
if self.do_trace {
|
if self.do_trace {
|
||||||
ext.trace_prepare_execute(self.reader.position - 1, opcode, requirements.gas_cost.as_u256(), Self::mem_written(instruction, &self.stack), Self::store_written(instruction, &self.stack));
|
ext.trace_prepare_execute(self.reader.position - 1, opcode, requirements.gas_cost.as_u256(), Self::mem_written(instruction, &self.stack), Self::store_written(instruction, &self.stack));
|
||||||
}
|
}
|
||||||
|
if let Err(e) = self.gasometer.as_mut().expect(GASOMETER_PROOF).verify_gas(&requirements.gas_cost) {
|
||||||
self.gasometer.as_mut().expect(GASOMETER_PROOF).verify_gas(&requirements.gas_cost)?;
|
return InterpreterResult::Done(Err(e));
|
||||||
|
}
|
||||||
self.mem.expand(requirements.memory_required_size);
|
self.mem.expand(requirements.memory_required_size);
|
||||||
self.gasometer.as_mut().expect(GASOMETER_PROOF).current_mem_gas = requirements.memory_total_gas;
|
self.gasometer.as_mut().expect(GASOMETER_PROOF).current_mem_gas = requirements.memory_total_gas;
|
||||||
self.gasometer.as_mut().expect(GASOMETER_PROOF).current_gas = self.gasometer.as_mut().expect(GASOMETER_PROOF).current_gas - requirements.gas_cost;
|
self.gasometer.as_mut().expect(GASOMETER_PROOF).current_gas = self.gasometer.as_mut().expect(GASOMETER_PROOF).current_gas - requirements.gas_cost;
|
||||||
@ -360,18 +358,19 @@ impl<Cost: CostType> Interpreter<Cost> {
|
|||||||
|
|
||||||
// Execute instruction
|
// Execute instruction
|
||||||
let current_gas = self.gasometer.as_mut().expect(GASOMETER_PROOF).current_gas;
|
let current_gas = self.gasometer.as_mut().expect(GASOMETER_PROOF).current_gas;
|
||||||
let result = self.exec_instruction(
|
let result = match self.exec_instruction(
|
||||||
current_gas, ext, instruction, requirements.provide_gas
|
current_gas, ext, instruction, requirements.provide_gas
|
||||||
)?;
|
) {
|
||||||
|
Err(x) => return InterpreterResult::Done(Err(x)),
|
||||||
|
Ok(x) => x,
|
||||||
|
};
|
||||||
evm_debug!({ self.informant.after_instruction(instruction) });
|
evm_debug!({ self.informant.after_instruction(instruction) });
|
||||||
|
|
||||||
result
|
result
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
if let InstructionResult::Trap(trap) = result {
|
if let InstructionResult::Trap(trap) = result {
|
||||||
return Err(InterpreterResult::Trap(trap));
|
return InterpreterResult::Trap(trap);
|
||||||
}
|
}
|
||||||
|
|
||||||
if let InstructionResult::UnusedGas(ref gas) = result {
|
if let InstructionResult::UnusedGas(ref gas) = result {
|
||||||
@ -393,28 +392,31 @@ impl<Cost: CostType> Interpreter<Cost> {
|
|||||||
self.valid_jump_destinations = Some(self.cache.jump_destinations(&self.params.code_hash, &self.reader.code));
|
self.valid_jump_destinations = Some(self.cache.jump_destinations(&self.params.code_hash, &self.reader.code));
|
||||||
}
|
}
|
||||||
let jump_destinations = self.valid_jump_destinations.as_ref().expect("jump_destinations are initialized on first jump; qed");
|
let jump_destinations = self.valid_jump_destinations.as_ref().expect("jump_destinations are initialized on first jump; qed");
|
||||||
let pos = self.verify_jump(position, jump_destinations)?;
|
let pos = match self.verify_jump(position, jump_destinations) {
|
||||||
|
Ok(x) => x,
|
||||||
|
Err(e) => return InterpreterResult::Done(Err(e))
|
||||||
|
};
|
||||||
self.reader.position = pos;
|
self.reader.position = pos;
|
||||||
},
|
},
|
||||||
InstructionResult::StopExecutionNeedsReturn {gas, init_off, init_size, apply} => {
|
InstructionResult::StopExecutionNeedsReturn {gas, init_off, init_size, apply} => {
|
||||||
let mem = mem::replace(&mut self.mem, Vec::new());
|
let mem = mem::replace(&mut self.mem, Vec::new());
|
||||||
return Err(InterpreterResult::Done(Ok(GasLeft::NeedsReturn {
|
return InterpreterResult::Done(Ok(GasLeft::NeedsReturn {
|
||||||
gas_left: gas.as_u256(),
|
gas_left: gas.as_u256(),
|
||||||
data: mem.into_return_data(init_off, init_size),
|
data: mem.into_return_data(init_off, init_size),
|
||||||
apply_state: apply
|
apply_state: apply
|
||||||
})));
|
}));
|
||||||
},
|
},
|
||||||
InstructionResult::StopExecution => {
|
InstructionResult::StopExecution => {
|
||||||
return Err(InterpreterResult::Done(Ok(GasLeft::Known(self.gasometer.as_mut().expect(GASOMETER_PROOF).current_gas.as_u256()))));
|
return InterpreterResult::Done(Ok(GasLeft::Known(self.gasometer.as_mut().expect(GASOMETER_PROOF).current_gas.as_u256())));
|
||||||
},
|
},
|
||||||
_ => {},
|
_ => {},
|
||||||
}
|
}
|
||||||
|
|
||||||
if self.reader.position >= self.reader.len() {
|
if self.reader.position >= self.reader.len() {
|
||||||
return Err(InterpreterResult::Done(Ok(GasLeft::Known(self.gasometer.as_mut().expect(GASOMETER_PROOF).current_gas.as_u256()))));
|
return InterpreterResult::Done(Ok(GasLeft::Known(self.gasometer.as_mut().expect(GASOMETER_PROOF).current_gas.as_u256())));
|
||||||
}
|
}
|
||||||
|
|
||||||
Err(InterpreterResult::Continue)
|
InterpreterResult::Continue
|
||||||
}
|
}
|
||||||
|
|
||||||
fn verify_instruction(&self, ext: &dyn vm::Ext, instruction: Instruction, info: &InstructionInfo) -> vm::Result<()> {
|
fn verify_instruction(&self, ext: &dyn vm::Ext, instruction: Instruction, info: &InstructionInfo) -> vm::Result<()> {
|
||||||
|
Loading…
Reference in New Issue
Block a user