verifying new op handler tables layout against original tables

why:
  the previous approach was replacing the function-lets in
  opcode_impl.nim by the particulate table handlers. the test
  functions will verify the the handler functions are sort of
  correct but not the assignments in the fork tables.

  the handler names of old and new for tables are checked here.

caveat:
  verifying tables currently takes a while at compile time.
This commit is contained in:
Jordan Hrycaj 2021-04-19 10:15:35 +01:00 committed by zah
parent 4e2af7937b
commit 51587208b4
14 changed files with 408 additions and 28 deletions

View File

@ -59,6 +59,8 @@ proc mkOpTable(select: Fork): array[Op,Vm2OpExec] {.compileTime.} =
if select notin result[op].forks:
result[op] = result[Invalid]
result[op].opCode = op
if op == Stop:
result[op].name = "toBeReplacedByBreak"
# ------------------------------------------------------------------------------
# Public handler tables
@ -71,16 +73,6 @@ const
rc[w] = w.mkOpTable
rc
# vm2OpTabFrontier* = vm2OpHandlers[FkFrontier]
# vm2OpTabHomestead* = vm2OpHandlers[FkHomestead]
# vm2OpTabTangerine* = vm2OpHandlers[FkTangerine]
# vm2OpTabSpurious* = vm2OpHandlers[FkSpurious]
# vm2OpTabByzantium* = vm2OpHandlers[FkByzantium]
# vm2OpTabConstantinople* = vm2OpHandlers[FkConstantinople]
# vm2OpTabPetersburg* = vm2OpHandlers[FkPetersburg]
# vm2OpTabIstanbul* = vm2OpHandlers[FkIstanbul]
# vm2OpTabBerlin* = vm2OpHandlers[FkBerlin]
# ------------------------------------------------------------------------------
# Debugging ...
# ------------------------------------------------------------------------------

View File

