Skip to content

Commit

Permalink
EIP-5656: MCOPY instruction
Browse files Browse the repository at this point in the history
  • Loading branch information
jangko committed Jun 26, 2023
1 parent ff1a45e commit e121cf3
Show file tree
Hide file tree
Showing 5 changed files with 145 additions and 1 deletion.
3 changes: 3 additions & 0 deletions nimbus/evm/interpreter/gas_costs.nim
Original file line number Diff line number Diff line change
Expand Up @@ -630,6 +630,9 @@ template gasCosts(fork: EVMFork, prefix, ResultGasCostsName: untyped) =
# 5c & 5d: Transient storage operations
Tload: fixed GasWarmStorageRead,
Tstore: fixed GasWarmStorageRead,

# 5e: Memory copy
Mcopy: memExpansion `prefix gasCopy`,

# 5f, 60s & 70s: Push Operations
Push0: fixed GasBase,
Expand Down
2 changes: 1 addition & 1 deletion nimbus/evm/interpreter/op_codes.nim
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ type
Tload = 0x5c, ## Load word from transient storage.
Tstore = 0x5d, ## Save word to transient storage.

Nop0x5E = 0x5e, ## Transfers control to a subroutine.
Mcopy = 0x5e, ## Memory copy

# 5f, 60s & 70s: Push Operations.
Push0 = 0x5f, ## Place 0 on stack. EIP-3855
Expand Down
21 changes: 21 additions & 0 deletions nimbus/evm/interpreter/op_handlers/oph_memory.nim
Original file line number Diff line number Diff line change
Expand Up @@ -321,6 +321,19 @@ const
val = k.cpt.stack.popInt()
k.cpt.setTransientStorage(slot, val)

mCopyOp: Vm2OpFn = proc (k: var Vm2Ctx) =
## 0x5e, Copy memory
let (dst, src, size) = k.cpt.stack.popInt(3)

let (dstPos, srcPos, len) =
(dst.cleanMemRef, src.cleanMemRef, size.cleanMemRef)

k.cpt.gasMeter.consumeGas(
k.cpt.gasCosts[Mcopy].m_handler(k.cpt.memory.len, max(dstPos, srcPos), len),
reason = "Mcopy fee")

k.cpt.memory.copy(dstPos, srcPos, len)

#[
EIP-2315: temporary disabled
Reason : not included in berlin hard fork
Expand Down Expand Up @@ -525,6 +538,14 @@ const
info: "Save word to transient storage",
exec: (prep: vm2OpIgnore,
run: tstoreOp,
post: vm2OpIgnore)),

(opCode: Mcopy, ## 0x5e, Copy memory
forks: Vm2OpCancunAndLater,
name: "MCopy",
info: "Copy memory",
exec: (prep: vm2OpIgnore,
run: mCopyOp,
post: vm2OpIgnore))]

#[
Expand Down
12 changes: 12 additions & 0 deletions nimbus/evm/memory.nim
Original file line number Diff line number Diff line change
Expand Up @@ -52,3 +52,15 @@ proc write*(memory: var Memory, startPos: Natural, value: openArray[byte]) =
validateLte(startPos + size, memory.len)
for z, b in value:
memory.bytes[z + startPos] = b

proc copy*(memory: var Memory, dst, src, len: Natural) =
if len <= 0: return
memory.extend(max(dst, src), len)
if dst == src:
return
elif dst < src:
for i in 0..<len:
memory.bytes[dst+i] = memory.bytes[src+i]
else: # src > dst
for i in countdown(len-1, 0):
memory.bytes[dst+i] = memory.bytes[src+i]
108 changes: 108 additions & 0 deletions tests/test_op_memory.nim
Original file line number Diff line number Diff line change
Expand Up @@ -812,5 +812,113 @@ proc opMemoryMain*() =
"0x00"
"0x0000000000000000000000000000002000000000000000000000000000000000"

assembler:
title: "MCOPY 1"
code:
PUSH32 "0x0000000000000000000000000000000000000000000000000000000000000000"
PUSH1 "0x00"
MSTORE
PUSH32 "0x000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f"
PUSH1 "0x20"
MSTORE
PUSH1 "0x20" # len
PUSH1 "0x20" # src
PUSH1 "0x00" # dst
MCOPY
memory:
"0x000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f"
"0x000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f"
fork: Cancun

assembler:
title: "MCOPY 2: Overlap"
code:
PUSH32 "0x0101010101010101010101010101010101010101010101010101010101010101"
PUSH1 "0x00"
MSTORE
PUSH1 "0x20" # len
PUSH1 "0x00" # src
PUSH1 "0x00" # dst
MCOPY
memory:
"0x0101010101010101010101010101010101010101010101010101010101010101"
fork: Cancun

assembler:
title: "MCOPY 3"
code:
PUSH1 "0x00"
PUSH1 "0x00"
MSTORE8
PUSH1 "0x01"
PUSH1 "0x01"
MSTORE8
PUSH1 "0x02"
PUSH1 "0x02"
MSTORE8
PUSH1 "0x03"
PUSH1 "0x03"
MSTORE8
PUSH1 "0x04"
PUSH1 "0x04"
MSTORE8
PUSH1 "0x05"
PUSH1 "0x05"
MSTORE8
PUSH1 "0x06"
PUSH1 "0x06"
MSTORE8
PUSH1 "0x07"
PUSH1 "0x07"
MSTORE8
PUSH1 "0x08"
PUSH1 "0x08"
MSTORE8
PUSH1 "0x08" # len
PUSH1 "0x01" # src
PUSH1 "0x00" # dst
MCOPY
memory:
"0x0102030405060708080000000000000000000000000000000000000000000000"
fork: Cancun

assembler:
title: "MCOPY 4"
code:
PUSH1 "0x00"
PUSH1 "0x00"
MSTORE8
PUSH1 "0x01"
PUSH1 "0x01"
MSTORE8
PUSH1 "0x02"
PUSH1 "0x02"
MSTORE8
PUSH1 "0x03"
PUSH1 "0x03"
MSTORE8
PUSH1 "0x04"
PUSH1 "0x04"
MSTORE8
PUSH1 "0x05"
PUSH1 "0x05"
MSTORE8
PUSH1 "0x06"
PUSH1 "0x06"
MSTORE8
PUSH1 "0x07"
PUSH1 "0x07"
MSTORE8
PUSH1 "0x08"
PUSH1 "0x08"
MSTORE8
PUSH1 "0x08" # len
PUSH1 "0x00" # src
PUSH1 "0x01" # dst
MCOPY
memory:
"0x0000010203040506070000000000000000000000000000000000000000000000"
fork: Cancun

when isMainModule:
opMemoryMain()

0 comments on commit e121cf3

Please sign in to comment.