Block and stack ops, elegant stack/dup/swap multiple opcode short def
This commit is contained in:
parent
e6e3f09ebd
commit
0ec03afced
|
@ -0,0 +1,29 @@
|
|||
import
|
||||
../constants, ../errors, ../computation, ../vm_state, .. / vm / [stack]
|
||||
|
||||
{.this: computation.}
|
||||
{.experimental.}
|
||||
|
||||
using
|
||||
computation: var BaseComputation
|
||||
|
||||
proc blockhash*(computation) =
|
||||
let blockNumber = stack.popInt()
|
||||
let blockHash = vmState.getAncestorHash(blockNumber)
|
||||
stack.push(blockHash)
|
||||
|
||||
proc coinbase*(computation) =
|
||||
stack.push(vmState.coinbase)
|
||||
|
||||
proc timestamp*(computation) =
|
||||
stack.push(vmState.timestamp)
|
||||
|
||||
proc number*(computation) =
|
||||
stack.push(vmState.blockNumber)
|
||||
|
||||
proc difficulty*(computation) =
|
||||
stack.push(vmState.difficulty)
|
||||
|
||||
proc gaslimit*(computation) =
|
||||
stack.push(vmState.gasLimit)
|
||||
|
|
@ -0,0 +1,60 @@
|
|||
import
|
||||
strformat, macros,
|
||||
../constants, ../errors, ../computation, .. / vm / [stack, code_stream], .. / utils / [padding, bytes], bigints
|
||||
|
||||
{.this: computation.}
|
||||
{.experimental.}
|
||||
|
||||
using
|
||||
computation: var BaseComputation
|
||||
|
||||
proc pop*(computation) =
|
||||
discard stack.pop()
|
||||
|
||||
macro pushXX(size: static[int]): untyped =
|
||||
let computation = ident("computation")
|
||||
let value = ident("value")
|
||||
let name = ident(&"push{size}")
|
||||
result = quote:
|
||||
proc `name`*(`computation`: var BaseComputation) =
|
||||
let `value` = `computation`.code.read(`size`).toCString
|
||||
let stripped = `value`.strip(0.char)
|
||||
if stripped.len == 0:
|
||||
`computation`.stack.push(0.i256)
|
||||
else:
|
||||
let paddedValue = `value`.padRight(`size`, cstring"\x00")
|
||||
`computation`.stack.push(paddedValue)
|
||||
|
||||
|
||||
pushXX(1)
|
||||
pushXX(2)
|
||||
pushXX(3)
|
||||
pushXX(4)
|
||||
pushXX(5)
|
||||
pushXX(6)
|
||||
pushXX(7)
|
||||
pushXX(8)
|
||||
pushXX(9)
|
||||
pushXX(10)
|
||||
pushXX(11)
|
||||
pushXX(12)
|
||||
pushXX(13)
|
||||
pushXX(14)
|
||||
pushXX(15)
|
||||
pushXX(16)
|
||||
pushXX(17)
|
||||
pushXX(18)
|
||||
pushXX(19)
|
||||
pushXX(20)
|
||||
pushXX(21)
|
||||
pushXX(22)
|
||||
pushXX(23)
|
||||
pushXX(24)
|
||||
pushXX(25)
|
||||
pushXX(26)
|
||||
pushXX(27)
|
||||
pushXX(28)
|
||||
pushXX(29)
|
||||
pushXX(30)
|
||||
pushXX(31)
|
||||
pushXX(32)
|
|
@ -25,4 +25,3 @@ swapXX(13)
|
|||
swapXX(14)
|
||||
swapXX(15)
|
||||
swapXX(16)
|
||||
|
||||
|
|
|
@ -36,16 +36,31 @@ macro initOpcodes*(spec: untyped): untyped =
|
|||
var `value` = initTable[Op, Opcode]()
|
||||
|
||||
for child in spec:
|
||||
let op = child[0]
|
||||
let gasCost = child[1][0][0]
|
||||
let handler = child[1][0][1]
|
||||
let opcode = if gasCost.repr[0].isLowerAscii():
|
||||
quote:
|
||||
`value`[`op`] = Opcode(kind: `op`, gasCostHandler: `gasCost`, runLogic: `handler`)
|
||||
var ops, gasCosts, handlers: seq[NimNode]
|
||||
if child.kind == nnkInfix and child[0].repr == "..":
|
||||
ops = @[]
|
||||
gasCosts = @[]
|
||||
handlers = @[]
|
||||
let first = child[1].repr.parseInt
|
||||
let last = child[2][0].repr.parseInt
|
||||
let op = child[2][1][1].repr
|
||||
for z in first .. last:
|
||||
ops.add(nnkDotExpr.newTree(ident("Op"), ident(op.replace("XX", $z))))
|
||||
gasCosts.add(child[3][0][0])
|
||||
handlers.add(ident(child[3][0][1].repr.replace("XX", $z)))
|
||||
else:
|
||||
quote:
|
||||
`value`[`op`] = Opcode(kind: `op`, gasCostConstant: `gasCost`, runLogic: `handler`)
|
||||
result[1].add(opcode)
|
||||
ops = @[child[0]]
|
||||
gasCosts = @[child[1][0][0]]
|
||||
handlers = @[child[1][0][1]]
|
||||
for z in 0 ..< ops.len:
|
||||
let (op, gasCost, handler) = (ops[z], gasCosts[z], handlers[z])
|
||||
let opcode = if gasCost.repr[0].isLowerAscii():
|
||||
quote:
|
||||
`value`[`op`] = Opcode(kind: `op`, gasCostHandler: `gasCost`, runLogic: `handler`)
|
||||
else:
|
||||
quote:
|
||||
`value`[`op`] = Opcode(kind: `op`, gasCostConstant: `gasCost`, runLogic: `handler`)
|
||||
result[1].add(opcode)
|
||||
|
||||
result[1].add(value)
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@ import
|
|||
strformat, strutils, tables, macros,
|
||||
constants, bigints, errors, logging, vm_state,
|
||||
vm / [gas_meter, stack, code_stream, memory, message, value, gas_costs], db / chain, computation, opcode, opcode_values, utils / [header, address],
|
||||
logic / [arithmetic, comparison, sha3, context]
|
||||
logic / [arithmetic, comparison, sha3, context, block_ops, stack_ops, duplication, swap]
|
||||
|
||||
var opcodes = initOpcodes:
|
||||
# arithmetic
|
||||
|
@ -52,13 +52,21 @@ var opcodes = initOpcodes:
|
|||
Op.ExtCodeCopy: GAS_EXT_CODE_COST extCodeCopy
|
||||
|
||||
|
||||
# Op.Blockhash: GAS_BASE blockhash
|
||||
# Op.Coinbase: GAS_COINBASE coinbase
|
||||
# Op.Timestamp: GAS_BASE timestamp
|
||||
# Op.Number: GAS_BASE number
|
||||
# Op.Difficulty: GAS_BASE difficulty
|
||||
# Op.GasLimit: GAS_BASE gasLimitOp
|
||||
# Op.Pop: GAS_BASE popOp
|
||||
# block
|
||||
Op.Blockhash: GAS_BASE block_ops.blockhash
|
||||
Op.Coinbase: GAS_COINBASE coinbase
|
||||
Op.Timestamp: GAS_BASE timestamp
|
||||
Op.Number: GAS_BASE number
|
||||
Op.Difficulty: GAS_BASE difficulty
|
||||
Op.GasLimit: GAS_BASE gaslimit
|
||||
|
||||
|
||||
# stack
|
||||
Op.Pop: GAS_BASE stack_ops.pop
|
||||
1..32 Op.PushXX: GAS_VERY_LOW pushXX # XX replaced by macro
|
||||
1..16 Op.DupXX: GAS_VERY_LOW dupXX
|
||||
1..16 Op.SwapXX: GAS_VERY_LOW swapXX
|
||||
|
||||
# Op.MLoad: GAS_VERY_LOW mload
|
||||
# Op.MStore: GAS_VERY_LOW mstore
|
||||
# Op.MStore8: GAS_VERY_LOW mstore8
|
||||
|
@ -72,9 +80,6 @@ var opcodes = initOpcodes:
|
|||
# Op.MSize: GAS_BASE msize
|
||||
# Op.Gas: GAS_BASE gasOp
|
||||
# Op.JumpDest: GAS_JUMP_DEST jumpDest
|
||||
# Op.Push: GAS_VERY_LOW push
|
||||
# Op.Dup: GAS_VERY_LOW dup
|
||||
# Op.Swap: GAS_VERY_LOW swap
|
||||
# Op.Log0: GAS_LOG log0
|
||||
# Op.Log1: 2 * GAS_LOG log1
|
||||
# Op.Log2: 3 * GAS_LOG log2
|
||||
|
@ -168,5 +173,4 @@ runOpcodes(c):
|
|||
Op.Div
|
||||
Op.Sub
|
||||
Op.Mul
|
||||
Op.Mul
|
||||
|
||||
|
|
|
@ -28,7 +28,7 @@ method coinbase*(vmState: BaseVMState): cstring =
|
|||
method timestamp*(vmState: BaseVMState): int =
|
||||
vmState.blockHeader.timestamp
|
||||
|
||||
method blockBumber*(vmState: BaseVMState): Int256 =
|
||||
method blockNumber*(vmState: BaseVMState): Int256 =
|
||||
vmState.blockHeader.blockNumber
|
||||
|
||||
method difficulty*(vmState: BaseVMState): Int256 =
|
||||
|
|
Loading…
Reference in New Issue