@ -334,6 +334,7 @@ const
(opCode: Add, ## 0x01, Addition
forks: Vm2OpAllForks,
name: "add",
info: "Addition operation",
exec: (prep: vm2OpIgnore,
run: addOp,
@ -341,6 +342,7 @@ const
(opCode: Mul, ## 0x02, Multiplication
forks: Vm2OpAllForks,
name: "mul",
info: "Multiplication operation",
exec: (prep: vm2OpIgnore,
run: mulOp,
@ -348,6 +350,7 @@ const
(opCode: Sub, ## 0x03, Subtraction
forks: Vm2OpAllForks,
name: "sub",
info: "Subtraction operation",
exec: (prep: vm2OpIgnore,
run: subOp,
@ -355,6 +358,7 @@ const
(opCode: Div, ## 0x04, Division
forks: Vm2OpAllForks,
name: "divide",
info: "Integer division operation",
exec: (prep: vm2OpIgnore,
run: divideOp,
@ -362,6 +366,7 @@ const
(opCode: Sdiv, ## 0x05, Signed division
forks: Vm2OpAllForks,
name: "sdiv",
info: "Signed integer division operation (truncated)",
exec: (prep: vm2OpIgnore,
run: sdivOp,
@ -369,6 +374,7 @@ const
(opCode: Mod, ## 0x06, Modulo
forks: Vm2OpAllForks,
name: "modulo",
info: "Modulo remainder operation",
exec: (prep: vm2OpIgnore,
run: moduloOp,
@ -376,6 +382,7 @@ const
(opCode: Smod, ## 0x07, Signed modulo
forks: Vm2OpAllForks,
name: "smod",
info: "Signed modulo remainder operation",
exec: (prep: vm2OpIgnore,
run: smodOp,
@ -384,6 +391,7 @@ const
(opCode: AddMod, ## 0x08, Modulo addition, Intermediate
## computations do not roll over at 2^256
forks: Vm2OpAllForks,
name: "addmod",
info: "Modulo addition operation",
exec: (prep: vm2OpIgnore,
run: addmodOp,
@ -392,6 +400,7 @@ const
(opCode: MulMod, ## 0x09, Modulo multiplication, Intermediate
## computations do not roll over at 2^256
forks: Vm2OpAllForks,
name: "mulmod",
info: "Modulo multiplication operation",
exec: (prep: vm2OpIgnore,
run: mulmodOp,
@ -399,6 +408,7 @@ const
(opCode: Exp, ## 0x0a, Exponentiation
forks: Vm2OpAllForks,
name: "exp",
info: "Exponentiation operation",
exec: (prep: vm2OpIgnore,
run: expOp,
@ -406,6 +416,7 @@ const
(opCode: SignExtend, ## 0x0b, Extend 2's complemet length
forks: Vm2OpAllForks,
name: "signExtend",
info: "Extend length of twos complement signed integer",
exec: (prep: vm2OpIgnore,
run: signExtendOp,
@ -413,6 +424,7 @@ const
(opCode: Lt, ## 0x10, Less-than
forks: Vm2OpAllForks,
name: "lt",
info: "Less-than comparison",
exec: (prep: vm2OpIgnore,
run: ltOp,
@ -420,6 +432,7 @@ const
(opCode: Gt, ## 0x11, Greater-than
forks: Vm2OpAllForks,
name: "gt",
info: "Greater-than comparison",
exec: (prep: vm2OpIgnore,
run: gtOp,
@ -427,6 +440,7 @@ const
(opCode: Slt, ## 0x12, Signed less-than
forks: Vm2OpAllForks,
name: "slt",
info: "Signed less-than comparison",
exec: (prep: vm2OpIgnore,
run: sltOp,
@ -434,6 +448,7 @@ const
(opCode: Sgt, ## 0x13, Signed greater-than
forks: Vm2OpAllForks,
name: "sgt",
info: "Signed greater-than comparison",
exec: (prep: vm2OpIgnore,
run: sgtOp,
@ -441,6 +456,7 @@ const
(opCode: Eq, ## 0x14, Equality
forks: Vm2OpAllForks,
name: "eq",
info: "Equality comparison",
exec: (prep: vm2OpIgnore,
run: eqOp,
@ -448,6 +464,7 @@ const
(opCode: IsZero, ## 0x15, Not operator
forks: Vm2OpAllForks,
name: "isZero",
info: "Simple not operator (Note: real Yellow Paper description)",
exec: (prep: vm2OpIgnore,
run: isZeroOp,
@ -455,6 +472,7 @@ const
(opCode: And, ## 0x16, AND
forks: Vm2OpAllForks,
name: "andOp",
info: "Bitwise AND operation",
exec: (prep: vm2OpIgnore,
run: andOp,
@ -462,6 +480,7 @@ const
(opCode: Or, ## 0x17, OR
forks: Vm2OpAllForks,
name: "orOp",
info: "Bitwise OR operation",
exec: (prep: vm2OpIgnore,
run: orOp,
@ -469,6 +488,7 @@ const
(opCode: Xor, ## 0x18, XOR
forks: Vm2OpAllForks,
name: "xorOp",
info: "Bitwise XOR operation",
exec: (prep: vm2OpIgnore,
run: xorOp,
@ -476,6 +496,7 @@ const
(opCode: Not, ## 0x19, NOT
forks: Vm2OpAllForks,
name: "notOp",
info: "Bitwise NOT operation",
exec: (prep: vm2OpIgnore,
run: notOp,
@ -483,6 +504,7 @@ const
(opCode: Byte, ## 0x1a, Retrieve byte
forks: Vm2OpAllForks,
name: "byteOp",
info: "Retrieve single byte from word",
exec: (prep: vm2OpIgnore,
run: byteOp,
@ -492,6 +514,7 @@ const
(opCode: Shl, ## 0x1b, Shift left
forks: Vm2OpConstantinopleAndLater,
name: "shlOp",
info: "Shift left",
exec: (prep: vm2OpIgnore,
run: shlOp,
@ -499,6 +522,7 @@ const
(opCode: Shr, ## 0x1c, Shift right logical
forks: Vm2OpConstantinopleAndLater,
name: "shrOp",
info: "Logical shift right",
exec: (prep: vm2OpIgnore,
run: shrOp,
@ -506,6 +530,7 @@ const
(opCode: Sar, ## 0x1d, Shift right arithmetic
forks: Vm2OpConstantinopleAndLater,
name: "sarOp",
info: "Arithmetic shift right",
exec: (prep: vm2OpIgnore,
run: sarOp,

View File

@ -115,6 +115,7 @@ const
(opCode: Blockhash, ## 0x40, Hash of some most recent complete block
forks: Vm2OpAllForks,
name: "blockhash",
info: "Get the hash of one of the 256 most recent complete blocks",
exec: (prep: vm2OpIgnore,
run: blockhashOp,
@ -122,6 +123,7 @@ const
(opCode: Coinbase, ## 0x41, Beneficiary address
forks: Vm2OpAllForks,
name: "coinbase",
info: "Get the block's beneficiary address",
exec: (prep: vm2OpIgnore,
run: coinBaseOp,
@ -129,6 +131,7 @@ const
(opCode: Timestamp, ## 0x42, Block timestamp.
forks: Vm2OpAllForks,
name: "timestamp",
info: "Get the block's timestamp",
exec: (prep: vm2OpIgnore,
run: timestampOp,
@ -136,6 +139,7 @@ const
(opCode: Number, ## 0x43, Block number
forks: Vm2OpAllForks,
name: "blockNumber",
info: "Get the block's number",
exec: (prep: vm2OpIgnore,
run: blocknumberOp,
@ -143,6 +147,7 @@ const
(opCode: Difficulty, ## 0x44, Block difficulty
forks: Vm2OpAllForks,
name: "difficulty",
info: "Get the block's difficulty",
exec: (prep: vm2OpIgnore,
run: difficultyOp,
@ -150,20 +155,23 @@ const
(opCode: GasLimit, ## 0x45, Block gas limit
forks: Vm2OpAllForks,
name: "gasLimit",
info: "Get the block's gas limit",
exec: (prep: vm2OpIgnore,
run: gasLimitOp,
post: vm2OpIgnore)),
(opCode: ChainId, ## 0x46, EIP-155 chain identifier
forks: Vm2OpAllForks,
forks: Vm2OpIstanbulAndLater,
name: "chainId",
info: "Get current chains EIP-155 unique identifier",
exec: (prep: vm2OpIgnore,
run: chainIdOp,
post: vm2OpIgnore)),
(opCode: SelfBalance, ## 0x47, Contract balance.
forks: Vm2OpAllForks,
forks: Vm2OpIstanbulAndLater,
name: "selfBalance",
info: "Get current contract's balance",
exec: (prep: vm2OpIgnore,
run: selfBalanceOp,

View File

@ -529,6 +529,7 @@ const
(opCode: Call, ## 0xf1, Message-Call into an account
forks: Vm2OpAllForks,
name: "call",
info: "Message-Call into an account",
exec: (prep: vm2OpIgnore,
run: callOp,
@ -536,13 +537,15 @@ const
(opCode: CallCode, ## 0xf2, Message-Call with alternative code
forks: Vm2OpAllForks,
name: "callCode",
info: "Message-call into this account with alternative account's code",
exec: (prep: vm2OpIgnore,
run: callCodeOp,
post: vm2OpIgnore)),
(opCode: DelegateCall, ## 0xf4, CallCode with persisting sender and value
forks: Vm2OpAllForks,
forks: Vm2OpHomesteadAndLater,
name: "delegateCall",
info: "Message-call into this account with an alternative account's " &
"code but persisting the current values for sender and value.",
exec: (prep: vm2OpIgnore,
@ -550,7 +553,8 @@ const
post: vm2OpIgnore)),
(opCode: StaticCall, ## 0xfa, Static message-call into an account
forks: Vm2OpAllForks,
forks: Vm2OpByzantiumAndLater,
name: "staticCall",
info: "Static message-call into an account",
exec: (prep: vm2OpIgnore,
run: staticCallOp,

View File

@ -238,13 +238,15 @@ const
(opCode: Create, ## 0xf0, Create a new account with associated code
forks: Vm2OpAllForks,
name: "create",
info: "Create a new account with associated code",
exec: (prep: vm2OpIgnore,
run: createOp,
post: vm2OpIgnore)),
(opCode: Create2, ## 0xf5, Create using keccak256
forks: Vm2OpAllForks,
forks: Vm2OpConstantinopleAndLater,
name: "create2",
info: "Behaves identically to CREATE, except using keccak256",
exec: (prep: vm2OpIgnore,
run: create2Op,

View File

@ -104,7 +104,8 @@ type
Vm2OpExec* = tuple ## op code handler entry
opCode: Op ## index back-reference
forks: set[Fork] ## forks applicable for this operation
info: string ## pretty option name, info
name: string ## handler name
info: string ## handter info, explainer
exec: Vm2OpHanders
# ------------------------------------------------------------------------------

View File

@ -336,6 +336,7 @@ const
(opCode: Address, ## 0x20, Address
forks: Vm2OpAllForks,
name: "address",
info: "Get address of currently executing account",
exec: (prep: vm2OpIgnore,
run: addressOp,
@ -343,6 +344,7 @@ const
(opCode: Balance, ## 0x31, Balance
forks: Vm2OpAllForks - Vm2OpBerlinAndLater,
name: "balance",
info: "Get balance of the given account",
exec: (prep: vm2OpIgnore,
run: balanceOp,
@ -350,6 +352,7 @@ const
(opCode: Balance, ## 0x31, Balance for Berlin and later
forks: Vm2OpBerlinAndLater,
name: "balanceEIP2929",
info: "EIP2929: Get balance of the given account",
exec: (prep: vm2OpIgnore,
run: balanceEIP2929Op,
@ -357,6 +360,7 @@ const
(opCode: Origin, ## 0x32, Origination address
forks: Vm2OpAllForks,
name: "origin",
info: "Get execution origination address",
exec: (prep: vm2OpIgnore,
run: originOp,
@ -364,6 +368,7 @@ const
(opCode: Caller, ## 0x33, Caller address
forks: Vm2OpAllForks,
name: "caller",
info: "Get caller address",
exec: (prep: vm2OpIgnore,
run: callerOp,
@ -371,6 +376,7 @@ const
(opCode: CallValue, ## 0x34, Execution deposited value
forks: Vm2OpAllForks,
name: "callValue",
info: "Get deposited value by the instruction/transaction " &
"responsible for this execution",
exec: (prep: vm2OpIgnore,
@ -379,6 +385,7 @@ const
(opCode: CallDataLoad, ## 0x35, Input data
forks: Vm2OpAllForks,
name: "callDataLoad",
info: "Get input data of current environment",
exec: (prep: vm2OpIgnore,
run: callDataLoadOp,
@ -386,6 +393,7 @@ const
(opCode: CallDataSize, ## 0x36, Size of input data
forks: Vm2OpAllForks,
name: "callDataSize",
info: "Get size of input data in current environment",
exec: (prep: vm2OpIgnore,
run: callDataSizeOp,
@ -393,6 +401,7 @@ const
(opCode: CallDataCopy, ## 0x37, Copy input data to memory.
forks: Vm2OpAllForks,
name: "callDataCopy",
info: "Copy input data in current environment to memory",
exec: (prep: vm2OpIgnore,
run: callDataCopyOp,
@ -400,6 +409,7 @@ const
(opCode: CodeSize, ## 0x38, Size of code
forks: Vm2OpAllForks,
name: "codeSize",
info: "Get size of code running in current environment",
exec: (prep: vm2OpIgnore,
run: codeSizeOp,
@ -407,6 +417,7 @@ const
(opCode: CodeCopy, ## 0x39, Copy code to memory.
forks: Vm2OpAllForks,
name: "codeCopy",
info: "Copy code running in current environment to memory",
exec: (prep: vm2OpIgnore,
run: codeCopyOp,
@ -414,6 +425,7 @@ const
(opCode: GasPrice, ## 0x3a, Gas price
forks: Vm2OpAllForks,
name: "gasPrice",
info: "Get price of gas in current environment",
exec: (prep: vm2OpIgnore,
run: gasPriceOp,
@ -421,6 +433,7 @@ const
(opCode: ExtCodeSize, ## 0x3b, Account code size
forks: Vm2OpAllForks - Vm2OpBerlinAndLater,
name: "extCodeSize",
info: "Get size of an account's code",
exec: (prep: vm2OpIgnore,
run: extCodeSizeOp,
@ -428,6 +441,7 @@ const
(opCode: ExtCodeSize, ## 0x3b, Account code size for Berlin and later
forks: Vm2OpBerlinAndLater,
name: "extCodeSizeEIP2929",
info: "EIP2929: Get size of an account's code",
exec: (prep: vm2OpIgnore,
run: extCodeSizeEIP2929Op,
@ -435,6 +449,7 @@ const
(opCode: ExtCodeCopy, ## 0x3c, Account code copy to memory.
forks: Vm2OpAllForks - Vm2OpBerlinAndLater,
name: "extCodeCopy",
info: "Copy an account's code to memory",
exec: (prep: vm2OpIgnore,
run: extCodeCopyOp,
@ -442,13 +457,15 @@ const
(opCode: ExtCodeCopy, ## 0x3c, Account Code-copy for Berlin and later
forks: Vm2OpBerlinAndLater,
name: "extCodeCopyEIP2929",
info: "EIP2929: Copy an account's code to memory",
exec: (prep: vm2OpIgnore,
run: extCodeCopyEIP2929Op,
post: vm2OpIgnore)),
(opCode: ReturnDataSize, ## 0x3d, Previous call output data size
forks: Vm2OpAllForks,
forks: Vm2OpByzantiumAndLater,
name: "returnDataSize",
info: "Get size of output data from the previous call " &
"from the current environment",
exec: (prep: vm2OpIgnore,
@ -456,14 +473,16 @@ const
post: vm2OpIgnore)),
(opCode: ReturnDataCopy, ## 0x3e, Previous call output data copy to memory
forks: Vm2OpAllForks,
forks: Vm2OpByzantiumAndLater,
name: "returnDataCopy",
info: "Copy output data from the previous call to memory",
exec: (prep: vm2OpIgnore,
run: returnDataCopyOp,
post: vm2OpIgnore)),
(opCode: ExtCodeHash, ## 0x3f, Contract hash
forks: Vm2OpAllForks - Vm2OpBerlinAndLater,
forks: Vm2OpConstantinopleAndLater - Vm2OpBerlinAndLater,
name: "extCodeHash",
info: "Returns the keccak256 hash of a contracts code",
exec: (prep: vm2OpIgnore,
run: extCodeHashOp,
@ -471,6 +490,7 @@ const
(opCode: ExtCodeHash, ## 0x3f, Contract hash for berlin and later
forks: Vm2OpBerlinAndLater,
name: "extCodeHashEIP2929",
info: "EIP2929: Returns the keccak256 hash of a contracts code",
exec: (prep: vm2OpIgnore,
run: extCodeHashEIP2929Op,

View File

@ -115,6 +115,7 @@ const
(opCode: Op.Sha3, ## 0x20, Keccak-256
forks: Vm2OpAllForks,
name: "sha3",
info: "Compute Keccak-256 hash",
exec: (prep: vm2OpIgnore,
run: sha3Op,

View File

@ -20,7 +20,8 @@ import
../../../errors,
./oph_defs,
macros,
stint
stint,
strutils
type
OphNumToTextFn* = proc(n: int): string
@ -156,9 +157,11 @@ macro genOphList*(runHandler: static[OphNumToTextFn];
##
var records = nnkBracket.newTree()
for n in inxList:
var handlerName = n.runHandler.multiReplace(("Op",""),("OP",""))
records.add nnkPar.newTree(
"opCode".asIdent(n.opCode),
"forks".asIdent(recForkSet),
"name".asText(handlerName),
"info".asText(n.handlerInfo),
nnkExprColonExpr.newTree(
newIdentNode("exec"),

View File

@ -87,7 +87,7 @@ else:
# ------------------------------------------------------------------------------
proc fnName(n: int): string {.compileTime.} =
&"Log{n}Op"
&"log{n}Op"
proc opName(n: int): string {.compileTime.} =
&"Log{n}"

View File

@ -381,6 +381,7 @@ const
(opCode: Pop, ## x50, Remove item from stack
forks: Vm2OpAllForks,
name: "pop",
info: "Remove item from stack",
exec: (prep: vm2OpIgnore,
run: popOp,
@ -388,6 +389,7 @@ const
(opCode: Mload, ## 0x51, Load word from memory
forks: Vm2OpAllForks,
name: "mload",
info: "Load word from memory",
exec: (prep: vm2OpIgnore,
run: mloadOp,
@ -395,6 +397,7 @@ const
(opCode: Mstore, ## 0x52, Save word to memory
forks: Vm2OpAllForks,
name: "mstore",
info: "Save word to memory",
exec: (prep: vm2OpIgnore,
run: mstoreOp,
@ -402,6 +405,7 @@ const
(opCode: Mstore8, ## 0x53, Save byte to memory
forks: Vm2OpAllForks,
name: "mstore8",
info: "Save byte to memory",
exec: (prep: vm2OpIgnore,
run: mstore8Op,
@ -409,6 +413,7 @@ const
(opCode: Sload, ## 0x54, Load word from storage
forks: Vm2OpAllForks - Vm2OpBerlinAndLater,
name: "sload",
info: "Load word from storage",
exec: (prep: vm2OpIgnore,
run: sloadOp,
@ -416,6 +421,7 @@ const
(opCode: Sload, ## 0x54, sload for Berlin and later
forks: Vm2OpBerlinAndLater,
name: "sloadEIP2929",
info: "EIP2929: sload for Berlin and later",
exec: (prep: vm2OpIgnore,
run: sloadEIP2929Op,
@ -423,20 +429,31 @@ const
(opCode: Sstore, ## 0x55, Save word
forks: Vm2OpAllForks - Vm2OpConstantinopleAndLater,
name: "sstore",
info: "Save word to storage",
exec: (prep: vm2OpIgnore,
run: sstoreOp,
post: vm2OpIgnore)),
(opCode: Sstore, ## 0x55, sstore for Constantinople and later
forks: Vm2OpConstantinopleAndLater - Vm2OpIstanbulAndLater,
forks: Vm2OpConstantinopleAndLater - Vm2OpPetersburgAndLater,
name: "sstoreEIP1283",
info: "EIP1283: sstore for Constantinople and later",
exec: (prep: vm2OpIgnore,
run: sstoreEIP1283Op,
post: vm2OpIgnore)),
(opCode: Sstore, ## 0x55, sstore for Petersburg and later
forks: Vm2OpPetersburgAndLater - Vm2OpIstanbulAndLater,
name: "sstore",
info: "sstore for Constantinople and later",
exec: (prep: vm2OpIgnore,
run: sstoreOp,
post: vm2OpIgnore)),
(opCode: Sstore, ## 0x55, sstore for Istanbul and later
forks: Vm2OpIstanbulAndLater - Vm2OpBerlinAndLater,
name: "sstoreEIP2200",
info: "EIP2200: sstore for Istanbul and later",
exec: (prep: vm2OpIgnore,
run: sstoreEIP2200Op,
@ -444,13 +461,15 @@ const
(opCode: Sstore, ## 0x55, sstore for Berlin and later
forks: Vm2OpBerlinAndLater,
name: "sstoreEIP2929",
info: "EIP2929: sstore for Istanbul and later",
exec: (prep: vm2OpIgnore,
run: sstoreEIP2929Op,
post: vm2OpIgnore)),
(opCode: Jump, ## 0x56, Jump
forks: Vm2OpIstanbulAndLater,
forks: Vm2OpAllForks,
name: "jump",
info: "Alter the program counter",
exec: (prep: vm2OpIgnore,
run: jumpOp,
@ -458,6 +477,7 @@ const
(opCode: JumpI, ## 0x57, Conditional jump
forks: Vm2OpAllForks,
name: "jumpI",
info: "Conditionally alter the program counter",
exec: (prep: vm2OpIgnore,
run: jumpIOp,
@ -465,6 +485,7 @@ const
(opCode: Pc, ## 0x58, Program counter prior to instruction
forks: Vm2OpAllForks,
name: "pc",
info: "Get the value of the program counter prior to the increment "&
"corresponding to this instruction",
exec: (prep: vm2OpIgnore,
@ -473,6 +494,7 @@ const
(opCode: Msize, ## 0x59, Memory size
forks: Vm2OpAllForks,
name: "msize",
info: "Get the size of active memory in bytes",
exec: (prep: vm2OpIgnore,
run: msizeOp,
@ -480,6 +502,7 @@ const
(opCode: Gas, ## 0x5a, Get available gas
forks: Vm2OpAllForks,
name: "gas",
info: "Get the amount of available gas, including the corresponding "&
"reduction for the cost of this instruction",
exec: (prep: vm2OpIgnore,
@ -489,27 +512,31 @@ const
(opCode: JumpDest, ## 0x5b, Mark jump target. This operation has no effect
## on machine state during execution
forks: Vm2OpAllForks,
name: "jumpDest",
info: "Mark a valid destination for jumps",
exec: (prep: vm2OpIgnore,
run: jumpDestOp,
post: vm2OpIgnore)),
(opCode: BeginSub, ## 0x5c, Begin subroutine
forks: Vm2OpAllForks,
forks: Vm2OpBerlinAndLater,
name: "beginSub",
info: " Marks the entry point to a subroutine",
exec: (prep: vm2OpIgnore,
run: beginSubOp,
post: vm2OpIgnore)),
(opCode: ReturnSub, ## 0x5d, Return
forks: Vm2OpAllForks,
forks: Vm2OpBerlinAndLater,
name: "returnSub",
info: "Returns control to the caller of a subroutine",
exec: (prep: vm2OpIgnore,
run: returnSubOp,
post: vm2OpIgnore)),
(opCode: JumpSub, ## 0x5e, Call subroutine
forks: Vm2OpAllForks,
forks: Vm2OpBerlinAndLater,
name: "jumpSub",
info: "Transfers control to a subroutine",
exec: (prep: vm2OpIgnore,
run: jumpSubOp,

View File

@ -215,13 +215,15 @@ const
(opCode: Return, ## 0xf3, Halt execution returning output data.
forks: Vm2OpAllForks,
name: "returnOp",
info: "Halt execution returning output data",
exec: (prep: vm2OpIgnore,
run: returnOp,
post: vm2OpIgnore)),
(opCode: Revert, ## 0xfd, Halt and revert state changes
forks: Vm2OpAllForks,
forks: Vm2OpByzantiumAndLater,
name: "revert",
info: "Halt execution reverting state changes but returning data " &
"and remaining gas",
exec: (prep: vm2OpIgnore,
@ -230,6 +232,7 @@ const
(opCode: Invalid, ## 0xfe, invalid instruction.
forks: Vm2OpAllForks,
name: "invalidInstruction",
info: "Designated invalid instruction",
exec: (prep: vm2OpIgnore,
run: invalidOp,
@ -237,6 +240,7 @@ const
(opCode: SelfDestruct, ## 0xff, Halt execution, prep for later deletion
forks: Vm2OpAllForks - Vm2OpTangerineAndLater,
name: "selfDestruct",
info: "Halt execution and register account for later deletion",
exec: (prep: vm2OpIgnore,
run: selfDestructOp,
@ -244,6 +248,7 @@ const
(opCode: SelfDestruct, ## 0xff, EIP150: self destruct, Tangerine
forks: Vm2OpTangerineAndLater - Vm2OpSpuriousAndLater,
name: "selfDestructEIP150",
info: "EIP150: Halt execution and register account for later deletion",
exec: (prep: vm2OpIgnore,
run: selfDestructEIP150Op,
@ -251,6 +256,7 @@ const
(opCode: SelfDestruct, ## 0xff, EIP161: self destruct, Spurious and later
forks: Vm2OpSpuriousAndLater - Vm2OpBerlinAndLater,
name: "selfDestructEIP161",
info: "EIP161: Halt execution and register account for later deletion",
exec: (prep: vm2OpIgnore,
run: selfDestructEIP161Op,
@ -258,6 +264,7 @@ const
(opCode: SelfDestruct, ## 0xff, EIP2929: self destruct, Berlin and later
forks: Vm2OpBerlinAndLater,
name: "selfDestructEIP2929",
info: "EIP2929: Halt execution and register account for later deletion",
exec: (prep: vm2OpIgnore,
run: selfDestructEIP2929Op,

View File

@ -0,0 +1,289 @@
# 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
./forks_list,
./op_codes,
./op_handlers,
./utils/macros_gen_opcodes,
macros,
strformat
# ------------------------------------------------------------------------------
# The follwong is mostly original code excerpt from interpreter_dispatch.nim
# This module has no production use, rather it is used to verify the
# implementation in interpreter_dispatch_tables.nim.
# ------------------------------------------------------------------------------
let FrontierOpDispatch {.compileTime.}: array[Op, NimNode] = block:
fill_enum_table_holes(Op, newIdentNode("invalidInstruction")):
[
Stop: newIdentNode "toBeReplacedByBreak",
Add: newIdentNode "add",
Mul: newIdentNode "mul",
Sub: newIdentNode "sub",
Div: newIdentNode "divide",
Sdiv: newIdentNode "sdiv",
Mod: newIdentNode "modulo",
Smod: newIdentNode "smod",
Addmod: newIdentNode "addmod",
Mulmod: newIdentNode "mulmod",
Exp: newIdentNode "exp",
SignExtend: newIdentNode "signExtend",
# 10s: Comparison & Bitwise Logic Operations
Lt: newIdentNode "lt",
Gt: newIdentNode "gt",
Slt: newIdentNode "slt",
Sgt: newIdentNode "sgt",
Eq: newIdentNode "eq",
IsZero: newIdentNode "isZero",
And: newIdentNode "andOp",
Or: newIdentNode "orOp",
Xor: newIdentNode "xorOp",
Not: newIdentNode "notOp",
Byte: newIdentNode "byteOp",
# 20s: SHA3
Sha3: newIdentNode "sha3",
# 30s: Environmental Information
Address: newIdentNode "address",
Balance: newIdentNode "balance",
Origin: newIdentNode "origin",
Caller: newIdentNode "caller",
CallValue: newIdentNode "callValue",
CallDataLoad: newIdentNode "callDataLoad",
CallDataSize: newIdentNode "callDataSize",
CallDataCopy: newIdentNode "callDataCopy",
CodeSize: newIdentNode "codeSize",
CodeCopy: newIdentNode "codeCopy",
GasPrice: newIdentNode "gasPrice",
ExtCodeSize: newIdentNode "extCodeSize",
ExtCodeCopy: newIdentNode "extCodeCopy",
# ReturnDataSize: introduced in Byzantium
# ReturnDataCopy: introduced in Byzantium
# 40s: Block Information
Blockhash: newIdentNode "blockhash",
Coinbase: newIdentNode "coinbase",
Timestamp: newIdentNode "timestamp",
Number: newIdentNode "blockNumber",
Difficulty: newIdentNode "difficulty",
GasLimit: newIdentNode "gasLimit",
# 50s: Stack, Memory, Storage and Flow Operations
Pop: newIdentNode "pop",
Mload: newIdentNode "mload",
Mstore: newIdentNode "mstore",
Mstore8: newIdentNode "mstore8",
Sload: newIdentNode "sload",
Sstore: newIdentNode "sstore",
Jump: newIdentNode "jump",
JumpI: newIdentNode "jumpI",
Pc: newIdentNode "pc",
Msize: newIdentNode "msize",
Gas: newIdentNode "gas",
JumpDest: newIdentNode "jumpDest",
# 60s & 70s: Push Operations.
Push1: newIdentNode "push1",
Push2: newIdentNode "push2",
Push3: newIdentNode "push3",
Push4: newIdentNode "push4",
Push5: newIdentNode "push5",
Push6: newIdentNode "push6",
Push7: newIdentNode "push7",
Push8: newIdentNode "push8",
Push9: newIdentNode "push9",
Push10: newIdentNode "push10",
Push11: newIdentNode "push11",
Push12: newIdentNode "push12",
Push13: newIdentNode "push13",
Push14: newIdentNode "push14",
Push15: newIdentNode "push15",
Push16: newIdentNode "push16",
Push17: newIdentNode "push17",
Push18: newIdentNode "push18",
Push19: newIdentNode "push19",
Push20: newIdentNode "push20",
Push21: newIdentNode "push21",
Push22: newIdentNode "push22",
Push23: newIdentNode "push23",
Push24: newIdentNode "push24",
Push25: newIdentNode "push25",
Push26: newIdentNode "push26",
Push27: newIdentNode "push27",
Push28: newIdentNode "push28",
Push29: newIdentNode "push29",
Push30: newIdentNode "push30",
Push31: newIdentNode "push31",
Push32: newIdentNode "push32",
# 80s: Duplication Operations
Dup1: newIdentNode "dup1",
Dup2: newIdentNode "dup2",
Dup3: newIdentNode "dup3",
Dup4: newIdentNode "dup4",
Dup5: newIdentNode "dup5",
Dup6: newIdentNode "dup6",
Dup7: newIdentNode "dup7",
Dup8: newIdentNode "dup8",
Dup9: newIdentNode "dup9",
Dup10: newIdentNode "dup10",
Dup11: newIdentNode "dup11",
Dup12: newIdentNode "dup12",
Dup13: newIdentNode "dup13",
Dup14: newIdentNode "dup14",
Dup15: newIdentNode "dup15",
Dup16: newIdentNode "dup16",
# 90s: Exchange Operations
Swap1: newIdentNode "swap1",
Swap2: newIdentNode "swap2",
Swap3: newIdentNode "swap3",
Swap4: newIdentNode "swap4",
Swap5: newIdentNode "swap5",
Swap6: newIdentNode "swap6",
Swap7: newIdentNode "swap7",
Swap8: newIdentNode "swap8",
Swap9: newIdentNode "swap9",
Swap10: newIdentNode "swap10",
Swap11: newIdentNode "swap11",
Swap12: newIdentNode "swap12",
Swap13: newIdentNode "swap13",
Swap14: newIdentNode "swap14",
Swap15: newIdentNode "swap15",
Swap16: newIdentNode "swap16",
# a0s: Logging Operations
Log0: newIdentNode "log0",
Log1: newIdentNode "log1",
Log2: newIdentNode "log2",
Log3: newIdentNode "log3",
Log4: newIdentNode "log4",
# f0s: System operations
Create: newIdentNode "create",
Call: newIdentNode "call",
CallCode: newIdentNode "callCode",
Return: newIdentNode "returnOp",
# StaticCall: introduced in Byzantium
# Revert: introduced in Byzantium
# Invalid: newIdentNode "invalid",
SelfDestruct: newIdentNode "selfDestruct"
]
proc genHomesteadJumpTable(ops: array[Op, NimNode]): array[Op, NimNode] {.compileTime.} =
result = ops
result[DelegateCall] = newIdentNode "delegateCall"
let HomesteadOpDispatch {.compileTime.}: array[Op, NimNode] = genHomesteadJumpTable(FrontierOpDispatch)
proc genTangerineJumpTable(ops: array[Op, NimNode]): array[Op, NimNode] {.compileTime.} =
result = ops
result[SelfDestruct] = newIdentNode "selfDestructEIP150"
let TangerineOpDispatch {.compileTime.}: array[Op, NimNode] = genTangerineJumpTable(HomesteadOpDispatch)
proc genSpuriousJumpTable(ops: array[Op, NimNode]): array[Op, NimNode] {.compileTime.} =
result = ops
result[SelfDestruct] = newIdentNode "selfDestructEIP161"
let SpuriousOpDispatch {.compileTime.}: array[Op, NimNode] = genSpuriousJumpTable(TangerineOpDispatch)
proc genByzantiumJumpTable(ops: array[Op, NimNode]): array[Op, NimNode] {.compileTime.} =
result = ops
result[Revert] = newIdentNode "revert"
result[ReturnDataSize] = newIdentNode "returnDataSize"
result[ReturnDataCopy] = newIdentNode "returnDataCopy"
result[StaticCall] = newIdentNode"staticCall"
let ByzantiumOpDispatch {.compileTime.}: array[Op, NimNode] = genByzantiumJumpTable(SpuriousOpDispatch)
proc genConstantinopleJumpTable(ops: array[Op, NimNode]): array[Op, NimNode] {.compileTime.} =
result = ops
result[Shl] = newIdentNode "shlOp"
result[Shr] = newIdentNode "shrOp"
result[Sar] = newIdentNode "sarOp"
result[ExtCodeHash] = newIdentNode "extCodeHash"
result[Create2] = newIdentNode "create2"
result[SStore] = newIdentNode "sstoreEIP1283"
let ConstantinopleOpDispatch {.compileTime.}: array[Op, NimNode] = genConstantinopleJumpTable(ByzantiumOpDispatch)
proc genPetersburgJumpTable(ops: array[Op, NimNode]): array[Op, NimNode] {.compileTime.} =
result = ops
result[SStore] = newIdentNode "sstore" # disable EIP-1283
let PetersburgOpDispatch {.compileTime.}: array[Op, NimNode] = genPetersburgJumpTable(ConstantinopleOpDispatch)
proc genIstanbulJumpTable(ops: array[Op, NimNode]): array[Op, NimNode] {.compileTime.} =
result = ops
result[ChainId] = newIdentNode "chainId"
result[SelfBalance] = newIdentNode "selfBalance"
result[SStore] = newIdentNode "sstoreEIP2200"
let IstanbulOpDispatch {.compileTime.}: array[Op, NimNode] = genIstanbulJumpTable(PetersburgOpDispatch)
proc genBerlinJumpTable(ops: array[Op, NimNode]): array[Op, NimNode] {.compileTime.} =
result = ops
result[BeginSub] = newIdentNode "beginSub"
result[ReturnSub] = newIdentNode "returnSub"
result[JumpSub] = newIdentNode "jumpSub"
result[Balance] = newIdentNode "balanceEIP2929"
result[ExtCodeHash] = newIdentNode "extCodeHashEIP2929"
result[ExtCodeSize] = newIdentNode "extCodeSizeEIP2929"
result[ExtCodeCopy] = newIdentNode "extCodeCopyEIP2929"
result[SelfDestruct] = newIdentNode "selfDestructEIP2929"
result[SLoad] = newIdentNode "sloadEIP2929"
result[SStore] = newIdentNode "sstoreEIP2929"
let BerlinOpDispatch {.compileTime.}: array[Op, NimNode] = genBerlinJumpTable(IstanbulOpDispatch)
# ------------------------------------------------------------------------------
# Public
# ------------------------------------------------------------------------------
static:
let OrigAllOpDispatch = block:
var rc: array[Fork, array[Op, NimNode]]
rc[FkFrontier] = FrontierOpDispatch
rc[FkHomestead] = HomesteadOpDispatch
rc[FkTangerine] = TangerineOpDispatch
rc[FkSpurious] = SpuriousOpDispatch
rc[FkByzantium] = ByzantiumOpDispatch
rc[FkConstantinople] = ConstantinopleOpDispatch
rc[FkPetersburg] = PetersburgOpDispatch
rc[FkIstanbul] = IstanbulOpDispatch
rc[FkBerlin] = BerlinOpDispatch
rc
echo "*** verifying op handler tables will take a while ..."
var vm2OpHandlerErrors = 0
for fork in Fork:
for op in Op:
var
vm2OpName = vm2OpHandlers[fork][op].name
origName = OrigAllOpDispatch[fork][op].strVal
if origName != vm2OpName:
vm2OpHandlerErrors.inc
echo "*** problem: vm2OpHandlers",
& "[{fork}][{op}].name is \"{vm2OpName}\" expected \"{origName}\""
doAssert vm2OpHandlerErrors == 0
# ------------------------------------------------------------------------------
# End
# ------------------------------------------------------------------------------

View File

@ -7,6 +7,7 @@
import
./op_handlers/oph_defs,
./op_handlers_verify,
./op_handlers
# ##################################
@ -68,7 +69,7 @@ opHandler extCodeCopyEIP2929, Op.ExtCodeCopy
opHandler returnDataSize, Op.ReturnDataSize
opHandler returnDataCopy, Op.ReturnDataCopy
opHandler extCodeHash, Op.ExtCodeHash, FkFrontier
opHandler extCodeHash, Op.ExtCodeHash, FkConstantinople
opHandler extCodeHashEIP2929, Op.ExtCodeHash
opHandler blockhash, Op.Blockhash