Return BadInstruction instead of panic

This commit is contained in:
Tomusdrw 2016-01-14 02:45:16 +01:00
parent 4d41c3352e
commit ebd7081d59
3 changed files with 12 additions and 7 deletions

View File

@ -19,7 +19,7 @@ pub enum Error {
}, },
/// `BadInstructions` is returned when given instruction is not supported /// `BadInstructions` is returned when given instruction is not supported
BadInstruction { BadInstruction {
instruction: &'static str, instruction: u8,
}, },
/// `StackUnderflow` when there is not enough stack elements to execute instruction /// `StackUnderflow` when there is not enough stack elements to execute instruction
/// First parameter says how many elements were needed and the second how many were actually on Stack /// First parameter says how many elements were needed and the second how many were actually on Stack

View File

@ -242,7 +242,7 @@ pub fn get_info (instruction: Instruction) -> InstructionInfo {
RETURN => InstructionInfo::new("RETURN", 0, 2, 0, true, GasPriceTier::ZeroTier), RETURN => InstructionInfo::new("RETURN", 0, 2, 0, true, GasPriceTier::ZeroTier),
DELEGATECALL => InstructionInfo::new("DELEGATECALL", 0, 6, 1, true, GasPriceTier::SpecialTier), DELEGATECALL => InstructionInfo::new("DELEGATECALL", 0, 6, 1, true, GasPriceTier::SpecialTier),
SUICIDE => InstructionInfo::new("SUICIDE", 0, 1, 0, true, GasPriceTier::ZeroTier), SUICIDE => InstructionInfo::new("SUICIDE", 0, 1, 0, true, GasPriceTier::ZeroTier),
_ => panic!(format!("Undefined instruction: {}", instruction)) _ => InstructionInfo::new("INVALID_INSTRUCTION", 0, 0, 0, false, GasPriceTier::InvalidTier)
} }
} }

View File

@ -244,12 +244,12 @@ impl Interpreter {
if !schedule.have_delegate_call && instruction == instructions::DELEGATECALL { if !schedule.have_delegate_call && instruction == instructions::DELEGATECALL {
return Err(evm::Error::BadInstruction { return Err(evm::Error::BadInstruction {
instruction: info.name instruction: instruction
}); });
} }
if info.tier == instructions::GasPriceTier::InvalidTier { if info.tier == instructions::GasPriceTier::InvalidTier {
return Err(evm::Error::BadInstruction { return Err(evm::Error::BadInstruction {
instruction: info.name instruction: instruction
}); });
} }
@ -608,7 +608,7 @@ impl Interpreter {
stack.push(ext.env_info().gas_limit.clone()); stack.push(ext.env_info().gas_limit.clone());
}, },
_ => { _ => {
self.exec_stack_instruction(instruction, stack); try!(self.exec_stack_instruction(instruction, stack));
} }
}; };
Ok(InstructionResult::AdditionalGasCost(U256::zero())) Ok(InstructionResult::AdditionalGasCost(U256::zero()))
@ -678,7 +678,7 @@ impl Interpreter {
} }
} }
fn exec_stack_instruction(&self, instruction: Instruction, stack : &mut Stack<U256>) { fn exec_stack_instruction(&self, instruction: Instruction, stack : &mut Stack<U256>) -> Result<(), evm::Error> {
match instruction { match instruction {
instructions::DUP1...instructions::DUP16 => { instructions::DUP1...instructions::DUP16 => {
let position = instructions::get_dup_position(instruction); let position = instructions::get_dup_position(instruction);
@ -772,9 +772,14 @@ impl Interpreter {
// TODO instructions::ADDMOD => {}, // TODO instructions::ADDMOD => {},
// TODO instructions::MULMOD => {}, // TODO instructions::MULMOD => {},
// TODO instructions::SIGNEXTEND => {}, // TODO instructions::SIGNEXTEND => {},
_ => panic!(format!("Unknown stack instruction: {:x}", instruction)) _ => {
return Err(evm::Error::BadInstruction {
instruction: instruction
});
} }
} }
Ok(())
}
fn find_jump_destinations(&self, code : &Bytes) -> HashSet<CodePosition> { fn find_jump_destinations(&self, code : &Bytes) -> HashSet<CodePosition> {
let mut jump_dests = HashSet::new(); let mut jump_dests = HashSet::new();