Skip to content

Commit 49f43d2

Browse files
committed
EIP-4750: EOF - Functions
1 parent ac0ddf9 commit 49f43d2

File tree

10 files changed

+139
-13
lines changed

10 files changed

+139
-13
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
@@ -222,7 +222,8 @@ proc newComputation*(vmState: BaseVMState, message: Message,
222222
result.msg = message
223223
result.memory = Memory()
224224
result.stack = newStack()
225-
result.returnStack = @[]
225+
# disable EIP-2315
226+
# result.returnStack = @[]
226227
result.gasMeter.init(message.gas)
227228

228229
if result.msg.isCreate():
@@ -233,16 +234,27 @@ proc newComputation*(vmState: BaseVMState, message: Message,
233234
result.code = newCodeStream(
234235
vmState.readOnlyStateDB.getCode(message.codeAddress))
235236

237+
# EIP-4750
238+
result.returnStack = @[
239+
ReturnContext(section: 0, pc: 0, stackHeight: 0)
240+
]
241+
236242
proc newComputation*(vmState: BaseVMState, message: Message, code: seq[byte]): Computation =
237243
new result
238244
result.vmState = vmState
239245
result.msg = message
240246
result.memory = Memory()
241247
result.stack = newStack()
242-
result.returnStack = @[]
248+
# disable EIP-2315
249+
# result.returnStack = @[]
243250
result.gasMeter.init(message.gas)
244251
result.code = newCodeStream(code)
245252

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

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
@@ -503,23 +503,23 @@ const
503503
post: vm2OpIgnore)),
504504

505505
(opCode: Jump, ## 0x56, Jump
506-
forks: Vm2OpAllForks,
506+
forks: Vm2OpAllForks - Vm2OpEOFAndLater,
507507
name: "jump",
508508
info: "Alter the program counter",
509509
exec: (prep: vm2OpIgnore,
510510
run: jumpOp,
511511
post: vm2OpIgnore)),
512512

513513
(opCode: JumpI, ## 0x57, Conditional jump
514-
forks: Vm2OpAllForks,
514+
forks: Vm2OpAllForks - Vm2OpEOFAndLater,
515515
name: "jumpI",
516516
info: "Conditionally alter the program counter",
517517
exec: (prep: vm2OpIgnore,
518518
run: jumpIOp,
519519
post: vm2OpIgnore)),
520520

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

nimbus/evm/types.nim

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,13 +57,20 @@ type
5757
minerAddress* : EthAddress
5858
asyncFactory* : AsyncOperationFactory
5959

60+
# EIP-4750
61+
ReturnContext* = object
62+
section*: int
63+
pc*: int
64+
stackHeight*: int
65+
6066
Computation* = ref object
6167
# The execution computation
6268
vmState*: BaseVMState
6369
msg*: Message
6470
memory*: Memory
6571
stack*: Stack
66-
returnStack*: seq[int]
72+
# disable EIP-2315
73+
# returnStack*: seq[int]
6774
gasMeter*: GasMeter
6875
code*: CodeStream
6976
output*: seq[byte]
@@ -81,6 +88,7 @@ type
8188
pendingAsyncOperation*: Future[void]
8289
continuation*: proc() {.gcsafe, raises: [CatchableError].}
8390
initcodeEOF*: bool
91+
returnStack*: seq[ReturnContext]
8492

8593
Error* = ref object
8694
info*: string
@@ -189,4 +197,3 @@ method captureFault*(ctx: TracerRef, pc: int,
189197

190198
method capturePrepare*(ctx: TracerRef, depth: int) {.base, gcsafe.} =
191199
discard
192-

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.TracerRef,
24-
vmt.VMFlag
24+
vmt.VMFlag,
25+
vmt.ReturnContext
2526

2627
when defined(evmc_enabled):
2728
import

0 commit comments

Comments
 (0)