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(14)
|
||||||
swapXX(15)
|
swapXX(15)
|
||||||
swapXX(16)
|
swapXX(16)
|
||||||
|
|
||||||
|
|
|
@ -36,9 +36,24 @@ macro initOpcodes*(spec: untyped): untyped =
|
||||||
var `value` = initTable[Op, Opcode]()
|
var `value` = initTable[Op, Opcode]()
|
||||||
|
|
||||||
for child in spec:
|
for child in spec:
|
||||||
let op = child[0]
|
var ops, gasCosts, handlers: seq[NimNode]
|
||||||
let gasCost = child[1][0][0]
|
if child.kind == nnkInfix and child[0].repr == "..":
|
||||||
let handler = child[1][0][1]
|
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:
|
||||||
|
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():
|
let opcode = if gasCost.repr[0].isLowerAscii():
|
||||||
quote:
|
quote:
|
||||||
`value`[`op`] = Opcode(kind: `op`, gasCostHandler: `gasCost`, runLogic: `handler`)
|
`value`[`op`] = Opcode(kind: `op`, gasCostHandler: `gasCost`, runLogic: `handler`)
|
||||||
|
|
|
@ -2,7 +2,7 @@ import
|
||||||
strformat, strutils, tables, macros,
|
strformat, strutils, tables, macros,
|
||||||
constants, bigints, errors, logging, vm_state,
|
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],
|
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:
|
var opcodes = initOpcodes:
|
||||||
# arithmetic
|
# arithmetic
|
||||||
|
@ -52,13 +52,21 @@ var opcodes = initOpcodes:
|
||||||
Op.ExtCodeCopy: GAS_EXT_CODE_COST extCodeCopy
|
Op.ExtCodeCopy: GAS_EXT_CODE_COST extCodeCopy
|
||||||
|
|
||||||
|
|
||||||
# Op.Blockhash: GAS_BASE blockhash
|
# block
|
||||||
# Op.Coinbase: GAS_COINBASE coinbase
|
Op.Blockhash: GAS_BASE block_ops.blockhash
|
||||||
# Op.Timestamp: GAS_BASE timestamp
|
Op.Coinbase: GAS_COINBASE coinbase
|
||||||
# Op.Number: GAS_BASE number
|
Op.Timestamp: GAS_BASE timestamp
|
||||||
# Op.Difficulty: GAS_BASE difficulty
|
Op.Number: GAS_BASE number
|
||||||
# Op.GasLimit: GAS_BASE gasLimitOp
|
Op.Difficulty: GAS_BASE difficulty
|
||||||
# Op.Pop: GAS_BASE popOp
|
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.MLoad: GAS_VERY_LOW mload
|
||||||
# Op.MStore: GAS_VERY_LOW mstore
|
# Op.MStore: GAS_VERY_LOW mstore
|
||||||
# Op.MStore8: GAS_VERY_LOW mstore8
|
# Op.MStore8: GAS_VERY_LOW mstore8
|
||||||
|
@ -72,9 +80,6 @@ var opcodes = initOpcodes:
|
||||||
# Op.MSize: GAS_BASE msize
|
# Op.MSize: GAS_BASE msize
|
||||||
# Op.Gas: GAS_BASE gasOp
|
# Op.Gas: GAS_BASE gasOp
|
||||||
# Op.JumpDest: GAS_JUMP_DEST jumpDest
|
# 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.Log0: GAS_LOG log0
|
||||||
# Op.Log1: 2 * GAS_LOG log1
|
# Op.Log1: 2 * GAS_LOG log1
|
||||||
# Op.Log2: 3 * GAS_LOG log2
|
# Op.Log2: 3 * GAS_LOG log2
|
||||||
|
@ -168,5 +173,4 @@ runOpcodes(c):
|
||||||
Op.Div
|
Op.Div
|
||||||
Op.Sub
|
Op.Sub
|
||||||
Op.Mul
|
Op.Mul
|
||||||
Op.Mul
|
|
||||||
|
|
||||||
|
|
|
@ -28,7 +28,7 @@ method coinbase*(vmState: BaseVMState): cstring =
|
||||||
method timestamp*(vmState: BaseVMState): int =
|
method timestamp*(vmState: BaseVMState): int =
|
||||||
vmState.blockHeader.timestamp
|
vmState.blockHeader.timestamp
|
||||||
|
|
||||||
method blockBumber*(vmState: BaseVMState): Int256 =
|
method blockNumber*(vmState: BaseVMState): Int256 =
|
||||||
vmState.blockHeader.blockNumber
|
vmState.blockHeader.blockNumber
|
||||||
|
|
||||||
method difficulty*(vmState: BaseVMState): Int256 =
|
method difficulty*(vmState: BaseVMState): Int256 =
|
||||||
|
|
Loading…
Reference in New Issue