Skip to content

Commit 99d1135

Browse files
committed
EIP-4750: EOF - Functions
1 parent 4600d65 commit 99d1135

File tree

10 files changed

+139
-12
lines changed

10 files changed

+139
-12
lines changed

nimbus/evm/code_stream.nim

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,12 @@ proc parseEOF*(c: CodeStream): Result[void, EOFV1Error] =
119119
func hasEOFCode*(c: CodeStream): bool =
120120
hasEOFMagic(c.legacyCode)
121121

122+
func getType*(c: CodeStream, idx: int): FunctionMetaData =
123+
c.container.types[idx]
124+
125+
func section*(c: CodeStream): int =
126+
c.section
127+
122128
proc next*(c: var CodeStream): Op =
123129
if c.pc != c.codeLen:
124130
result = Op(c.codeView[c.pc])

nimbus/evm/computation.nim

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -224,7 +224,8 @@ proc newComputation*(vmState: BaseVMState, message: Message,
224224
result.msg = message
225225
result.memory = Memory()
226226
result.stack = newStack()
227-
result.returnStack = @[]
227+
# disable EIP-2315
228+
# result.returnStack = @[]
228229
result.gasMeter.init(message.gas)
229230

230231
if result.msg.isCreate():
@@ -235,16 +236,27 @@ proc newComputation*(vmState: BaseVMState, message: Message,
235236
result.code = newCodeStream(
236237
vmState.readOnlyStateDB.getCode(message.codeAddress))
237238

239+
# EIP-4750
240+
result.returnStack = @[
241+
ReturnContext(section: 0, pc: 0, stackHeight: 0)
242+
]
243+
238244
proc newComputation*(vmState: BaseVMState, message: Message, code: seq[byte]): Computation =
239245
new result
240246
result.vmState = vmState
241247
result.msg = message
242248
result.memory = Memory()
243249
result.stack = newStack()
244-
result.returnStack = @[]
250+
# disable EIP-2315
251+
# result.returnStack = @[]
245252
result.gasMeter.init(message.gas)
246253
result.code = newCodeStream(code)
247254

255+
# EIP-4750
256+
result.returnStack = @[
257+
ReturnContext(section: 0, pc: 0, stackHeight: 0)
258+
]
259+
248260
template gasCosts*(c: Computation): untyped =
249261
c.vmState.gasCosts
250262

nimbus/evm/interpreter/gas_costs.nim

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -631,7 +631,7 @@ template gasCosts(fork: EVMFork, prefix, ResultGasCostsName: untyped) =
631631
# 5c & 5d: Transient storage operations
632632
Tload: fixed GasWarmStorageRead,
633633
Tstore: fixed GasWarmStorageRead,
634-
634+
635635
# 5e: Memory copy
636636
Mcopy: memExpansion `prefix gasCopy`,
637637

@@ -713,6 +713,10 @@ template gasCosts(fork: EVMFork, prefix, ResultGasCostsName: untyped) =
713713
Log3: memExpansion `prefix gasLog3`,
714714
Log4: memExpansion `prefix gasLog4`,
715715

716+
# b0s: Function Operations
717+
CallF: fixed GasLow,
718+
RetF: fixed GasVeryLow,
719+
716720
# e0s: Static jumps
717721
RJump: fixed GasBase,
718722
RJumpI: fixed GasMidLow,

nimbus/evm/interpreter/op_codes.nim

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -175,8 +175,12 @@ type
175175
Log4 = 0xa4, ## Append log record with four topics.
176176

177177
Nop0xA5, Nop0xA6, Nop0xA7, Nop0xA8, Nop0xA9, Nop0xAA,
178-
Nop0xAB, Nop0xAC, Nop0xAD, Nop0xAE, Nop0xAF, Nop0xB0,
179-
Nop0xB1, Nop0xB2, Nop0xB3, Nop0xB4, Nop0xB5, Nop0xB6,
178+
Nop0xAB, Nop0xAC, Nop0xAD, Nop0xAE, Nop0xAF,
179+
180+
CallF = 0xb0, ## call a function (EIP4750)
181+
RetF = 0xb1, ## return from a function (EIP4750)
182+
183+
Nop0xB2, Nop0xB3, Nop0xB4, Nop0xB5, Nop0xB6,
180184
Nop0xB7, Nop0xB8, Nop0xB9, Nop0xBA, Nop0xBB, Nop0xBC,
181185
Nop0xBD, Nop0xBE, Nop0xBF, Nop0xC0, Nop0xC1, Nop0xC2,
182186
Nop0xC3, Nop0xC4, Nop0xC5, Nop0xC6, Nop0xC7, Nop0xC8,

nimbus/evm/interpreter/op_dispatcher.nim

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,14 @@ proc toCaseStmt(forkArg, opArg, k: NimNode): NimNode =
104104
quote do:
105105
`forkCaseSubExpr`
106106
break
107+
of RetF:
108+
quote do:
109+
`forkCaseSubExpr`
110+
# EIP-4750: If returning from top frame, exit cleanly.
111+
let c = `k`.cpt
112+
if c.fork >= FkEOF and
113+
c.returnStack.len == 0:
114+
break
107115
else:
108116
# FIXME-manyOpcodesNowRequireContinuations
109117
# We used to have another clause in this case statement for various
@@ -149,6 +157,11 @@ template genLowMemDispatcher*(fork: EVMFork; op: Op; k: Vm2Ctx) =
149157
case c.instr
150158
of Return, Revert, SelfDestruct:
151159
break
160+
of RetF:
161+
# EIP-4750: If returning from top frame, exit cleanly.
162+
if fork >= FkEOF and
163+
k.cpt.returnStack.len == 0:
164+
break
152165
else:
153166
# FIXME-manyOpcodesNowRequireContinuations
154167
if not k.cpt.continuation.isNil:

nimbus/evm/interpreter/op_handlers.nim

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ import
2424
./op_handlers/[oph_defs,
2525
oph_arithmetic, oph_hash, oph_envinfo, oph_blockdata,
2626
oph_memory, oph_push, oph_dup, oph_swap, oph_log,
27-
oph_create, oph_call, oph_sysops]
27+
oph_create, oph_call, oph_sysops, oph_function]
2828

2929
const
3030
allHandlersList = @[
@@ -40,7 +40,8 @@ const
4040
(vm2OpExecLog, "Log"),
4141
(vm2OpExecCreate, "Create"),
4242
(vm2OpExecCall, "Call"),
43-
(vm2OpExecSysOp, "SysOp")]
43+
(vm2OpExecSysOp, "SysOp"),
44+
(vm2OpExecFunction, "Function")]
4445

