Skip to content

Commit aae98e1

Browse files
committed
EIP-4200: EOF - Static relative jumps
1 parent 6814140 commit aae98e1

File tree

6 files changed

+84
-6
lines changed

6 files changed

+84
-6
lines changed

nimbus/common/evmforks.nim

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,3 +28,7 @@ const
2828
FkParis* = EVMC_PARIS
2929
FkShanghai* = EVMC_SHANGHAI
3030
FkCancun* = EVMC_CANCUN
31+
32+
33+
# Meta forks related to specific EIP
34+
FkEOF* = FkCancun

nimbus/evm/code_stream.nim

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,14 @@ proc readVmWord*(c: var CodeStream, n: int): UInt256 =
6464
for i in 0 ..< toWrite : result_bytes[i] = c.bytes[last - i - 1]
6565
c.pc = last
6666

67+
proc readInt16*(c: var CodeStream): int =
68+
result = (c.bytes[c.pc].int shl 8) or c.bytes[c.pc+1].int
69+
c.pc += 2
70+
71+
proc readByte*(c: var CodeStream): byte =
72+
result = c.bytes[c.pc]
73+
inc c.pc
74+
6775
proc len*(c: CodeStream): int =
6876
len(c.bytes)
6977

nimbus/evm/interpreter/gas_costs.nim

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ type
2020
GasZero, # Nothing paid for operations of the set Wzero.
2121
GasBase, # Amount of gas to pay for operations of the set Wbase.
2222
GasVeryLow, # Amount of gas to pay for operations of the set Wverylow.
23+
GasMidLow, # Introduced in Shanghai EIP4200
2324
GasLow, # Amount of gas to pay for operations of the set Wlow.
2425
GasMid, # Amount of gas to pay for operations of the set Wmid.
2526
GasHigh, # Amount of gas to pay for operations of the set Whigh.
@@ -618,9 +619,9 @@ template gasCosts(fork: EVMFork, prefix, ResultGasCostsName: untyped) =
618619
Msize: fixed GasBase,
619620
Gas: fixed GasBase,
620621
JumpDest: fixed GasJumpDest,
621-
BeginSub: fixed GasBase,
622-
ReturnSub: fixed GasLow,
623-
JumpSub: fixed GasHigh,
622+
RJump: fixed GasBase,
623+
RJumpI: fixed GasMidLow,
624+
RJumpV: fixed GasMidLow,
624625

625626
# 5f, 60s & 70s: Push Operations
626627
Push0: fixed GasBase,
@@ -720,6 +721,7 @@ const
720721
GasZero: 0'i64,
721722
GasBase: 2,
722723
GasVeryLow: 3,
724+
GasMidLow: 4, # Introduced in Shanghai (EIP4200)
723725
GasLow: 5,
724726
GasMid: 8,
725727
GasHigh: 10,

nimbus/evm/interpreter/op_codes.nim

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -126,9 +126,9 @@ type
126126
JumpDest = 0x5b, ## Mark a valid destination for jumps. This
127127
## operation has no effect on machine state during
128128
## execution.
129-
BeginSub = 0x5c, ## Marks the entry point to a subroutine
130-
ReturnSub = 0x5d, ## Returns control to the caller of a subroutine.
131-
JumpSub = 0x5e, ## Transfers control to a subroutine.
129+
Rjump = 0x5c, ## Relative jump (EIP4200)
130+
RJumpI = 0x5d, ## Conditional relative jump (EIP4200)
131+
RJumpV = 0x5e, ## Relative jump via jump table (EIP4200)
132132

133133
# 5f, 60s & 70s: Push Operations.
134134
Push0 = 0x5f, ## Place 0 on stack. EIP-3855

nimbus/evm/interpreter/op_handlers/oph_defs.nim

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,11 @@ const
8787
Vm2OpShanghaiAndLater* =
8888
Vm2OpParisAndLater - {FkParis}
8989

90+
Vm2OpCancunAndLater* =
91+
Vm2OpShanghaiAndLater - {FkShanghai}
92+
93+
Vm2OpEOFAndLater* = Vm2OpCancunAndLater
94+
9095
# ------------------------------------------------------------------------------
9196
# End
9297
# ------------------------------------------------------------------------------

nimbus/evm/interpreter/op_handlers/oph_memory.nim

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -293,6 +293,41 @@ const
293293
## on machine state during execution.
294294
discard
295295

296+
# -------
297+
298+
rjumpOp: Vm2OpFn = proc (k: var Vm2Ctx) =
299+
## 0x5c, Relative jump (EIP4200)
300+
let relativeOffset = k.cpt.code.readInt16()
301+
k.cpt.code.pc += relativeOffset
302+
303+
rjumpiOp: Vm2OpFn = proc (k: var Vm2Ctx) =
304+
## 0x5d, Conditional relative jump (EIP4200)
305+
let condition = k.cpt.stack.popInt()
306+
if condition.isZero:
307+
# Not branching, just skip over immediate argument.
308+
k.cpt.code.pc += 2
309+
return
310+
311+
k.rjumpOp()
312+
313+
rjumpvOp: Vm2OpFn = proc (k: var Vm2Ctx) =
314+
## 0x5e, Relative jump via jump table (EIP4200)
315+
let count = k.cpt.code.readByte().int
316+
let savedPC = k.cpt.code.pc
317+
let idx = k.cpt.stack.popInt().truncate(int)
318+
if idx >= count:
319+
# Index out-of-bounds, don't branch, just skip over immediate
320+
# argument.
321+
k.cpt.code.pc += count * 2
322+
return
323+
324+
# get jump table entry
325+
k.cpt.code.pc += idx * 2
326+
let relativeOffset = k.cpt.code.readInt16()
327+
328+
# move pc past operand(1 + count * 2) and relativeOffset
329+
k.cpt.code.pc = savedPC + count * 2 + relativeOffset
330+
296331
#[
297332
EIP-2315: temporary disabled
298333
Reason : not included in berlin hard fork
@@ -481,6 +516,30 @@ const
481516
info: "Mark a valid destination for jumps",
482517
exec: (prep: vm2OpIgnore,
483518
run: jumpDestOp,
519+
post: vm2OpIgnore)),
520+
521+
(opCode: RJump, ## 0x5c, Relative jump (EIP4200)
522+
forks: Vm2OpEOFAndLater,
523+
name: "RJump",
524+
info: "Relative jump via jump table",
525+
exec: (prep: vm2OpIgnore,
526+
run: rjumpOp,
527+
post: vm2OpIgnore)),
528+
529+
(opCode: RJumpI, ## 0x5d, Conditional relative jump (EIP4200)
530+
forks: Vm2OpEOFAndLater,
531+
name: "RJumpI",
532+
info: "Relative jump via jump table",
533+
exec: (prep: vm2OpIgnore,
534+
run: rjumpiOp,
535+
post: vm2OpIgnore)),
536+
537+
(opCode: RJumpV, ## 0x5e, Relative jump via jump table (EIP4200)
538+
forks: Vm2OpEOFAndLater,
539+
name: "RJumpV",
540+
info: "Relative jump via jump table",
541+
exec: (prep: vm2OpIgnore,
542+
run: rjumpvOp,
484543
post: vm2OpIgnore))]
485544

486545
#[

0 commit comments

Comments
 (0)