update handler prototype using call-by-reference argument
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
This commit is contained in:
parent
06b34a4a56
commit
9b70ab5f8f
|
@ -107,7 +107,7 @@ const
|
|||
rc[fork][op].run = tab[op].exec.run
|
||||
rc
|
||||
|
||||
proc opHandlersRun*(fork: Fork; op: Op; d: Vm2Ctx) {.inline.} =
|
||||
proc opHandlersRun*(fork: Fork; op: Op; d: var Vm2Ctx) {.inline.} =
|
||||
## Given a particular `fork` and an `op`-code, run the associated handler
|
||||
vmOpHandlers[fork][op].run(d)
|
||||
|
||||
|
|
|
@ -76,25 +76,25 @@ else:
|
|||
# ------------------------------------------------------------------------------
|
||||
|
||||
const
|
||||
addOp: Vm2OpFn = proc (k: Vm2Ctx) =
|
||||
addOp: Vm2OpFn = proc (k: var Vm2Ctx) =
|
||||
## 0x01, Addition
|
||||
let (lhs, rhs) = k.cpt.stack.popInt(2)
|
||||
k.cpt.stack.push:
|
||||
lhs + rhs
|
||||
|
||||
mulOp: Vm2OpFn = proc(k: Vm2Ctx) =
|
||||
mulOp: Vm2OpFn = proc(k: var Vm2Ctx) =
|
||||
## 0x02, Multiplication
|
||||
let (lhs, rhs) = k.cpt.stack.popInt(2)
|
||||
k.cpt.stack.push:
|
||||
lhs * rhs
|
||||
|
||||
subOp: Vm2OpFn = proc(k: Vm2Ctx) =
|
||||
subOp: Vm2OpFn = proc(k: var Vm2Ctx) =
|
||||
## 0x03, Substraction
|
||||
let (lhs, rhs) = k.cpt.stack.popInt(2)
|
||||
k.cpt.stack.push:
|
||||
lhs - rhs
|
||||
|
||||
divideOp: Vm2OpFn = proc(k: Vm2Ctx) =
|
||||
divideOp: Vm2OpFn = proc(k: var Vm2Ctx) =
|
||||
## 0x04, Division
|
||||
let (lhs, rhs) = k.cpt.stack.popInt(2)
|
||||
k.cpt.stack.push:
|
||||
|
@ -105,7 +105,7 @@ const
|
|||
lhs div rhs
|
||||
|
||||
|
||||
sdivOp: Vm2OpFn = proc(k: Vm2Ctx) =
|
||||
sdivOp: Vm2OpFn = proc(k: var Vm2Ctx) =
|
||||
## 0x05, Signed division
|
||||
let (lhs, rhs) = k.cpt.stack.popInt(2)
|
||||
|
||||
|
@ -121,7 +121,7 @@ const
|
|||
k.cpt.stack.push(r)
|
||||
|
||||
|
||||
moduloOp: Vm2OpFn = proc(k: Vm2Ctx) =
|
||||
moduloOp: Vm2OpFn = proc(k: var Vm2Ctx) =
|
||||
## 0x06, Modulo
|
||||
let (lhs, rhs) = k.cpt.stack.popInt(2)
|
||||
k.cpt.stack.push:
|
||||
|
@ -131,7 +131,7 @@ const
|
|||
lhs mod rhs
|
||||
|
||||
|
||||
smodOp: Vm2OpFn = proc(k: Vm2Ctx) =
|
||||
smodOp: Vm2OpFn = proc(k: var Vm2Ctx) =
|
||||
## 0x07, Signed modulo
|
||||
let (lhs, rhs) = k.cpt.stack.popInt(2)
|
||||
|
||||
|
@ -147,7 +147,7 @@ const
|
|||
k.cpt.stack.push(r)
|
||||
|
||||
|
||||
addmodOp: Vm2OpFn = proc(k: Vm2Ctx) =
|
||||
addmodOp: Vm2OpFn = proc(k: var Vm2Ctx) =
|
||||
## 0x08, Modulo addition
|
||||
## Intermediate computations do not roll over at 2^256
|
||||
let (lhs, rhs, modulus) = k.cpt.stack.popInt(3)
|
||||
|
@ -159,7 +159,7 @@ const
|
|||
addmod(lhs, rhs, modulus)
|
||||
|
||||
|
||||
mulmodOp: Vm2OpFn = proc(k: Vm2Ctx) =
|
||||
mulmodOp: Vm2OpFn = proc(k: var Vm2Ctx) =
|
||||
## 0x09, Modulo multiplication
|
||||
## Intermediate computations do not roll over at 2^256
|
||||
let (lhs, rhs, modulus) = k.cpt.stack.popInt(3)
|
||||
|
@ -171,7 +171,7 @@ const
|
|||
mulmod(lhs, rhs, modulus)
|
||||
|
||||
|
||||
expOp: Vm2OpFn = proc(k: Vm2Ctx) =
|
||||
expOp: Vm2OpFn = proc(k: var Vm2Ctx) =
|
||||
## 0x0A, Exponentiation
|
||||
let (base, exponent) = k.cpt.stack.popInt(2)
|
||||
|
||||
|
@ -191,7 +191,7 @@ const
|
|||
zero(UInt256)
|
||||
|
||||
|
||||
signExtendOp: Vm2OpFn = proc(k: Vm2Ctx) =
|
||||
signExtendOp: Vm2OpFn = proc(k: var Vm2Ctx) =
|
||||
## 0x0B, Sign extend
|
||||
## Extend length of two’s complement signed integer.
|
||||
let (bits, value) = k.cpt.stack.popInt(2)
|
||||
|
@ -213,67 +213,67 @@ const
|
|||
res
|
||||
|
||||
|
||||
ltOp: Vm2OpFn = proc(k: Vm2Ctx) =
|
||||
ltOp: Vm2OpFn = proc(k: var Vm2Ctx) =
|
||||
## 0x10, Less-than comparison
|
||||
let (lhs, rhs) = k.cpt.stack.popInt(2)
|
||||
k.cpt.stack.push:
|
||||
(lhs < rhs).uint.u256
|
||||
|
||||
gtOp: Vm2OpFn = proc(k: Vm2Ctx) =
|
||||
gtOp: Vm2OpFn = proc(k: var Vm2Ctx) =
|
||||
## 0x11, Greater-than comparison
|
||||
let (lhs, rhs) = k.cpt.stack.popInt(2)
|
||||
k.cpt.stack.push:
|
||||
(lhs > rhs).uint.u256
|
||||
|
||||
sltOp: Vm2OpFn = proc(k: Vm2Ctx) =
|
||||
sltOp: Vm2OpFn = proc(k: var Vm2Ctx) =
|
||||
## 0x12, Signed less-than comparison
|
||||
let (lhs, rhs) = k.cpt.stack.popInt(2)
|
||||
k.cpt.stack.push:
|
||||
(cast[Int256](lhs) < cast[Int256](rhs)).uint.u256
|
||||
|
||||
sgtOp: Vm2OpFn = proc(k: Vm2Ctx) =
|
||||
sgtOp: Vm2OpFn = proc(k: var Vm2Ctx) =
|
||||
## 0x14, Signed greater-than comparison
|
||||
let (lhs, rhs) = k.cpt.stack.popInt(2)
|
||||
k.cpt.stack.push:
|
||||
(cast[Int256](lhs) > cast[Int256](rhs)).uint.u256
|
||||
|
||||
eqOp: Vm2OpFn = proc(k: Vm2Ctx) =
|
||||
eqOp: Vm2OpFn = proc(k: var Vm2Ctx) =
|
||||
## 0x14, Signed greater-than comparison
|
||||
let (lhs, rhs) = k.cpt.stack.popInt(2)
|
||||
k.cpt.stack.push:
|
||||
(lhs == rhs).uint.u256
|
||||
|
||||
isZeroOp: Vm2OpFn = proc(k: Vm2Ctx) =
|
||||
isZeroOp: Vm2OpFn = proc(k: var Vm2Ctx) =
|
||||
## 0x15, Check if zero
|
||||
let (value) = k.cpt.stack.popInt(1)
|
||||
k.cpt.stack.push:
|
||||
value.isZero.uint.u256
|
||||
|
||||
andOp: Vm2OpFn = proc(k: Vm2Ctx) =
|
||||
andOp: Vm2OpFn = proc(k: var Vm2Ctx) =
|
||||
## 0x16, Bitwise AND
|
||||
let (lhs, rhs) = k.cpt.stack.popInt(2)
|
||||
k.cpt.stack.push:
|
||||
lhs and rhs
|
||||
|
||||
orOp: Vm2OpFn = proc(k: Vm2Ctx) =
|
||||
orOp: Vm2OpFn = proc(k: var Vm2Ctx) =
|
||||
## 0x17, Bitwise OR
|
||||
let (lhs, rhs) = k.cpt.stack.popInt(2)
|
||||
k.cpt.stack.push:
|
||||
lhs or rhs
|
||||
|
||||
xorOp: Vm2OpFn = proc(k: Vm2Ctx) =
|
||||
xorOp: Vm2OpFn = proc(k: var Vm2Ctx) =
|
||||
## 0x18, Bitwise XOR
|
||||
let (lhs, rhs) = k.cpt.stack.popInt(2)
|
||||
k.cpt.stack.push:
|
||||
lhs xor rhs
|
||||
|
||||
notOp: Vm2OpFn = proc(k: Vm2Ctx) =
|
||||
notOp: Vm2OpFn = proc(k: var Vm2Ctx) =
|
||||
## 0x19, Check if zero
|
||||
let (value) = k.cpt.stack.popInt(1)
|
||||
k.cpt.stack.push:
|
||||
value.not
|
||||
|
||||
byteOp: Vm2OpFn = proc(k: Vm2Ctx) =
|
||||
byteOp: Vm2OpFn = proc(k: var Vm2Ctx) =
|
||||
## 0x20, Retrieve single byte from word.
|
||||
let (position, value) = k.cpt.stack.popInt(2)
|
||||
let pos = position.truncate(int)
|
||||
|
@ -288,7 +288,7 @@ const
|
|||
|
||||
# Constantinople's new opcodes
|
||||
|
||||
shlOp: Vm2OpFn = proc(k: Vm2Ctx) =
|
||||
shlOp: Vm2OpFn = proc(k: var Vm2Ctx) =
|
||||
let (shift, num) = k.cpt.stack.popInt(2)
|
||||
let shiftLen = shift.safeInt
|
||||
if shiftLen >= 256:
|
||||
|
@ -298,7 +298,7 @@ const
|
|||
k.cpt.stack.push:
|
||||
num shl shiftLen
|
||||
|
||||
shrOp: Vm2OpFn = proc(k: Vm2Ctx) =
|
||||
shrOp: Vm2OpFn = proc(k: var Vm2Ctx) =
|
||||
let (shift, num) = k.cpt.stack.popInt(2)
|
||||
let shiftLen = shift.safeInt
|
||||
if shiftLen >= 256:
|
||||
|
@ -309,7 +309,7 @@ const
|
|||
k.cpt.stack.push:
|
||||
num shr shiftLen
|
||||
|
||||
sarOp: Vm2OpFn = proc(k: Vm2Ctx) =
|
||||
sarOp: Vm2OpFn = proc(k: var Vm2Ctx) =
|
||||
let shiftLen = k.cpt.stack.popInt().safeInt
|
||||
let num = cast[Int256](k.cpt.stack.popInt())
|
||||
if shiftLen >= 256:
|
||||
|
|
|
@ -65,43 +65,43 @@ else:
|
|||
# ------------------------------------------------------------------------------
|
||||
|
||||
const
|
||||
blockhashOp: Vm2OpFn = proc (k: Vm2Ctx) =
|
||||
blockhashOp: Vm2OpFn = proc (k: var Vm2Ctx) =
|
||||
## 0x40, Get the hash of one of the 256 most recent complete blocks.
|
||||
let (blockNumber) = k.cpt.stack.popInt(1)
|
||||
k.cpt.stack.push:
|
||||
k.cpt.getBlockHash(blockNumber)
|
||||
|
||||
coinBaseOp: Vm2OpFn = proc (k: Vm2Ctx) =
|
||||
coinBaseOp: Vm2OpFn = proc (k: var Vm2Ctx) =
|
||||
## 0x41, Get the block's beneficiary address.
|
||||
k.cpt.stack.push:
|
||||
k.cpt.getCoinbase
|
||||
|
||||
timestampOp: Vm2OpFn = proc (k: Vm2Ctx) =
|
||||
timestampOp: Vm2OpFn = proc (k: var Vm2Ctx) =
|
||||
## 0x42, Get the block's timestamp.
|
||||
k.cpt.stack.push:
|
||||
k.cpt.getTimestamp
|
||||
|
||||
blocknumberOp: Vm2OpFn = proc (k: Vm2Ctx) =
|
||||
blocknumberOp: Vm2OpFn = proc (k: var Vm2Ctx) =
|
||||
## 0x43, Get the block's number.
|
||||
k.cpt.stack.push:
|
||||
k.cpt.getBlockNumber
|
||||
|
||||
difficultyOp: Vm2OpFn = proc (k: Vm2Ctx) =
|
||||
difficultyOp: Vm2OpFn = proc (k: var Vm2Ctx) =
|
||||
## 0x44, Get the block's difficulty
|
||||
k.cpt.stack.push:
|
||||
k.cpt.getDifficulty
|
||||
|
||||
gasLimitOp: Vm2OpFn = proc (k: Vm2Ctx) =
|
||||
gasLimitOp: Vm2OpFn = proc (k: var Vm2Ctx) =
|
||||
## 0x45, Get the block's gas limit
|
||||
k.cpt.stack.push:
|
||||
k.cpt.getGasLimit
|
||||
|
||||
chainIdOp: Vm2OpFn = proc (k: Vm2Ctx) =
|
||||
chainIdOp: Vm2OpFn = proc (k: var Vm2Ctx) =
|
||||
## 0x46, Get current chain’s EIP-155 unique identifier.
|
||||
k.cpt.stack.push:
|
||||
k.cpt.getChainId
|
||||
|
||||
selfBalanceOp: Vm2OpFn = proc (k: Vm2Ctx) =
|
||||
selfBalanceOp: Vm2OpFn = proc (k: var Vm2Ctx) =
|
||||
## 0x47, Get current contract's balance.
|
||||
k.cpt.stack.push:
|
||||
k.cpt.getBalance(k.cpt.msg.contractAddress)
|
||||
|
|
|
@ -225,7 +225,7 @@ proc staticCallParams(c: Computation): LocalParams =
|
|||
# ------------------------------------------------------------------------------
|
||||
|
||||
const
|
||||
callOp: Vm2OpFn = proc(k: Vm2Ctx) =
|
||||
callOp: Vm2OpFn = proc(k: var Vm2Ctx) =
|
||||
## 0xf1, Message-Call into an account
|
||||
|
||||
if emvcStatic == k.cpt.msg.flags and k.cpt.stack[^3, UInt256] > 0.u256:
|
||||
|
@ -288,24 +288,27 @@ const
|
|||
data: k.cpt.memory.read(p.memInPos, p.memInLen),
|
||||
flags: p.flags)
|
||||
|
||||
var child = newComputation(k.cpt.vmState, msg)
|
||||
k.cpt.chainTo(child):
|
||||
# call -- need to un-capture k
|
||||
var
|
||||
c = k.cpt
|
||||
child = newComputation(c.vmState, msg)
|
||||
c.chainTo(child):
|
||||
if not child.shouldBurnGas:
|
||||
k.cpt.gasMeter.returnGas(child.gasMeter.gasRemaining)
|
||||
c.gasMeter.returnGas(child.gasMeter.gasRemaining)
|
||||
|
||||
if child.isSuccess:
|
||||
k.cpt.merge(child)
|
||||
k.cpt.stack.top(1)
|
||||
c.merge(child)
|
||||
c.stack.top(1)
|
||||
|
||||
k.cpt.returnData = child.output
|
||||
c.returnData = child.output
|
||||
let actualOutputSize = min(p.memOutLen, child.output.len)
|
||||
if actualOutputSize > 0:
|
||||
k.cpt.memory.write(p.memOutPos,
|
||||
child.output.toOpenArray(0, actualOutputSize - 1))
|
||||
c.memory.write(p.memOutPos,
|
||||
child.output.toOpenArray(0, actualOutputSize - 1))
|
||||
|
||||
# ---------------------
|
||||
|
||||
callCodeOp: Vm2OpFn = proc(k: Vm2Ctx) =
|
||||
callCodeOp: Vm2OpFn = proc(k: var Vm2Ctx) =
|
||||
## 0xf2, Message-call into this account with an alternative account's code.
|
||||
let
|
||||
p = k.cpt.callCodeParams
|
||||
|
@ -366,24 +369,27 @@ const
|
|||
data: k.cpt.memory.read(p.memInPos, p.memInLen),
|
||||
flags: p.flags)
|
||||
|
||||
var child = newComputation(k.cpt.vmState, msg)
|
||||
k.cpt.chainTo(child):
|
||||
# call -- need to un-capture k
|
||||
var
|
||||
c = k.cpt
|
||||
child = newComputation(c.vmState, msg)
|
||||
c.chainTo(child):
|
||||
if not child.shouldBurnGas:
|
||||
k.cpt.gasMeter.returnGas(child.gasMeter.gasRemaining)
|
||||
c.gasMeter.returnGas(child.gasMeter.gasRemaining)
|
||||
|
||||
if child.isSuccess:
|
||||
k.cpt.merge(child)
|
||||
k.cpt.stack.top(1)
|
||||
c.merge(child)
|
||||
c.stack.top(1)
|
||||
|
||||
k.cpt.returnData = child.output
|
||||
c.returnData = child.output
|
||||
let actualOutputSize = min(p.memOutLen, child.output.len)
|
||||
if actualOutputSize > 0:
|
||||
k.cpt.memory.write(p.memOutPos,
|
||||
child.output.toOpenArray(0, actualOutputSize - 1))
|
||||
c.memory.write(p.memOutPos,
|
||||
child.output.toOpenArray(0, actualOutputSize - 1))
|
||||
|
||||
# ---------------------
|
||||
|
||||
delegateCallOp: Vm2OpFn = proc(k: Vm2Ctx) =
|
||||
delegateCallOp: Vm2OpFn = proc(k: var Vm2Ctx) =
|
||||
## 0xf4, Message-call into this account with an alternative account's
|
||||
## code, but persisting the current values for sender and value.
|
||||
let
|
||||
|
@ -433,24 +439,27 @@ const
|
|||
data: k.cpt.memory.read(p.memInPos, p.memInLen),
|
||||
flags: p.flags)
|
||||
|
||||
var child = newComputation(k.cpt.vmState, msg)
|
||||
k.cpt.chainTo(child):
|
||||
# call -- need to un-capture k
|
||||
var
|
||||
c = k.cpt
|
||||
child = newComputation(c.vmState, msg)
|
||||
c.chainTo(child):
|
||||
if not child.shouldBurnGas:
|
||||
k.cpt.gasMeter.returnGas(child.gasMeter.gasRemaining)
|
||||
c.gasMeter.returnGas(child.gasMeter.gasRemaining)
|
||||
|
||||
if child.isSuccess:
|
||||
k.cpt.merge(child)
|
||||
k.cpt.stack.top(1)
|
||||
c.merge(child)
|
||||
c.stack.top(1)
|
||||
|
||||
k.cpt.returnData = child.output
|
||||
c.returnData = child.output
|
||||
let actualOutputSize = min(p.memOutLen, child.output.len)
|
||||
if actualOutputSize > 0:
|
||||
k.cpt.memory.write(p.memOutPos,
|
||||
child.output.toOpenArray(0, actualOutputSize - 1))
|
||||
c.memory.write(p.memOutPos,
|
||||
child.output.toOpenArray(0, actualOutputSize - 1))
|
||||
|
||||
# ---------------------
|
||||
|
||||
staticCallOp: Vm2OpFn = proc(k: Vm2Ctx) =
|
||||
staticCallOp: Vm2OpFn = proc(k: var Vm2Ctx) =
|
||||
## 0xfa, Static message-call into an account.
|
||||
|
||||
let
|
||||
|
@ -505,20 +514,23 @@ const
|
|||
data: k.cpt.memory.read(p.memInPos, p.memInLen),
|
||||
flags: p.flags)
|
||||
|
||||
var child = newComputation(k.cpt.vmState, msg)
|
||||
k.cpt.chainTo(child):
|
||||
# call -- need to un-capture k
|
||||
var
|
||||
c = k.cpt
|
||||
child = newComputation(c.vmState, msg)
|
||||
c.chainTo(child):
|
||||
if not child.shouldBurnGas:
|
||||
k.cpt.gasMeter.returnGas(child.gasMeter.gasRemaining)
|
||||
c.gasMeter.returnGas(child.gasMeter.gasRemaining)
|
||||
|
||||
if child.isSuccess:
|
||||
k.cpt.merge(child)
|
||||
k.cpt.stack.top(1)
|
||||
c.merge(child)
|
||||
c.stack.top(1)
|
||||
|
||||
k.cpt.returnData = child.output
|
||||
c.returnData = child.output
|
||||
let actualOutputSize = min(p.memOutLen, child.output.len)
|
||||
if actualOutputSize > 0:
|
||||
k.cpt.memory.write(p.memOutPos,
|
||||
child.output.toOpenArray(0, actualOutputSize - 1))
|
||||
c.memory.write(p.memOutPos,
|
||||
child.output.toOpenArray(0, actualOutputSize - 1))
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# Public, op exec table entries
|
||||
|
|
|
@ -97,7 +97,7 @@ else:
|
|||
# ------------------------------------------------------------------------------
|
||||
|
||||
const
|
||||
createOp: Vm2OpFn = proc(k: Vm2Ctx) =
|
||||
createOp: Vm2OpFn = proc(k: var Vm2Ctx) =
|
||||
## 0xf0, Create a new account with associated code
|
||||
checkInStaticContext(k.cpt)
|
||||
|
||||
|
@ -150,20 +150,23 @@ const
|
|||
value: endowment,
|
||||
data: k.cpt.memory.read(memPos, memLen))
|
||||
|
||||
var child = newComputation(k.cpt.vmState, childMsg, salt)
|
||||
k.cpt.chainTo(child):
|
||||
# call -- need to un-capture k
|
||||
var
|
||||
c = k.cpt
|
||||
child = newComputation(c.vmState, childMsg, salt)
|
||||
c.chainTo(child):
|
||||
if not child.shouldBurnGas:
|
||||
k.cpt.gasMeter.returnGas(child.gasMeter.gasRemaining)
|
||||
c.gasMeter.returnGas(child.gasMeter.gasRemaining)
|
||||
|
||||
if child.isSuccess:
|
||||
k.cpt.merge(child)
|
||||
k.cpt.stack.top child.msg.contractAddress
|
||||
c.merge(child)
|
||||
c.stack.top child.msg.contractAddress
|
||||
else:
|
||||
k.cpt.returnData = child.output
|
||||
c.returnData = child.output
|
||||
|
||||
# ---------------------
|
||||
|
||||
create2Op: Vm2OpFn = proc(k: Vm2Ctx) =
|
||||
create2Op: Vm2OpFn = proc(k: var Vm2Ctx) =
|
||||
## 0xf5, Behaves identically to CREATE, except using keccak256
|
||||
checkInStaticContext(k.cpt)
|
||||
|
||||
|
@ -218,16 +221,19 @@ const
|
|||
value: endowment,
|
||||
data: k.cpt.memory.read(memPos, memLen))
|
||||
|
||||
var child = newComputation(k.cpt.vmState, childMsg, salt)
|
||||
k.cpt.chainTo(child):
|
||||
# call -- need to un-capture k
|
||||
var
|
||||
c = k.cpt
|
||||
child = newComputation(c.vmState, childMsg, salt)
|
||||
c.chainTo(child):
|
||||
if not child.shouldBurnGas:
|
||||
k.cpt.gasMeter.returnGas(child.gasMeter.gasRemaining)
|
||||
c.gasMeter.returnGas(child.gasMeter.gasRemaining)
|
||||
|
||||
if child.isSuccess:
|
||||
k.cpt.merge(child)
|
||||
k.cpt.stack.top child.msg.contractAddress
|
||||
c.merge(child)
|
||||
c.stack.top child.msg.contractAddress
|
||||
else:
|
||||
k.cpt.returnData = child.output
|
||||
c.returnData = child.output
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# Public, op exec table entries
|
||||
|
|
|
@ -85,13 +85,13 @@ export
|
|||
Op, Fork, Computation, Memory, Stack, UInt256, Message, EthAddress
|
||||
|
||||
type
|
||||
Vm2Ctx* = object of RootObj
|
||||
cpt*: Computation ## computation text
|
||||
rc*: int ## return code from op handler
|
||||
Vm2Ctx* = tuple
|
||||
cpt: Computation ## computation text
|
||||
rc: int ## return code from op handler
|
||||
|
||||
Vm2OpFn* = ## general op handler, return codes are passed
|
||||
## back via argument descriptor ``k``
|
||||
proc(k: Vm2Ctx) {.gcsafe.}
|
||||
proc(k: var Vm2Ctx) {.gcsafe.}
|
||||
|
||||
|
||||
Vm2OpHanders* = tuple ## three step op code execution, typically
|
||||
|
@ -114,7 +114,7 @@ type
|
|||
|
||||
const
|
||||
vm2OpIgnore*: Vm2OpFn = ## No operation, placeholder function
|
||||
proc(k: Vm2Ctx) = discard
|
||||
proc(k: var Vm2Ctx) = discard
|
||||
|
||||
# similar to: toSeq(Fork).mapIt({it}).foldl(a+b)
|
||||
Vm2OpAllForks* =
|
||||
|
|
|
@ -59,7 +59,7 @@ proc fnInfo(n: int): string {.compileTime.} =
|
|||
&"Duplicate {blurb} item in the stack"
|
||||
|
||||
|
||||
proc dupImpl(k: Vm2Ctx; n: int) =
|
||||
proc dupImpl(k: var Vm2Ctx; n: int) =
|
||||
k.cpt.stack.dup(n)
|
||||
|
||||
const
|
||||
|
|
|
@ -121,20 +121,20 @@ proc writePaddedResult(mem: var Memory,
|
|||
# ------------------------------------------------------------------------------
|
||||
|
||||
const
|
||||
addressOp: Vm2OpFn = proc (k: Vm2Ctx) =
|
||||
addressOp: Vm2OpFn = proc (k: var Vm2Ctx) =
|
||||
## 0x30, Get address of currently executing account.
|
||||
k.cpt.stack.push:
|
||||
k.cpt.msg.contractAddress
|
||||
|
||||
# ------------------
|
||||
|
||||
balanceOp: Vm2OpFn = proc (k: Vm2Ctx) =
|
||||
balanceOp: Vm2OpFn = proc (k: var Vm2Ctx) =
|
||||
## 0x31, Get balance of the given account.
|
||||
let address = k.cpt.stack.popAddress
|
||||
k.cpt.stack.push:
|
||||
k.cpt.getBalance(address)
|
||||
|
||||
balanceEIP2929Op: Vm2OpFn = proc (k: Vm2Ctx) =
|
||||
balanceEIP2929Op: Vm2OpFn = proc (k: var Vm2Ctx) =
|
||||
## 0x31, EIP292: Get balance of the given account for Berlin and later
|
||||
let address = k.cpt.stack.popAddress()
|
||||
|
||||
|
@ -145,23 +145,23 @@ const
|
|||
|
||||
# ------------------
|
||||
|
||||
originOp: Vm2OpFn = proc (k: Vm2Ctx) =
|
||||
originOp: Vm2OpFn = proc (k: var Vm2Ctx) =
|
||||
## 0x32, Get execution origination address.
|
||||
k.cpt.stack.push:
|
||||
k.cpt.getOrigin()
|
||||
|
||||
callerOp: Vm2OpFn = proc (k: Vm2Ctx) =
|
||||
callerOp: Vm2OpFn = proc (k: var Vm2Ctx) =
|
||||
## 0x33, Get caller address.
|
||||
k.cpt.stack.push:
|
||||
k.cpt.msg.sender
|
||||
|
||||
callValueOp: Vm2OpFn = proc (k: Vm2Ctx) =
|
||||
callValueOp: Vm2OpFn = proc (k: var Vm2Ctx) =
|
||||
## 0x34, Get deposited value by the instruction/transaction
|
||||
## responsible for this execution
|
||||
k.cpt.stack.push:
|
||||
k.cpt.msg.value
|
||||
|
||||
callDataLoadOp: Vm2OpFn = proc (k: Vm2Ctx) =
|
||||
callDataLoadOp: Vm2OpFn = proc (k: var Vm2Ctx) =
|
||||
## 0x35, Get input data of current environment
|
||||
let (startPos) = k.cpt.stack.popInt(1)
|
||||
let start = startPos.cleanMemRef
|
||||
|
@ -181,13 +181,13 @@ const
|
|||
value
|
||||
|
||||
|
||||
callDataSizeOp: Vm2OpFn = proc (k: Vm2Ctx) =
|
||||
callDataSizeOp: Vm2OpFn = proc (k: var Vm2Ctx) =
|
||||
## 0x36, Get size of input data in current environment.
|
||||
k.cpt.stack.push:
|
||||
k.cpt.msg.data.len.u256
|
||||
|
||||
|
||||
callDataCopyOp: Vm2OpFn = proc (k: Vm2Ctx) =
|
||||
callDataCopyOp: Vm2OpFn = proc (k: var Vm2Ctx) =
|
||||
## 0x37, Copy input data in current environment to memory.
|
||||
let (memStartPos, copyStartPos, size) = k.cpt.stack.popInt(3)
|
||||
|
||||
|
@ -202,13 +202,13 @@ const
|
|||
k.cpt.memory.writePaddedResult(k.cpt.msg.data, memPos, copyPos, len)
|
||||
|
||||
|
||||
codeSizeOp: Vm2OpFn = proc (k: Vm2Ctx) =
|
||||
codeSizeOp: Vm2OpFn = proc (k: var Vm2Ctx) =
|
||||
## 0x38, Get size of code running in current environment.
|
||||
k.cpt.stack.push:
|
||||
k.cpt.code.len
|
||||
|
||||
|
||||
codeCopyOp: Vm2OpFn = proc (k: Vm2Ctx) =
|
||||
codeCopyOp: Vm2OpFn = proc (k: var Vm2Ctx) =
|
||||
## 0x39, Copy code running in current environment to memory.
|
||||
let (memStartPos, copyStartPos, size) = k.cpt.stack.popInt(3)
|
||||
|
||||
|
@ -223,20 +223,20 @@ const
|
|||
k.cpt.memory.writePaddedResult(k.cpt.code.bytes, memPos, copyPos, len)
|
||||
|
||||
|
||||
gasPriceOp: Vm2OpFn = proc (k: Vm2Ctx) =
|
||||
gasPriceOp: Vm2OpFn = proc (k: var Vm2Ctx) =
|
||||
## 0x3A, Get price of gas in current environment.
|
||||
k.cpt.stack.push:
|
||||
k.cpt.getGasPrice()
|
||||
|
||||
# -----------
|
||||
|
||||
extCodeSizeOp: Vm2OpFn = proc (k: Vm2Ctx) =
|
||||
extCodeSizeOp: Vm2OpFn = proc (k: var Vm2Ctx) =
|
||||
## 0x3b, Get size of an account's code
|
||||
let address = k.cpt.stack.popAddress()
|
||||
k.cpt.stack.push:
|
||||
k.cpt.getCodeSize(address)
|
||||
|
||||
extCodeSizeEIP2929Op: Vm2OpFn = proc (k: Vm2Ctx) =
|
||||
extCodeSizeEIP2929Op: Vm2OpFn = proc (k: var Vm2Ctx) =
|
||||
## 0x3b, Get size of an account's code
|
||||
let address = k.cpt.stack.popAddress()
|
||||
|
||||
|
@ -247,7 +247,7 @@ const
|
|||
|
||||
# -----------
|
||||
|
||||
extCodeCopyOp: Vm2OpFn = proc (k: Vm2Ctx) =
|
||||
extCodeCopyOp: Vm2OpFn = proc (k: var Vm2Ctx) =
|
||||
## 0x3c, Copy an account's code to memory.
|
||||
let address = k.cpt.stack.popAddress()
|
||||
|
||||
|
@ -263,7 +263,7 @@ const
|
|||
k.cpt.memory.writePaddedResult(codeBytes, memPos, codePos, len)
|
||||
|
||||
|
||||
extCodeCopyEIP2929Op: Vm2OpFn = proc (k: Vm2Ctx) =
|
||||
extCodeCopyEIP2929Op: Vm2OpFn = proc (k: var Vm2Ctx) =
|
||||
## 0x3c, Copy an account's code to memory.
|
||||
let address = k.cpt.stack.popAddress()
|
||||
|
||||
|
@ -282,14 +282,14 @@ const
|
|||
|
||||
# -----------
|
||||
|
||||
returnDataSizeOp: Vm2OpFn = proc (k: Vm2Ctx) =
|
||||
returnDataSizeOp: Vm2OpFn = proc (k: var Vm2Ctx) =
|
||||
## 0x3d, Get size of output data from the previous call from the
|
||||
## current environment.
|
||||
k.cpt.stack.push:
|
||||
k.cpt.returnData.len
|
||||
|
||||
|
||||
returnDataCopyOp: Vm2OpFn = proc (k: Vm2Ctx) =
|
||||
returnDataCopyOp: Vm2OpFn = proc (k: var Vm2Ctx) =
|
||||
## 0x3e, Copy output data from the previous call to memory.
|
||||
let (memStartPos, copyStartPos, size) = k.cpt.stack.popInt(3)
|
||||
|
||||
|
@ -311,13 +311,13 @@ const
|
|||
|
||||
# ---------------
|
||||
|
||||
extCodeHashOp: Vm2OpFn = proc (k: Vm2Ctx) =
|
||||
extCodeHashOp: Vm2OpFn = proc (k: var Vm2Ctx) =
|
||||
## 0x3f, Returns the keccak256 hash of a contract’s code
|
||||
let address = k.cpt.stack.popAddress()
|
||||
k.cpt.stack.push:
|
||||
k.cpt.getCodeHash(address)
|
||||
|
||||
extCodeHashEIP2929Op: Vm2OpFn = proc (k: Vm2Ctx) =
|
||||
extCodeHashEIP2929Op: Vm2OpFn = proc (k: var Vm2Ctx) =
|
||||
## 0x3f, EIP2929: Returns the keccak256 hash of a contract’s code
|
||||
let address = k.cpt.stack.popAddress()
|
||||
|
||||
|
|
|
@ -85,7 +85,7 @@ else:
|
|||
# ------------------------------------------------------------------------------
|
||||
|
||||
const
|
||||
sha3Op: Vm2OpFn = proc (k: Vm2Ctx) =
|
||||
sha3Op: Vm2OpFn = proc (k: var Vm2Ctx) =
|
||||
## 0x20, Compute Keccak-256 hash.
|
||||
let (startPos, length) = k.cpt.stack.popInt(2)
|
||||
|
||||
|
|
|
@ -25,7 +25,7 @@ import
|
|||
|
||||
type
|
||||
OphNumToTextFn* = proc(n: int): string
|
||||
OpHanldlerImplFn* = proc(k: Vm2Ctx; n: int)
|
||||
OpHanldlerImplFn* = proc(k: var Vm2Ctx; n: int)
|
||||
|
||||
const
|
||||
recForkSet = "Vm2OpAllForks"
|
||||
|
@ -114,7 +114,7 @@ macro genOphHandlers*(runHandler: static[OphNumToTextFn];
|
|||
body: static[OpHanldlerImplFn]): untyped =
|
||||
## Generate the equivalent of
|
||||
## ::
|
||||
## const <runHandler>: Vm2OpFn = proc (k: Vm2Ctx) =
|
||||
## const <runHandler>: Vm2OpFn = proc (k: var Vm2Ctx) =
|
||||
## ## <itemInfo(n)>,
|
||||
## <body(k,n)>
|
||||
##
|
||||
|
@ -127,9 +127,9 @@ macro genOphHandlers*(runHandler: static[OphNumToTextFn];
|
|||
fnName = ident(n.runHandler)
|
||||
comment = newCommentStmtNode(n.itemInfo)
|
||||
|
||||
# => push##Op: Vm2OpFn = proc (k: Vm2Ctx) = ...
|
||||
# => push##Op: Vm2OpFn = proc (k: var Vm2Ctx) = ...
|
||||
result.add quote do:
|
||||
const `fnName`: Vm2OpFn = proc(k: Vm2Ctx) =
|
||||
const `fnName`: Vm2OpFn = proc(k: var Vm2Ctx) =
|
||||
`comment`
|
||||
`body`(k,`n`)
|
||||
# echo ">>>", result.repr
|
||||
|
|
|
@ -134,7 +134,7 @@ const
|
|||
# Private, op handlers implementation
|
||||
# ------------------------------------------------------------------------------
|
||||
|
||||
proc wrapperFn(k: Vm2Ctx; n: int) =
|
||||
proc wrapperFn(k: var Vm2Ctx; n: int) =
|
||||
logImpl(k.cpt, logOpArg[n], n)
|
||||
|
||||
genOphHandlers fnName, fnInfo, inxRange, wrapperFn
|
||||
|
|
|
@ -163,11 +163,11 @@ proc jumpImpl(c: Computation; jumpTarget: UInt256) =
|
|||
# ------------------------------------------------------------------------------
|
||||
|
||||
const
|
||||
popOp: Vm2OpFn = proc (k: Vm2Ctx) =
|
||||
popOp: Vm2OpFn = proc (k: var Vm2Ctx) =
|
||||
## 0x50, Remove item from stack.
|
||||
discard k.cpt.stack.popInt
|
||||
|
||||
mloadOp: Vm2OpFn = proc (k: Vm2Ctx) =
|
||||
mloadOp: Vm2OpFn = proc (k: var Vm2Ctx) =
|
||||
## 0x51, Load word from memory
|
||||
let (memStartPos) = k.cpt.stack.popInt(1)
|
||||
|
||||
|
@ -181,7 +181,7 @@ const
|
|||
k.cpt.memory.read(memPos, 32)
|
||||
|
||||
|
||||
mstoreOp: Vm2OpFn = proc (k: Vm2Ctx) =
|
||||
mstoreOp: Vm2OpFn = proc (k: var Vm2Ctx) =
|
||||
## 0x52, Save word to memory
|
||||
let (memStartPos, value) = k.cpt.stack.popInt(2)
|
||||
|
||||
|
@ -194,7 +194,7 @@ const
|
|||
k.cpt.memory.write(memPos, value.toByteArrayBE)
|
||||
|
||||
|
||||
mstore8Op: Vm2OpFn = proc (k: Vm2Ctx) =
|
||||
mstore8Op: Vm2OpFn = proc (k: var Vm2Ctx) =
|
||||
## 0x53, Save byte to memory
|
||||
let (memStartPos, value) = k.cpt.stack.popInt(2)
|
||||
|
||||
|
@ -208,13 +208,13 @@ const
|
|||
|
||||
# -------
|
||||
|
||||
sloadOp: Vm2OpFn = proc (k: Vm2Ctx) =
|
||||
sloadOp: Vm2OpFn = proc (k: var Vm2Ctx) =
|
||||
## 0x54, Load word from storage.
|
||||
let (slot) = k.cpt.stack.popInt(1)
|
||||
k.cpt.stack.push:
|
||||
k.cpt.getStorage(slot)
|
||||
|
||||
sloadEIP2929Op: Vm2OpFn = proc (k: Vm2Ctx) =
|
||||
sloadEIP2929Op: Vm2OpFn = proc (k: var Vm2Ctx) =
|
||||
## 0x54, EIP2929: Load word from storage for Berlin and later
|
||||
let (slot) = k.cpt.stack.popInt(1)
|
||||
|
||||
|
@ -230,7 +230,7 @@ const
|
|||
|
||||
# -------
|
||||
|
||||
sstoreOp: Vm2OpFn = proc (k: Vm2Ctx) =
|
||||
sstoreOp: Vm2OpFn = proc (k: var Vm2Ctx) =
|
||||
## 0x55, Save word to storage.
|
||||
let (slot, newValue) = k.cpt.stack.popInt(2)
|
||||
|
||||
|
@ -256,7 +256,7 @@ const
|
|||
db.setStorage(k.cpt.msg.contractAddress, slot, newValue)
|
||||
|
||||
|
||||
sstoreEIP1283Op: Vm2OpFn = proc (k: Vm2Ctx) =
|
||||
sstoreEIP1283Op: Vm2OpFn = proc (k: var Vm2Ctx) =
|
||||
## 0x55, EIP1283: sstore for Constantinople and later
|
||||
let (slot, newValue) = k.cpt.stack.popInt(2)
|
||||
|
||||
|
@ -264,7 +264,7 @@ const
|
|||
sstoreNetGasMeteringImpl(k.cpt, slot, newValue)
|
||||
|
||||
|
||||
sstoreEIP2200Op: Vm2OpFn = proc (k: Vm2Ctx) =
|
||||
sstoreEIP2200Op: Vm2OpFn = proc (k: var Vm2Ctx) =
|
||||
## 0x55, EIP2200: sstore for Istanbul and later
|
||||
let (slot, newValue) = k.cpt.stack.popInt(2)
|
||||
|
||||
|
@ -279,7 +279,7 @@ const
|
|||
sstoreNetGasMeteringImpl(k.cpt, slot, newValue)
|
||||
|
||||
|
||||
sstoreEIP2929Op: Vm2OpFn = proc (k: Vm2Ctx) =
|
||||
sstoreEIP2929Op: Vm2OpFn = proc (k: var Vm2Ctx) =
|
||||
## 0x55, EIP2929: sstore for Berlin and later
|
||||
let (slot, newValue) = k.cpt.stack.popInt(2)
|
||||
checkInStaticContext(k.cpt)
|
||||
|
@ -299,47 +299,47 @@ const
|
|||
|
||||
# -------
|
||||
|
||||
jumpOp: Vm2OpFn = proc (k: Vm2Ctx) =
|
||||
jumpOp: Vm2OpFn = proc (k: var Vm2Ctx) =
|
||||
## 0x56, Alter the program counter
|
||||
let (jumpTarget) = k.cpt.stack.popInt(1)
|
||||
jumpImpl(k.cpt, jumpTarget)
|
||||
|
||||
jumpIOp: Vm2OpFn = proc (k: Vm2Ctx) =
|
||||
jumpIOp: Vm2OpFn = proc (k: var Vm2Ctx) =
|
||||
## 0x57, Conditionally alter the program counter.
|
||||
let (jumpTarget, testedValue) = k.cpt.stack.popInt(2)
|
||||
if testedValue != 0:
|
||||
jumpImpl(k.cpt, jumpTarget)
|
||||
|
||||
pcOp: Vm2OpFn = proc (k: Vm2Ctx) =
|
||||
pcOp: Vm2OpFn = proc (k: var Vm2Ctx) =
|
||||
## 0x58, Get the value of the program counter prior to the increment
|
||||
## corresponding to this instruction.
|
||||
k.cpt.stack.push:
|
||||
max(k.cpt.code.pc - 1, 0)
|
||||
|
||||
msizeOp: Vm2OpFn = proc (k: Vm2Ctx) =
|
||||
msizeOp: Vm2OpFn = proc (k: var Vm2Ctx) =
|
||||
## 0x59, Get the size of active memory in bytes.
|
||||
k.cpt.stack.push:
|
||||
k.cpt.memory.len
|
||||
|
||||
gasOp: Vm2OpFn = proc (k: Vm2Ctx) =
|
||||
gasOp: Vm2OpFn = proc (k: var Vm2Ctx) =
|
||||
## 0x5a, Get the amount of available gas, including the corresponding
|
||||
## reduction for the cost of this instruction.
|
||||
k.cpt.stack.push:
|
||||
k.cpt.gasMeter.gasRemaining
|
||||
|
||||
jumpDestOp: Vm2OpFn = proc (k: Vm2Ctx) =
|
||||
jumpDestOp: Vm2OpFn = proc (k: var Vm2Ctx) =
|
||||
## 0x5b, Mark a valid destination for jumps. This operation has no effect
|
||||
## on machine state during execution.
|
||||
discard
|
||||
|
||||
beginSubOp: Vm2OpFn = proc (k: Vm2Ctx) =
|
||||
beginSubOp: Vm2OpFn = proc (k: var Vm2Ctx) =
|
||||
## 0x5c, Marks the entry point to a subroutine
|
||||
raise newException(
|
||||
OutOfGas,
|
||||
"Abort: Attempt to execute BeginSub opcode")
|
||||
|
||||
|
||||
returnSubOp: Vm2OpFn = proc (k: Vm2Ctx) =
|
||||
returnSubOp: Vm2OpFn = proc (k: var Vm2Ctx) =
|
||||
## 0x5d, Returns control to the caller of a subroutine.
|
||||
if k.cpt.returnStack.len == 0:
|
||||
raise newException(
|
||||
|
@ -348,7 +348,7 @@ const
|
|||
k.cpt.code.pc = k.cpt.returnStack.pop()
|
||||
|
||||
|
||||
jumpSubOp: Vm2OpFn = proc (k: Vm2Ctx) =
|
||||
jumpSubOp: Vm2OpFn = proc (k: var Vm2Ctx) =
|
||||
## 0x5e, Transfers control to a subroutine.
|
||||
let (jumpTarget) = k.cpt.stack.popInt(1)
|
||||
|
||||
|
|
|
@ -61,7 +61,7 @@ proc fnInfo(n: int): string {.compileTime.} =
|
|||
&"Push {blurb} on the stack"
|
||||
|
||||
|
||||
proc pushImpl(k: Vm2Ctx; n: int) =
|
||||
proc pushImpl(k: var Vm2Ctx; n: int) =
|
||||
k.cpt.stack.push:
|
||||
k.cpt.code.readVmWord(n)
|
||||
|
||||
|
|
|
@ -58,7 +58,7 @@ proc fnInfo(n: int): string {.compileTime.} =
|
|||
&"Exchange first and {blurb} stack items"
|
||||
|
||||
|
||||
proc swapImpl(k: Vm2Ctx; n: int) =
|
||||
proc swapImpl(k: var Vm2Ctx; n: int) =
|
||||
k.cpt.stack.swap(n)
|
||||
|
||||
const
|
||||
|
|
|
@ -105,7 +105,7 @@ else:
|
|||
# ------------------------------------------------------------------------------
|
||||
|
||||
const
|
||||
returnOp: Vm2OpFn = proc(k: Vm2Ctx) =
|
||||
returnOp: Vm2OpFn = proc(k: var Vm2Ctx) =
|
||||
## 0xf3, Halt execution returning output data.
|
||||
let (startPos, size) = k.cpt.stack.popInt(2)
|
||||
|
||||
|
@ -117,7 +117,7 @@ const
|
|||
k.cpt.output = k.cpt.memory.read(pos, len)
|
||||
|
||||
|
||||
revertOp: Vm2OpFn = proc(k: Vm2Ctx) =
|
||||
revertOp: Vm2OpFn = proc(k: var Vm2Ctx) =
|
||||
## 0xfd, Halt execution reverting state changes but returning data
|
||||
## and remaining gas.
|
||||
let (startPos, size) = k.cpt.stack.popInt(2)
|
||||
|
@ -133,20 +133,20 @@ const
|
|||
k.cpt.setError("REVERT opcode executed", false)
|
||||
|
||||
|
||||
invalidOp: Vm2OpFn = proc(k: Vm2Ctx) =
|
||||
invalidOp: Vm2OpFn = proc(k: var Vm2Ctx) =
|
||||
raise newException(InvalidInstruction,
|
||||
"Invalid instruction, received an opcode " &
|
||||
"not implemented in the current fork.")
|
||||
|
||||
# -----------
|
||||
|
||||
selfDestructOp: Vm2OpFn = proc(k: Vm2Ctx) =
|
||||
selfDestructOp: Vm2OpFn = proc(k: var Vm2Ctx) =
|
||||
## 0xff, Halt execution and register account for later deletion.
|
||||
let beneficiary = k.cpt.stack.popAddress()
|
||||
k.cpt.selfDestruct(beneficiary)
|
||||
|
||||
|
||||
selfDestructEIP150Op: Vm2OpFn = proc(k: Vm2Ctx) =
|
||||
selfDestructEIP150Op: Vm2OpFn = proc(k: var Vm2Ctx) =
|
||||
## selfDestructEip150 (auto generated comment)
|
||||
let beneficiary = k.cpt.stack.popAddress()
|
||||
|
||||
|
@ -161,7 +161,7 @@ const
|
|||
k.cpt.selfDestruct(beneficiary)
|
||||
|
||||
|
||||
selfDestructEip161Op: Vm2OpFn = proc(k: Vm2Ctx) =
|
||||
selfDestructEip161Op: Vm2OpFn = proc(k: var Vm2Ctx) =
|
||||
## selfDestructEip161 (auto generated comment)
|
||||
checkInStaticContext(k.cpt)
|
||||
|
||||
|
@ -181,7 +181,7 @@ const
|
|||
k.cpt.selfDestruct(beneficiary)
|
||||
|
||||
|
||||
selfDestructEIP2929Op: Vm2OpFn = proc(k: Vm2Ctx) =
|
||||
selfDestructEIP2929Op: Vm2OpFn = proc(k: var Vm2Ctx) =
|
||||
## selfDestructEIP2929 (auto generated comment)
|
||||
checkInStaticContext(k.cpt)
|
||||
|
||||
|
|
|
@ -15,17 +15,14 @@ logScope:
|
|||
|
||||
|
||||
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
|
||||
desc: Vm2Ctx
|
||||
|
||||
desc.cpt = c
|
||||
var op = c.instr
|
||||
|
||||
if op == Stop:
|
||||
trace "op: Stop"
|
||||
|
@ -39,6 +36,7 @@ proc selectVM(c: Computation, fork: Fork) {.gcsafe.} =
|
|||
if BaseGasCosts[op].kind == GckFixed:
|
||||
c.gasMeter.consumeGas(c.gasCosts[op].cost, reason = $op)
|
||||
|
||||
desc.cpt = c
|
||||
opHandlersRun(fork, op, desc)
|
||||
|
||||
if c.tracingEnabled:
|
||||
|
@ -47,7 +45,7 @@ proc selectVM(c: Computation, fork: Fork) {.gcsafe.} =
|
|||
case op
|
||||
of Create, Create2, Call, CallCode, DelegateCall, StaticCall:
|
||||
if not c.continuation.isNil:
|
||||
return
|
||||
break
|
||||
of Return, Revert, SelfDestruct:
|
||||
break
|
||||
else:
|
||||
|
|
Loading…
Reference in New Issue