4546
# ------------------------------------------------------------------------------
4647
# Helper
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
# Nimbus
2+
# Copyright (c) 2018 Status Research & Development GmbH
3+
# Licensed under either of
4+
# * Apache License, version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or
5+
# http://www.apache.org/licenses/LICENSE-2.0)
6+
# * MIT license ([LICENSE-MIT](LICENSE-MIT) or
7+
# http://opensource.org/licenses/MIT)
8+
# at your option. This file may not be copied, modified, or distributed except
9+
# according to those terms.
10+
11+
## EVM Opcode Handlers: Function Operations
12+
## ======================================
13+
##
14+
15+
import
16+
../../../errors,
17+
../../code_stream,
18+
../../stack,
19+
../../types,
20+
../op_codes,
21+
./oph_defs
22+
23+
# ------------------------------------------------------------------------------
24+
# Private, op handlers implementation
25+
# ------------------------------------------------------------------------------
26+
27+
const
28+
callfOp: Vm2OpFn = proc (k: var Vm2Ctx) =
29+
## 0xb0, Call a function.
30+
let
31+
idx = k.cpt.code.readInt16()
32+
typ = k.cpt.code.getType(idx)
33+
34+
if k.cpt.stack.len + typ.maxStackHeight.int >= 1024:
35+
raise newException(
36+
StackDepthError, "CallF stack overflow")
37+
38+
k.cpt.returnStack.add ReturnContext(
39+
section : k.cpt.code.section,
40+
pc : k.cpt.code.pc,
41+
stackHeight: k.cpt.stack.len - typ.input.int
42+
)
43+
44+
k.cpt.code.setSection(idx)
45+
k.cpt.code.pc = 0
46+
47+
retfOp: Vm2OpFn = proc (k: var Vm2Ctx) =
48+
## 0x50, Return from a function.
49+
let ctx = k.cpt.returnStack.pop()
50+
k.cpt.code.setSection(ctx.section)
51+
k.cpt.code.pc = ctx.pc
52+
53+
# ------------------------------------------------------------------------------
54+
# Public, op exec table entries
55+
# ------------------------------------------------------------------------------
56+
57+
const
58+
vm2OpExecFunction*: seq[Vm2OpExec] = @[
59+
60+
(opCode: CallF, ## 0xb0, Call a function
61+
forks: Vm2OpEOFAndLater,
62+
name: "CallF",
63+
info: "Create a new account with associated code",
64+
exec: (prep: vm2OpIgnore,
65+
run: callfOp,
66+
post: vm2OpIgnore)),
67+
68+
(opCode: RetF, ## 0xb1, Return from a function
69+
forks: Vm2OpEOFAndLater,
70+
name: "RetF",
71+
info: "Behaves identically to CREATE, except using keccak256",
72+
exec: (prep: vm2OpIgnore,
73+
run: retfOp,
74+
post: vm2OpIgnore))]
75+
76+
# ------------------------------------------------------------------------------
77+
# End
78+
# ------------------------------------------------------------------------------

