From 6b874cedb8033d95207d72b5ac1a472b81870247 Mon Sep 17 00:00:00 2001 From: Arkadiy Paronyan Date: Mon, 12 Jun 2017 22:42:58 +0200 Subject: [PATCH] Fixed mem write for empty slice (#5825) --- ethcore/src/evm/instructions.rs | 280 +++++++++++++------------- ethcore/src/evm/interpreter/memory.rs | 14 +- 2 files changed, 154 insertions(+), 140 deletions(-) diff --git a/ethcore/src/evm/instructions.rs b/ethcore/src/evm/instructions.rs index 6e3b27351..26d9ca989 100644 --- a/ethcore/src/evm/instructions.rs +++ b/ethcore/src/evm/instructions.rs @@ -138,166 +138,172 @@ pub fn get_tier_idx (tier: GasPriceTier) -> usize { } } +/// EVM instruction information. #[derive(Copy, Clone, Default)] pub struct InstructionInfo { + /// Mnemonic name. pub name: &'static str, + /// Additional code bytes used. Used only for PUSHxx. pub additional: usize, + /// Number of stack arguments. pub args: usize, + /// Number of returned stack items. pub ret: usize, - pub side_effects: bool, + /// Gas price tier. pub tier: GasPriceTier } impl InstructionInfo { - pub fn new(name: &'static str, additional: usize, args: usize, ret: usize, side_effects: bool, tier: GasPriceTier) -> Self { + /// Create new instruction info. + pub fn new(name: &'static str, additional: usize, args: usize, ret: usize, tier: GasPriceTier) -> Self { InstructionInfo { name: name, additional: additional, args: args, ret: ret, - side_effects: side_effects, tier: tier } } } lazy_static! { + /// Static instruction table. pub static ref INSTRUCTIONS: [InstructionInfo; 0x100] = { let mut arr = [InstructionInfo::default(); 0x100]; - arr[STOP as usize] = InstructionInfo::new("STOP", 0, 0, 0, true, GasPriceTier::Zero); - arr[ADD as usize] = InstructionInfo::new("ADD", 0, 2, 1, false, GasPriceTier::VeryLow); - arr[SUB as usize] = InstructionInfo::new("SUB", 0, 2, 1, false, GasPriceTier::VeryLow); - arr[MUL as usize] = InstructionInfo::new("MUL", 0, 2, 1, false, GasPriceTier::Low); - arr[DIV as usize] = InstructionInfo::new("DIV", 0, 2, 1, false, GasPriceTier::Low); - arr[SDIV as usize] = InstructionInfo::new("SDIV", 0, 2, 1, false, GasPriceTier::Low); - arr[MOD as usize] = InstructionInfo::new("MOD", 0, 2, 1, false, GasPriceTier::Low); - arr[SMOD as usize] = InstructionInfo::new("SMOD", 0, 2, 1, false, GasPriceTier::Low); - arr[EXP as usize] = InstructionInfo::new("EXP", 0, 2, 1, false, GasPriceTier::Special); - arr[NOT as usize] = InstructionInfo::new("NOT", 0, 1, 1, false, GasPriceTier::VeryLow); - arr[LT as usize] = InstructionInfo::new("LT", 0, 2, 1, false, GasPriceTier::VeryLow); - arr[GT as usize] = InstructionInfo::new("GT", 0, 2, 1, false, GasPriceTier::VeryLow); - arr[SLT as usize] = InstructionInfo::new("SLT", 0, 2, 1, false, GasPriceTier::VeryLow); - arr[SGT as usize] = InstructionInfo::new("SGT", 0, 2, 1, false, GasPriceTier::VeryLow); - arr[EQ as usize] = InstructionInfo::new("EQ", 0, 2, 1, false, GasPriceTier::VeryLow); - arr[ISZERO as usize] = InstructionInfo::new("ISZERO", 0, 1, 1, false, GasPriceTier::VeryLow); - arr[AND as usize] = InstructionInfo::new("AND", 0, 2, 1, false, GasPriceTier::VeryLow); - arr[OR as usize] = InstructionInfo::new("OR", 0, 2, 1, false, GasPriceTier::VeryLow); - arr[XOR as usize] = InstructionInfo::new("XOR", 0, 2, 1, false, GasPriceTier::VeryLow); - arr[BYTE as usize] = InstructionInfo::new("BYTE", 0, 2, 1, false, GasPriceTier::VeryLow); - arr[ADDMOD as usize] = InstructionInfo::new("ADDMOD", 0, 3, 1, false, GasPriceTier::Mid); - arr[MULMOD as usize] = InstructionInfo::new("MULMOD", 0, 3, 1, false, GasPriceTier::Mid); - arr[SIGNEXTEND as usize] = InstructionInfo::new("SIGNEXTEND", 0, 2, 1, false, GasPriceTier::Low); - arr[RETURNDATASIZE as usize] = InstructionInfo::new("RETURNDATASIZE", 0, 0, 1, false, GasPriceTier::Base); - arr[RETURNDATACOPY as usize] = InstructionInfo::new("RETURNDATACOPY", 0, 3, 0, true, GasPriceTier::VeryLow); - arr[SHA3 as usize] = InstructionInfo::new("SHA3", 0, 2, 1, false, GasPriceTier::Special); - arr[ADDRESS as usize] = InstructionInfo::new("ADDRESS", 0, 0, 1, false, GasPriceTier::Base); - arr[BALANCE as usize] = InstructionInfo::new("BALANCE", 0, 1, 1, false, GasPriceTier::Special); - arr[ORIGIN as usize] = InstructionInfo::new("ORIGIN", 0, 0, 1, false, GasPriceTier::Base); - arr[CALLER as usize] = InstructionInfo::new("CALLER", 0, 0, 1, false, GasPriceTier::Base); - arr[CALLVALUE as usize] = InstructionInfo::new("CALLVALUE", 0, 0, 1, false, GasPriceTier::Base); - arr[CALLDATALOAD as usize] = InstructionInfo::new("CALLDATALOAD", 0, 1, 1, false, GasPriceTier::VeryLow); - arr[CALLDATASIZE as usize] = InstructionInfo::new("CALLDATASIZE", 0, 0, 1, false, GasPriceTier::Base); - arr[CALLDATACOPY as usize] = InstructionInfo::new("CALLDATACOPY", 0, 3, 0, true, GasPriceTier::VeryLow); - arr[CODESIZE as usize] = InstructionInfo::new("CODESIZE", 0, 0, 1, false, GasPriceTier::Base); - arr[CODECOPY as usize] = InstructionInfo::new("CODECOPY", 0, 3, 0, true, GasPriceTier::VeryLow); - arr[GASPRICE as usize] = InstructionInfo::new("GASPRICE", 0, 0, 1, false, GasPriceTier::Base); - arr[EXTCODESIZE as usize] = InstructionInfo::new("EXTCODESIZE", 0, 1, 1, false, GasPriceTier::Special); - arr[EXTCODECOPY as usize] = InstructionInfo::new("EXTCODECOPY", 0, 4, 0, true, GasPriceTier::Special); - arr[BLOCKHASH as usize] = InstructionInfo::new("BLOCKHASH", 0, 1, 1, false, GasPriceTier::Ext); - arr[COINBASE as usize] = InstructionInfo::new("COINBASE", 0, 0, 1, false, GasPriceTier::Base); - arr[TIMESTAMP as usize] = InstructionInfo::new("TIMESTAMP", 0, 0, 1, false, GasPriceTier::Base); - arr[NUMBER as usize] = InstructionInfo::new("NUMBER", 0, 0, 1, false, GasPriceTier::Base); - arr[DIFFICULTY as usize] = InstructionInfo::new("DIFFICULTY", 0, 0, 1, false, GasPriceTier::Base); - arr[GASLIMIT as usize] = InstructionInfo::new("GASLIMIT", 0, 0, 1, false, GasPriceTier::Base); - arr[POP as usize] = InstructionInfo::new("POP", 0, 1, 0, false, GasPriceTier::Base); - arr[MLOAD as usize] = InstructionInfo::new("MLOAD", 0, 1, 1, false, GasPriceTier::VeryLow); - arr[MSTORE as usize] = InstructionInfo::new("MSTORE", 0, 2, 0, true, GasPriceTier::VeryLow); - arr[MSTORE8 as usize] = InstructionInfo::new("MSTORE8", 0, 2, 0, true, GasPriceTier::VeryLow); - arr[SLOAD as usize] = InstructionInfo::new("SLOAD", 0, 1, 1, false, GasPriceTier::Special); - arr[SSTORE as usize] = InstructionInfo::new("SSTORE", 0, 2, 0, true, GasPriceTier::Special); - arr[JUMP as usize] = InstructionInfo::new("JUMP", 0, 1, 0, true, GasPriceTier::Mid); - arr[JUMPI as usize] = InstructionInfo::new("JUMPI", 0, 2, 0, true, GasPriceTier::High); - arr[PC as usize] = InstructionInfo::new("PC", 0, 0, 1, false, GasPriceTier::Base); - arr[MSIZE as usize] = InstructionInfo::new("MSIZE", 0, 0, 1, false, GasPriceTier::Base); - arr[GAS as usize] = InstructionInfo::new("GAS", 0, 0, 1, false, GasPriceTier::Base); - arr[JUMPDEST as usize] = InstructionInfo::new("JUMPDEST", 0, 0, 0, true, GasPriceTier::Special); - arr[PUSH1 as usize] = InstructionInfo::new("PUSH1", 1, 0, 1, false, GasPriceTier::VeryLow); - arr[PUSH2 as usize] = InstructionInfo::new("PUSH2", 2, 0, 1, false, GasPriceTier::VeryLow); - arr[PUSH3 as usize] = InstructionInfo::new("PUSH3", 3, 0, 1, false, GasPriceTier::VeryLow); - arr[PUSH4 as usize] = InstructionInfo::new("PUSH4", 4, 0, 1, false, GasPriceTier::VeryLow); - arr[PUSH5 as usize] = InstructionInfo::new("PUSH5", 5, 0, 1, false, GasPriceTier::VeryLow); - arr[PUSH6 as usize] = InstructionInfo::new("PUSH6", 6, 0, 1, false, GasPriceTier::VeryLow); - arr[PUSH7 as usize] = InstructionInfo::new("PUSH7", 7, 0, 1, false, GasPriceTier::VeryLow); - arr[PUSH8 as usize] = InstructionInfo::new("PUSH8", 8, 0, 1, false, GasPriceTier::VeryLow); - arr[PUSH9 as usize] = InstructionInfo::new("PUSH9", 9, 0, 1, false, GasPriceTier::VeryLow); - arr[PUSH10 as usize] = InstructionInfo::new("PUSH10", 10, 0, 1, false, GasPriceTier::VeryLow); - arr[PUSH11 as usize] = InstructionInfo::new("PUSH11", 11, 0, 1, false, GasPriceTier::VeryLow); - arr[PUSH12 as usize] = InstructionInfo::new("PUSH12", 12, 0, 1, false, GasPriceTier::VeryLow); - arr[PUSH13 as usize] = InstructionInfo::new("PUSH13", 13, 0, 1, false, GasPriceTier::VeryLow); - arr[PUSH14 as usize] = InstructionInfo::new("PUSH14", 14, 0, 1, false, GasPriceTier::VeryLow); - arr[PUSH15 as usize] = InstructionInfo::new("PUSH15", 15, 0, 1, false, GasPriceTier::VeryLow); - arr[PUSH16 as usize] = InstructionInfo::new("PUSH16", 16, 0, 1, false, GasPriceTier::VeryLow); - arr[PUSH17 as usize] = InstructionInfo::new("PUSH17", 17, 0, 1, false, GasPriceTier::VeryLow); - arr[PUSH18 as usize] = InstructionInfo::new("PUSH18", 18, 0, 1, false, GasPriceTier::VeryLow); - arr[PUSH19 as usize] = InstructionInfo::new("PUSH19", 19, 0, 1, false, GasPriceTier::VeryLow); - arr[PUSH20 as usize] = InstructionInfo::new("PUSH20", 20, 0, 1, false, GasPriceTier::VeryLow); - arr[PUSH21 as usize] = InstructionInfo::new("PUSH21", 21, 0, 1, false, GasPriceTier::VeryLow); - arr[PUSH22 as usize] = InstructionInfo::new("PUSH22", 22, 0, 1, false, GasPriceTier::VeryLow); - arr[PUSH23 as usize] = InstructionInfo::new("PUSH23", 23, 0, 1, false, GasPriceTier::VeryLow); - arr[PUSH24 as usize] = InstructionInfo::new("PUSH24", 24, 0, 1, false, GasPriceTier::VeryLow); - arr[PUSH25 as usize] = InstructionInfo::new("PUSH25", 25, 0, 1, false, GasPriceTier::VeryLow); - arr[PUSH26 as usize] = InstructionInfo::new("PUSH26", 26, 0, 1, false, GasPriceTier::VeryLow); - arr[PUSH27 as usize] = InstructionInfo::new("PUSH27", 27, 0, 1, false, GasPriceTier::VeryLow); - arr[PUSH28 as usize] = InstructionInfo::new("PUSH28", 28, 0, 1, false, GasPriceTier::VeryLow); - arr[PUSH29 as usize] = InstructionInfo::new("PUSH29", 29, 0, 1, false, GasPriceTier::VeryLow); - arr[PUSH30 as usize] = InstructionInfo::new("PUSH30", 30, 0, 1, false, GasPriceTier::VeryLow); - arr[PUSH31 as usize] = InstructionInfo::new("PUSH31", 31, 0, 1, false, GasPriceTier::VeryLow); - arr[PUSH32 as usize] = InstructionInfo::new("PUSH32", 32, 0, 1, false, GasPriceTier::VeryLow); - arr[DUP1 as usize] = InstructionInfo::new("DUP1", 0, 1, 2, false, GasPriceTier::VeryLow); - arr[DUP2 as usize] = InstructionInfo::new("DUP2", 0, 2, 3, false, GasPriceTier::VeryLow); - arr[DUP3 as usize] = InstructionInfo::new("DUP3", 0, 3, 4, false, GasPriceTier::VeryLow); - arr[DUP4 as usize] = InstructionInfo::new("DUP4", 0, 4, 5, false, GasPriceTier::VeryLow); - arr[DUP5 as usize] = InstructionInfo::new("DUP5", 0, 5, 6, false, GasPriceTier::VeryLow); - arr[DUP6 as usize] = InstructionInfo::new("DUP6", 0, 6, 7, false, GasPriceTier::VeryLow); - arr[DUP7 as usize] = InstructionInfo::new("DUP7", 0, 7, 8, false, GasPriceTier::VeryLow); - arr[DUP8 as usize] = InstructionInfo::new("DUP8", 0, 8, 9, false, GasPriceTier::VeryLow); - arr[DUP9 as usize] = InstructionInfo::new("DUP9", 0, 9, 10, false, GasPriceTier::VeryLow); - arr[DUP10 as usize] = InstructionInfo::new("DUP10", 0, 10, 11, false, GasPriceTier::VeryLow); - arr[DUP11 as usize] = InstructionInfo::new("DUP11", 0, 11, 12, false, GasPriceTier::VeryLow); - arr[DUP12 as usize] = InstructionInfo::new("DUP12", 0, 12, 13, false, GasPriceTier::VeryLow); - arr[DUP13 as usize] = InstructionInfo::new("DUP13", 0, 13, 14, false, GasPriceTier::VeryLow); - arr[DUP14 as usize] = InstructionInfo::new("DUP14", 0, 14, 15, false, GasPriceTier::VeryLow); - arr[DUP15 as usize] = InstructionInfo::new("DUP15", 0, 15, 16, false, GasPriceTier::VeryLow); - arr[DUP16 as usize] = InstructionInfo::new("DUP16", 0, 16, 17, false, GasPriceTier::VeryLow); - arr[SWAP1 as usize] = InstructionInfo::new("SWAP1", 0, 2, 2, false, GasPriceTier::VeryLow); - arr[SWAP2 as usize] = InstructionInfo::new("SWAP2", 0, 3, 3, false, GasPriceTier::VeryLow); - arr[SWAP3 as usize] = InstructionInfo::new("SWAP3", 0, 4, 4, false, GasPriceTier::VeryLow); - arr[SWAP4 as usize] = InstructionInfo::new("SWAP4", 0, 5, 5, false, GasPriceTier::VeryLow); - arr[SWAP5 as usize] = InstructionInfo::new("SWAP5", 0, 6, 6, false, GasPriceTier::VeryLow); - arr[SWAP6 as usize] = InstructionInfo::new("SWAP6", 0, 7, 7, false, GasPriceTier::VeryLow); - arr[SWAP7 as usize] = InstructionInfo::new("SWAP7", 0, 8, 8, false, GasPriceTier::VeryLow); - arr[SWAP8 as usize] = InstructionInfo::new("SWAP8", 0, 9, 9, false, GasPriceTier::VeryLow); - arr[SWAP9 as usize] = InstructionInfo::new("SWAP9", 0, 10, 10, false, GasPriceTier::VeryLow); - arr[SWAP10 as usize] = InstructionInfo::new("SWAP10", 0, 11, 11, false, GasPriceTier::VeryLow); - arr[SWAP11 as usize] = InstructionInfo::new("SWAP11", 0, 12, 12, false, GasPriceTier::VeryLow); - arr[SWAP12 as usize] = InstructionInfo::new("SWAP12", 0, 13, 13, false, GasPriceTier::VeryLow); - arr[SWAP13 as usize] = InstructionInfo::new("SWAP13", 0, 14, 14, false, GasPriceTier::VeryLow); - arr[SWAP14 as usize] = InstructionInfo::new("SWAP14", 0, 15, 15, false, GasPriceTier::VeryLow); - arr[SWAP15 as usize] = InstructionInfo::new("SWAP15", 0, 16, 16, false, GasPriceTier::VeryLow); - arr[SWAP16 as usize] = InstructionInfo::new("SWAP16", 0, 17, 17, false, GasPriceTier::VeryLow); - arr[LOG0 as usize] = InstructionInfo::new("LOG0", 0, 2, 0, true, GasPriceTier::Special); - arr[LOG1 as usize] = InstructionInfo::new("LOG1", 0, 3, 0, true, GasPriceTier::Special); - arr[LOG2 as usize] = InstructionInfo::new("LOG2", 0, 4, 0, true, GasPriceTier::Special); - arr[LOG3 as usize] = InstructionInfo::new("LOG3", 0, 5, 0, true, GasPriceTier::Special); - arr[LOG4 as usize] = InstructionInfo::new("LOG4", 0, 6, 0, true, GasPriceTier::Special); - arr[CREATE as usize] = InstructionInfo::new("CREATE", 0, 3, 1, true, GasPriceTier::Special); - arr[CALL as usize] = InstructionInfo::new("CALL", 0, 7, 1, true, GasPriceTier::Special); - arr[CALLCODE as usize] = InstructionInfo::new("CALLCODE", 0, 7, 1, true, GasPriceTier::Special); - arr[RETURN as usize] = InstructionInfo::new("RETURN", 0, 2, 0, true, GasPriceTier::Zero); - arr[DELEGATECALL as usize] = InstructionInfo::new("DELEGATECALL", 0, 6, 1, true, GasPriceTier::Special); - arr[SUICIDE as usize] = InstructionInfo::new("SUICIDE", 0, 1, 0, true, GasPriceTier::Special); - arr[CREATE2 as usize] = InstructionInfo::new("CREATE2", 0, 3, 1, true, GasPriceTier::Special); - arr[REVERT as usize] = InstructionInfo::new("REVERT", 0, 2, 0, true, GasPriceTier::Zero); + arr[STOP as usize] = InstructionInfo::new("STOP", 0, 0, 0, GasPriceTier::Zero); + arr[ADD as usize] = InstructionInfo::new("ADD", 0, 2, 1, GasPriceTier::VeryLow); + arr[SUB as usize] = InstructionInfo::new("SUB", 0, 2, 1, GasPriceTier::VeryLow); + arr[MUL as usize] = InstructionInfo::new("MUL", 0, 2, 1, GasPriceTier::Low); + arr[DIV as usize] = InstructionInfo::new("DIV", 0, 2, 1, GasPriceTier::Low); + arr[SDIV as usize] = InstructionInfo::new("SDIV", 0, 2, 1, GasPriceTier::Low); + arr[MOD as usize] = InstructionInfo::new("MOD", 0, 2, 1, GasPriceTier::Low); + arr[SMOD as usize] = InstructionInfo::new("SMOD", 0, 2, 1, GasPriceTier::Low); + arr[EXP as usize] = InstructionInfo::new("EXP", 0, 2, 1, GasPriceTier::Special); + arr[NOT as usize] = InstructionInfo::new("NOT", 0, 1, 1, GasPriceTier::VeryLow); + arr[LT as usize] = InstructionInfo::new("LT", 0, 2, 1, GasPriceTier::VeryLow); + arr[GT as usize] = InstructionInfo::new("GT", 0, 2, 1, GasPriceTier::VeryLow); + arr[SLT as usize] = InstructionInfo::new("SLT", 0, 2, 1, GasPriceTier::VeryLow); + arr[SGT as usize] = InstructionInfo::new("SGT", 0, 2, 1, GasPriceTier::VeryLow); + arr[EQ as usize] = InstructionInfo::new("EQ", 0, 2, 1, GasPriceTier::VeryLow); + arr[ISZERO as usize] = InstructionInfo::new("ISZERO", 0, 1, 1, GasPriceTier::VeryLow); + arr[AND as usize] = InstructionInfo::new("AND", 0, 2, 1, GasPriceTier::VeryLow); + arr[OR as usize] = InstructionInfo::new("OR", 0, 2, 1, GasPriceTier::VeryLow); + arr[XOR as usize] = InstructionInfo::new("XOR", 0, 2, 1, GasPriceTier::VeryLow); + arr[BYTE as usize] = InstructionInfo::new("BYTE", 0, 2, 1, GasPriceTier::VeryLow); + arr[ADDMOD as usize] = InstructionInfo::new("ADDMOD", 0, 3, 1, GasPriceTier::Mid); + arr[MULMOD as usize] = InstructionInfo::new("MULMOD", 0, 3, 1, GasPriceTier::Mid); + arr[SIGNEXTEND as usize] = InstructionInfo::new("SIGNEXTEND", 0, 2, 1, GasPriceTier::Low); + arr[RETURNDATASIZE as usize] = InstructionInfo::new("RETURNDATASIZE", 0, 0, 1, GasPriceTier::Base); + arr[RETURNDATACOPY as usize] = InstructionInfo::new("RETURNDATACOPY", 0, 3, 0, GasPriceTier::VeryLow); + arr[SHA3 as usize] = InstructionInfo::new("SHA3", 0, 2, 1, GasPriceTier::Special); + arr[ADDRESS as usize] = InstructionInfo::new("ADDRESS", 0, 0, 1, GasPriceTier::Base); + arr[BALANCE as usize] = InstructionInfo::new("BALANCE", 0, 1, 1, GasPriceTier::Special); + arr[ORIGIN as usize] = InstructionInfo::new("ORIGIN", 0, 0, 1, GasPriceTier::Base); + arr[CALLER as usize] = InstructionInfo::new("CALLER", 0, 0, 1, GasPriceTier::Base); + arr[CALLVALUE as usize] = InstructionInfo::new("CALLVALUE", 0, 0, 1, GasPriceTier::Base); + arr[CALLDATALOAD as usize] = InstructionInfo::new("CALLDATALOAD", 0, 1, 1, GasPriceTier::VeryLow); + arr[CALLDATASIZE as usize] = InstructionInfo::new("CALLDATASIZE", 0, 0, 1, GasPriceTier::Base); + arr[CALLDATACOPY as usize] = InstructionInfo::new("CALLDATACOPY", 0, 3, 0, GasPriceTier::VeryLow); + arr[CODESIZE as usize] = InstructionInfo::new("CODESIZE", 0, 0, 1, GasPriceTier::Base); + arr[CODECOPY as usize] = InstructionInfo::new("CODECOPY", 0, 3, 0, GasPriceTier::VeryLow); + arr[GASPRICE as usize] = InstructionInfo::new("GASPRICE", 0, 0, 1, GasPriceTier::Base); + arr[EXTCODESIZE as usize] = InstructionInfo::new("EXTCODESIZE", 0, 1, 1, GasPriceTier::Special); + arr[EXTCODECOPY as usize] = InstructionInfo::new("EXTCODECOPY", 0, 4, 0, GasPriceTier::Special); + arr[BLOCKHASH as usize] = InstructionInfo::new("BLOCKHASH", 0, 1, 1, GasPriceTier::Ext); + arr[COINBASE as usize] = InstructionInfo::new("COINBASE", 0, 0, 1, GasPriceTier::Base); + arr[TIMESTAMP as usize] = InstructionInfo::new("TIMESTAMP", 0, 0, 1, GasPriceTier::Base); + arr[NUMBER as usize] = InstructionInfo::new("NUMBER", 0, 0, 1, GasPriceTier::Base); + arr[DIFFICULTY as usize] = InstructionInfo::new("DIFFICULTY", 0, 0, 1, GasPriceTier::Base); + arr[GASLIMIT as usize] = InstructionInfo::new("GASLIMIT", 0, 0, 1, GasPriceTier::Base); + arr[POP as usize] = InstructionInfo::new("POP", 0, 1, 0, GasPriceTier::Base); + arr[MLOAD as usize] = InstructionInfo::new("MLOAD", 0, 1, 1, GasPriceTier::VeryLow); + arr[MSTORE as usize] = InstructionInfo::new("MSTORE", 0, 2, 0, GasPriceTier::VeryLow); + arr[MSTORE8 as usize] = InstructionInfo::new("MSTORE8", 0, 2, 0, GasPriceTier::VeryLow); + arr[SLOAD as usize] = InstructionInfo::new("SLOAD", 0, 1, 1, GasPriceTier::Special); + arr[SSTORE as usize] = InstructionInfo::new("SSTORE", 0, 2, 0, GasPriceTier::Special); + arr[JUMP as usize] = InstructionInfo::new("JUMP", 0, 1, 0, GasPriceTier::Mid); + arr[JUMPI as usize] = InstructionInfo::new("JUMPI", 0, 2, 0, GasPriceTier::High); + arr[PC as usize] = InstructionInfo::new("PC", 0, 0, 1, GasPriceTier::Base); + arr[MSIZE as usize] = InstructionInfo::new("MSIZE", 0, 0, 1, GasPriceTier::Base); + arr[GAS as usize] = InstructionInfo::new("GAS", 0, 0, 1, GasPriceTier::Base); + arr[JUMPDEST as usize] = InstructionInfo::new("JUMPDEST", 0, 0, 0, GasPriceTier::Special); + arr[PUSH1 as usize] = InstructionInfo::new("PUSH1", 1, 0, 1, GasPriceTier::VeryLow); + arr[PUSH2 as usize] = InstructionInfo::new("PUSH2", 2, 0, 1, GasPriceTier::VeryLow); + arr[PUSH3 as usize] = InstructionInfo::new("PUSH3", 3, 0, 1, GasPriceTier::VeryLow); + arr[PUSH4 as usize] = InstructionInfo::new("PUSH4", 4, 0, 1, GasPriceTier::VeryLow); + arr[PUSH5 as usize] = InstructionInfo::new("PUSH5", 5, 0, 1, GasPriceTier::VeryLow); + arr[PUSH6 as usize] = InstructionInfo::new("PUSH6", 6, 0, 1, GasPriceTier::VeryLow); + arr[PUSH7 as usize] = InstructionInfo::new("PUSH7", 7, 0, 1, GasPriceTier::VeryLow); + arr[PUSH8 as usize] = InstructionInfo::new("PUSH8", 8, 0, 1, GasPriceTier::VeryLow); + arr[PUSH9 as usize] = InstructionInfo::new("PUSH9", 9, 0, 1, GasPriceTier::VeryLow); + arr[PUSH10 as usize] = InstructionInfo::new("PUSH10", 10, 0, 1, GasPriceTier::VeryLow); + arr[PUSH11 as usize] = InstructionInfo::new("PUSH11", 11, 0, 1, GasPriceTier::VeryLow); + arr[PUSH12 as usize] = InstructionInfo::new("PUSH12", 12, 0, 1, GasPriceTier::VeryLow); + arr[PUSH13 as usize] = InstructionInfo::new("PUSH13", 13, 0, 1, GasPriceTier::VeryLow); + arr[PUSH14 as usize] = InstructionInfo::new("PUSH14", 14, 0, 1, GasPriceTier::VeryLow); + arr[PUSH15 as usize] = InstructionInfo::new("PUSH15", 15, 0, 1, GasPriceTier::VeryLow); + arr[PUSH16 as usize] = InstructionInfo::new("PUSH16", 16, 0, 1, GasPriceTier::VeryLow); + arr[PUSH17 as usize] = InstructionInfo::new("PUSH17", 17, 0, 1, GasPriceTier::VeryLow); + arr[PUSH18 as usize] = InstructionInfo::new("PUSH18", 18, 0, 1, GasPriceTier::VeryLow); + arr[PUSH19 as usize] = InstructionInfo::new("PUSH19", 19, 0, 1, GasPriceTier::VeryLow); + arr[PUSH20 as usize] = InstructionInfo::new("PUSH20", 20, 0, 1, GasPriceTier::VeryLow); + arr[PUSH21 as usize] = InstructionInfo::new("PUSH21", 21, 0, 1, GasPriceTier::VeryLow); + arr[PUSH22 as usize] = InstructionInfo::new("PUSH22", 22, 0, 1, GasPriceTier::VeryLow); + arr[PUSH23 as usize] = InstructionInfo::new("PUSH23", 23, 0, 1, GasPriceTier::VeryLow); + arr[PUSH24 as usize] = InstructionInfo::new("PUSH24", 24, 0, 1, GasPriceTier::VeryLow); + arr[PUSH25 as usize] = InstructionInfo::new("PUSH25", 25, 0, 1, GasPriceTier::VeryLow); + arr[PUSH26 as usize] = InstructionInfo::new("PUSH26", 26, 0, 1, GasPriceTier::VeryLow); + arr[PUSH27 as usize] = InstructionInfo::new("PUSH27", 27, 0, 1, GasPriceTier::VeryLow); + arr[PUSH28 as usize] = InstructionInfo::new("PUSH28", 28, 0, 1, GasPriceTier::VeryLow); + arr[PUSH29 as usize] = InstructionInfo::new("PUSH29", 29, 0, 1, GasPriceTier::VeryLow); + arr[PUSH30 as usize] = InstructionInfo::new("PUSH30", 30, 0, 1, GasPriceTier::VeryLow); + arr[PUSH31 as usize] = InstructionInfo::new("PUSH31", 31, 0, 1, GasPriceTier::VeryLow); + arr[PUSH32 as usize] = InstructionInfo::new("PUSH32", 32, 0, 1, GasPriceTier::VeryLow); + arr[DUP1 as usize] = InstructionInfo::new("DUP1", 0, 1, 2, GasPriceTier::VeryLow); + arr[DUP2 as usize] = InstructionInfo::new("DUP2", 0, 2, 3, GasPriceTier::VeryLow); + arr[DUP3 as usize] = InstructionInfo::new("DUP3", 0, 3, 4, GasPriceTier::VeryLow); + arr[DUP4 as usize] = InstructionInfo::new("DUP4", 0, 4, 5, GasPriceTier::VeryLow); + arr[DUP5 as usize] = InstructionInfo::new("DUP5", 0, 5, 6, GasPriceTier::VeryLow); + arr[DUP6 as usize] = InstructionInfo::new("DUP6", 0, 6, 7, GasPriceTier::VeryLow); + arr[DUP7 as usize] = InstructionInfo::new("DUP7", 0, 7, 8, GasPriceTier::VeryLow); + arr[DUP8 as usize] = InstructionInfo::new("DUP8", 0, 8, 9, GasPriceTier::VeryLow); + arr[DUP9 as usize] = InstructionInfo::new("DUP9", 0, 9, 10, GasPriceTier::VeryLow); + arr[DUP10 as usize] = InstructionInfo::new("DUP10", 0, 10, 11, GasPriceTier::VeryLow); + arr[DUP11 as usize] = InstructionInfo::new("DUP11", 0, 11, 12, GasPriceTier::VeryLow); + arr[DUP12 as usize] = InstructionInfo::new("DUP12", 0, 12, 13, GasPriceTier::VeryLow); + arr[DUP13 as usize] = InstructionInfo::new("DUP13", 0, 13, 14, GasPriceTier::VeryLow); + arr[DUP14 as usize] = InstructionInfo::new("DUP14", 0, 14, 15, GasPriceTier::VeryLow); + arr[DUP15 as usize] = InstructionInfo::new("DUP15", 0, 15, 16, GasPriceTier::VeryLow); + arr[DUP16 as usize] = InstructionInfo::new("DUP16", 0, 16, 17, GasPriceTier::VeryLow); + arr[SWAP1 as usize] = InstructionInfo::new("SWAP1", 0, 2, 2, GasPriceTier::VeryLow); + arr[SWAP2 as usize] = InstructionInfo::new("SWAP2", 0, 3, 3, GasPriceTier::VeryLow); + arr[SWAP3 as usize] = InstructionInfo::new("SWAP3", 0, 4, 4, GasPriceTier::VeryLow); + arr[SWAP4 as usize] = InstructionInfo::new("SWAP4", 0, 5, 5, GasPriceTier::VeryLow); + arr[SWAP5 as usize] = InstructionInfo::new("SWAP5", 0, 6, 6, GasPriceTier::VeryLow); + arr[SWAP6 as usize] = InstructionInfo::new("SWAP6", 0, 7, 7, GasPriceTier::VeryLow); + arr[SWAP7 as usize] = InstructionInfo::new("SWAP7", 0, 8, 8, GasPriceTier::VeryLow); + arr[SWAP8 as usize] = InstructionInfo::new("SWAP8", 0, 9, 9, GasPriceTier::VeryLow); + arr[SWAP9 as usize] = InstructionInfo::new("SWAP9", 0, 10, 10, GasPriceTier::VeryLow); + arr[SWAP10 as usize] = InstructionInfo::new("SWAP10", 0, 11, 11, GasPriceTier::VeryLow); + arr[SWAP11 as usize] = InstructionInfo::new("SWAP11", 0, 12, 12, GasPriceTier::VeryLow); + arr[SWAP12 as usize] = InstructionInfo::new("SWAP12", 0, 13, 13, GasPriceTier::VeryLow); + arr[SWAP13 as usize] = InstructionInfo::new("SWAP13", 0, 14, 14, GasPriceTier::VeryLow); + arr[SWAP14 as usize] = InstructionInfo::new("SWAP14", 0, 15, 15, GasPriceTier::VeryLow); + arr[SWAP15 as usize] = InstructionInfo::new("SWAP15", 0, 16, 16, GasPriceTier::VeryLow); + arr[SWAP16 as usize] = InstructionInfo::new("SWAP16", 0, 17, 17, GasPriceTier::VeryLow); + arr[LOG0 as usize] = InstructionInfo::new("LOG0", 0, 2, 0, GasPriceTier::Special); + arr[LOG1 as usize] = InstructionInfo::new("LOG1", 0, 3, 0, GasPriceTier::Special); + arr[LOG2 as usize] = InstructionInfo::new("LOG2", 0, 4, 0, GasPriceTier::Special); + arr[LOG3 as usize] = InstructionInfo::new("LOG3", 0, 5, 0, GasPriceTier::Special); + arr[LOG4 as usize] = InstructionInfo::new("LOG4", 0, 6, 0, GasPriceTier::Special); + arr[CREATE as usize] = InstructionInfo::new("CREATE", 0, 3, 1, GasPriceTier::Special); + arr[CALL as usize] = InstructionInfo::new("CALL", 0, 7, 1, GasPriceTier::Special); + arr[CALLCODE as usize] = InstructionInfo::new("CALLCODE", 0, 7, 1, GasPriceTier::Special); + arr[RETURN as usize] = InstructionInfo::new("RETURN", 0, 2, 0, GasPriceTier::Zero); + arr[DELEGATECALL as usize] = InstructionInfo::new("DELEGATECALL", 0, 6, 1, GasPriceTier::Special); + arr[SUICIDE as usize] = InstructionInfo::new("SUICIDE", 0, 1, 0, GasPriceTier::Special); + arr[CREATE2 as usize] = InstructionInfo::new("CREATE2", 0, 3, 1, GasPriceTier::Special); + arr[REVERT as usize] = InstructionInfo::new("REVERT", 0, 2, 0, GasPriceTier::Zero); arr }; } diff --git a/ethcore/src/evm/interpreter/memory.rs b/ethcore/src/evm/interpreter/memory.rs index 555e4bc30..00f7a7d79 100644 --- a/ethcore/src/evm/interpreter/memory.rs +++ b/ethcore/src/evm/interpreter/memory.rs @@ -89,9 +89,10 @@ impl Memory for Vec { } fn write_slice(&mut self, offset: U256, slice: &[u8]) { - let off = offset.low_u64() as usize; - - self[off..off+slice.len()].copy_from_slice(slice); + if !slice.is_empty() { + let off = offset.low_u64() as usize; + self[off..off+slice.len()].copy_from_slice(slice); + } } fn write(&mut self, offset: U256, value: U256) { @@ -183,5 +184,12 @@ mod tests { assert_eq!(mem.read_slice(U256::from(0), U256::from(7)), "a67890g".as_bytes()); } + + // write empty slice out of bounds + { + let slice = []; + mem.write_slice(U256::from(0x1000), &slice); + assert_eq!(mem.size(), 32); + } } }