diff --git a/nimbus/vm/interpreter/gas_costs.nim b/nimbus/vm/interpreter/gas_costs.nim index c1147c1db..5b22931bf 100644 --- a/nimbus/vm/interpreter/gas_costs.nim +++ b/nimbus/vm/interpreter/gas_costs.nim @@ -535,6 +535,9 @@ template gasCosts(fork: Fork, prefix, ResultGasCostsName: untyped) = Msize: fixed GasBase, Gas: fixed GasBase, JumpDest: fixed GasJumpDest, + BeginSub: fixed GasBase, + ReturnSub: fixed GasLow, + JumpSub: fixed GasHigh, # 60s & 70s: Push Operations Push1: fixed GasVeryLow, diff --git a/nimbus/vm/interpreter/opcode_values.nim b/nimbus/vm/interpreter/opcode_values.nim index f85a354ca..5b6aa0e22 100644 --- a/nimbus/vm/interpreter/opcode_values.nim +++ b/nimbus/vm/interpreter/opcode_values.nim @@ -95,6 +95,9 @@ fill_enum_holes: Msize = 0x59, # Get the size of active memory in bytes. Gas = 0x5a, # Get the amount of available gas, including the corresponding reduction for the cost of this instruction. JumpDest = 0x5b, # Mark a valid destination for jumps. This operation has no effect on machine state during execution. + BeginSub = 0x5c, # Marks the entry point to a subroutine + ReturnSub = 0x5d, # Returns control to the caller of a subroutine. + JumpSub = 0x5e, # Transfers control to a subroutine. # 60s & 70s: Push Operations. Push1 = 0x60, # Place 1-byte item on stack. diff --git a/nimbus/vm/interpreter/opcodes_impl.nim b/nimbus/vm/interpreter/opcodes_impl.nim index 67446d58c..68285d8e0 100644 --- a/nimbus/vm/interpreter/opcodes_impl.nim +++ b/nimbus/vm/interpreter/opcodes_impl.nim @@ -542,6 +542,18 @@ op jumpDest, inline = true: ## 0x5b, Mark a valid destination for jumps. This operation has no effect on machine state during execution. discard +op beginSub, inline = true: + ## 0x5c, Marks the entry point to a subroutine + discard + +op returnSub, inline = true: + ## 0x5d, Returns control to the caller of a subroutine. + discard + +op jumpSub, inline = true: + ## 0x5e, Transfers control to a subroutine. + discard + # ########################################## # 60s & 70s: Push Operations. # 80s: Duplication Operations diff --git a/nimbus/vm/interpreter_dispatch.nim b/nimbus/vm/interpreter_dispatch.nim index adeeaf66a..8439c4c68 100644 --- a/nimbus/vm/interpreter_dispatch.nim +++ b/nimbus/vm/interpreter_dispatch.nim @@ -229,6 +229,14 @@ proc genIstanbulJumpTable(ops: array[Op, NimNode]): array[Op, NimNode] {.compile let IstanbulOpDispatch {.compileTime.}: array[Op, NimNode] = genIstanbulJumpTable(PetersburgOpDispatch) +proc genBerlinJumpTable(ops: array[Op, NimNode]): array[Op, NimNode] {.compileTime.} = + result = ops + result[BeginSub] = newIdentNode "beginSub" + result[ReturnSub] = newIdentNode "returnSub" + result[JumpSub] = newIdentNode "jumpSub" + +let BerlinOpDispatch {.compileTime.}: array[Op, NimNode] = genBerlinJumpTable(IstanbulOpDispatch) + proc opTableToCaseStmt(opTable: array[Op, NimNode], c: NimNode): NimNode = let instr = quote do: `c`.instr @@ -308,6 +316,9 @@ macro genPetersburgDispatch(c: Computation): untyped = macro genIstanbulDispatch(c: Computation): untyped = result = opTableToCaseStmt(IstanbulOpDispatch, c) +macro genBerlinDispatch(c: Computation): untyped = + result = opTableToCaseStmt(BerlinOpDispatch, c) + proc frontierVM(c: Computation) = genFrontierDispatch(c) @@ -332,6 +343,9 @@ proc petersburgVM(c: Computation) {.gcsafe.} = proc istanbulVM(c: Computation) {.gcsafe.} = genIstanbulDispatch(c) +proc berlinVM(c: Computation) {.gcsafe.} = + genBerlinDispatch(c) + proc selectVM(c: Computation, fork: Fork) {.gcsafe.} = # TODO: Optimise getting fork and updating opCodeExec only when necessary case fork @@ -349,8 +363,10 @@ proc selectVM(c: Computation, fork: Fork) {.gcsafe.} = c.constantinopleVM() of FkPetersburg: c.petersburgVM() - else: + of FkIstanbul: c.istanbulVM() + else: + c.berlinVM() proc executeOpcodes(c: Computation) = let fork = c.fork