Last active
June 7, 2018 19:53
-
-
Save mratsim/a54b8e366063b0e75c122a3cf9066d91 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Nimbus | |
# Copyright (c) 2018 Status Research & Development GmbH | |
# Licensed under either of | |
# * Apache License, version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or http://www.apache.org/licenses/LICENSE-2.0) | |
# * MIT license ([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT) | |
# at your option. This file may not be copied, modified, or distributed except according to those terms. | |
import tables | |
type | |
# Yellow Paper Appendix H - https://ethereum.github.io/yellowpaper/paper.pdf | |
# Special notes from Yellow Paper: | |
# - Signed values are treated as two’s complement signed 256-bit integers. | |
# - When −2^255 is negated, there is an overflow | |
# - For addmod and mulmod, intermediate computations are not subject to the 2^256 modulo. | |
# Nimbus authors note: | |
# - This means that we can't naively do (Uint256 + Uint256) mod uint256, | |
# because the intermediate sum (or multiplication) might roll over if | |
# intermediate result is greater or equal 2^256 | |
Op* {.pure.} = enum | |
# 0s: Stop and Arithmetic Operations | |
Stop = 0x00, # Halts execution. | |
Add = 0x01, # Addition operation. | |
Mul = 0x02, # Multiplication operation. | |
Sub = 0x03, # Subtraction operation. | |
Div = 0x04, # Integer division operation. | |
Sdiv = 0x05, # Signed integer division operation (truncated). | |
Mod = 0x06, # Modulo remainder operation. | |
Smod = 0x07, # Signed modulo remainder operation. | |
Addmod = 0x08, # Modulo addition operation. | |
Mulmod = 0x09, # Modulo multiplication operation. | |
Exp = 0x0A, # Exponential operation | |
SignExtend = 0x0B, # Extend length of two’s complement signed integer. | |
# 10s: Comparison & Bitwise Logic Operations | |
Lt = 0x10, # Less-than comparison. | |
Gt = 0x11, # Greater-than comparison. | |
Slt = 0x12, # Signed less-than comparison. | |
Sgt = 0x13, # Signed greater-than comparison. | |
Eq = 0x14, # Equality comparison. | |
IsZero = 0x15, # Simple not operator. (Note: real Yellow Paper description) | |
And = 0x16, # Bitwise AND operation. | |
Or = 0x17, # Bitwise OR operation. | |
Xor = 0x18, # Bitwise XOR operation. | |
Not = 0x19, # Bitwise NOT operation. | |
Byte = 0x1A, # Retrieve single byte from word. | |
# 20s: SHA3 | |
Sha3 = 0x20, # Compute Keccak-256 hash. | |
# 30s: Environmental Information | |
Address = 0x30, # Get address of currently executing account. | |
Balance = 0x31, # Get balance of the given account. | |
Origin = 0x32, # Get execution origination address. | |
Caller = 0x33, # Get caller address. | |
CallValue = 0x34, # Get deposited value by the instruction/transaction responsible for this execution. | |
CallDataLoad = 0x35, # Get input data of current environment. | |
CallDataSize = 0x36, # Get size of input data in current environment. | |
CallDataCopy = 0x37, # Copy input data in current environment to memory. | |
CodeSize = 0x38, # Get size of code running in current environment. | |
CodeCopy = 0x39, # Copy code running in current environment to memory. | |
GasPrice = 0x3a, # Get price of gas in current environment. | |
ExtCodeSize = 0x3b, # Get size of an account's code | |
ExtCodeCopy = 0x3c, # Copy an account's code to memory. | |
ReturnDataSize = 0x3d, # Get size of output data from the previous call from the current environment. | |
ReturnDataCopy = 0x3e, # Copy output data from the previous call to memory. | |
# 40s: Block Information | |
Blockhash = 0x40, # Get the hash of one of the 256 most recent complete blocks. | |
Coinbase = 0x41, # Get the block's beneficiary address. | |
Timestamp = 0x42, # Get the block's timestamp. | |
Number = 0x43, # Get the block's number. | |
Difficulty = 0x44, # Get the block's difficulty. | |
GasLimit = 0x45, # Get the block's gas limit. | |
# 50s: Stack, Memory, Storage and Flow Operations | |
Pop = 0x50, # Remove item from stack. | |
Mload = 0x51, # Load word from memory. | |
Mstore = 0x52, # Save word to memory. | |
Mstore8 = 0x53, # Save byte to memory. | |
Sload = 0x54, # Load word from storage. | |
Sstore = 0x55, # Save word to storage. | |
Jump = 0x56, # Alter the program counter. | |
JumpI = 0x57, # Conditionally alter the program counter. | |
Pc = 0x58, # Get the value of the program counter prior to the increment corresponding to this instruction. | |
Msize = 0x59, # Get the size of active memory in bytes. | |
Gas = 0x5a, # Get the amount of available gas, including the corresponding reduction for the cost of this instruction. | |
JumpDest = 0x5b, # Mark a valid destination for jumps. This operation has no effect on machine state during execution. | |
# 60s & 70s: Push Operations. | |
Push1 = 0x60, # Place 1-byte item on stack. | |
Push2 = 0x61, # Place 2-byte item on stack. | |
Push3, | |
Push4, | |
Push5, | |
Push6, | |
Push7, | |
Push8, | |
Push9, | |
Push10, | |
Push11, | |
Push12, | |
Push13, | |
Push14, | |
Push15, | |
Push16, | |
Push17, | |
Push18, | |
Push19, | |
Push20, | |
Push21, | |
Push22, | |
Push23, | |
Push24, | |
Push25, | |
Push26, | |
Push27, | |
Push28, | |
Push29, | |
Push30, | |
Push31, | |
Push32 = 0x7f, # Place 32-byte (full word) item on stack. | |
# 80s: Duplication Operations | |
Dup1 = 0x80, # Duplicate 1st stack item. | |
Dup2 = 0x81, # Duplicate 2nd stack item. | |
Dup3, | |
Dup4, | |
Dup5, | |
Dup6, | |
Dup7, | |
Dup8, | |
Dup9, | |
Dup10, | |
Dup11, | |
Dup12, | |
Dup13, | |
Dup14, | |
Dup15, | |
Dup16 = 0x8f, # Duplicate 16th stack item. | |
# 90s: Exchange Operations | |
Swap1 = 0x90, # Exchange 1st and 2nd stack items. | |
Swap2 = 0x91, # Exchange 1st and 3rd stack items. | |
Swap3, | |
Swap4, | |
Swap5, | |
Swap6, | |
Swap7, | |
Swap8, | |
Swap9, | |
Swap10, | |
Swap11, | |
Swap12, | |
Swap13, | |
Swap14, | |
Swap15, | |
Swap16 = 0x9f, # Exchange 1st and 17th stack items. | |
# a0s: Logging Operations | |
Log0 = 0xa0, # Append log record with no topics. | |
Log1 = 0xa1, # Append log record with one topics. | |
Log2, | |
Log3, | |
Log4 = 0xa4, # Append log record with four topics. | |
# f0s: System operations | |
Create = 0xf0, # Create a new account with associated code. | |
Call = 0xf1, # Message-call into an account. | |
CallCode = 0xf2, # Message-call into this account with an alternative account's code. | |
Return = 0xf3, # Halt execution returning output data. | |
DelegateCall = 0xf4, # Message-call into this account with an alternative account's code, but persisting the current values for sender and value. | |
StaticCall = 0xfa, # Static message-call into an account. | |
Revert = 0xfd, # Halt execution reverting state changes but returning data and remaining gas. | |
Invalid = 0xfe, # Designated invalid instruction. | |
SelfDestruct = 0xff # Halt execution and register account for later deletion. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Nimbus | |
# Copyright (c) 2018 Status Research & Development GmbH | |
# Licensed under either of | |
# * Apache License, version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or http://www.apache.org/licenses/LICENSE-2.0) | |
# * MIT license ([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT) | |
# at your option. This file may not be copied, modified, or distributed except according to those terms. | |
import | |
strformat, strutils, tables, macros, | |
constants, stint, errors, logging, vm_state, | |
vm / [gas_meter, stack, code_stream, memory, message], db / db_chain, computation, opcode, opcode_values, utils / [header, address], | |
logic / [arithmetic, comparison, sha3, context, block_ops, stack_ops, duplication, swap, memory_ops, storage, flow, logging_ops, invalid, call, system_ops], | |
./vm_types | |
## Before | |
var OPCODE_TABLE* = initOpcodes: | |
# arithmetic | |
Op.Add: GasVeryLow add | |
Op.Mul: GasLow mul | |
Op.Sub: GasVeryLow sub | |
Op.Div: GasLow divide | |
Op.SDiv: GasLow sdiv | |
Op.Mod: GasLow modulo | |
Op.SMod: GasLow smod | |
Op.AddMod: GasMid addmod | |
Op.MulMod: GasMid mulmod | |
Op.Exp: GasInHandler arithmetic.exp | |
Op.SignExtend: GasLow signextend | |
# comparison | |
Op.Lt: GasVeryLow lt | |
Op.Gt: GasVeryLow gt | |
Op.SLt: GasVeryLow slt | |
Op.SGt: GasVeryLow sgt | |
Op.Eq: GasVeryLow eq | |
Op.IsZero: GasVeryLow iszero | |
Op.And: GasVeryLow andOp | |
Op.Or: GasVeryLow orOp | |
Op.Xor: GasVeryLow xorOp | |
Op.Not: GasVeryLow notOp | |
Op.Byte: GasVeryLow byteOp | |
# sha3 | |
Op.SHA3: GasSHA3 sha3op | |
# context | |
Op.Address: GasBase context.address | |
Op.Balance: GasBalance balance | |
Op.Origin: GasBase origin | |
Op.Caller: GasBase caller | |
Op.CallValue: GasBase callValue | |
Op.CallDataLoad: GasVeryLow callDataLoad | |
Op.CallDataSize: GasBase callDataSize | |
Op.CallDataCopy: GasBase callDataCopy | |
Op.CodeSize: GasBase codesize | |
Op.CodeCopy: GasBase codecopy | |
Op.ExtCodeSize: GasExtCode extCodeSize | |
Op.ExtCodeCopy: GasExtCode extCodeCopy | |
# block | |
Op.Blockhash: GasBase block_ops.blockhash | |
Op.Coinbase: GasCoinbase coinbase | |
Op.Timestamp: GasBase timestamp | |
Op.Number: GasBase number | |
Op.Difficulty: GasBase difficulty | |
Op.GasLimit: GasBase gaslimit | |
# stack | |
Op.Pop: GasBase stack_ops.pop | |
1..32 Op.PushXX: GasVeryLow pushXX # XX replaced by macro | |
1..16 Op.DupXX: GasVeryLow dupXX | |
1..16 Op.SwapXX: GasVeryLow swapXX | |
# memory | |
Op.MLoad: GasVeryLow mload | |
Op.MStore: GasVeryLow mstore | |
Op.MStore8: GasVeryLow mstore8 | |
Op.MSize: GasBase msize | |
# storage | |
Op.SLoad: GasSload sload | |
Op.SStore: GasInHandler sstore | |
# flow | |
Op.Jump: GasMid jump | |
Op.JumpI: GasMid jumpi | |
Op.PC: GasHigh pc | |
Op.Gas: GasBase flow.gas | |
Op.JumpDest: GasJumpDest jumpdest | |
Op.Stop: GasZero stop | |
# logging | |
0..4 Op.LogXX: GasInHandler logXX | |
# invalid | |
Op.Invalid: GasZero invalidOp | |
# system | |
Op.Return: GasZero returnOp | |
Op.SelfDestruct: GasSelfDestruct selfdestruct | |
# call | |
OPCODE_TABLE[Op.Call] = Call(kind: Op.Call) | |
OPCODE_TABLE[Op.CallCode] = CallCode(kind: Op.CallCode) | |
OPCODE_TABLE[Op.DelegateCall] = DelegateCall(kind: Op.DelegateCall) | |
# system | |
OPCODE_TABLE[Op.Create] = Create(kind: Op.Create) | |
##### After | |
const | |
OpLogic: Table[Op, proc(computation: var BaseComputation){.nimcall.}] = { | |
# 0s: Stop and Arithmetic Operations | |
STOP: stop, # 0 | |
ADD: arithmetic.add, # 1 | |
MUL: mul, # 2 | |
SUB: sub, # 3 | |
DIV: divide, # 4 | |
SDIV: sdiv, # 5 | |
MOD: modulo, # 6 | |
SMOD: smod, # 7 | |
ADDMOD: arithmetic.addmod, # 8 | |
MULMOD: arithmetic.mulmod, # 9 | |
EXP: arithmetic.exp, # 10 | |
SIGNEXTEND: signextend, # 11 | |
# 10s: Comparison & Bitwise Logic Operations | |
LT: lt, # 16 | |
GT: gt, # 17 | |
SLT: slt, # 18 | |
SGT: sgt, # 19 | |
EQ: eq, # 20 | |
ISZERO: comparison.isZero, # 21 | |
AND: andOp, # 22 | |
OR: orOp, # 23 | |
XOR: xorOp, # 24 | |
NOT: notOp, # 25 | |
BYTE: byteOp, # 26 | |
# 20s: SHA3 | |
SHA3: sha3op, # 32 | |
# 30s: Environmental Information | |
ADDRESS: context.address, # 48 | |
BALANCE: balance, # 49 | |
ORIGIN: context.origin, # 50 | |
CALLER: caller, # 51 | |
CALLVALUE: callValue, # 52 | |
CALLDATALOAD: callDataLoad, # 53 | |
CALLDATASIZE: callDataSize, # 54 | |
CALLDATACOPY: callDataCopy, # 55 | |
CODESIZE: codesize, # 56 | |
CODECOPY: codecopy, # 57 | |
GASPRICE: gasPrice, # 58 # TODO this wasn't used previously | |
EXTCODESIZE: extCodeSize, # 59 | |
EXTCODECOPY: extCodeCopy, # 60 | |
RETURNDATASIZE: returnDataSize, # 61 # TODO this wasn't used previously | |
RETURNDATACOPY: returnDataCopy, # 62 | |
# 40s: Block Information | |
BLOCKHASH: block_ops.blockhash, # 64 | |
COINBASE: block_ops.coinbase, # 65 | |
TIMESTAMP: block_ops.timestamp, # 66 | |
NUMBER: block_ops.number, # 67 | |
DIFFICULTY: block_ops.difficulty, # 68 | |
GASLIMIT: block_ops.gaslimit, # 69 | |
# 50s: Stack, Memory, Storage and Flow Operations | |
POP: stack_ops.pop, # 80 | |
MLOAD: mload, # 81 | |
MSTORE: mstore, # 82 | |
MSTORE8: mstore8, # 83 | |
SLOAD: sload, # 84 | |
SSTORE: sstore, # 85 | |
JUMP: jump, # 86 | |
JUMPI: jumpi, # 87 | |
PC: pc, # 88 | |
MSIZE: msize, # 89 | |
GAS: flow.gas, # 90 | |
JUMPDEST: jumpDest, # 91 | |
# 60s & 70s: Push Operations | |
PUSH1: push1, # 96 | |
PUSH2: push2, # 97 | |
PUSH3: push3, # 98 | |
PUSH4: push4, # 99 | |
PUSH5: push5, # 100 | |
PUSH6: push6, # 101 | |
PUSH7: push7, # 102 | |
PUSH8: push8, # 103 | |
PUSH9: push9, # 104 | |
PUSH10: push10, | |
PUSH11: push11, | |
PUSH12: push12, | |
PUSH13: push13, | |
PUSH14: push14, | |
PUSH15: push15, | |
PUSH16: push16, | |
PUSH17: push17, | |
PUSH18: push18, | |
PUSH19: push19, | |
PUSH20: push20, | |
PUSH21: push21, | |
PUSH22: push22, | |
PUSH23: push23, | |
PUSH24: push24, | |
PUSH25: push25, | |
PUSH26: push26, | |
PUSH27: push27, | |
PUSH28: push28, | |
PUSH29: push29, | |
PUSH30: push30, | |
PUSH31: push31, | |
PUSH32: push32, | |
# 80s: Duplication Operations | |
DUP1: dup1, # 128 | |
DUP2: dup2, # 129 | |
DUP3: dup3, # 130 | |
DUP4: dup4, # 131 | |
DUP5: dup5, # 132 | |
DUP6: dup6, # 133 | |
DUP7: dup7, # 134 | |
DUP8: dup8, # 135 | |
DUP9: dup9, # 136 | |
DUP10: dup10, # 137 | |
DUP11: dup11, # 138 | |
DUP12: dup12, # 139 | |
DUP13: dup13, # 140 | |
DUP14: dup14, # 141 | |
DUP15: dup15, # 142 | |
DUP16: dup16, # 143 | |
# 90s: Exchange Operations | |
SWAP1: swap1, # 144 | |
SWAP2: swap2, # 145 | |
SWAP3: swap3, # 146 | |
SWAP4: swap4, # 147 | |
SWAP5: swap5, # 148 | |
SWAP6: swap6, # 149 | |
SWAP7: swap7, # 150 | |
SWAP8: swap8, # 151 | |
SWAP9: swap9, # 152 | |
SWAP10: swap10, # 153 | |
SWAP11: swap11, # 154 | |
SWAP12: swap12, # 155 | |
SWAP13: swap13, # 156 | |
SWAP14: swap14, # 157 | |
SWAP15: swap15, # 158 | |
SWAP16: swap16, # 159 | |
# a0s: Logging Operations | |
LOG0: log0, # 160 | |
LOG1: log1, # 161 | |
LOG2: log2, # 162 | |
LOG3: log3, # 163 | |
LOG4: log4, # 164 | |
# f0s: System operations | |
# CREATE: create, # 240 | |
# CALL: call, # 241 | |
# CALLCODE: callCode, # 242 | |
RETURN: returnOp, # 243 | |
# DELEGATECALL: delegateCall, # 244 | |
# STATICCALL: staticCall, # 250 | |
Op.REVERT: revert, # 253 | |
INVALID: invalidOp, # 254 | |
SELFDESTRUCT: selfDestruct # 255 | |
}.toTable |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment