aboutsummaryrefslogtreecommitdiffstats
path: root/libevmasm/Instruction.h
diff options
context:
space:
mode:
authorDimitry <winsvega@mail.ru>2016-04-02 04:11:01 +0800
committerDimitry <winsvega@mail.ru>2016-04-02 04:11:01 +0800
commitccbd3ff63feb696025c18211c3c93bab47f755b0 (patch)
tree35ac9927eb5d6bb609efe763de6999e493c25e13 /libevmasm/Instruction.h
parentc492d9be00c843b8390959bd9f203c4047cb9f69 (diff)
downloaddexon-solidity-ccbd3ff63feb696025c18211c3c93bab47f755b0.tar.gz
dexon-solidity-ccbd3ff63feb696025c18211c3c93bab47f755b0.tar.zst
dexon-solidity-ccbd3ff63feb696025c18211c3c93bab47f755b0.zip
move libevmcore to solidity
Diffstat (limited to 'libevmasm/Instruction.h')
-rw-r--r--libevmasm/Instruction.h268
1 files changed, 268 insertions, 0 deletions
diff --git a/libevmasm/Instruction.h b/libevmasm/Instruction.h
new file mode 100644
index 00000000..2d415c08
--- /dev/null
+++ b/libevmasm/Instruction.h
@@ -0,0 +1,268 @@
+/*
+ This file is part of cpp-ethereum.
+
+ cpp-ethereum is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ cpp-ethereum is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
+*/
+/** @file Instruction.h
+ * @author Gav Wood <i@gavwood.com>
+ * @date 2014
+ */
+
+#pragma once
+
+#include <functional>
+#include <libdevcore/Common.h>
+#include <libdevcore/Assertions.h>
+#include "Exceptions.h"
+
+namespace dev
+{
+namespace eth
+{
+
+DEV_SIMPLE_EXCEPTION(InvalidDeposit);
+DEV_SIMPLE_EXCEPTION(InvalidOpcode);
+
+/// Virtual machine bytecode instruction.
+enum class Instruction: uint8_t
+{
+ STOP = 0x00, ///< halts execution
+ ADD, ///< addition operation
+ MUL, ///< mulitplication operation
+ SUB, ///< subtraction operation
+ DIV, ///< integer division operation
+ SDIV, ///< signed integer division operation
+ MOD, ///< modulo remainder operation
+ SMOD, ///< signed modulo remainder operation
+ ADDMOD, ///< unsigned modular addition
+ MULMOD, ///< unsigned modular multiplication
+ EXP, ///< exponential operation
+ SIGNEXTEND, ///< extend length of signed integer
+
+ LT = 0x10, ///< less-than comparision
+ GT, ///< greater-than comparision
+ SLT, ///< signed less-than comparision
+ SGT, ///< signed greater-than comparision
+ EQ, ///< equality comparision
+ ISZERO, ///< simple not operator
+ AND, ///< bitwise AND operation
+ OR, ///< bitwise OR operation
+ XOR, ///< bitwise XOR operation
+ NOT, ///< bitwise NOT opertation
+ BYTE, ///< retrieve single byte from word
+
+ SHA3 = 0x20, ///< compute SHA3-256 hash
+
+ ADDRESS = 0x30, ///< get address of currently executing account
+ BALANCE, ///< get balance of the given account
+ ORIGIN, ///< get execution origination address
+ CALLER, ///< get caller address
+ CALLVALUE, ///< get deposited value by the instruction/transaction responsible for this execution
+ CALLDATALOAD, ///< get input data of current environment
+ CALLDATASIZE, ///< get size of input data in current environment
+ CALLDATACOPY, ///< copy input data in current environment to memory
+ CODESIZE, ///< get size of code running in current environment
+ CODECOPY, ///< copy code running in current environment to memory
+ GASPRICE, ///< get price of gas in current environment
+ EXTCODESIZE, ///< get external code size (from another contract)
+ EXTCODECOPY, ///< copy external code (from another contract)
+
+ BLOCKHASH = 0x40, ///< get hash of most recent complete block
+ COINBASE, ///< get the block's coinbase address
+ TIMESTAMP, ///< get the block's timestamp
+ NUMBER, ///< get the block's number
+ DIFFICULTY, ///< get the block's difficulty
+ GASLIMIT, ///< get the block's gas limit
+
+ POP = 0x50, ///< remove item from stack
+ MLOAD, ///< load word from memory
+ MSTORE, ///< save word to memory
+ MSTORE8, ///< save byte to memory
+ SLOAD, ///< load word from storage
+ SSTORE, ///< save word to storage
+ JUMP, ///< alter the program counter
+ JUMPI, ///< conditionally alter the program counter
+ PC, ///< get the program counter
+ MSIZE, ///< get the size of active memory
+ GAS, ///< get the amount of available gas
+ JUMPDEST, ///< set a potential jump destination
+
+ PUSH1 = 0x60, ///< place 1 byte item on stack
+ PUSH2, ///< place 2 byte item on stack
+ PUSH3, ///< place 3 byte item on stack
+ PUSH4, ///< place 4 byte item on stack
+ PUSH5, ///< place 5 byte item on stack
+ PUSH6, ///< place 6 byte item on stack
+ PUSH7, ///< place 7 byte item on stack
+ PUSH8, ///< place 8 byte item on stack
+ PUSH9, ///< place 9 byte item on stack
+ PUSH10, ///< place 10 byte item on stack
+ PUSH11, ///< place 11 byte item on stack
+ PUSH12, ///< place 12 byte item on stack
+ PUSH13, ///< place 13 byte item on stack
+ PUSH14, ///< place 14 byte item on stack
+ PUSH15, ///< place 15 byte item on stack
+ PUSH16, ///< place 16 byte item on stack
+ PUSH17, ///< place 17 byte item on stack
+ PUSH18, ///< place 18 byte item on stack
+ PUSH19, ///< place 19 byte item on stack
+ PUSH20, ///< place 20 byte item on stack
+ PUSH21, ///< place 21 byte item on stack
+ PUSH22, ///< place 22 byte item on stack
+ PUSH23, ///< place 23 byte item on stack
+ PUSH24, ///< place 24 byte item on stack
+ PUSH25, ///< place 25 byte item on stack
+ PUSH26, ///< place 26 byte item on stack
+ PUSH27, ///< place 27 byte item on stack
+ PUSH28, ///< place 28 byte item on stack
+ PUSH29, ///< place 29 byte item on stack
+ PUSH30, ///< place 30 byte item on stack
+ PUSH31, ///< place 31 byte item on stack
+ PUSH32, ///< place 32 byte item on stack
+
+ DUP1 = 0x80, ///< copies the highest item in the stack to the top of the stack
+ DUP2, ///< copies the second highest item in the stack to the top of the stack
+ DUP3, ///< copies the third highest item in the stack to the top of the stack
+ DUP4, ///< copies the 4th highest item in the stack to the top of the stack
+ DUP5, ///< copies the 5th highest item in the stack to the top of the stack
+ DUP6, ///< copies the 6th highest item in the stack to the top of the stack
+ DUP7, ///< copies the 7th highest item in the stack to the top of the stack
+ DUP8, ///< copies the 8th highest item in the stack to the top of the stack
+ DUP9, ///< copies the 9th highest item in the stack to the top of the stack
+ DUP10, ///< copies the 10th highest item in the stack to the top of the stack
+ DUP11, ///< copies the 11th highest item in the stack to the top of the stack
+ DUP12, ///< copies the 12th highest item in the stack to the top of the stack
+ DUP13, ///< copies the 13th highest item in the stack to the top of the stack
+ DUP14, ///< copies the 14th highest item in the stack to the top of the stack
+ DUP15, ///< copies the 15th highest item in the stack to the top of the stack
+ DUP16, ///< copies the 16th highest item in the stack to the top of the stack
+
+ SWAP1 = 0x90, ///< swaps the highest and second highest value on the stack
+ SWAP2, ///< swaps the highest and third highest value on the stack
+ SWAP3, ///< swaps the highest and 4th highest value on the stack
+ SWAP4, ///< swaps the highest and 5th highest value on the stack
+ SWAP5, ///< swaps the highest and 6th highest value on the stack
+ SWAP6, ///< swaps the highest and 7th highest value on the stack
+ SWAP7, ///< swaps the highest and 8th highest value on the stack
+ SWAP8, ///< swaps the highest and 9th highest value on the stack
+ SWAP9, ///< swaps the highest and 10th highest value on the stack
+ SWAP10, ///< swaps the highest and 11th highest value on the stack
+ SWAP11, ///< swaps the highest and 12th highest value on the stack
+ SWAP12, ///< swaps the highest and 13th highest value on the stack
+ SWAP13, ///< swaps the highest and 14th highest value on the stack
+ SWAP14, ///< swaps the highest and 15th highest value on the stack
+ SWAP15, ///< swaps the highest and 16th highest value on the stack
+ SWAP16, ///< swaps the highest and 17th highest value on the stack
+
+ LOG0 = 0xa0, ///< Makes a log entry; no topics.
+ LOG1, ///< Makes a log entry; 1 topic.
+ LOG2, ///< Makes a log entry; 2 topics.
+ LOG3, ///< Makes a log entry; 3 topics.
+ LOG4, ///< Makes a log entry; 4 topics.
+
+ CREATE = 0xf0, ///< create a new account with associated code
+ CALL, ///< message-call into an account
+ CALLCODE, ///< message-call with another account's code only
+ RETURN, ///< halt execution returning output data
+ DELEGATECALL, ///< like CALLCODE but keeps caller's value and sender
+ SUICIDE = 0xff ///< halt execution and register account for later deletion
+};
+
+/// @returns the number of PUSH Instruction _inst
+inline unsigned getPushNumber(Instruction _inst)
+{
+ return (byte)_inst - unsigned(Instruction::PUSH1) + 1;
+}
+
+/// @returns the number of DUP Instruction _inst
+inline unsigned getDupNumber(Instruction _inst)
+{
+ return (byte)_inst - unsigned(Instruction::DUP1) + 1;
+}
+
+/// @returns the number of SWAP Instruction _inst
+inline unsigned getSwapNumber(Instruction _inst)
+{
+ return (byte)_inst - unsigned(Instruction::SWAP1) + 1;
+}
+
+/// @returns the PUSH<_number> instruction
+inline Instruction pushInstruction(unsigned _number)
+{
+ assertThrow(1 <= _number && _number <= 32, InvalidOpcode, "Invalid PUSH instruction requested.");
+ return Instruction(unsigned(Instruction::PUSH1) + _number - 1);
+}
+
+/// @returns the DUP<_number> instruction
+inline Instruction dupInstruction(unsigned _number)
+{
+ assertThrow(1 <= _number && _number <= 16, InvalidOpcode, "Invalid DUP instruction requested.");
+ return Instruction(unsigned(Instruction::DUP1) + _number - 1);
+}
+
+/// @returns the SWAP<_number> instruction
+inline Instruction swapInstruction(unsigned _number)
+{
+ assertThrow(1 <= _number && _number <= 16, InvalidOpcode, "Invalid SWAP instruction requested.");
+ return Instruction(unsigned(Instruction::SWAP1) + _number - 1);
+}
+
+/// @returns the LOG<_number> instruction
+inline Instruction logInstruction(unsigned _number)
+{
+ assertThrow(_number <= 4, InvalidOpcode, "Invalid LOG instruction requested.");
+ return Instruction(unsigned(Instruction::LOG0) + _number);
+}
+
+enum Tier
+{
+ ZeroTier = 0, // 0, Zero
+ BaseTier, // 2, Quick
+ VeryLowTier, // 3, Fastest
+ LowTier, // 5, Fast
+ MidTier, // 8, Mid
+ HighTier, // 10, Slow
+ ExtTier, // 20, Ext
+ SpecialTier, // multiparam or otherwise special
+ InvalidTier // Invalid.
+};
+
+/// Information structure for a particular instruction.
+struct InstructionInfo
+{
+ std::string name; ///< The name of the instruction.
+ int additional; ///< Additional items required in memory for this instructions (only for PUSH).
+ int args; ///< Number of items required on the stack for this instruction (and, for the purposes of ret, the number taken from the stack).
+ int ret; ///< Number of items placed (back) on the stack by this instruction, assuming args items were removed.
+ bool sideEffects; ///< false if the only effect on the execution environment (apart from gas usage) is a change to a topmost segment of the stack
+ int gasPriceTier; ///< Tier for gas pricing.
+};
+
+/// Information on all the instructions.
+InstructionInfo instructionInfo(Instruction _inst);
+
+/// check whether instructions exists
+bool isValidInstruction(Instruction _inst);
+
+/// Convert from string mnemonic to Instruction type.
+extern const std::map<std::string, Instruction> c_instructions;
+
+/// Iterate through EVM code and call a function on each instruction.
+void eachInstruction(bytes const& _mem, std::function<void(Instruction,u256 const&)> const& _onInstruction);
+
+/// Convert from EVM code to simple EVM assembly language.
+std::string disassemble(bytes const& _mem);
+
+}
+}