mirror of
https://github.com/status-im/nimbus-eth1.git
synced 2025-01-26 20:19:31 +00:00
9b70ab5f8f
why: this allows for passing back information which can eventually be used for reducing use of exceptions caveat: call/create currently needs to un-capture the call-by-reference (wrapper) argument using the Computation reference inside
72 lines
1.9 KiB
Nim
72 lines
1.9 KiB
Nim
# 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
|
|
chronicles,
|
|
./interpreter/[gas_meter, op_handlers, op_handlers/oph_defs, v2gas_costs],
|
|
./code_stream, ./v2types, ./v2precompiles
|
|
|
|
logScope:
|
|
topics = "vm opcode"
|
|
|
|
|
|
proc selectVM(c: Computation, fork: Fork) {.gcsafe.} =
|
|
var desc: Vm2Ctx
|
|
|
|
if c.tracingEnabled:
|
|
c.prepareTracer()
|
|
|
|
while true:
|
|
c.instr = c.code.next()
|
|
var op = c.instr
|
|
|
|
if op == Stop:
|
|
trace "op: Stop"
|
|
if not c.code.atEnd() and c.tracingEnabled:
|
|
c.opIndex = c.traceOpCodeStarted(Stop)
|
|
c.traceOpCodeEnded(Stop, c.opIndex)
|
|
break
|
|
|
|
if c.tracingEnabled:
|
|
c.opIndex = c.traceOpCodeStarted(op)
|
|
if BaseGasCosts[op].kind == GckFixed:
|
|
c.gasMeter.consumeGas(c.gasCosts[op].cost, reason = $op)
|
|
|
|
desc.cpt = c
|
|
opHandlersRun(fork, op, desc)
|
|
|
|
if c.tracingEnabled:
|
|
c.traceOpCodeEnded(op, c.opIndex)
|
|
|
|
case op
|
|
of Create, Create2, Call, CallCode, DelegateCall, StaticCall:
|
|
if not c.continuation.isNil:
|
|
break
|
|
of Return, Revert, SelfDestruct:
|
|
break
|
|
else:
|
|
discard
|
|
|
|
|
|
proc executeOpcodes(c: Computation) =
|
|
let fork = c.fork
|
|
|
|
block:
|
|
if not c.continuation.isNil:
|
|
c.continuation = nil
|
|
elif c.execPrecompiles(fork):
|
|
break
|
|
|
|
try:
|
|
c.selectVM(fork)
|
|
except CatchableError as e:
|
|
c.setError(&"Opcode Dispatch Error msg={e.msg}, depth={c.msg.depth}", true)
|
|
|
|
if c.isError() and c.continuation.isNil:
|
|
if c.tracingEnabled: c.traceError()
|
|
debug "executeOpcodes error", msg=c.error.info
|