EIP-5656: MCOPY instruction

This commit is contained in:
jangko 2023-06-26 16:58:59 +07:00
parent ff1a45e095
commit e121cf3864
No known key found for this signature in database
GPG Key ID: 31702AE10541E6B9
5 changed files with 145 additions and 1 deletions

View File

@ -631,6 +631,9 @@ template gasCosts(fork: EVMFork, prefix, ResultGasCostsName: untyped) =
Tload: fixed GasWarmStorageRead,
Tstore: fixed GasWarmStorageRead,
# 5e: Memory copy
Mcopy: memExpansion `prefix gasCopy`,
# 5f, 60s & 70s: Push Operations
Push0: fixed GasBase,
Push1: fixed GasVeryLow,

View File

@ -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

View File

@ -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
@ -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))]
#[

View File

@ -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]

View File

@ -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()