nimbus/evm/interpreter/op_handlers/oph_memory.nim

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -507,23 +507,23 @@ const
507507
post: vm2OpIgnore)),
508508

509509
(opCode: Jump, ## 0x56, Jump
510-
forks: Vm2OpAllForks,
510+
forks: Vm2OpAllForks - Vm2OpEOFAndLater,
511511
name: "jump",
512512
info: "Alter the program counter",
513513
exec: (prep: vm2OpIgnore,
514514
run: jumpOp,
515515
post: vm2OpIgnore)),
516516

517517
(opCode: JumpI, ## 0x57, Conditional jump
518-
forks: Vm2OpAllForks,
518+
forks: Vm2OpAllForks - Vm2OpEOFAndLater,
519519
name: "jumpI",
520520
info: "Conditionally alter the program counter",
521521
exec: (prep: vm2OpIgnore,
522522
run: jumpIOp,
523523
post: vm2OpIgnore)),
524524

525525
(opCode: Pc, ## 0x58, Program counter prior to instruction
526-
forks: Vm2OpAllForks,
526+
forks: Vm2OpAllForks - Vm2OpEOFAndLater,
527527
name: "pc",
528528
info: "Get the value of the program counter prior to the increment "&
529529
"corresponding to this instruction",

nimbus/evm/types.nim

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,13 +76,20 @@ type
7676
storageKeys*: seq[HashSet[UInt256]]
7777
gasUsed*: GasInt
7878

79+
# EIP-4750
80+
ReturnContext* = object
81+
section*: int
82+
pc*: int
83+
stackHeight*: int
84+
7985
Computation* = ref object
8086
# The execution computation
8187
vmState*: BaseVMState
8288
msg*: Message
8389
memory*: Memory
8490
stack*: Stack
85-
returnStack*: seq[int]
91+
# disable EIP-2315
92+
# returnStack*: seq[int]
8693
gasMeter*: GasMeter
8794
code*: CodeStream
8895
output*: seq[byte]
@@ -100,6 +107,7 @@ type
100107
pendingAsyncOperation*: Future[void]
101108
continuation*: proc() {.gcsafe, raises: [CatchableError].}
102109
initcodeEOF*: bool
110+
returnStack*: seq[ReturnContext]
103111

104112
Error* = ref object
105113
info*: string

nimbus/vm_types.nim

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,8 @@ export
2121
vmt.MsgFlags,
2222
vmt.TracerFlags,
2323
vmt.TransactionTracer,
24-
vmt.VMFlag
24+
vmt.VMFlag,
25+
vmt.ReturnContext
2526

2627
when defined(evmc_enabled):
2728
import

0 commit comments

Comments
 (0)