2021-04-12 17:13:30 +00:00
|
|
|
# Nimbus
|
2024-06-15 16:18:53 +00:00
|
|
|
# Copyright (c) 2018-2024 Status Research & Development GmbH
|
2021-04-12 17:13:30 +00:00
|
|
|
# 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.
|
|
|
|
|
|
|
|
## EVM Opcode Handler Tables
|
|
|
|
## =========================
|
|
|
|
##
|
|
|
|
|
|
|
|
const
|
|
|
|
noisy {.intdefine.}: int = 0
|
2021-04-23 17:43:44 +00:00
|
|
|
# isNoisy {.used.} = noisy > 0
|
|
|
|
isChatty {.used.} = noisy > 1
|
2021-04-21 17:04:54 +00:00
|
|
|
|
2021-04-12 17:13:30 +00:00
|
|
|
import
|
2021-04-13 16:23:39 +00:00
|
|
|
strformat,
|
2022-12-02 04:35:41 +00:00
|
|
|
../../common/evmforks,
|
2021-04-12 17:13:30 +00:00
|
|
|
./op_codes,
|
|
|
|
./op_handlers/[oph_defs,
|
2021-04-14 10:40:55 +00:00
|
|
|
oph_arithmetic, oph_hash, oph_envinfo, oph_blockdata,
|
2021-04-15 13:40:31 +00:00
|
|
|
oph_memory, oph_push, oph_dup, oph_swap, oph_log,
|
2021-04-16 15:06:02 +00:00
|
|
|
oph_create, oph_call, oph_sysops]
|
2021-04-12 17:13:30 +00:00
|
|
|
|
2021-04-21 17:04:54 +00:00
|
|
|
const
|
|
|
|
allHandlersList = @[
|
2024-06-15 16:18:53 +00:00
|
|
|
(VmOpExecArithmetic, "Arithmetic"),
|
|
|
|
(VmOpExecHash, "Hash"),
|
|
|
|
(VmOpExecEnvInfo, "EnvInfo"),
|
|
|
|
(VmOpExecBlockData, "BlockData"),
|
|
|
|
(VmOpExecMemory, "Memory"),
|
|
|
|
(VmOpExecPush, "Push"),
|
|
|
|
(VmOpExecPushZero, "PushZero"),
|
|
|
|
(VmOpExecDup, "Dup"),
|
|
|
|
(VmOpExecSwap, "Swap"),
|
|
|
|
(VmOpExecLog, "Log"),
|
|
|
|
(VmOpExecCreate, "Create"),
|
|
|
|
(VmOpExecCall, "Call"),
|
|
|
|
(VmOpExecSysOp, "SysOp")]
|
2021-04-21 17:04:54 +00:00
|
|
|
|
2021-04-12 17:13:30 +00:00
|
|
|
# ------------------------------------------------------------------------------
|
|
|
|
# Helper
|
|
|
|
# ------------------------------------------------------------------------------
|
|
|
|
|
2024-06-15 16:18:53 +00:00
|
|
|
proc mkOpTable(selected: EVMFork): array[Op,VmOpExec] {.compileTime.} =
|
2021-04-21 17:04:54 +00:00
|
|
|
|
|
|
|
# Collect selected <fork> entries
|
|
|
|
for (subList,subName) in allHandlersList:
|
|
|
|
for w in subList:
|
|
|
|
if selected notin w.forks:
|
|
|
|
continue
|
|
|
|
# definitions must be mutually exclusive
|
|
|
|
var prvInfo = result[w.opCode].info
|
|
|
|
if prvInfo != "" or 0 < result[w.opCode].forks.card:
|
|
|
|
echo &"*** {subName}: duplicate <{w.opCode}> entry: ",
|
|
|
|
&"\"{prvInfo}\" vs. \"{w.info}\""
|
|
|
|
doAssert result[w.opCode].info == ""
|
|
|
|
doAssert result[w.opCode].forks.card == 0
|
|
|
|
result[w.opCode] = w
|
2021-04-14 16:34:24 +00:00
|
|
|
|
2021-04-21 17:04:54 +00:00
|
|
|
# Initialise unused entries
|
2021-04-12 17:13:30 +00:00
|
|
|
for op in Op:
|
2021-04-21 17:04:54 +00:00
|
|
|
if selected notin result[op].forks:
|
2021-04-14 16:34:24 +00:00
|
|
|
result[op] = result[Invalid]
|
|
|
|
result[op].opCode = op
|
2021-04-19 09:15:35 +00:00
|
|
|
if op == Stop:
|
|
|
|
result[op].name = "toBeReplacedByBreak"
|
2021-04-12 17:13:30 +00:00
|
|
|
|
|
|
|
# ------------------------------------------------------------------------------
|
2021-04-20 11:14:43 +00:00
|
|
|
# Public functions
|
2021-04-12 17:13:30 +00:00
|
|
|
# ------------------------------------------------------------------------------
|
|
|
|
|
2021-04-20 11:22:48 +00:00
|
|
|
#const
|
2024-06-15 16:18:53 +00:00
|
|
|
# VmOpHandlers* = block:
|
|
|
|
# var rc: array[Fork, array[Op, VmOpExec]]
|
2021-04-20 11:22:48 +00:00
|
|
|
# for w in Fork:
|
|
|
|
# rc[w] = w.mkOpTable
|
|
|
|
# rc
|
2021-04-12 17:13:30 +00:00
|
|
|
|
2021-04-20 11:14:43 +00:00
|
|
|
type
|
2021-04-22 11:02:13 +00:00
|
|
|
vmOpHandlersRec* = tuple
|
|
|
|
name: string ## Name (or ID) of op handler
|
|
|
|
info: string ## Some op handler info
|
2024-06-15 16:18:53 +00:00
|
|
|
run: VmOpFn ## Executable handler
|
2021-04-15 13:40:31 +00:00
|
|
|
|
2021-04-20 11:14:43 +00:00
|
|
|
const
|
|
|
|
# Pack handler record.
|
|
|
|
#
|
|
|
|
# Important:
|
|
|
|
# As of NIM 1.2.10, this mapping to another record is crucial for
|
|
|
|
#
|
|
|
|
# vmOpHandlers[fork][op].run
|
|
|
|
#
|
|
|
|
# to pick right function when <op> is a variable . Using
|
|
|
|
#
|
2024-06-15 16:18:53 +00:00
|
|
|
# VmOpHandlers[fork][op].exec.run
|
2021-04-20 11:14:43 +00:00
|
|
|
#
|
|
|
|
# only works when <op> is a constant. There seems to be some optimisation
|
|
|
|
# that garbles the <exec> sub-structures elements <prep>, <run>, and <post>.
|
|
|
|
# Moreover, <post> is seen NULL under the debugger. It is untested yet
|
2024-06-15 16:18:53 +00:00
|
|
|
# under what circumstances the VmOpHandlers[] matrix is set up correctly.
|
2021-04-20 11:14:43 +00:00
|
|
|
# Linearising/flattening the index has no effect here.
|
|
|
|
#
|
2021-04-22 11:02:13 +00:00
|
|
|
vmOpHandlers* = ## Op handler records matrix indexed `fork` x `op`
|
|
|
|
block:
|
2022-12-02 04:35:41 +00:00
|
|
|
var rc: array[EVMFork, array[Op, vmOpHandlersRec]]
|
|
|
|
for fork in EVMFork:
|
2021-04-22 11:02:13 +00:00
|
|
|
var tab = fork.mkOpTable
|
|
|
|
for op in Op:
|
|
|
|
rc[fork][op].name = tab[op].name
|
|
|
|
rc[fork][op].info = tab[op].info
|
|
|
|
rc[fork][op].run = tab[op].exec.run
|
|
|
|
rc
|
2021-04-14 16:34:24 +00:00
|
|
|
|
2021-04-20 11:14:43 +00:00
|
|
|
# ------------------------------------------------------------------------------
|
|
|
|
# Debugging ...
|
|
|
|
# ------------------------------------------------------------------------------
|
2021-04-14 16:34:24 +00:00
|
|
|
|
2021-04-23 17:43:44 +00:00
|
|
|
when isMainModule and isChatty:
|
2021-04-22 11:02:13 +00:00
|
|
|
|
2024-06-15 16:18:53 +00:00
|
|
|
proc opHandlersRun(fork: EVMFork; op: Op; d: var VmCtx) {.used.} =
|
2021-04-22 11:02:13 +00:00
|
|
|
## Given a particular `fork` and an `op`-code, run the associated handler
|
|
|
|
vmOpHandlers[fork][op].run(d)
|
|
|
|
|
2022-12-02 04:35:41 +00:00
|
|
|
proc opHandlersName(fork: EVMFork; op: Op): string {.used.} =
|
2021-04-22 11:02:13 +00:00
|
|
|
## Get name (or ID) of op handler
|
|
|
|
vmOpHandlers[fork][op].name
|
|
|
|
|
2022-12-02 04:35:41 +00:00
|
|
|
proc opHandlersInfo(fork: EVMFork; op: Op): string {.used.} =
|
2021-04-22 11:02:13 +00:00
|
|
|
## Get some op handler info
|
|
|
|
vmOpHandlers[fork][op].info
|
|
|
|
|
2021-04-20 11:14:43 +00:00
|
|
|
echo ">>> berlin[shl]: ", FkBerlin.opHandlersInfo(Shl)
|
|
|
|
echo ">>> berlin[push32]: ", FkBerlin.opHandlersInfo(Push32)
|
|
|
|
echo ">>> berlin[dup16]: ", FkBerlin.opHandlersInfo(Dup16)
|
|
|
|
echo ">>> berlin[swap16]: ", FkBerlin.opHandlersInfo(Swap16)
|
|
|
|
echo ">>> berlin[log4]: ", FkBerlin.opHandlersInfo(Log4)
|
|
|
|
|
2024-06-15 16:18:53 +00:00
|
|
|
echo ">>> frontier[sstore]: ", FkFrontier.opHandlersInfo(Sstore)
|
2021-04-20 11:14:43 +00:00
|
|
|
echo ">>> constantinople[sstore]: ", FkConstantinople.opHandlersInfo(Sstore)
|
2024-06-15 16:18:53 +00:00
|
|
|
echo ">>> berlin[sstore]: ", FkBerlin.opHandlersInfo(Sstore)
|
|
|
|
echo ">>> paris[sstore]: ", FkParis.opHandlersInfo(Sstore)
|
2021-04-12 17:13:30 +00:00
|
|
|
|
|
|
|
# ------------------------------------------------------------------------------
|
|
|
|
# End
|
|
|
|
# ------------------------------------------------------------------------------
|