WIP opcode dsl, code stream changes
This commit is contained in:
parent
72c8ad4877
commit
7b5f7e762b
|
@ -1,6 +1,6 @@
|
|||
import
|
||||
../constants, ../utils_numeric, ../computation,
|
||||
.. / vm / [gas_meter, stack],
|
||||
.. / vm / [gas_meter, stack], ../opcode, ../opcode_values,
|
||||
helpers, bigints
|
||||
|
||||
proc add*(computation: var BaseComputation) =
|
||||
|
@ -101,3 +101,19 @@ proc signextend(computation: var BaseComputation) =
|
|||
else:
|
||||
res = value
|
||||
pushRes()
|
||||
|
||||
# TODO: why fail
|
||||
# newOpcode(Op.Mul, GAS_VERY_LOW, mul)
|
||||
|
||||
# type
|
||||
# OpcodeMul* = ref object of Opcode
|
||||
# method kind*(opcode247321: OpcodeMul): Op =
|
||||
# Op.Mul
|
||||
|
||||
# method gasCost*(opcode247323: OpcodeMul): Int256 =
|
||||
# GAS_VERY_LOW
|
||||
|
||||
# method run*(opcode247325: OpcodeMul; computation: var BaseComputation) =
|
||||
# computation.gasMeter.consumeGas(GAS_VERY_LOW, reason = $Op.Mul)
|
||||
# mul(computation)
|
||||
|
||||
|
|
|
@ -0,0 +1,50 @@
|
|||
import
|
||||
strformat, strutils, sequtils, macros,
|
||||
constants, logging, errors, opcode_values, computation, vm/stack, bigints
|
||||
|
||||
type
|
||||
Opcode* = ref object of RootObj
|
||||
|
||||
method run*(opcode: var Opcode, computation: var BaseComputation) {.base.} =
|
||||
# Hook for performing the actual VM execution.
|
||||
raise newException(ValueError, "Must be implemented by subclasses")
|
||||
|
||||
method kind*(opcode: Opcode): Op {.base.} =
|
||||
raise newException(ValueError, "Must be implemented by subclasses")
|
||||
|
||||
method gasCost*(opcode: Opcode): Op {.base.} =
|
||||
raise newException(ValueError, "Must be implemented by subclasses")
|
||||
|
||||
method logger*(opcode: Opcode): Logger =
|
||||
logging.getLogger(&"vm.logic.call.{$opcode.kind}")
|
||||
|
||||
# TODO: not extremely happy with the method approach, maybe optimize
|
||||
# a bit the run, so we directly replace it with handler's body
|
||||
macro newOpcode*(kind: untyped, gasCost: untyped, handler: untyped): untyped =
|
||||
# newOpcode(Op.Mul, GAS_LOW, mul)
|
||||
let name = ident(&"Opcode{kind[1].repr}")
|
||||
let computation = ident("computation")
|
||||
result = quote:
|
||||
type
|
||||
`name`* = ref object of Opcode
|
||||
|
||||
method kind*(opcode: `name`): Op =
|
||||
`kind`
|
||||
|
||||
method gasCost*(opcode: `name`): Int256 =
|
||||
`gasCost`
|
||||
|
||||
var code: NimNode
|
||||
if handler.kind != nnkStmtList:
|
||||
code = quote:
|
||||
method `run`*(opcode: `name`, `computation`: var BaseComputation) =
|
||||
`computation`.gasMeter.consumeGas(`gasCost`, reason = $`kind`)
|
||||
`handler`(`computation`)
|
||||
else:
|
||||
code = quote:
|
||||
method `run*`(opcode: `name`, `computation`: var BaseComputation) =
|
||||
`computation`.gasMeter.consumeGas(`gasCost`, reason = $`kind`)
|
||||
`handler`
|
||||
|
||||
result.add(code)
|
||||
echo result.repr
|
|
@ -1,159 +1,160 @@
|
|||
# TODO : hex
|
||||
const
|
||||
STOP* = 0.byte
|
||||
ADD* = 1.byte
|
||||
MUL* = 2.byte
|
||||
SUB* = 3.byte
|
||||
DIV* = 4.byte
|
||||
SDIV* = 5.byte
|
||||
MOD* = 6.byte
|
||||
SMOD* = 7.byte
|
||||
ADDMOD* = 8.byte
|
||||
MULMOD* = 9.byte
|
||||
EXP* = 10.byte
|
||||
SIGNEXTEND* = 11.byte
|
||||
type
|
||||
Op* {.pure.} = enum
|
||||
STOP, # 0
|
||||
ADD, # 1
|
||||
MUL, # 2
|
||||
SUB, # 3
|
||||
DIV, # 4
|
||||
SDIV, # 5
|
||||
MOD, # 6
|
||||
SMOD, # 7
|
||||
ADDMOD, # 8
|
||||
MULMOD, # 9
|
||||
EXP, # 10
|
||||
SIGNEXTEND, # 11
|
||||
|
||||
LT* = 16.byte
|
||||
GT* = 17.byte
|
||||
SLT* = 18.byte
|
||||
SGT* = 19.byte
|
||||
EQ* = 20.byte
|
||||
ISZERO* = 21.byte
|
||||
AND* = 22.byte
|
||||
OR* = 23.byte
|
||||
XOR* = 24.byte
|
||||
NOT* = 25.byte
|
||||
BYTE* = 26.byte
|
||||
LT, # 16
|
||||
GT, # 17
|
||||
SLT, # 18
|
||||
SGT, # 19
|
||||
EQ, # 20
|
||||
ISZERO, # 21
|
||||
AND, # 22
|
||||
OR, # 23
|
||||
XOR, # 24
|
||||
NOT, # 25
|
||||
BYTE, # 26
|
||||
|
||||
SHA3* = 32.byte
|
||||
|
||||
ADDRESS* = 48.byte
|
||||
BALANCE* = 49.byte
|
||||
ORIGIN* = 50.byte
|
||||
SHA3, # 32
|
||||
|
||||
ADDRESS, # 48
|
||||
BALANCE, # 49
|
||||
ORIGIN, # 50
|
||||
|
||||
CALLER* = 51.byte
|
||||
CALLVALUE* = 52.byte
|
||||
CALLDATALOAD* = 53.byte
|
||||
CALLDATASIZE* = 54.byte
|
||||
CALLDATACOPY* = 55.byte
|
||||
CALLER, # 51
|
||||
CALLVALUE, # 52
|
||||
CALLDATALOAD, # 53
|
||||
CALLDATASIZE, # 54
|
||||
CALLDATACOPY, # 55
|
||||
|
||||
CODESIZE* = 56.byte
|
||||
CODECOPY* = 57.byte
|
||||
CODESIZE, # 56
|
||||
CODECOPY, # 57
|
||||
|
||||
GASPRICE* = 58.byte
|
||||
GASPRICE, # 58
|
||||
|
||||
EXTCODESIZE* = 59.byte
|
||||
EXTCODECOPY* = 60.byte
|
||||
EXTCODESIZE, # 59
|
||||
EXTCODECOPY, # 60
|
||||
|
||||
RETURNDATASIZE* = 61.byte
|
||||
RETURNDATACOPY* = 62.byte
|
||||
RETURNDATASIZE, # 61
|
||||
RETURNDATACOPY, # 62
|
||||
|
||||
BLOCKHASH* = 64.byte
|
||||
BLOCKHASH, # 64
|
||||
|
||||
COINBASE* = 65.byte
|
||||
COINBASE, # 65
|
||||
|
||||
TIMESTAMP* = 66.byte
|
||||
TIMESTAMP, # 66
|
||||
|
||||
NUMBER* = 67.byte
|
||||
NUMBER, # 67
|
||||
|
||||
DIFFICULTY* = 68.byte
|
||||
DIFFICULTY, # 68
|
||||
|
||||
GASLIMIT* = 69.byte
|
||||
|
||||
POP* = 80.byte
|
||||
GASLIMIT, # 69
|
||||
|
||||
POP, # 80
|
||||
|
||||
MLOAD* = 81.byte
|
||||
MSTORE* = 82.byte
|
||||
MSTORE8 = 83.byte
|
||||
MLOAD, # 81
|
||||
MSTORE, # 82
|
||||
MSTORE8 # 83
|
||||
|
||||
SLOAD* = 84.byte
|
||||
SSTORE* = 85.byte
|
||||
SLOAD, # 84
|
||||
SSTORE, # 85
|
||||
|
||||
JUMP* = 86.byte
|
||||
JUMPI* = 87.byte
|
||||
JUMP, # 86
|
||||
JUMPI, # 87
|
||||
|
||||
PC* = 88.byte
|
||||
PC, # 88
|
||||
|
||||
MSIZE* = 89.byte
|
||||
MSIZE, # 89
|
||||
|
||||
GAS* = 90.byte
|
||||
GAS, # 90
|
||||
|
||||
JUMPDEST* = 91.byte
|
||||
|
||||
PUSH1* = 96.byte
|
||||
PUSH2* = 97.byte
|
||||
PUSH3* = 98.byte
|
||||
PUSH4* = 99.byte
|
||||
PUSH5* = 100.byte
|
||||
PUSH6* = 101.byte
|
||||
PUSH7* = 102.byte
|
||||
PUSH8* = 103.byte
|
||||
PUSH9* = 104.byte
|
||||
PUSH10* = 105.byte
|
||||
PUSH11* = 106.byte
|
||||
PUSH12* = 107.byte
|
||||
PUSH13* = 108.byte
|
||||
PUSH14* = 109.byte
|
||||
PUSH15* = 110.byte
|
||||
PUSH16* = 111.byte
|
||||
PUSH17* = 112.byte
|
||||
PUSH18* = 113.byte
|
||||
PUSH19* = 114.byte
|
||||
PUSH20* = 115.byte
|
||||
PUSH21* = 116.byte
|
||||
PUSH22* = 117.byte
|
||||
PUSH23* = 118.byte
|
||||
PUSH24* = 119.byte
|
||||
PUSH25* = 120.byte
|
||||
PUSH26* = 121.byte
|
||||
PUSH27* = 122.byte
|
||||
PUSH28* = 123.byte
|
||||
PUSH29* = 124.byte
|
||||
PUSH30* = 125.byte
|
||||
PUSH31* = 126.byte
|
||||
PUSH32* = 127.byte
|
||||
DUP1* = 128.byte
|
||||
DUP2* = 129.byte
|
||||
DUP3* = 130.byte
|
||||
DUP4* = 131.byte
|
||||
DUP5* = 132.byte
|
||||
DUP6* = 133.byte
|
||||
DUP7* = 134.byte
|
||||
DUP8* = 135.byte
|
||||
DUP9* = 136.byte
|
||||
DUP10* = 137.byte
|
||||
DUP11* = 138.byte
|
||||
DUP12* = 139.byte
|
||||
DUP13* = 140.byte
|
||||
DUP14* = 141.byte
|
||||
DUP15* = 142.byte
|
||||
DUP16* = 143.byte
|
||||
SWAP1* = 144.byte
|
||||
SWAP2* = 145.byte
|
||||
SWAP3* = 146.byte
|
||||
SWAP4* = 147.byte
|
||||
SWAP5* = 148.byte
|
||||
SWAP6* = 149.byte
|
||||
SWAP7* = 150.byte
|
||||
SWAP8* = 151.byte
|
||||
SWAP9* = 152.byte
|
||||
SWAP10* = 153.byte
|
||||
SWAP11* = 154.byte
|
||||
SWAP12* = 155.byte
|
||||
SWAP13* = 156.byte
|
||||
SWAP14* = 157.byte
|
||||
SWAP15* = 158.byte
|
||||
SWAP16* = 159.byte
|
||||
LOG0* = 160.byte
|
||||
LOG1* = 161.byte
|
||||
LOG2* = 162.byte
|
||||
LOG3* = 163.byte
|
||||
LOG4* = 164.byte
|
||||
CREATE* = 240.byte
|
||||
CALL* = 241.byte
|
||||
CALLCODE* = 242.byte
|
||||
RETURN* = 243.byte
|
||||
DELEGATECALL* = 244.byte
|
||||
STATICCALL* = 250.byte
|
||||
REVERT* = 253.byte
|
||||
SELFDESTRUCT* = 255.byte
|
||||
JUMPDEST, # 91
|
||||
|
||||
PUSH1, # 96
|
||||
PUSH2, # 97
|
||||
PUSH3, # 98
|
||||
PUSH4, # 99
|
||||
PUSH5, # 100
|
||||
PUSH6, # 101
|
||||
PUSH7, # 102
|
||||
PUSH8, # 103
|
||||
PUSH9, # 104
|
||||
PUSH10, # 105
|
||||
PUSH11, # 106
|
||||
PUSH12, # 107
|
||||
PUSH13, # 108
|
||||
PUSH14, # 109
|
||||
PUSH15, # 110
|
||||
PUSH16, # 111
|
||||
PUSH17, # 112
|
||||
PUSH18, # 113
|
||||
PUSH19, # 114
|
||||
PUSH20, # 115
|
||||
PUSH21, # 116
|
||||
PUSH22, # 117
|
||||
PUSH23, # 118
|
||||
PUSH24, # 119
|
||||
PUSH25, # 120
|
||||
PUSH26, # 121
|
||||
PUSH27, # 122
|
||||
PUSH28, # 123
|
||||
PUSH29, # 124
|
||||
PUSH30, # 125
|
||||
PUSH31, # 126
|
||||
PUSH32, # 127
|
||||
DUP1, # 128
|
||||
DUP2, # 129
|
||||
DUP3, # 130
|
||||
DUP4, # 131
|
||||
DUP5, # 132
|
||||
DUP6, # 133
|
||||
DUP7, # 134
|
||||
DUP8, # 135
|
||||
DUP9, # 136
|
||||
DUP10, # 137
|
||||
DUP11, # 138
|
||||
DUP12, # 139
|
||||
DUP13, # 140
|
||||
DUP14, # 141
|
||||
DUP15, # 142
|
||||
DUP16, # 143
|
||||
SWAP1, # 144
|
||||
SWAP2, # 145
|
||||
SWAP3, # 146
|
||||
SWAP4, # 147
|
||||
SWAP5, # 148
|
||||
SWAP6, # 149
|
||||
SWAP7, # 150
|
||||
SWAP8, # 151
|
||||
SWAP9, # 152
|
||||
SWAP10, # 153
|
||||
SWAP11, # 154
|
||||
SWAP12, # 155
|
||||
SWAP13, # 156
|
||||
SWAP14, # 157
|
||||
SWAP15, # 158
|
||||
SWAP16, # 159
|
||||
LOG0, # 160
|
||||
LOG1, # 161
|
||||
LOG2, # 162
|
||||
LOG3, # 163
|
||||
LOG4, # 164
|
||||
CREATE, # 240
|
||||
CALL, # 241
|
||||
CALLCODE, # 242
|
||||
RETURN, # 243
|
||||
DELEGATECALL, # 244
|
||||
STATICCALL, # 250
|
||||
REVERT, # 253
|
||||
SELFDESTRUCT # 255
|
||||
|
|
|
@ -30,24 +30,24 @@ proc read*(c: var CodeStream, size: int): seq[byte] =
|
|||
proc len*(c: CodeStream): int =
|
||||
len(c.bytes)
|
||||
|
||||
proc next*(c: var CodeStream): byte =
|
||||
proc next*(c: var CodeStream): Op =
|
||||
var nextOpcode = c.read(1)
|
||||
if nextOpcode[0] != 0x0.byte:
|
||||
return nextOpcode[0]
|
||||
return Op(nextOpcode[0])
|
||||
else:
|
||||
return opcode_values.STOP
|
||||
return Op.STOP
|
||||
|
||||
|
||||
iterator items*(c: var CodeStream): byte =
|
||||
iterator items*(c: var CodeStream): Op =
|
||||
var nextOpcode = c.next()
|
||||
while nextOpcode != opcode_values.STOP:
|
||||
while nextOpcode != Op.STOP:
|
||||
yield nextOpcode
|
||||
nextOpcode = c.next()
|
||||
|
||||
proc `[]`*(c: CodeStream, offset: int): byte =
|
||||
c.bytes[offset]
|
||||
|
||||
proc peek*(c: var CodeStream): byte =
|
||||
proc peek*(c: var CodeStream): Op =
|
||||
var currentPc = c.pc
|
||||
result = c.next()
|
||||
c.pc = currentPc
|
||||
|
@ -74,8 +74,8 @@ proc isValidOpcode*(c: var CodeStream, position: int): bool =
|
|||
else:
|
||||
var i = c.depthProcessed
|
||||
while i <= position:
|
||||
var opcode = c[i]
|
||||
if opcode >= opcode_values.PUSH1 and opcode <= opcode_values.PUSH32:
|
||||
var opcode = Op(c[i])
|
||||
if opcode >= Op.PUSH1 and opcode <= Op.PUSH32:
|
||||
var leftBound = (i + 1)
|
||||
var rightBound = leftBound + (opcode.int - 95)
|
||||
for z in leftBound ..< rightBound:
|
||||
|
|
Loading…
Reference in New Issue