From 2817504e767bbee8895a84a777f0f5db8ac4f994 Mon Sep 17 00:00:00 2001 From: Giulio Rebuffo Date: Fri, 15 May 2026 23:29:34 +0200 Subject: [PATCH] Inline fixed-width PUSH immediates --- vm/gen/main.go | 66 +- vm/table_gen.go | 2702 ++++++++++++++++++++++++++++++++--------------- 2 files changed, 1892 insertions(+), 876 deletions(-) diff --git a/vm/gen/main.go b/vm/gen/main.go index 86d9ffb9..cea754b4 100644 --- a/vm/gen/main.go +++ b/vm/gen/main.go @@ -497,33 +497,54 @@ func (e *emitter) emitLog(n int) { e.p("logNImpl(interp, host, %d)\n", n) } -// emitPushGeneric emits the combined PUSH5-PUSH31 case (excluding PUSH20 and PUSH32). -func (e *emitter) emitPushGeneric() { - e.p("case ") - first := true - for i := 5; i <= 31; i++ { - if i == 20 { - continue // PUSH20 has its own case - } - if !first { - e.p(", ") - } - if i <= 16 || i == 17 || i == 18 || i == 19 || i == 21 || i == 22 || i == 23 || i == 24 || - i == 25 || i == 26 || i == 27 || i == 28 || i == 29 || i == 30 || i == 31 { - e.p("opcode.PUSH%d", i) +func pushLimbExpr(n, limb int) string { + end := n - limb*8 + if end <= 0 { + return "0" + } + start := end - 8 + if start < 0 { + start = 0 + } + parts := make([]string, 0, end-start) + for i := start; i < end; i++ { + shift := uint((end - i - 1) * 8) + part := fmt.Sprintf("uint64(c[p+%d])", i) + if shift != 0 { + part = fmt.Sprintf("%s<<%d", part, shift) } - first = false + parts = append(parts, part) } - e.p(":\n") + return strings.Join(parts, " | ") +} + +// emitPushFixed emits a PUSH case with a compile-time immediate width. +func (e *emitter) emitPushFixed(n int) { + e.p("case opcode.PUSH%d:\n", n) e.emitGas("spec.GasVerylow") e.p("s := interp.Stack\n") e.p("if s.top >= StackLimit {\n") e.emitFlushOnError() e.p("interp.HaltOverflow()\n") e.p("} else {\n") - e.p("n := int(op - opcode.PUSH0)\n") - e.p("s.data[s.top] = *new(uint256.Int).SetBytes(bc.code[bc.pc : bc.pc+n])\n") - e.p("bc.pc += n\n") + e.p("c := bc.code\n") + e.p("p := bc.pc\n") + for limb := 0; limb < 4; limb++ { + expr := pushLimbExpr(n, limb) + if expr != "0" { + e.p("l%d := %s\n", limb, expr) + } + } + e.p("bc.pc = p + %d\n", n) + limbs := make([]string, 4) + for limb := 0; limb < 4; limb++ { + if pushLimbExpr(n, limb) == "0" { + limbs[limb] = "0" + } else { + limbs[limb] = fmt.Sprintf("l%d", limb) + } + } + e.p("s.data[s.top] = uint256.Int{%s, %s, %s, %s}\n", limbs[0], limbs[1], limbs[2], limbs[3]) e.p("s.top++\n") e.p("}\n") } @@ -564,7 +585,12 @@ func (e *emitter) emitAllCases() { op.mode = modeAccumulate e.emitPush(op) } - e.emitPushGeneric() + for i := 5; i <= 31; i++ { + if i == 20 { + continue // PUSH20 has its own hand-specialized case. + } + e.emitPushFixed(i) + } for i := 1; i <= 16; i++ { e.emitDup(i) } diff --git a/vm/table_gen.go b/vm/table_gen.go index 36f92e82..212a0252 100644 --- a/vm/table_gen.go +++ b/vm/table_gen.go @@ -1658,7 +1658,7 @@ func (DefaultRunner) Run(interp *Interpreter, host Host) { s.top++ } - case opcode.PUSH5, opcode.PUSH6, opcode.PUSH7, opcode.PUSH8, opcode.PUSH9, opcode.PUSH10, opcode.PUSH11, opcode.PUSH12, opcode.PUSH13, opcode.PUSH14, opcode.PUSH15, opcode.PUSH16, opcode.PUSH17, opcode.PUSH18, opcode.PUSH19, opcode.PUSH21, opcode.PUSH22, opcode.PUSH23, opcode.PUSH24, opcode.PUSH25, opcode.PUSH26, opcode.PUSH27, opcode.PUSH28, opcode.PUSH29, opcode.PUSH30, opcode.PUSH31: + case opcode.PUSH5: gasCounter += spec.GasVerylow s := interp.Stack if s.top >= StackLimit { @@ -1670,15 +1670,17 @@ func (DefaultRunner) Run(interp *Interpreter, host Host) { gasCounter = 0 interp.HaltOverflow() } else { - n := int(op - opcode.PUSH0) - s.data[s.top] = *new(uint256.Int).SetBytes(bc.code[bc.pc : bc.pc+n]) - bc.pc += n + c := bc.code + p := bc.pc + l0 := uint64(c[p+0])<<32 | uint64(c[p+1])<<24 | uint64(c[p+2])<<16 | uint64(c[p+3])<<8 | uint64(c[p+4]) + bc.pc = p + 5 + s.data[s.top] = uint256.Int{l0, 0, 0, 0} s.top++ } - case opcode.DUP1: + case opcode.PUSH6: gasCounter += spec.GasVerylow s := interp.Stack - if s.top < 1 || s.top >= StackLimit { + if s.top >= StackLimit { if gas.remaining < gasCounter { interp.HaltOOG() return @@ -1687,13 +1689,17 @@ func (DefaultRunner) Run(interp *Interpreter, host Host) { gasCounter = 0 interp.HaltOverflow() } else { - s.data[s.top] = s.data[s.top-1] + c := bc.code + p := bc.pc + l0 := uint64(c[p+0])<<40 | uint64(c[p+1])<<32 | uint64(c[p+2])<<24 | uint64(c[p+3])<<16 | uint64(c[p+4])<<8 | uint64(c[p+5]) + bc.pc = p + 6 + s.data[s.top] = uint256.Int{l0, 0, 0, 0} s.top++ } - case opcode.DUP2: + case opcode.PUSH7: gasCounter += spec.GasVerylow s := interp.Stack - if s.top < 2 || s.top >= StackLimit { + if s.top >= StackLimit { if gas.remaining < gasCounter { interp.HaltOOG() return @@ -1702,13 +1708,17 @@ func (DefaultRunner) Run(interp *Interpreter, host Host) { gasCounter = 0 interp.HaltOverflow() } else { - s.data[s.top] = s.data[s.top-2] + c := bc.code + p := bc.pc + l0 := uint64(c[p+0])<<48 | uint64(c[p+1])<<40 | uint64(c[p+2])<<32 | uint64(c[p+3])<<24 | uint64(c[p+4])<<16 | uint64(c[p+5])<<8 | uint64(c[p+6]) + bc.pc = p + 7 + s.data[s.top] = uint256.Int{l0, 0, 0, 0} s.top++ } - case opcode.DUP3: + case opcode.PUSH8: gasCounter += spec.GasVerylow s := interp.Stack - if s.top < 3 || s.top >= StackLimit { + if s.top >= StackLimit { if gas.remaining < gasCounter { interp.HaltOOG() return @@ -1717,13 +1727,17 @@ func (DefaultRunner) Run(interp *Interpreter, host Host) { gasCounter = 0 interp.HaltOverflow() } else { - s.data[s.top] = s.data[s.top-3] + c := bc.code + p := bc.pc + l0 := uint64(c[p+0])<<56 | uint64(c[p+1])<<48 | uint64(c[p+2])<<40 | uint64(c[p+3])<<32 | uint64(c[p+4])<<24 | uint64(c[p+5])<<16 | uint64(c[p+6])<<8 | uint64(c[p+7]) + bc.pc = p + 8 + s.data[s.top] = uint256.Int{l0, 0, 0, 0} s.top++ } - case opcode.DUP4: + case opcode.PUSH9: gasCounter += spec.GasVerylow s := interp.Stack - if s.top < 4 || s.top >= StackLimit { + if s.top >= StackLimit { if gas.remaining < gasCounter { interp.HaltOOG() return @@ -1732,13 +1746,18 @@ func (DefaultRunner) Run(interp *Interpreter, host Host) { gasCounter = 0 interp.HaltOverflow() } else { - s.data[s.top] = s.data[s.top-4] + c := bc.code + p := bc.pc + l0 := uint64(c[p+1])<<56 | uint64(c[p+2])<<48 | uint64(c[p+3])<<40 | uint64(c[p+4])<<32 | uint64(c[p+5])<<24 | uint64(c[p+6])<<16 | uint64(c[p+7])<<8 | uint64(c[p+8]) + l1 := uint64(c[p+0]) + bc.pc = p + 9 + s.data[s.top] = uint256.Int{l0, l1, 0, 0} s.top++ } - case opcode.DUP5: + case opcode.PUSH10: gasCounter += spec.GasVerylow s := interp.Stack - if s.top < 5 || s.top >= StackLimit { + if s.top >= StackLimit { if gas.remaining < gasCounter { interp.HaltOOG() return @@ -1747,13 +1766,18 @@ func (DefaultRunner) Run(interp *Interpreter, host Host) { gasCounter = 0 interp.HaltOverflow() } else { - s.data[s.top] = s.data[s.top-5] + c := bc.code + p := bc.pc + l0 := uint64(c[p+2])<<56 | uint64(c[p+3])<<48 | uint64(c[p+4])<<40 | uint64(c[p+5])<<32 | uint64(c[p+6])<<24 | uint64(c[p+7])<<16 | uint64(c[p+8])<<8 | uint64(c[p+9]) + l1 := uint64(c[p+0])<<8 | uint64(c[p+1]) + bc.pc = p + 10 + s.data[s.top] = uint256.Int{l0, l1, 0, 0} s.top++ } - case opcode.DUP6: + case opcode.PUSH11: gasCounter += spec.GasVerylow s := interp.Stack - if s.top < 6 || s.top >= StackLimit { + if s.top >= StackLimit { if gas.remaining < gasCounter { interp.HaltOOG() return @@ -1762,13 +1786,18 @@ func (DefaultRunner) Run(interp *Interpreter, host Host) { gasCounter = 0 interp.HaltOverflow() } else { - s.data[s.top] = s.data[s.top-6] + c := bc.code + p := bc.pc + l0 := uint64(c[p+3])<<56 | uint64(c[p+4])<<48 | uint64(c[p+5])<<40 | uint64(c[p+6])<<32 | uint64(c[p+7])<<24 | uint64(c[p+8])<<16 | uint64(c[p+9])<<8 | uint64(c[p+10]) + l1 := uint64(c[p+0])<<16 | uint64(c[p+1])<<8 | uint64(c[p+2]) + bc.pc = p + 11 + s.data[s.top] = uint256.Int{l0, l1, 0, 0} s.top++ } - case opcode.DUP7: + case opcode.PUSH12: gasCounter += spec.GasVerylow s := interp.Stack - if s.top < 7 || s.top >= StackLimit { + if s.top >= StackLimit { if gas.remaining < gasCounter { interp.HaltOOG() return @@ -1777,13 +1806,18 @@ func (DefaultRunner) Run(interp *Interpreter, host Host) { gasCounter = 0 interp.HaltOverflow() } else { - s.data[s.top] = s.data[s.top-7] + c := bc.code + p := bc.pc + l0 := uint64(c[p+4])<<56 | uint64(c[p+5])<<48 | uint64(c[p+6])<<40 | uint64(c[p+7])<<32 | uint64(c[p+8])<<24 | uint64(c[p+9])<<16 | uint64(c[p+10])<<8 | uint64(c[p+11]) + l1 := uint64(c[p+0])<<24 | uint64(c[p+1])<<16 | uint64(c[p+2])<<8 | uint64(c[p+3]) + bc.pc = p + 12 + s.data[s.top] = uint256.Int{l0, l1, 0, 0} s.top++ } - case opcode.DUP8: + case opcode.PUSH13: gasCounter += spec.GasVerylow s := interp.Stack - if s.top < 8 || s.top >= StackLimit { + if s.top >= StackLimit { if gas.remaining < gasCounter { interp.HaltOOG() return @@ -1792,13 +1826,18 @@ func (DefaultRunner) Run(interp *Interpreter, host Host) { gasCounter = 0 interp.HaltOverflow() } else { - s.data[s.top] = s.data[s.top-8] + c := bc.code + p := bc.pc + l0 := uint64(c[p+5])<<56 | uint64(c[p+6])<<48 | uint64(c[p+7])<<40 | uint64(c[p+8])<<32 | uint64(c[p+9])<<24 | uint64(c[p+10])<<16 | uint64(c[p+11])<<8 | uint64(c[p+12]) + l1 := uint64(c[p+0])<<32 | uint64(c[p+1])<<24 | uint64(c[p+2])<<16 | uint64(c[p+3])<<8 | uint64(c[p+4]) + bc.pc = p + 13 + s.data[s.top] = uint256.Int{l0, l1, 0, 0} s.top++ } - case opcode.DUP9: + case opcode.PUSH14: gasCounter += spec.GasVerylow s := interp.Stack - if s.top < 9 || s.top >= StackLimit { + if s.top >= StackLimit { if gas.remaining < gasCounter { interp.HaltOOG() return @@ -1807,13 +1846,18 @@ func (DefaultRunner) Run(interp *Interpreter, host Host) { gasCounter = 0 interp.HaltOverflow() } else { - s.data[s.top] = s.data[s.top-9] + c := bc.code + p := bc.pc + l0 := uint64(c[p+6])<<56 | uint64(c[p+7])<<48 | uint64(c[p+8])<<40 | uint64(c[p+9])<<32 | uint64(c[p+10])<<24 | uint64(c[p+11])<<16 | uint64(c[p+12])<<8 | uint64(c[p+13]) + l1 := uint64(c[p+0])<<40 | uint64(c[p+1])<<32 | uint64(c[p+2])<<24 | uint64(c[p+3])<<16 | uint64(c[p+4])<<8 | uint64(c[p+5]) + bc.pc = p + 14 + s.data[s.top] = uint256.Int{l0, l1, 0, 0} s.top++ } - case opcode.DUP10: + case opcode.PUSH15: gasCounter += spec.GasVerylow s := interp.Stack - if s.top < 10 || s.top >= StackLimit { + if s.top >= StackLimit { if gas.remaining < gasCounter { interp.HaltOOG() return @@ -1822,13 +1866,18 @@ func (DefaultRunner) Run(interp *Interpreter, host Host) { gasCounter = 0 interp.HaltOverflow() } else { - s.data[s.top] = s.data[s.top-10] + c := bc.code + p := bc.pc + l0 := uint64(c[p+7])<<56 | uint64(c[p+8])<<48 | uint64(c[p+9])<<40 | uint64(c[p+10])<<32 | uint64(c[p+11])<<24 | uint64(c[p+12])<<16 | uint64(c[p+13])<<8 | uint64(c[p+14]) + l1 := uint64(c[p+0])<<48 | uint64(c[p+1])<<40 | uint64(c[p+2])<<32 | uint64(c[p+3])<<24 | uint64(c[p+4])<<16 | uint64(c[p+5])<<8 | uint64(c[p+6]) + bc.pc = p + 15 + s.data[s.top] = uint256.Int{l0, l1, 0, 0} s.top++ } - case opcode.DUP11: + case opcode.PUSH16: gasCounter += spec.GasVerylow s := interp.Stack - if s.top < 11 || s.top >= StackLimit { + if s.top >= StackLimit { if gas.remaining < gasCounter { interp.HaltOOG() return @@ -1837,13 +1886,18 @@ func (DefaultRunner) Run(interp *Interpreter, host Host) { gasCounter = 0 interp.HaltOverflow() } else { - s.data[s.top] = s.data[s.top-11] + c := bc.code + p := bc.pc + l0 := uint64(c[p+8])<<56 | uint64(c[p+9])<<48 | uint64(c[p+10])<<40 | uint64(c[p+11])<<32 | uint64(c[p+12])<<24 | uint64(c[p+13])<<16 | uint64(c[p+14])<<8 | uint64(c[p+15]) + l1 := uint64(c[p+0])<<56 | uint64(c[p+1])<<48 | uint64(c[p+2])<<40 | uint64(c[p+3])<<32 | uint64(c[p+4])<<24 | uint64(c[p+5])<<16 | uint64(c[p+6])<<8 | uint64(c[p+7]) + bc.pc = p + 16 + s.data[s.top] = uint256.Int{l0, l1, 0, 0} s.top++ } - case opcode.DUP12: + case opcode.PUSH17: gasCounter += spec.GasVerylow s := interp.Stack - if s.top < 12 || s.top >= StackLimit { + if s.top >= StackLimit { if gas.remaining < gasCounter { interp.HaltOOG() return @@ -1852,13 +1906,19 @@ func (DefaultRunner) Run(interp *Interpreter, host Host) { gasCounter = 0 interp.HaltOverflow() } else { - s.data[s.top] = s.data[s.top-12] + c := bc.code + p := bc.pc + l0 := uint64(c[p+9])<<56 | uint64(c[p+10])<<48 | uint64(c[p+11])<<40 | uint64(c[p+12])<<32 | uint64(c[p+13])<<24 | uint64(c[p+14])<<16 | uint64(c[p+15])<<8 | uint64(c[p+16]) + l1 := uint64(c[p+1])<<56 | uint64(c[p+2])<<48 | uint64(c[p+3])<<40 | uint64(c[p+4])<<32 | uint64(c[p+5])<<24 | uint64(c[p+6])<<16 | uint64(c[p+7])<<8 | uint64(c[p+8]) + l2 := uint64(c[p+0]) + bc.pc = p + 17 + s.data[s.top] = uint256.Int{l0, l1, l2, 0} s.top++ } - case opcode.DUP13: + case opcode.PUSH18: gasCounter += spec.GasVerylow s := interp.Stack - if s.top < 13 || s.top >= StackLimit { + if s.top >= StackLimit { if gas.remaining < gasCounter { interp.HaltOOG() return @@ -1867,13 +1927,19 @@ func (DefaultRunner) Run(interp *Interpreter, host Host) { gasCounter = 0 interp.HaltOverflow() } else { - s.data[s.top] = s.data[s.top-13] + c := bc.code + p := bc.pc + l0 := uint64(c[p+10])<<56 | uint64(c[p+11])<<48 | uint64(c[p+12])<<40 | uint64(c[p+13])<<32 | uint64(c[p+14])<<24 | uint64(c[p+15])<<16 | uint64(c[p+16])<<8 | uint64(c[p+17]) + l1 := uint64(c[p+2])<<56 | uint64(c[p+3])<<48 | uint64(c[p+4])<<40 | uint64(c[p+5])<<32 | uint64(c[p+6])<<24 | uint64(c[p+7])<<16 | uint64(c[p+8])<<8 | uint64(c[p+9]) + l2 := uint64(c[p+0])<<8 | uint64(c[p+1]) + bc.pc = p + 18 + s.data[s.top] = uint256.Int{l0, l1, l2, 0} s.top++ } - case opcode.DUP14: + case opcode.PUSH19: gasCounter += spec.GasVerylow s := interp.Stack - if s.top < 14 || s.top >= StackLimit { + if s.top >= StackLimit { if gas.remaining < gasCounter { interp.HaltOOG() return @@ -1882,13 +1948,19 @@ func (DefaultRunner) Run(interp *Interpreter, host Host) { gasCounter = 0 interp.HaltOverflow() } else { - s.data[s.top] = s.data[s.top-14] + c := bc.code + p := bc.pc + l0 := uint64(c[p+11])<<56 | uint64(c[p+12])<<48 | uint64(c[p+13])<<40 | uint64(c[p+14])<<32 | uint64(c[p+15])<<24 | uint64(c[p+16])<<16 | uint64(c[p+17])<<8 | uint64(c[p+18]) + l1 := uint64(c[p+3])<<56 | uint64(c[p+4])<<48 | uint64(c[p+5])<<40 | uint64(c[p+6])<<32 | uint64(c[p+7])<<24 | uint64(c[p+8])<<16 | uint64(c[p+9])<<8 | uint64(c[p+10]) + l2 := uint64(c[p+0])<<16 | uint64(c[p+1])<<8 | uint64(c[p+2]) + bc.pc = p + 19 + s.data[s.top] = uint256.Int{l0, l1, l2, 0} s.top++ } - case opcode.DUP15: + case opcode.PUSH21: gasCounter += spec.GasVerylow s := interp.Stack - if s.top < 15 || s.top >= StackLimit { + if s.top >= StackLimit { if gas.remaining < gasCounter { interp.HaltOOG() return @@ -1897,13 +1969,19 @@ func (DefaultRunner) Run(interp *Interpreter, host Host) { gasCounter = 0 interp.HaltOverflow() } else { - s.data[s.top] = s.data[s.top-15] + c := bc.code + p := bc.pc + l0 := uint64(c[p+13])<<56 | uint64(c[p+14])<<48 | uint64(c[p+15])<<40 | uint64(c[p+16])<<32 | uint64(c[p+17])<<24 | uint64(c[p+18])<<16 | uint64(c[p+19])<<8 | uint64(c[p+20]) + l1 := uint64(c[p+5])<<56 | uint64(c[p+6])<<48 | uint64(c[p+7])<<40 | uint64(c[p+8])<<32 | uint64(c[p+9])<<24 | uint64(c[p+10])<<16 | uint64(c[p+11])<<8 | uint64(c[p+12]) + l2 := uint64(c[p+0])<<32 | uint64(c[p+1])<<24 | uint64(c[p+2])<<16 | uint64(c[p+3])<<8 | uint64(c[p+4]) + bc.pc = p + 21 + s.data[s.top] = uint256.Int{l0, l1, l2, 0} s.top++ } - case opcode.DUP16: + case opcode.PUSH22: gasCounter += spec.GasVerylow s := interp.Stack - if s.top < 16 || s.top >= StackLimit { + if s.top >= StackLimit { if gas.remaining < gasCounter { interp.HaltOOG() return @@ -1912,14 +1990,19 @@ func (DefaultRunner) Run(interp *Interpreter, host Host) { gasCounter = 0 interp.HaltOverflow() } else { - s.data[s.top] = s.data[s.top-16] + c := bc.code + p := bc.pc + l0 := uint64(c[p+14])<<56 | uint64(c[p+15])<<48 | uint64(c[p+16])<<40 | uint64(c[p+17])<<32 | uint64(c[p+18])<<24 | uint64(c[p+19])<<16 | uint64(c[p+20])<<8 | uint64(c[p+21]) + l1 := uint64(c[p+6])<<56 | uint64(c[p+7])<<48 | uint64(c[p+8])<<40 | uint64(c[p+9])<<32 | uint64(c[p+10])<<24 | uint64(c[p+11])<<16 | uint64(c[p+12])<<8 | uint64(c[p+13]) + l2 := uint64(c[p+0])<<40 | uint64(c[p+1])<<32 | uint64(c[p+2])<<24 | uint64(c[p+3])<<16 | uint64(c[p+4])<<8 | uint64(c[p+5]) + bc.pc = p + 22 + s.data[s.top] = uint256.Int{l0, l1, l2, 0} s.top++ } - case opcode.SWAP1: + case opcode.PUSH23: gasCounter += spec.GasVerylow s := interp.Stack - t := s.top - 1 - if t < 1 { + if s.top >= StackLimit { if gas.remaining < gasCounter { interp.HaltOOG() return @@ -1928,13 +2011,19 @@ func (DefaultRunner) Run(interp *Interpreter, host Host) { gasCounter = 0 interp.HaltOverflow() } else { - s.data[t], s.data[t-1] = s.data[t-1], s.data[t] + c := bc.code + p := bc.pc + l0 := uint64(c[p+15])<<56 | uint64(c[p+16])<<48 | uint64(c[p+17])<<40 | uint64(c[p+18])<<32 | uint64(c[p+19])<<24 | uint64(c[p+20])<<16 | uint64(c[p+21])<<8 | uint64(c[p+22]) + l1 := uint64(c[p+7])<<56 | uint64(c[p+8])<<48 | uint64(c[p+9])<<40 | uint64(c[p+10])<<32 | uint64(c[p+11])<<24 | uint64(c[p+12])<<16 | uint64(c[p+13])<<8 | uint64(c[p+14]) + l2 := uint64(c[p+0])<<48 | uint64(c[p+1])<<40 | uint64(c[p+2])<<32 | uint64(c[p+3])<<24 | uint64(c[p+4])<<16 | uint64(c[p+5])<<8 | uint64(c[p+6]) + bc.pc = p + 23 + s.data[s.top] = uint256.Int{l0, l1, l2, 0} + s.top++ } - case opcode.SWAP2: + case opcode.PUSH24: gasCounter += spec.GasVerylow s := interp.Stack - t := s.top - 1 - if t < 2 { + if s.top >= StackLimit { if gas.remaining < gasCounter { interp.HaltOOG() return @@ -1943,13 +2032,19 @@ func (DefaultRunner) Run(interp *Interpreter, host Host) { gasCounter = 0 interp.HaltOverflow() } else { - s.data[t], s.data[t-2] = s.data[t-2], s.data[t] + c := bc.code + p := bc.pc + l0 := uint64(c[p+16])<<56 | uint64(c[p+17])<<48 | uint64(c[p+18])<<40 | uint64(c[p+19])<<32 | uint64(c[p+20])<<24 | uint64(c[p+21])<<16 | uint64(c[p+22])<<8 | uint64(c[p+23]) + l1 := uint64(c[p+8])<<56 | uint64(c[p+9])<<48 | uint64(c[p+10])<<40 | uint64(c[p+11])<<32 | uint64(c[p+12])<<24 | uint64(c[p+13])<<16 | uint64(c[p+14])<<8 | uint64(c[p+15]) + l2 := uint64(c[p+0])<<56 | uint64(c[p+1])<<48 | uint64(c[p+2])<<40 | uint64(c[p+3])<<32 | uint64(c[p+4])<<24 | uint64(c[p+5])<<16 | uint64(c[p+6])<<8 | uint64(c[p+7]) + bc.pc = p + 24 + s.data[s.top] = uint256.Int{l0, l1, l2, 0} + s.top++ } - case opcode.SWAP3: + case opcode.PUSH25: gasCounter += spec.GasVerylow s := interp.Stack - t := s.top - 1 - if t < 3 { + if s.top >= StackLimit { if gas.remaining < gasCounter { interp.HaltOOG() return @@ -1958,13 +2053,20 @@ func (DefaultRunner) Run(interp *Interpreter, host Host) { gasCounter = 0 interp.HaltOverflow() } else { - s.data[t], s.data[t-3] = s.data[t-3], s.data[t] + c := bc.code + p := bc.pc + l0 := uint64(c[p+17])<<56 | uint64(c[p+18])<<48 | uint64(c[p+19])<<40 | uint64(c[p+20])<<32 | uint64(c[p+21])<<24 | uint64(c[p+22])<<16 | uint64(c[p+23])<<8 | uint64(c[p+24]) + l1 := uint64(c[p+9])<<56 | uint64(c[p+10])<<48 | uint64(c[p+11])<<40 | uint64(c[p+12])<<32 | uint64(c[p+13])<<24 | uint64(c[p+14])<<16 | uint64(c[p+15])<<8 | uint64(c[p+16]) + l2 := uint64(c[p+1])<<56 | uint64(c[p+2])<<48 | uint64(c[p+3])<<40 | uint64(c[p+4])<<32 | uint64(c[p+5])<<24 | uint64(c[p+6])<<16 | uint64(c[p+7])<<8 | uint64(c[p+8]) + l3 := uint64(c[p+0]) + bc.pc = p + 25 + s.data[s.top] = uint256.Int{l0, l1, l2, l3} + s.top++ } - case opcode.SWAP4: + case opcode.PUSH26: gasCounter += spec.GasVerylow s := interp.Stack - t := s.top - 1 - if t < 4 { + if s.top >= StackLimit { if gas.remaining < gasCounter { interp.HaltOOG() return @@ -1973,13 +2075,20 @@ func (DefaultRunner) Run(interp *Interpreter, host Host) { gasCounter = 0 interp.HaltOverflow() } else { - s.data[t], s.data[t-4] = s.data[t-4], s.data[t] + c := bc.code + p := bc.pc + l0 := uint64(c[p+18])<<56 | uint64(c[p+19])<<48 | uint64(c[p+20])<<40 | uint64(c[p+21])<<32 | uint64(c[p+22])<<24 | uint64(c[p+23])<<16 | uint64(c[p+24])<<8 | uint64(c[p+25]) + l1 := uint64(c[p+10])<<56 | uint64(c[p+11])<<48 | uint64(c[p+12])<<40 | uint64(c[p+13])<<32 | uint64(c[p+14])<<24 | uint64(c[p+15])<<16 | uint64(c[p+16])<<8 | uint64(c[p+17]) + l2 := uint64(c[p+2])<<56 | uint64(c[p+3])<<48 | uint64(c[p+4])<<40 | uint64(c[p+5])<<32 | uint64(c[p+6])<<24 | uint64(c[p+7])<<16 | uint64(c[p+8])<<8 | uint64(c[p+9]) + l3 := uint64(c[p+0])<<8 | uint64(c[p+1]) + bc.pc = p + 26 + s.data[s.top] = uint256.Int{l0, l1, l2, l3} + s.top++ } - case opcode.SWAP5: + case opcode.PUSH27: gasCounter += spec.GasVerylow s := interp.Stack - t := s.top - 1 - if t < 5 { + if s.top >= StackLimit { if gas.remaining < gasCounter { interp.HaltOOG() return @@ -1988,13 +2097,20 @@ func (DefaultRunner) Run(interp *Interpreter, host Host) { gasCounter = 0 interp.HaltOverflow() } else { - s.data[t], s.data[t-5] = s.data[t-5], s.data[t] + c := bc.code + p := bc.pc + l0 := uint64(c[p+19])<<56 | uint64(c[p+20])<<48 | uint64(c[p+21])<<40 | uint64(c[p+22])<<32 | uint64(c[p+23])<<24 | uint64(c[p+24])<<16 | uint64(c[p+25])<<8 | uint64(c[p+26]) + l1 := uint64(c[p+11])<<56 | uint64(c[p+12])<<48 | uint64(c[p+13])<<40 | uint64(c[p+14])<<32 | uint64(c[p+15])<<24 | uint64(c[p+16])<<16 | uint64(c[p+17])<<8 | uint64(c[p+18]) + l2 := uint64(c[p+3])<<56 | uint64(c[p+4])<<48 | uint64(c[p+5])<<40 | uint64(c[p+6])<<32 | uint64(c[p+7])<<24 | uint64(c[p+8])<<16 | uint64(c[p+9])<<8 | uint64(c[p+10]) + l3 := uint64(c[p+0])<<16 | uint64(c[p+1])<<8 | uint64(c[p+2]) + bc.pc = p + 27 + s.data[s.top] = uint256.Int{l0, l1, l2, l3} + s.top++ } - case opcode.SWAP6: + case opcode.PUSH28: gasCounter += spec.GasVerylow s := interp.Stack - t := s.top - 1 - if t < 6 { + if s.top >= StackLimit { if gas.remaining < gasCounter { interp.HaltOOG() return @@ -2003,13 +2119,20 @@ func (DefaultRunner) Run(interp *Interpreter, host Host) { gasCounter = 0 interp.HaltOverflow() } else { - s.data[t], s.data[t-6] = s.data[t-6], s.data[t] + c := bc.code + p := bc.pc + l0 := uint64(c[p+20])<<56 | uint64(c[p+21])<<48 | uint64(c[p+22])<<40 | uint64(c[p+23])<<32 | uint64(c[p+24])<<24 | uint64(c[p+25])<<16 | uint64(c[p+26])<<8 | uint64(c[p+27]) + l1 := uint64(c[p+12])<<56 | uint64(c[p+13])<<48 | uint64(c[p+14])<<40 | uint64(c[p+15])<<32 | uint64(c[p+16])<<24 | uint64(c[p+17])<<16 | uint64(c[p+18])<<8 | uint64(c[p+19]) + l2 := uint64(c[p+4])<<56 | uint64(c[p+5])<<48 | uint64(c[p+6])<<40 | uint64(c[p+7])<<32 | uint64(c[p+8])<<24 | uint64(c[p+9])<<16 | uint64(c[p+10])<<8 | uint64(c[p+11]) + l3 := uint64(c[p+0])<<24 | uint64(c[p+1])<<16 | uint64(c[p+2])<<8 | uint64(c[p+3]) + bc.pc = p + 28 + s.data[s.top] = uint256.Int{l0, l1, l2, l3} + s.top++ } - case opcode.SWAP7: + case opcode.PUSH29: gasCounter += spec.GasVerylow s := interp.Stack - t := s.top - 1 - if t < 7 { + if s.top >= StackLimit { if gas.remaining < gasCounter { interp.HaltOOG() return @@ -2018,13 +2141,20 @@ func (DefaultRunner) Run(interp *Interpreter, host Host) { gasCounter = 0 interp.HaltOverflow() } else { - s.data[t], s.data[t-7] = s.data[t-7], s.data[t] + c := bc.code + p := bc.pc + l0 := uint64(c[p+21])<<56 | uint64(c[p+22])<<48 | uint64(c[p+23])<<40 | uint64(c[p+24])<<32 | uint64(c[p+25])<<24 | uint64(c[p+26])<<16 | uint64(c[p+27])<<8 | uint64(c[p+28]) + l1 := uint64(c[p+13])<<56 | uint64(c[p+14])<<48 | uint64(c[p+15])<<40 | uint64(c[p+16])<<32 | uint64(c[p+17])<<24 | uint64(c[p+18])<<16 | uint64(c[p+19])<<8 | uint64(c[p+20]) + l2 := uint64(c[p+5])<<56 | uint64(c[p+6])<<48 | uint64(c[p+7])<<40 | uint64(c[p+8])<<32 | uint64(c[p+9])<<24 | uint64(c[p+10])<<16 | uint64(c[p+11])<<8 | uint64(c[p+12]) + l3 := uint64(c[p+0])<<32 | uint64(c[p+1])<<24 | uint64(c[p+2])<<16 | uint64(c[p+3])<<8 | uint64(c[p+4]) + bc.pc = p + 29 + s.data[s.top] = uint256.Int{l0, l1, l2, l3} + s.top++ } - case opcode.SWAP8: + case opcode.PUSH30: gasCounter += spec.GasVerylow s := interp.Stack - t := s.top - 1 - if t < 8 { + if s.top >= StackLimit { if gas.remaining < gasCounter { interp.HaltOOG() return @@ -2033,13 +2163,20 @@ func (DefaultRunner) Run(interp *Interpreter, host Host) { gasCounter = 0 interp.HaltOverflow() } else { - s.data[t], s.data[t-8] = s.data[t-8], s.data[t] + c := bc.code + p := bc.pc + l0 := uint64(c[p+22])<<56 | uint64(c[p+23])<<48 | uint64(c[p+24])<<40 | uint64(c[p+25])<<32 | uint64(c[p+26])<<24 | uint64(c[p+27])<<16 | uint64(c[p+28])<<8 | uint64(c[p+29]) + l1 := uint64(c[p+14])<<56 | uint64(c[p+15])<<48 | uint64(c[p+16])<<40 | uint64(c[p+17])<<32 | uint64(c[p+18])<<24 | uint64(c[p+19])<<16 | uint64(c[p+20])<<8 | uint64(c[p+21]) + l2 := uint64(c[p+6])<<56 | uint64(c[p+7])<<48 | uint64(c[p+8])<<40 | uint64(c[p+9])<<32 | uint64(c[p+10])<<24 | uint64(c[p+11])<<16 | uint64(c[p+12])<<8 | uint64(c[p+13]) + l3 := uint64(c[p+0])<<40 | uint64(c[p+1])<<32 | uint64(c[p+2])<<24 | uint64(c[p+3])<<16 | uint64(c[p+4])<<8 | uint64(c[p+5]) + bc.pc = p + 30 + s.data[s.top] = uint256.Int{l0, l1, l2, l3} + s.top++ } - case opcode.SWAP9: + case opcode.PUSH31: gasCounter += spec.GasVerylow s := interp.Stack - t := s.top - 1 - if t < 9 { + if s.top >= StackLimit { if gas.remaining < gasCounter { interp.HaltOOG() return @@ -2048,13 +2185,20 @@ func (DefaultRunner) Run(interp *Interpreter, host Host) { gasCounter = 0 interp.HaltOverflow() } else { - s.data[t], s.data[t-9] = s.data[t-9], s.data[t] + c := bc.code + p := bc.pc + l0 := uint64(c[p+23])<<56 | uint64(c[p+24])<<48 | uint64(c[p+25])<<40 | uint64(c[p+26])<<32 | uint64(c[p+27])<<24 | uint64(c[p+28])<<16 | uint64(c[p+29])<<8 | uint64(c[p+30]) + l1 := uint64(c[p+15])<<56 | uint64(c[p+16])<<48 | uint64(c[p+17])<<40 | uint64(c[p+18])<<32 | uint64(c[p+19])<<24 | uint64(c[p+20])<<16 | uint64(c[p+21])<<8 | uint64(c[p+22]) + l2 := uint64(c[p+7])<<56 | uint64(c[p+8])<<48 | uint64(c[p+9])<<40 | uint64(c[p+10])<<32 | uint64(c[p+11])<<24 | uint64(c[p+12])<<16 | uint64(c[p+13])<<8 | uint64(c[p+14]) + l3 := uint64(c[p+0])<<48 | uint64(c[p+1])<<40 | uint64(c[p+2])<<32 | uint64(c[p+3])<<24 | uint64(c[p+4])<<16 | uint64(c[p+5])<<8 | uint64(c[p+6]) + bc.pc = p + 31 + s.data[s.top] = uint256.Int{l0, l1, l2, l3} + s.top++ } - case opcode.SWAP10: + case opcode.DUP1: gasCounter += spec.GasVerylow s := interp.Stack - t := s.top - 1 - if t < 10 { + if s.top < 1 || s.top >= StackLimit { if gas.remaining < gasCounter { interp.HaltOOG() return @@ -2063,13 +2207,13 @@ func (DefaultRunner) Run(interp *Interpreter, host Host) { gasCounter = 0 interp.HaltOverflow() } else { - s.data[t], s.data[t-10] = s.data[t-10], s.data[t] + s.data[s.top] = s.data[s.top-1] + s.top++ } - case opcode.SWAP11: + case opcode.DUP2: gasCounter += spec.GasVerylow s := interp.Stack - t := s.top - 1 - if t < 11 { + if s.top < 2 || s.top >= StackLimit { if gas.remaining < gasCounter { interp.HaltOOG() return @@ -2078,13 +2222,13 @@ func (DefaultRunner) Run(interp *Interpreter, host Host) { gasCounter = 0 interp.HaltOverflow() } else { - s.data[t], s.data[t-11] = s.data[t-11], s.data[t] + s.data[s.top] = s.data[s.top-2] + s.top++ } - case opcode.SWAP12: + case opcode.DUP3: gasCounter += spec.GasVerylow s := interp.Stack - t := s.top - 1 - if t < 12 { + if s.top < 3 || s.top >= StackLimit { if gas.remaining < gasCounter { interp.HaltOOG() return @@ -2093,13 +2237,13 @@ func (DefaultRunner) Run(interp *Interpreter, host Host) { gasCounter = 0 interp.HaltOverflow() } else { - s.data[t], s.data[t-12] = s.data[t-12], s.data[t] + s.data[s.top] = s.data[s.top-3] + s.top++ } - case opcode.SWAP13: + case opcode.DUP4: gasCounter += spec.GasVerylow s := interp.Stack - t := s.top - 1 - if t < 13 { + if s.top < 4 || s.top >= StackLimit { if gas.remaining < gasCounter { interp.HaltOOG() return @@ -2108,13 +2252,13 @@ func (DefaultRunner) Run(interp *Interpreter, host Host) { gasCounter = 0 interp.HaltOverflow() } else { - s.data[t], s.data[t-13] = s.data[t-13], s.data[t] + s.data[s.top] = s.data[s.top-4] + s.top++ } - case opcode.SWAP14: + case opcode.DUP5: gasCounter += spec.GasVerylow s := interp.Stack - t := s.top - 1 - if t < 14 { + if s.top < 5 || s.top >= StackLimit { if gas.remaining < gasCounter { interp.HaltOOG() return @@ -2123,13 +2267,13 @@ func (DefaultRunner) Run(interp *Interpreter, host Host) { gasCounter = 0 interp.HaltOverflow() } else { - s.data[t], s.data[t-14] = s.data[t-14], s.data[t] + s.data[s.top] = s.data[s.top-5] + s.top++ } - case opcode.SWAP15: + case opcode.DUP6: gasCounter += spec.GasVerylow s := interp.Stack - t := s.top - 1 - if t < 15 { + if s.top < 6 || s.top >= StackLimit { if gas.remaining < gasCounter { interp.HaltOOG() return @@ -2138,13 +2282,13 @@ func (DefaultRunner) Run(interp *Interpreter, host Host) { gasCounter = 0 interp.HaltOverflow() } else { - s.data[t], s.data[t-15] = s.data[t-15], s.data[t] + s.data[s.top] = s.data[s.top-6] + s.top++ } - case opcode.SWAP16: + case opcode.DUP7: gasCounter += spec.GasVerylow s := interp.Stack - t := s.top - 1 - if t < 16 { + if s.top < 7 || s.top >= StackLimit { if gas.remaining < gasCounter { interp.HaltOOG() return @@ -2153,24 +2297,400 @@ func (DefaultRunner) Run(interp *Interpreter, host Host) { gasCounter = 0 interp.HaltOverflow() } else { - s.data[t], s.data[t-16] = s.data[t-16], s.data[t] - } - case opcode.LOG0: - if gas.remaining < gasCounter { - interp.HaltOOG() - return - } - gas.remaining -= gasCounter - gasCounter = 0 - logNImpl(interp, host, 0) - case opcode.LOG1: - if gas.remaining < gasCounter { - interp.HaltOOG() - return + s.data[s.top] = s.data[s.top-7] + s.top++ } - gas.remaining -= gasCounter - gasCounter = 0 - logNImpl(interp, host, 1) + case opcode.DUP8: + gasCounter += spec.GasVerylow + s := interp.Stack + if s.top < 8 || s.top >= StackLimit { + if gas.remaining < gasCounter { + interp.HaltOOG() + return + } + gas.remaining -= gasCounter + gasCounter = 0 + interp.HaltOverflow() + } else { + s.data[s.top] = s.data[s.top-8] + s.top++ + } + case opcode.DUP9: + gasCounter += spec.GasVerylow + s := interp.Stack + if s.top < 9 || s.top >= StackLimit { + if gas.remaining < gasCounter { + interp.HaltOOG() + return + } + gas.remaining -= gasCounter + gasCounter = 0 + interp.HaltOverflow() + } else { + s.data[s.top] = s.data[s.top-9] + s.top++ + } + case opcode.DUP10: + gasCounter += spec.GasVerylow + s := interp.Stack + if s.top < 10 || s.top >= StackLimit { + if gas.remaining < gasCounter { + interp.HaltOOG() + return + } + gas.remaining -= gasCounter + gasCounter = 0 + interp.HaltOverflow() + } else { + s.data[s.top] = s.data[s.top-10] + s.top++ + } + case opcode.DUP11: + gasCounter += spec.GasVerylow + s := interp.Stack + if s.top < 11 || s.top >= StackLimit { + if gas.remaining < gasCounter { + interp.HaltOOG() + return + } + gas.remaining -= gasCounter + gasCounter = 0 + interp.HaltOverflow() + } else { + s.data[s.top] = s.data[s.top-11] + s.top++ + } + case opcode.DUP12: + gasCounter += spec.GasVerylow + s := interp.Stack + if s.top < 12 || s.top >= StackLimit { + if gas.remaining < gasCounter { + interp.HaltOOG() + return + } + gas.remaining -= gasCounter + gasCounter = 0 + interp.HaltOverflow() + } else { + s.data[s.top] = s.data[s.top-12] + s.top++ + } + case opcode.DUP13: + gasCounter += spec.GasVerylow + s := interp.Stack + if s.top < 13 || s.top >= StackLimit { + if gas.remaining < gasCounter { + interp.HaltOOG() + return + } + gas.remaining -= gasCounter + gasCounter = 0 + interp.HaltOverflow() + } else { + s.data[s.top] = s.data[s.top-13] + s.top++ + } + case opcode.DUP14: + gasCounter += spec.GasVerylow + s := interp.Stack + if s.top < 14 || s.top >= StackLimit { + if gas.remaining < gasCounter { + interp.HaltOOG() + return + } + gas.remaining -= gasCounter + gasCounter = 0 + interp.HaltOverflow() + } else { + s.data[s.top] = s.data[s.top-14] + s.top++ + } + case opcode.DUP15: + gasCounter += spec.GasVerylow + s := interp.Stack + if s.top < 15 || s.top >= StackLimit { + if gas.remaining < gasCounter { + interp.HaltOOG() + return + } + gas.remaining -= gasCounter + gasCounter = 0 + interp.HaltOverflow() + } else { + s.data[s.top] = s.data[s.top-15] + s.top++ + } + case opcode.DUP16: + gasCounter += spec.GasVerylow + s := interp.Stack + if s.top < 16 || s.top >= StackLimit { + if gas.remaining < gasCounter { + interp.HaltOOG() + return + } + gas.remaining -= gasCounter + gasCounter = 0 + interp.HaltOverflow() + } else { + s.data[s.top] = s.data[s.top-16] + s.top++ + } + case opcode.SWAP1: + gasCounter += spec.GasVerylow + s := interp.Stack + t := s.top - 1 + if t < 1 { + if gas.remaining < gasCounter { + interp.HaltOOG() + return + } + gas.remaining -= gasCounter + gasCounter = 0 + interp.HaltOverflow() + } else { + s.data[t], s.data[t-1] = s.data[t-1], s.data[t] + } + case opcode.SWAP2: + gasCounter += spec.GasVerylow + s := interp.Stack + t := s.top - 1 + if t < 2 { + if gas.remaining < gasCounter { + interp.HaltOOG() + return + } + gas.remaining -= gasCounter + gasCounter = 0 + interp.HaltOverflow() + } else { + s.data[t], s.data[t-2] = s.data[t-2], s.data[t] + } + case opcode.SWAP3: + gasCounter += spec.GasVerylow + s := interp.Stack + t := s.top - 1 + if t < 3 { + if gas.remaining < gasCounter { + interp.HaltOOG() + return + } + gas.remaining -= gasCounter + gasCounter = 0 + interp.HaltOverflow() + } else { + s.data[t], s.data[t-3] = s.data[t-3], s.data[t] + } + case opcode.SWAP4: + gasCounter += spec.GasVerylow + s := interp.Stack + t := s.top - 1 + if t < 4 { + if gas.remaining < gasCounter { + interp.HaltOOG() + return + } + gas.remaining -= gasCounter + gasCounter = 0 + interp.HaltOverflow() + } else { + s.data[t], s.data[t-4] = s.data[t-4], s.data[t] + } + case opcode.SWAP5: + gasCounter += spec.GasVerylow + s := interp.Stack + t := s.top - 1 + if t < 5 { + if gas.remaining < gasCounter { + interp.HaltOOG() + return + } + gas.remaining -= gasCounter + gasCounter = 0 + interp.HaltOverflow() + } else { + s.data[t], s.data[t-5] = s.data[t-5], s.data[t] + } + case opcode.SWAP6: + gasCounter += spec.GasVerylow + s := interp.Stack + t := s.top - 1 + if t < 6 { + if gas.remaining < gasCounter { + interp.HaltOOG() + return + } + gas.remaining -= gasCounter + gasCounter = 0 + interp.HaltOverflow() + } else { + s.data[t], s.data[t-6] = s.data[t-6], s.data[t] + } + case opcode.SWAP7: + gasCounter += spec.GasVerylow + s := interp.Stack + t := s.top - 1 + if t < 7 { + if gas.remaining < gasCounter { + interp.HaltOOG() + return + } + gas.remaining -= gasCounter + gasCounter = 0 + interp.HaltOverflow() + } else { + s.data[t], s.data[t-7] = s.data[t-7], s.data[t] + } + case opcode.SWAP8: + gasCounter += spec.GasVerylow + s := interp.Stack + t := s.top - 1 + if t < 8 { + if gas.remaining < gasCounter { + interp.HaltOOG() + return + } + gas.remaining -= gasCounter + gasCounter = 0 + interp.HaltOverflow() + } else { + s.data[t], s.data[t-8] = s.data[t-8], s.data[t] + } + case opcode.SWAP9: + gasCounter += spec.GasVerylow + s := interp.Stack + t := s.top - 1 + if t < 9 { + if gas.remaining < gasCounter { + interp.HaltOOG() + return + } + gas.remaining -= gasCounter + gasCounter = 0 + interp.HaltOverflow() + } else { + s.data[t], s.data[t-9] = s.data[t-9], s.data[t] + } + case opcode.SWAP10: + gasCounter += spec.GasVerylow + s := interp.Stack + t := s.top - 1 + if t < 10 { + if gas.remaining < gasCounter { + interp.HaltOOG() + return + } + gas.remaining -= gasCounter + gasCounter = 0 + interp.HaltOverflow() + } else { + s.data[t], s.data[t-10] = s.data[t-10], s.data[t] + } + case opcode.SWAP11: + gasCounter += spec.GasVerylow + s := interp.Stack + t := s.top - 1 + if t < 11 { + if gas.remaining < gasCounter { + interp.HaltOOG() + return + } + gas.remaining -= gasCounter + gasCounter = 0 + interp.HaltOverflow() + } else { + s.data[t], s.data[t-11] = s.data[t-11], s.data[t] + } + case opcode.SWAP12: + gasCounter += spec.GasVerylow + s := interp.Stack + t := s.top - 1 + if t < 12 { + if gas.remaining < gasCounter { + interp.HaltOOG() + return + } + gas.remaining -= gasCounter + gasCounter = 0 + interp.HaltOverflow() + } else { + s.data[t], s.data[t-12] = s.data[t-12], s.data[t] + } + case opcode.SWAP13: + gasCounter += spec.GasVerylow + s := interp.Stack + t := s.top - 1 + if t < 13 { + if gas.remaining < gasCounter { + interp.HaltOOG() + return + } + gas.remaining -= gasCounter + gasCounter = 0 + interp.HaltOverflow() + } else { + s.data[t], s.data[t-13] = s.data[t-13], s.data[t] + } + case opcode.SWAP14: + gasCounter += spec.GasVerylow + s := interp.Stack + t := s.top - 1 + if t < 14 { + if gas.remaining < gasCounter { + interp.HaltOOG() + return + } + gas.remaining -= gasCounter + gasCounter = 0 + interp.HaltOverflow() + } else { + s.data[t], s.data[t-14] = s.data[t-14], s.data[t] + } + case opcode.SWAP15: + gasCounter += spec.GasVerylow + s := interp.Stack + t := s.top - 1 + if t < 15 { + if gas.remaining < gasCounter { + interp.HaltOOG() + return + } + gas.remaining -= gasCounter + gasCounter = 0 + interp.HaltOverflow() + } else { + s.data[t], s.data[t-15] = s.data[t-15], s.data[t] + } + case opcode.SWAP16: + gasCounter += spec.GasVerylow + s := interp.Stack + t := s.top - 1 + if t < 16 { + if gas.remaining < gasCounter { + interp.HaltOOG() + return + } + gas.remaining -= gasCounter + gasCounter = 0 + interp.HaltOverflow() + } else { + s.data[t], s.data[t-16] = s.data[t-16], s.data[t] + } + case opcode.LOG0: + if gas.remaining < gasCounter { + interp.HaltOOG() + return + } + gas.remaining -= gasCounter + gasCounter = 0 + logNImpl(interp, host, 0) + case opcode.LOG1: + if gas.remaining < gasCounter { + interp.HaltOOG() + return + } + gas.remaining -= gasCounter + gasCounter = 0 + logNImpl(interp, host, 1) case opcode.LOG2: if gas.remaining < gasCounter { interp.HaltOOG() @@ -2317,223 +2837,497 @@ func (r *TracingRunner) Run(interp *Interpreter, host Host) { } else { s.top-- - a := s.data[s.top] - top := &s.data[s.top-1] - top.SDiv(&a, top) + a := s.data[s.top] + top := &s.data[s.top-1] + top.SDiv(&a, top) + + } + case opcode.MOD: + if gas.remaining < spec.GasLow { + interp.HaltOOG() + return + } + gas.remaining -= spec.GasLow + s := interp.Stack + if s.top < 2 { + interp.HaltUnderflow() + } else { + s.top-- + + a := s.data[s.top] + top := &s.data[s.top-1] + if !top.IsZero() { + top.Mod(&a, top) + } + + } + case opcode.SMOD: + if gas.remaining < spec.GasLow { + interp.HaltOOG() + return + } + gas.remaining -= spec.GasLow + s := interp.Stack + if s.top < 2 { + interp.HaltUnderflow() + } else { + s.top-- + + a := s.data[s.top] + top := &s.data[s.top-1] + top.SMod(&a, top) + + } + case opcode.ADDMOD: + if gas.remaining < spec.GasMid { + interp.HaltOOG() + return + } + gas.remaining -= spec.GasMid + s := interp.Stack + if s.top < 3 { + interp.HaltUnderflow() + } else { + s.top -= 2 + + a := s.data[s.top+1] + b := s.data[s.top] + top := &s.data[s.top-1] + top.AddMod(&a, &b, top) + + } + case opcode.MULMOD: + if gas.remaining < spec.GasMid { + interp.HaltOOG() + return + } + gas.remaining -= spec.GasMid + s := interp.Stack + if s.top < 3 { + interp.HaltUnderflow() + } else { + s.top -= 2 + + a := s.data[s.top+1] + b := s.data[s.top] + top := &s.data[s.top-1] + top.MulMod(&a, &b, top) + + } + case opcode.EXP: + if gas.remaining < spec.GasHigh { + interp.HaltOOG() + return + } + gas.remaining -= spec.GasHigh + opExp(interp) + case opcode.SIGNEXTEND: + if gas.remaining < spec.GasLow { + interp.HaltOOG() + return + } + gas.remaining -= spec.GasLow + s := interp.Stack + if s.top < 2 { + interp.HaltUnderflow() + } else { + s.top-- + + ext := s.data[s.top] + top := &s.data[s.top-1] + top.ExtendSign(top, &ext) + + } + case opcode.LT: + if gas.remaining < spec.GasVerylow { + interp.HaltOOG() + return + } + gas.remaining -= spec.GasVerylow + s := interp.Stack + if s.top < 2 { + interp.HaltUnderflow() + } else { + s.top-- + + if s.data[s.top].Lt(&s.data[s.top-1]) { + s.data[s.top-1] = uint256.Int{1, 0, 0, 0} + } else { + s.data[s.top-1] = uint256.Int{} + } + + } + case opcode.GT: + if gas.remaining < spec.GasVerylow { + interp.HaltOOG() + return + } + gas.remaining -= spec.GasVerylow + s := interp.Stack + if s.top < 2 { + interp.HaltUnderflow() + } else { + s.top-- + + if s.data[s.top].Gt(&s.data[s.top-1]) { + s.data[s.top-1] = uint256.Int{1, 0, 0, 0} + } else { + s.data[s.top-1] = uint256.Int{} + } + + } + case opcode.SLT: + if gas.remaining < spec.GasVerylow { + interp.HaltOOG() + return + } + gas.remaining -= spec.GasVerylow + s := interp.Stack + if s.top < 2 { + interp.HaltUnderflow() + } else { + s.top-- + + a := &s.data[s.top] + b := &s.data[s.top-1] + aNeg := a[3] >> 63 + bNeg := b[3] >> 63 + var lt bool + if aNeg != bNeg { + lt = aNeg > bNeg + } else { + lt = a.Lt(b) + } + if lt { + s.data[s.top-1] = uint256.Int{1, 0, 0, 0} + } else { + s.data[s.top-1] = uint256.Int{} + } + + } + case opcode.SGT: + if gas.remaining < spec.GasVerylow { + interp.HaltOOG() + return + } + gas.remaining -= spec.GasVerylow + s := interp.Stack + if s.top < 2 { + interp.HaltUnderflow() + } else { + s.top-- + + a := &s.data[s.top] + b := &s.data[s.top-1] + aNeg := a[3] >> 63 + bNeg := b[3] >> 63 + var gt bool + if aNeg != bNeg { + gt = bNeg > aNeg + } else { + gt = a.Gt(b) + } + if gt { + s.data[s.top-1] = uint256.Int{1, 0, 0, 0} + } else { + s.data[s.top-1] = uint256.Int{} + } + + } + case opcode.EQ: + if gas.remaining < spec.GasVerylow { + interp.HaltOOG() + return + } + gas.remaining -= spec.GasVerylow + s := interp.Stack + if s.top < 2 { + interp.HaltUnderflow() + } else { + s.top-- + + if s.data[s.top].Eq(&s.data[s.top-1]) { + s.data[s.top-1] = uint256.Int{1, 0, 0, 0} + } else { + s.data[s.top-1] = uint256.Int{} + } + + } + case opcode.ISZERO: + if gas.remaining < spec.GasVerylow { + interp.HaltOOG() + return + } + gas.remaining -= spec.GasVerylow + s := interp.Stack + if s.top == 0 { + interp.HaltUnderflow() + } else { + + if s.data[s.top-1].IsZero() { + s.data[s.top-1] = uint256.Int{1, 0, 0, 0} + } else { + s.data[s.top-1] = uint256.Int{} + } + + } + case opcode.AND: + if gas.remaining < spec.GasVerylow { + interp.HaltOOG() + return + } + gas.remaining -= spec.GasVerylow + s := interp.Stack + if s.top < 2 { + interp.HaltUnderflow() + } else { + s.top-- + + s.data[s.top-1].And(&s.data[s.top], &s.data[s.top-1]) } - case opcode.MOD: - if gas.remaining < spec.GasLow { + case opcode.OR: + if gas.remaining < spec.GasVerylow { interp.HaltOOG() return } - gas.remaining -= spec.GasLow + gas.remaining -= spec.GasVerylow s := interp.Stack if s.top < 2 { interp.HaltUnderflow() } else { s.top-- - a := s.data[s.top] - top := &s.data[s.top-1] - if !top.IsZero() { - top.Mod(&a, top) - } + s.data[s.top-1].Or(&s.data[s.top], &s.data[s.top-1]) } - case opcode.SMOD: - if gas.remaining < spec.GasLow { + case opcode.XOR: + if gas.remaining < spec.GasVerylow { interp.HaltOOG() return } - gas.remaining -= spec.GasLow + gas.remaining -= spec.GasVerylow s := interp.Stack if s.top < 2 { interp.HaltUnderflow() } else { s.top-- - a := s.data[s.top] - top := &s.data[s.top-1] - top.SMod(&a, top) + s.data[s.top-1].Xor(&s.data[s.top], &s.data[s.top-1]) } - case opcode.ADDMOD: - if gas.remaining < spec.GasMid { + case opcode.NOT: + if gas.remaining < spec.GasVerylow { interp.HaltOOG() return } - gas.remaining -= spec.GasMid + gas.remaining -= spec.GasVerylow s := interp.Stack - if s.top < 3 { + if s.top == 0 { interp.HaltUnderflow() } else { - s.top -= 2 - a := s.data[s.top+1] - b := s.data[s.top] - top := &s.data[s.top-1] - top.AddMod(&a, &b, top) + s.data[s.top-1].Not(&s.data[s.top-1]) } - case opcode.MULMOD: - if gas.remaining < spec.GasMid { + case opcode.BYTE: + if gas.remaining < spec.GasVerylow { interp.HaltOOG() return } - gas.remaining -= spec.GasMid + gas.remaining -= spec.GasVerylow s := interp.Stack - if s.top < 3 { + if s.top < 2 { interp.HaltUnderflow() } else { - s.top -= 2 + s.top-- - a := s.data[s.top+1] - b := s.data[s.top] + a := s.data[s.top] top := &s.data[s.top-1] - top.MulMod(&a, &b, top) + idx, overflow := a.Uint64WithOverflow() + if !overflow && idx < 32 { + index := uint256.Int{idx, 0, 0, 0} + top.Byte(&index) + } else { + *top = uint256.Int{} + } } - case opcode.EXP: - if gas.remaining < spec.GasHigh { + case opcode.SHL: + if gas.remaining < spec.GasVerylow { interp.HaltOOG() return } - gas.remaining -= spec.GasHigh - opExp(interp) - case opcode.SIGNEXTEND: - if gas.remaining < spec.GasLow { + gas.remaining -= spec.GasVerylow + if !interp.RuntimeFlag.ForkID.IsEnabledIn(spec.Constantinople) { + interp.HaltNotActivated() + } else { + s := interp.Stack + if s.top < 2 { + interp.HaltUnderflow() + } else { + s.top-- + + shift := s.data[s.top] + top := &s.data[s.top-1] + sa, overflow := shift.Uint64WithOverflow() + if !overflow && sa < 256 { + top.Lsh(top, uint(sa)) + } else { + *top = uint256.Int{} + } + + } + } + case opcode.SHR: + if gas.remaining < spec.GasVerylow { interp.HaltOOG() return } - gas.remaining -= spec.GasLow - s := interp.Stack - if s.top < 2 { - interp.HaltUnderflow() + gas.remaining -= spec.GasVerylow + if !interp.RuntimeFlag.ForkID.IsEnabledIn(spec.Constantinople) { + interp.HaltNotActivated() } else { - s.top-- + s := interp.Stack + if s.top < 2 { + interp.HaltUnderflow() + } else { + s.top-- - ext := s.data[s.top] - top := &s.data[s.top-1] - top.ExtendSign(top, &ext) + shift := s.data[s.top] + top := &s.data[s.top-1] + sa, overflow := shift.Uint64WithOverflow() + if !overflow && sa < 256 { + top.Rsh(top, uint(sa)) + } else { + *top = uint256.Int{} + } + } } - case opcode.LT: + case opcode.SAR: if gas.remaining < spec.GasVerylow { interp.HaltOOG() return } gas.remaining -= spec.GasVerylow - s := interp.Stack - if s.top < 2 { - interp.HaltUnderflow() + if !interp.RuntimeFlag.ForkID.IsEnabledIn(spec.Constantinople) { + interp.HaltNotActivated() } else { - s.top-- - - if s.data[s.top].Lt(&s.data[s.top-1]) { - s.data[s.top-1] = uint256.Int{1, 0, 0, 0} + s := interp.Stack + if s.top < 2 { + interp.HaltUnderflow() } else { - s.data[s.top-1] = uint256.Int{} + s.top-- + + shift := s.data[s.top] + top := &s.data[s.top-1] + sa, overflow := shift.Uint64WithOverflow() + if !overflow && sa < 256 { + top.SRsh(top, uint(sa)) + } else if top[3]&(1<<63) != 0 { + *top = uint256.Int{^uint64(0), ^uint64(0), ^uint64(0), ^uint64(0)} + } else { + *top = uint256.Int{} + } + } + } + case opcode.CLZ: + if gas.remaining < spec.GasLow { + interp.HaltOOG() + return + } + gas.remaining -= spec.GasLow + if !interp.RuntimeFlag.ForkID.IsEnabledIn(spec.Osaka) { + interp.HaltNotActivated() + } else { + s := interp.Stack + if s.top == 0 { + interp.HaltUnderflow() + } else { + top := &s.data[s.top-1] + *top = uint256.Int{uint64(256 - top.BitLen()), 0, 0, 0} + + } } - case opcode.GT: - if gas.remaining < spec.GasVerylow { + case opcode.KECCAK256: + if gas.remaining < spec.GasKeccak256 { interp.HaltOOG() return } - gas.remaining -= spec.GasVerylow + gas.remaining -= spec.GasKeccak256 + opKeccak256(interp) + case opcode.ADDRESS: + if gas.remaining < spec.GasBase { + interp.HaltOOG() + return + } + gas.remaining -= spec.GasBase s := interp.Stack - if s.top < 2 { - interp.HaltUnderflow() + if s.top >= StackLimit { + interp.HaltOverflow() } else { - s.top-- - if s.data[s.top].Gt(&s.data[s.top-1]) { - s.data[s.top-1] = uint256.Int{1, 0, 0, 0} - } else { - s.data[s.top-1] = uint256.Int{} - } + s.data[s.top] = interp.Input.TargetAddress.ToU256() + s.top++ } - case opcode.SLT: - if gas.remaining < spec.GasVerylow { + case opcode.BALANCE: + if gas.remaining < interp.ForkGas.Balance { interp.HaltOOG() return } - gas.remaining -= spec.GasVerylow + gas.remaining -= interp.ForkGas.Balance + opBalance(interp, host) + case opcode.ORIGIN: + if gas.remaining < spec.GasBase { + interp.HaltOOG() + return + } + gas.remaining -= spec.GasBase s := interp.Stack - if s.top < 2 { - interp.HaltUnderflow() + if s.top >= StackLimit { + interp.HaltOverflow() } else { - s.top-- - a := &s.data[s.top] - b := &s.data[s.top-1] - aNeg := a[3] >> 63 - bNeg := b[3] >> 63 - var lt bool - if aNeg != bNeg { - lt = aNeg > bNeg - } else { - lt = a.Lt(b) - } - if lt { - s.data[s.top-1] = uint256.Int{1, 0, 0, 0} - } else { - s.data[s.top-1] = uint256.Int{} - } + addr := host.Caller() + s.data[s.top] = addr.ToU256() + s.top++ } - case opcode.SGT: - if gas.remaining < spec.GasVerylow { + case opcode.CALLER: + if gas.remaining < spec.GasBase { interp.HaltOOG() return } - gas.remaining -= spec.GasVerylow + gas.remaining -= spec.GasBase s := interp.Stack - if s.top < 2 { - interp.HaltUnderflow() + if s.top >= StackLimit { + interp.HaltOverflow() } else { - s.top-- - a := &s.data[s.top] - b := &s.data[s.top-1] - aNeg := a[3] >> 63 - bNeg := b[3] >> 63 - var gt bool - if aNeg != bNeg { - gt = bNeg > aNeg - } else { - gt = a.Gt(b) - } - if gt { - s.data[s.top-1] = uint256.Int{1, 0, 0, 0} - } else { - s.data[s.top-1] = uint256.Int{} - } + s.data[s.top] = interp.Input.CallerAddress.ToU256() + s.top++ } - case opcode.EQ: - if gas.remaining < spec.GasVerylow { + case opcode.CALLVALUE: + if gas.remaining < spec.GasBase { interp.HaltOOG() return } - gas.remaining -= spec.GasVerylow + gas.remaining -= spec.GasBase s := interp.Stack - if s.top < 2 { - interp.HaltUnderflow() + if s.top >= StackLimit { + interp.HaltOverflow() } else { - s.top-- - if s.data[s.top].Eq(&s.data[s.top-1]) { - s.data[s.top-1] = uint256.Int{1, 0, 0, 0} - } else { - s.data[s.top-1] = uint256.Int{} - } + s.data[s.top] = interp.Input.CallValue + s.top++ } - case opcode.ISZERO: + case opcode.CALLDATALOAD: if gas.remaining < spec.GasVerylow { interp.HaltOOG() return @@ -2544,321 +3338,464 @@ func (r *TracingRunner) Run(interp *Interpreter, host Host) { interp.HaltUnderflow() } else { - if s.data[s.top-1].IsZero() { - s.data[s.top-1] = uint256.Int{1, 0, 0, 0} - } else { - s.data[s.top-1] = uint256.Int{} + top := &s.data[s.top-1] + offset, overflow := top.Uint64WithOverflow() + if overflow { + offset = ^uint64(0) + } + input := interp.Input.Input + var word [32]byte + if offset < uint64(len(input)) { + src := input[offset:] + if len(src) >= 32 { + copy(word[:], src[:32]) + } else { + copy(word[:], src) + } } + *top = *new(uint256.Int).SetBytes32((word)[:]) } - case opcode.AND: - if gas.remaining < spec.GasVerylow { + case opcode.CALLDATASIZE: + if gas.remaining < spec.GasBase { interp.HaltOOG() return } - gas.remaining -= spec.GasVerylow + gas.remaining -= spec.GasBase s := interp.Stack - if s.top < 2 { - interp.HaltUnderflow() + if s.top >= StackLimit { + interp.HaltOverflow() } else { - s.top-- - s.data[s.top-1].And(&s.data[s.top], &s.data[s.top-1]) + s.data[s.top] = uint256.Int{uint64(len(interp.Input.Input)), 0, 0, 0} + s.top++ } - case opcode.OR: + case opcode.CALLDATACOPY: if gas.remaining < spec.GasVerylow { interp.HaltOOG() return } gas.remaining -= spec.GasVerylow + opCalldatacopy(interp) + case opcode.CODESIZE: + if gas.remaining < spec.GasBase { + interp.HaltOOG() + return + } + gas.remaining -= spec.GasBase s := interp.Stack - if s.top < 2 { - interp.HaltUnderflow() + if s.top >= StackLimit { + interp.HaltOverflow() } else { - s.top-- - s.data[s.top-1].Or(&s.data[s.top], &s.data[s.top-1]) + s.data[s.top] = uint256.Int{uint64(bc.originalLen), 0, 0, 0} + s.top++ } - case opcode.XOR: + case opcode.CODECOPY: if gas.remaining < spec.GasVerylow { interp.HaltOOG() return } gas.remaining -= spec.GasVerylow + opCodecopy(interp) + case opcode.GASPRICE: + if gas.remaining < spec.GasBase { + interp.HaltOOG() + return + } + gas.remaining -= spec.GasBase s := interp.Stack - if s.top < 2 { - interp.HaltUnderflow() + if s.top >= StackLimit { + interp.HaltOverflow() } else { - s.top-- - s.data[s.top-1].Xor(&s.data[s.top], &s.data[s.top-1]) + s.data[s.top] = host.EffectiveGasPrice() + s.top++ } - case opcode.NOT: + case opcode.EXTCODESIZE: + if gas.remaining < interp.ForkGas.ExtCodeSize { + interp.HaltOOG() + return + } + gas.remaining -= interp.ForkGas.ExtCodeSize + opExtcodesize(interp, host) + case opcode.EXTCODECOPY: + if gas.remaining < interp.ForkGas.ExtCodeSize { + interp.HaltOOG() + return + } + gas.remaining -= interp.ForkGas.ExtCodeSize + opExtcodecopy(interp, host) + case opcode.RETURNDATASIZE: + if gas.remaining < spec.GasBase { + interp.HaltOOG() + return + } + gas.remaining -= spec.GasBase + if !interp.RuntimeFlag.ForkID.IsEnabledIn(spec.Byzantium) { + interp.HaltNotActivated() + } else { + s := interp.Stack + if s.top >= StackLimit { + interp.HaltOverflow() + } else { + + s.data[s.top] = uint256.Int{uint64(len(interp.ReturnData)), 0, 0, 0} + s.top++ + + } + } + case opcode.RETURNDATACOPY: if gas.remaining < spec.GasVerylow { interp.HaltOOG() return } gas.remaining -= spec.GasVerylow + if !interp.RuntimeFlag.ForkID.IsEnabledIn(spec.Byzantium) { + interp.HaltNotActivated() + } else { + opReturndatacopy(interp) + } + case opcode.EXTCODEHASH: + if gas.remaining < interp.ForkGas.ExtCodeHash { + interp.HaltOOG() + return + } + gas.remaining -= interp.ForkGas.ExtCodeHash + if !interp.RuntimeFlag.ForkID.IsEnabledIn(spec.Constantinople) { + interp.HaltNotActivated() + } else { + opExtcodehash(interp, host) + } + case opcode.BLOCKHASH: + if gas.remaining < spec.GasBlockhash { + interp.HaltOOG() + return + } + gas.remaining -= spec.GasBlockhash s := interp.Stack if s.top == 0 { interp.HaltUnderflow() } else { - s.data[s.top-1].Not(&s.data[s.top-1]) + top := &s.data[s.top-1] + hash := host.BlockHash(*top) + *top = hash.ToU256() } - case opcode.BYTE: - if gas.remaining < spec.GasVerylow { + case opcode.COINBASE: + if gas.remaining < spec.GasBase { interp.HaltOOG() return } - gas.remaining -= spec.GasVerylow + gas.remaining -= spec.GasBase s := interp.Stack - if s.top < 2 { - interp.HaltUnderflow() + if s.top >= StackLimit { + interp.HaltOverflow() } else { - s.top-- - a := s.data[s.top] - top := &s.data[s.top-1] - idx, overflow := a.Uint64WithOverflow() - if !overflow && idx < 32 { - index := uint256.Int{idx, 0, 0, 0} - top.Byte(&index) - } else { - *top = uint256.Int{} - } + addr := host.Beneficiary() + s.data[s.top] = addr.ToU256() + s.top++ } - case opcode.SHL: - if gas.remaining < spec.GasVerylow { + case opcode.TIMESTAMP: + if gas.remaining < spec.GasBase { interp.HaltOOG() return } - gas.remaining -= spec.GasVerylow - if !interp.RuntimeFlag.ForkID.IsEnabledIn(spec.Constantinople) { - interp.HaltNotActivated() + gas.remaining -= spec.GasBase + s := interp.Stack + if s.top >= StackLimit { + interp.HaltOverflow() } else { - s := interp.Stack - if s.top < 2 { - interp.HaltUnderflow() - } else { - s.top-- - shift := s.data[s.top] - top := &s.data[s.top-1] - sa, overflow := shift.Uint64WithOverflow() - if !overflow && sa < 256 { - top.Lsh(top, uint(sa)) - } else { - *top = uint256.Int{} - } + s.data[s.top] = host.Timestamp() + s.top++ - } } - case opcode.SHR: - if gas.remaining < spec.GasVerylow { + case opcode.NUMBER: + if gas.remaining < spec.GasBase { interp.HaltOOG() return } - gas.remaining -= spec.GasVerylow - if !interp.RuntimeFlag.ForkID.IsEnabledIn(spec.Constantinople) { - interp.HaltNotActivated() + gas.remaining -= spec.GasBase + s := interp.Stack + if s.top >= StackLimit { + interp.HaltOverflow() } else { - s := interp.Stack - if s.top < 2 { - interp.HaltUnderflow() - } else { - s.top-- - shift := s.data[s.top] - top := &s.data[s.top-1] - sa, overflow := shift.Uint64WithOverflow() - if !overflow && sa < 256 { - top.Rsh(top, uint(sa)) - } else { - *top = uint256.Int{} - } + s.data[s.top] = host.BlockNumber() + s.top++ - } } - case opcode.SAR: - if gas.remaining < spec.GasVerylow { + case opcode.DIFFICULTY: + if gas.remaining < spec.GasBase { interp.HaltOOG() return } - gas.remaining -= spec.GasVerylow - if !interp.RuntimeFlag.ForkID.IsEnabledIn(spec.Constantinople) { - interp.HaltNotActivated() + gas.remaining -= spec.GasBase + opDifficulty(interp, host) + case opcode.GASLIMIT: + if gas.remaining < spec.GasBase { + interp.HaltOOG() + return + } + gas.remaining -= spec.GasBase + s := interp.Stack + if s.top >= StackLimit { + interp.HaltOverflow() } else { - s := interp.Stack - if s.top < 2 { - interp.HaltUnderflow() - } else { - s.top-- - shift := s.data[s.top] - top := &s.data[s.top-1] - sa, overflow := shift.Uint64WithOverflow() - if !overflow && sa < 256 { - top.SRsh(top, uint(sa)) - } else if top[3]&(1<<63) != 0 { - *top = uint256.Int{^uint64(0), ^uint64(0), ^uint64(0), ^uint64(0)} - } else { - *top = uint256.Int{} - } + s.data[s.top] = host.GasLimit() + s.top++ - } } - case opcode.CLZ: - if gas.remaining < spec.GasLow { + case opcode.CHAINID: + if gas.remaining < spec.GasBase { interp.HaltOOG() return } - gas.remaining -= spec.GasLow - if !interp.RuntimeFlag.ForkID.IsEnabledIn(spec.Osaka) { + gas.remaining -= spec.GasBase + if !interp.RuntimeFlag.ForkID.IsEnabledIn(spec.Istanbul) { interp.HaltNotActivated() } else { s := interp.Stack - if s.top == 0 { - interp.HaltUnderflow() + if s.top >= StackLimit { + interp.HaltOverflow() } else { - - top := &s.data[s.top-1] - *top = uint256.Int{uint64(256 - top.BitLen()), 0, 0, 0} - + opChainid(interp, host) } } - case opcode.KECCAK256: - if gas.remaining < spec.GasKeccak256 { + case opcode.SELFBALANCE: + if gas.remaining < spec.GasLow { interp.HaltOOG() return } - gas.remaining -= spec.GasKeccak256 - opKeccak256(interp) - case opcode.ADDRESS: + gas.remaining -= spec.GasLow + if !interp.RuntimeFlag.ForkID.IsEnabledIn(spec.Istanbul) { + interp.HaltNotActivated() + } else { + s := interp.Stack + if s.top >= StackLimit { + interp.HaltOverflow() + } else { + opSelfbalance(interp, host) + } + } + case opcode.BASEFEE: if gas.remaining < spec.GasBase { interp.HaltOOG() return } gas.remaining -= spec.GasBase - s := interp.Stack - if s.top >= StackLimit { - interp.HaltOverflow() + if !interp.RuntimeFlag.ForkID.IsEnabledIn(spec.London) { + interp.HaltNotActivated() } else { - - s.data[s.top] = interp.Input.TargetAddress.ToU256() - s.top++ - + s := interp.Stack + if s.top >= StackLimit { + interp.HaltOverflow() + } else { + opBasefee(interp, host) + } } - case opcode.BALANCE: - if gas.remaining < interp.ForkGas.Balance { + case opcode.BLOBHASH: + if gas.remaining < spec.GasVerylow { interp.HaltOOG() return } - gas.remaining -= interp.ForkGas.Balance - opBalance(interp, host) - case opcode.ORIGIN: + gas.remaining -= spec.GasVerylow + if !interp.RuntimeFlag.ForkID.IsEnabledIn(spec.Cancun) { + interp.HaltNotActivated() + } else { + opBlobhash(interp, host) + } + case opcode.BLOBBASEFEE: if gas.remaining < spec.GasBase { interp.HaltOOG() return } gas.remaining -= spec.GasBase - s := interp.Stack - if s.top >= StackLimit { - interp.HaltOverflow() + if !interp.RuntimeFlag.ForkID.IsEnabledIn(spec.Cancun) { + interp.HaltNotActivated() } else { - - addr := host.Caller() - s.data[s.top] = addr.ToU256() - s.top++ - + s := interp.Stack + if s.top >= StackLimit { + interp.HaltOverflow() + } else { + opBlobbasefee(interp, host) + } } - case opcode.CALLER: + case opcode.SLOTNUM: if gas.remaining < spec.GasBase { interp.HaltOOG() return } gas.remaining -= spec.GasBase - s := interp.Stack - if s.top >= StackLimit { - interp.HaltOverflow() + if !interp.RuntimeFlag.ForkID.IsEnabledIn(spec.Amsterdam) { + interp.HaltNotActivated() } else { - - s.data[s.top] = interp.Input.CallerAddress.ToU256() - s.top++ - + s := interp.Stack + if s.top >= StackLimit { + interp.HaltOverflow() + } else { + opSlotnum(interp, host) + } } - case opcode.CALLVALUE: + case opcode.POP: if gas.remaining < spec.GasBase { interp.HaltOOG() return } gas.remaining -= spec.GasBase - s := interp.Stack - if s.top >= StackLimit { - interp.HaltOverflow() + if interp.Stack.top == 0 { + interp.HaltUnderflow() } else { - s.data[s.top] = interp.Input.CallValue - s.top++ + interp.Stack.top-- } - case opcode.CALLDATALOAD: + case opcode.MLOAD: if gas.remaining < spec.GasVerylow { interp.HaltOOG() return } gas.remaining -= spec.GasVerylow + s := interp.Stack if s.top == 0 { interp.HaltUnderflow() - } else { - - top := &s.data[s.top-1] - offset, overflow := top.Uint64WithOverflow() - if overflow { - offset = ^uint64(0) - } - input := interp.Input.Input - var word [32]byte - if offset < uint64(len(input)) { - src := input[offset:] - if len(src) >= 32 { - copy(word[:], src[:32]) - } else { - copy(word[:], src) + return + } + top := &s.data[s.top-1] + if top[1]|top[2]|top[3] == 0 { + offset := int(top[0]) + if offset >= 0 && offset+32 <= interp.Memory.Len() { + *top = interp.Memory.GetU256(offset) + } else { + if interp.ResizeMemory(offset, 32) { + *top = interp.Memory.GetU256(offset) } } - *top = *new(uint256.Int).SetBytes32((word)[:]) - + } else { + interp.Halt(InstructionResultInvalidOperandOOG) } - case opcode.CALLDATASIZE: - if gas.remaining < spec.GasBase { + + case opcode.MSTORE: + if gas.remaining < spec.GasVerylow { interp.HaltOOG() return } - gas.remaining -= spec.GasBase + gas.remaining -= spec.GasVerylow + s := interp.Stack - if s.top >= StackLimit { - interp.HaltOverflow() + if s.top < 2 { + interp.HaltUnderflow() + return + } + s.top -= 2 + offsetVal := s.data[s.top+1] + value := s.data[s.top] + if offsetVal[1]|offsetVal[2]|offsetVal[3] == 0 { + offset := int(offsetVal[0]) + if offset >= 0 && offset+32 <= interp.Memory.Len() { + interp.Memory.SetU256(offset, value) + } else { + if interp.ResizeMemory(offset, 32) { + interp.Memory.SetU256(offset, value) + } + } } else { - - s.data[s.top] = uint256.Int{uint64(len(interp.Input.Input)), 0, 0, 0} - s.top++ - + interp.Halt(InstructionResultInvalidOperandOOG) } - case opcode.CALLDATACOPY: + + case opcode.MSTORE8: if gas.remaining < spec.GasVerylow { interp.HaltOOG() return } gas.remaining -= spec.GasVerylow - opCalldatacopy(interp) - case opcode.CODESIZE: + opMstore8(interp) + case opcode.SLOAD: + if gas.remaining < interp.ForkGas.Sload { + interp.HaltOOG() + return + } + gas.remaining -= interp.ForkGas.Sload + opSload(interp, host) + case opcode.SSTORE: + opSstore(interp, host) + case opcode.JUMP: + if gas.remaining < spec.GasMid { + interp.HaltOOG() + return + } + gas.remaining -= spec.GasMid + + s := interp.Stack + if s.top == 0 { + interp.HaltUnderflow() + return + } + s.top-- + target := s.data[s.top] + if target[1]|target[2]|target[3] != 0 { + interp.Halt(InstructionResultInvalidJump) + return + } + dest := int(target[0]) + if dest >= bc.originalLen || bc.code[dest] != opcode.JUMPDEST { + interp.Halt(InstructionResultInvalidJump) + return + } + if !bc.jumpTableReady { + bc.ensureJumpTable() + } + if bc.jumpTable[dest/8]&(1<<(uint(dest)%8)) == 0 { + interp.Halt(InstructionResultInvalidJump) + return + } + bc.pc = dest + + case opcode.JUMPI: + if gas.remaining < spec.GasHigh { + interp.HaltOOG() + return + } + gas.remaining -= spec.GasHigh + + s := interp.Stack + if s.top < 2 { + interp.HaltUnderflow() + return + } + s.top -= 2 + cond := s.data[s.top] + target := s.data[s.top+1] + if !cond.IsZero() { + if target[1]|target[2]|target[3] != 0 { + interp.Halt(InstructionResultInvalidJump) + return + } + dest := int(target[0]) + if dest >= bc.originalLen || bc.code[dest] != opcode.JUMPDEST { + interp.Halt(InstructionResultInvalidJump) + return + } + if !bc.jumpTableReady { + bc.ensureJumpTable() + } + if bc.jumpTable[dest/8]&(1<<(uint(dest)%8)) == 0 { + interp.Halt(InstructionResultInvalidJump) + return + } + bc.pc = dest + } + + case opcode.PC: if gas.remaining < spec.GasBase { interp.HaltOOG() return @@ -2869,18 +3806,11 @@ func (r *TracingRunner) Run(interp *Interpreter, host Host) { interp.HaltOverflow() } else { - s.data[s.top] = uint256.Int{uint64(bc.originalLen), 0, 0, 0} + s.data[s.top] = uint256.Int{uint64(bc.pc - 1), 0, 0, 0} s.top++ } - case opcode.CODECOPY: - if gas.remaining < spec.GasVerylow { - interp.HaltOOG() - return - } - gas.remaining -= spec.GasVerylow - opCodecopy(interp) - case opcode.GASPRICE: + case opcode.MSIZE: if gas.remaining < spec.GasBase { interp.HaltOOG() return @@ -2891,582 +3821,638 @@ func (r *TracingRunner) Run(interp *Interpreter, host Host) { interp.HaltOverflow() } else { - s.data[s.top] = host.EffectiveGasPrice() + s.data[s.top] = uint256.Int{uint64(interp.Memory.Len()), 0, 0, 0} s.top++ } - case opcode.EXTCODESIZE: - if gas.remaining < interp.ForkGas.ExtCodeSize { + case opcode.GAS: + if gas.remaining < spec.GasBase { interp.HaltOOG() return } - gas.remaining -= interp.ForkGas.ExtCodeSize - opExtcodesize(interp, host) - case opcode.EXTCODECOPY: - if gas.remaining < interp.ForkGas.ExtCodeSize { + gas.remaining -= spec.GasBase + opGas(interp) + case opcode.JUMPDEST: + if gas.remaining < spec.GasJumpdest { interp.HaltOOG() return } - gas.remaining -= interp.ForkGas.ExtCodeSize - opExtcodecopy(interp, host) - case opcode.RETURNDATASIZE: - if gas.remaining < spec.GasBase { + gas.remaining -= spec.GasJumpdest + case opcode.TLOAD: + if gas.remaining < spec.GasWarmStorageReadCost { interp.HaltOOG() return } - gas.remaining -= spec.GasBase - if !interp.RuntimeFlag.ForkID.IsEnabledIn(spec.Byzantium) { + gas.remaining -= spec.GasWarmStorageReadCost + if !interp.RuntimeFlag.ForkID.IsEnabledIn(spec.Cancun) { interp.HaltNotActivated() } else { - s := interp.Stack - if s.top >= StackLimit { - interp.HaltOverflow() - } else { - - s.data[s.top] = uint256.Int{uint64(len(interp.ReturnData)), 0, 0, 0} - s.top++ - - } + opTload(interp, host) } - case opcode.RETURNDATACOPY: - if gas.remaining < spec.GasVerylow { + case opcode.TSTORE: + if gas.remaining < spec.GasWarmStorageReadCost { interp.HaltOOG() return } - gas.remaining -= spec.GasVerylow - if !interp.RuntimeFlag.ForkID.IsEnabledIn(spec.Byzantium) { + gas.remaining -= spec.GasWarmStorageReadCost + if !interp.RuntimeFlag.ForkID.IsEnabledIn(spec.Cancun) { interp.HaltNotActivated() } else { - opReturndatacopy(interp) + opTstore(interp, host) } - case opcode.EXTCODEHASH: - if gas.remaining < interp.ForkGas.ExtCodeHash { + case opcode.MCOPY: + if gas.remaining < spec.GasVerylow { interp.HaltOOG() return } - gas.remaining -= interp.ForkGas.ExtCodeHash - if !interp.RuntimeFlag.ForkID.IsEnabledIn(spec.Constantinople) { + gas.remaining -= spec.GasVerylow + if !interp.RuntimeFlag.ForkID.IsEnabledIn(spec.Cancun) { interp.HaltNotActivated() } else { - opExtcodehash(interp, host) + opMcopy(interp) } - case opcode.BLOCKHASH: - if gas.remaining < spec.GasBlockhash { + case opcode.DUPN: + if gas.remaining < spec.GasVerylow { interp.HaltOOG() return } - gas.remaining -= spec.GasBlockhash - s := interp.Stack - if s.top == 0 { - interp.HaltUnderflow() + gas.remaining -= spec.GasVerylow + if !interp.RuntimeFlag.ForkID.IsEnabledIn(spec.Amsterdam) { + interp.HaltNotActivated() } else { - - top := &s.data[s.top-1] - hash := host.BlockHash(*top) - *top = hash.ToU256() - + opDupN(interp) } - case opcode.COINBASE: - if gas.remaining < spec.GasBase { + case opcode.SWAPN: + if gas.remaining < spec.GasVerylow { interp.HaltOOG() return } - gas.remaining -= spec.GasBase - s := interp.Stack - if s.top >= StackLimit { - interp.HaltOverflow() + gas.remaining -= spec.GasVerylow + if !interp.RuntimeFlag.ForkID.IsEnabledIn(spec.Amsterdam) { + interp.HaltNotActivated() } else { - - addr := host.Beneficiary() - s.data[s.top] = addr.ToU256() - s.top++ - + opSwapN(interp) } - case opcode.TIMESTAMP: - if gas.remaining < spec.GasBase { + case opcode.EXCHANGE: + if gas.remaining < spec.GasVerylow { interp.HaltOOG() return } - gas.remaining -= spec.GasBase - s := interp.Stack - if s.top >= StackLimit { - interp.HaltOverflow() + gas.remaining -= spec.GasVerylow + if !interp.RuntimeFlag.ForkID.IsEnabledIn(spec.Amsterdam) { + interp.HaltNotActivated() } else { - - s.data[s.top] = host.Timestamp() - s.top++ - + opExchange(interp) } - case opcode.NUMBER: - if gas.remaining < spec.GasBase { + case opcode.CREATE: + opCreate(interp, host) + case opcode.CALL: + if gas.remaining < interp.ForkGas.Call { interp.HaltOOG() return } - gas.remaining -= spec.GasBase - s := interp.Stack - if s.top >= StackLimit { - interp.HaltOverflow() - } else { - - s.data[s.top] = host.BlockNumber() - s.top++ - + gas.remaining -= interp.ForkGas.Call + opCall(interp, host) + case opcode.CALLCODE: + if gas.remaining < interp.ForkGas.Call { + interp.HaltOOG() + return } - case opcode.DIFFICULTY: - if gas.remaining < spec.GasBase { + gas.remaining -= interp.ForkGas.Call + opCallcode(interp, host) + case opcode.RETURN: + opReturn(interp) + case opcode.DELEGATECALL: + if gas.remaining < interp.ForkGas.Call { interp.HaltOOG() return } - gas.remaining -= spec.GasBase - opDifficulty(interp, host) - case opcode.GASLIMIT: - if gas.remaining < spec.GasBase { + gas.remaining -= interp.ForkGas.Call + if !interp.RuntimeFlag.ForkID.IsEnabledIn(spec.Homestead) { + interp.HaltNotActivated() + } else { + opDelegatecall(interp, host) + } + case opcode.CREATE2: + if !interp.RuntimeFlag.ForkID.IsEnabledIn(spec.Petersburg) { + interp.HaltNotActivated() + } else { + opCreate2(interp, host) + } + case opcode.STATICCALL: + if gas.remaining < interp.ForkGas.Call { interp.HaltOOG() return } - gas.remaining -= spec.GasBase - s := interp.Stack - if s.top >= StackLimit { - interp.HaltOverflow() + gas.remaining -= interp.ForkGas.Call + if !interp.RuntimeFlag.ForkID.IsEnabledIn(spec.Byzantium) { + interp.HaltNotActivated() + } else { + opStaticcall(interp, host) + } + case opcode.REVERT: + if !interp.RuntimeFlag.ForkID.IsEnabledIn(spec.Byzantium) { + interp.HaltNotActivated() } else { + opRevert(interp) + } + case opcode.INVALID: - s.data[s.top] = host.GasLimit() - s.top++ + interp.Halt(InstructionResultInvalidFEOpcode) + case opcode.SELFDESTRUCT: + if gas.remaining < interp.ForkGas.Selfdestruct { + interp.HaltOOG() + return } - case opcode.CHAINID: + gas.remaining -= interp.ForkGas.Selfdestruct + opSelfdestruct(interp, host) + case opcode.PUSH0: if gas.remaining < spec.GasBase { interp.HaltOOG() return } gas.remaining -= spec.GasBase - if !interp.RuntimeFlag.ForkID.IsEnabledIn(spec.Istanbul) { + if !interp.RuntimeFlag.ForkID.IsEnabledIn(spec.Shanghai) { interp.HaltNotActivated() } else { s := interp.Stack if s.top >= StackLimit { interp.HaltOverflow() } else { - opChainid(interp, host) + + s.data[s.top] = uint256.Int{} + s.top++ + } } - case opcode.SELFBALANCE: - if gas.remaining < spec.GasLow { + case opcode.PUSH1: + if gas.remaining < spec.GasVerylow { interp.HaltOOG() return } - gas.remaining -= spec.GasLow - if !interp.RuntimeFlag.ForkID.IsEnabledIn(spec.Istanbul) { - interp.HaltNotActivated() + gas.remaining -= spec.GasVerylow + s := interp.Stack + if s.top >= StackLimit { + interp.HaltOverflow() } else { - s := interp.Stack - if s.top >= StackLimit { - interp.HaltOverflow() - } else { - opSelfbalance(interp, host) - } + + s.data[s.top] = uint256.Int{uint64(bc.code[bc.pc]), 0, 0, 0} + bc.pc++ + s.top++ + } - case opcode.BASEFEE: - if gas.remaining < spec.GasBase { + case opcode.PUSH2: + if gas.remaining < spec.GasVerylow { interp.HaltOOG() return } - gas.remaining -= spec.GasBase - if !interp.RuntimeFlag.ForkID.IsEnabledIn(spec.London) { - interp.HaltNotActivated() + gas.remaining -= spec.GasVerylow + s := interp.Stack + if s.top >= StackLimit { + interp.HaltOverflow() } else { - s := interp.Stack - if s.top >= StackLimit { - interp.HaltOverflow() - } else { - opBasefee(interp, host) - } + + v := uint64(bc.code[bc.pc])<<8 | uint64(bc.code[bc.pc+1]) + bc.pc += 2 + s.data[s.top] = uint256.Int{v, 0, 0, 0} + s.top++ + + } + case opcode.PUSH3: + if gas.remaining < spec.GasVerylow { + interp.HaltOOG() + return + } + gas.remaining -= spec.GasVerylow + s := interp.Stack + if s.top >= StackLimit { + interp.HaltOverflow() + } else { + + c := bc.code + p := bc.pc + v := uint64(c[p])<<16 | uint64(c[p+1])<<8 | uint64(c[p+2]) + bc.pc = p + 3 + s.data[s.top] = uint256.Int{v, 0, 0, 0} + s.top++ + } - case opcode.BLOBHASH: + case opcode.PUSH4: if gas.remaining < spec.GasVerylow { interp.HaltOOG() return } gas.remaining -= spec.GasVerylow - if !interp.RuntimeFlag.ForkID.IsEnabledIn(spec.Cancun) { - interp.HaltNotActivated() + s := interp.Stack + if s.top >= StackLimit { + interp.HaltOverflow() } else { - opBlobhash(interp, host) + + c := bc.code + p := bc.pc + v := uint64(c[p])<<24 | uint64(c[p+1])<<16 | uint64(c[p+2])<<8 | uint64(c[p+3]) + bc.pc = p + 4 + s.data[s.top] = uint256.Int{v, 0, 0, 0} + s.top++ + } - case opcode.BLOBBASEFEE: - if gas.remaining < spec.GasBase { + case opcode.PUSH20: + if gas.remaining < spec.GasVerylow { interp.HaltOOG() return } - gas.remaining -= spec.GasBase - if !interp.RuntimeFlag.ForkID.IsEnabledIn(spec.Cancun) { - interp.HaltNotActivated() + gas.remaining -= spec.GasVerylow + s := interp.Stack + if s.top >= StackLimit { + interp.HaltOverflow() } else { - s := interp.Stack - if s.top >= StackLimit { - interp.HaltOverflow() - } else { - opBlobbasefee(interp, host) - } + + c := bc.code + p := bc.pc + // 20 bytes = limb2 (4 bytes) + limb1 (8 bytes) + limb0 (8 bytes) + l2 := uint64(c[p])<<24 | uint64(c[p+1])<<16 | uint64(c[p+2])<<8 | uint64(c[p+3]) + l1 := uint64(c[p+4])<<56 | uint64(c[p+5])<<48 | uint64(c[p+6])<<40 | uint64(c[p+7])<<32 | + uint64(c[p+8])<<24 | uint64(c[p+9])<<16 | uint64(c[p+10])<<8 | uint64(c[p+11]) + l0 := uint64(c[p+12])<<56 | uint64(c[p+13])<<48 | uint64(c[p+14])<<40 | uint64(c[p+15])<<32 | + uint64(c[p+16])<<24 | uint64(c[p+17])<<16 | uint64(c[p+18])<<8 | uint64(c[p+19]) + bc.pc = p + 20 + s.data[s.top] = uint256.Int{l0, l1, l2, 0} + s.top++ + } - case opcode.SLOTNUM: - if gas.remaining < spec.GasBase { + case opcode.PUSH32: + if gas.remaining < spec.GasVerylow { interp.HaltOOG() return } - gas.remaining -= spec.GasBase - if !interp.RuntimeFlag.ForkID.IsEnabledIn(spec.Amsterdam) { - interp.HaltNotActivated() + gas.remaining -= spec.GasVerylow + s := interp.Stack + if s.top >= StackLimit { + interp.HaltOverflow() } else { - s := interp.Stack - if s.top >= StackLimit { - interp.HaltOverflow() - } else { - opSlotnum(interp, host) - } + + c := bc.code + p := bc.pc + l3 := uint64(c[p])<<56 | uint64(c[p+1])<<48 | uint64(c[p+2])<<40 | uint64(c[p+3])<<32 | + uint64(c[p+4])<<24 | uint64(c[p+5])<<16 | uint64(c[p+6])<<8 | uint64(c[p+7]) + l2 := uint64(c[p+8])<<56 | uint64(c[p+9])<<48 | uint64(c[p+10])<<40 | uint64(c[p+11])<<32 | + uint64(c[p+12])<<24 | uint64(c[p+13])<<16 | uint64(c[p+14])<<8 | uint64(c[p+15]) + l1 := uint64(c[p+16])<<56 | uint64(c[p+17])<<48 | uint64(c[p+18])<<40 | uint64(c[p+19])<<32 | + uint64(c[p+20])<<24 | uint64(c[p+21])<<16 | uint64(c[p+22])<<8 | uint64(c[p+23]) + l0 := uint64(c[p+24])<<56 | uint64(c[p+25])<<48 | uint64(c[p+26])<<40 | uint64(c[p+27])<<32 | + uint64(c[p+28])<<24 | uint64(c[p+29])<<16 | uint64(c[p+30])<<8 | uint64(c[p+31]) + bc.pc = p + 32 + s.data[s.top] = uint256.Int{l0, l1, l2, l3} + s.top++ + } - case opcode.POP: - if gas.remaining < spec.GasBase { + case opcode.PUSH5: + if gas.remaining < spec.GasVerylow { interp.HaltOOG() return } - gas.remaining -= spec.GasBase - if interp.Stack.top == 0 { - interp.HaltUnderflow() + gas.remaining -= spec.GasVerylow + s := interp.Stack + if s.top >= StackLimit { + interp.HaltOverflow() } else { - - interp.Stack.top-- - + c := bc.code + p := bc.pc + l0 := uint64(c[p+0])<<32 | uint64(c[p+1])<<24 | uint64(c[p+2])<<16 | uint64(c[p+3])<<8 | uint64(c[p+4]) + bc.pc = p + 5 + s.data[s.top] = uint256.Int{l0, 0, 0, 0} + s.top++ } - case opcode.MLOAD: + case opcode.PUSH6: if gas.remaining < spec.GasVerylow { interp.HaltOOG() return } gas.remaining -= spec.GasVerylow - s := interp.Stack - if s.top == 0 { - interp.HaltUnderflow() - return - } - top := &s.data[s.top-1] - if top[1]|top[2]|top[3] == 0 { - offset := int(top[0]) - if offset >= 0 && offset+32 <= interp.Memory.Len() { - *top = interp.Memory.GetU256(offset) - } else { - if interp.ResizeMemory(offset, 32) { - *top = interp.Memory.GetU256(offset) - } - } + if s.top >= StackLimit { + interp.HaltOverflow() } else { - interp.Halt(InstructionResultInvalidOperandOOG) + c := bc.code + p := bc.pc + l0 := uint64(c[p+0])<<40 | uint64(c[p+1])<<32 | uint64(c[p+2])<<24 | uint64(c[p+3])<<16 | uint64(c[p+4])<<8 | uint64(c[p+5]) + bc.pc = p + 6 + s.data[s.top] = uint256.Int{l0, 0, 0, 0} + s.top++ } - - case opcode.MSTORE: + case opcode.PUSH7: if gas.remaining < spec.GasVerylow { interp.HaltOOG() return } gas.remaining -= spec.GasVerylow - s := interp.Stack - if s.top < 2 { - interp.HaltUnderflow() - return - } - s.top -= 2 - offsetVal := s.data[s.top+1] - value := s.data[s.top] - if offsetVal[1]|offsetVal[2]|offsetVal[3] == 0 { - offset := int(offsetVal[0]) - if offset >= 0 && offset+32 <= interp.Memory.Len() { - interp.Memory.SetU256(offset, value) - } else { - if interp.ResizeMemory(offset, 32) { - interp.Memory.SetU256(offset, value) - } - } + if s.top >= StackLimit { + interp.HaltOverflow() } else { - interp.Halt(InstructionResultInvalidOperandOOG) + c := bc.code + p := bc.pc + l0 := uint64(c[p+0])<<48 | uint64(c[p+1])<<40 | uint64(c[p+2])<<32 | uint64(c[p+3])<<24 | uint64(c[p+4])<<16 | uint64(c[p+5])<<8 | uint64(c[p+6]) + bc.pc = p + 7 + s.data[s.top] = uint256.Int{l0, 0, 0, 0} + s.top++ } - - case opcode.MSTORE8: + case opcode.PUSH8: if gas.remaining < spec.GasVerylow { interp.HaltOOG() return } gas.remaining -= spec.GasVerylow - opMstore8(interp) - case opcode.SLOAD: - if gas.remaining < interp.ForkGas.Sload { - interp.HaltOOG() - return + s := interp.Stack + if s.top >= StackLimit { + interp.HaltOverflow() + } else { + c := bc.code + p := bc.pc + l0 := uint64(c[p+0])<<56 | uint64(c[p+1])<<48 | uint64(c[p+2])<<40 | uint64(c[p+3])<<32 | uint64(c[p+4])<<24 | uint64(c[p+5])<<16 | uint64(c[p+6])<<8 | uint64(c[p+7]) + bc.pc = p + 8 + s.data[s.top] = uint256.Int{l0, 0, 0, 0} + s.top++ } - gas.remaining -= interp.ForkGas.Sload - opSload(interp, host) - case opcode.SSTORE: - opSstore(interp, host) - case opcode.JUMP: - if gas.remaining < spec.GasMid { + case opcode.PUSH9: + if gas.remaining < spec.GasVerylow { interp.HaltOOG() return } - gas.remaining -= spec.GasMid - + gas.remaining -= spec.GasVerylow s := interp.Stack - if s.top == 0 { - interp.HaltUnderflow() - return - } - s.top-- - target := s.data[s.top] - if target[1]|target[2]|target[3] != 0 { - interp.Halt(InstructionResultInvalidJump) - return + if s.top >= StackLimit { + interp.HaltOverflow() + } else { + c := bc.code + p := bc.pc + l0 := uint64(c[p+1])<<56 | uint64(c[p+2])<<48 | uint64(c[p+3])<<40 | uint64(c[p+4])<<32 | uint64(c[p+5])<<24 | uint64(c[p+6])<<16 | uint64(c[p+7])<<8 | uint64(c[p+8]) + l1 := uint64(c[p+0]) + bc.pc = p + 9 + s.data[s.top] = uint256.Int{l0, l1, 0, 0} + s.top++ } - dest := int(target[0]) - if dest >= bc.originalLen || bc.code[dest] != opcode.JUMPDEST { - interp.Halt(InstructionResultInvalidJump) + case opcode.PUSH10: + if gas.remaining < spec.GasVerylow { + interp.HaltOOG() return } - if !bc.jumpTableReady { - bc.ensureJumpTable() - } - if bc.jumpTable[dest/8]&(1<<(uint(dest)%8)) == 0 { - interp.Halt(InstructionResultInvalidJump) - return + gas.remaining -= spec.GasVerylow + s := interp.Stack + if s.top >= StackLimit { + interp.HaltOverflow() + } else { + c := bc.code + p := bc.pc + l0 := uint64(c[p+2])<<56 | uint64(c[p+3])<<48 | uint64(c[p+4])<<40 | uint64(c[p+5])<<32 | uint64(c[p+6])<<24 | uint64(c[p+7])<<16 | uint64(c[p+8])<<8 | uint64(c[p+9]) + l1 := uint64(c[p+0])<<8 | uint64(c[p+1]) + bc.pc = p + 10 + s.data[s.top] = uint256.Int{l0, l1, 0, 0} + s.top++ } - bc.pc = dest - - case opcode.JUMPI: - if gas.remaining < spec.GasHigh { + case opcode.PUSH11: + if gas.remaining < spec.GasVerylow { interp.HaltOOG() return } - gas.remaining -= spec.GasHigh - + gas.remaining -= spec.GasVerylow s := interp.Stack - if s.top < 2 { - interp.HaltUnderflow() - return + if s.top >= StackLimit { + interp.HaltOverflow() + } else { + c := bc.code + p := bc.pc + l0 := uint64(c[p+3])<<56 | uint64(c[p+4])<<48 | uint64(c[p+5])<<40 | uint64(c[p+6])<<32 | uint64(c[p+7])<<24 | uint64(c[p+8])<<16 | uint64(c[p+9])<<8 | uint64(c[p+10]) + l1 := uint64(c[p+0])<<16 | uint64(c[p+1])<<8 | uint64(c[p+2]) + bc.pc = p + 11 + s.data[s.top] = uint256.Int{l0, l1, 0, 0} + s.top++ } - s.top -= 2 - cond := s.data[s.top] - target := s.data[s.top+1] - if !cond.IsZero() { - if target[1]|target[2]|target[3] != 0 { - interp.Halt(InstructionResultInvalidJump) - return - } - dest := int(target[0]) - if dest >= bc.originalLen || bc.code[dest] != opcode.JUMPDEST { - interp.Halt(InstructionResultInvalidJump) - return - } - if !bc.jumpTableReady { - bc.ensureJumpTable() - } - if bc.jumpTable[dest/8]&(1<<(uint(dest)%8)) == 0 { - interp.Halt(InstructionResultInvalidJump) - return - } - bc.pc = dest + case opcode.PUSH12: + if gas.remaining < spec.GasVerylow { + interp.HaltOOG() + return } - - case opcode.PC: - if gas.remaining < spec.GasBase { + gas.remaining -= spec.GasVerylow + s := interp.Stack + if s.top >= StackLimit { + interp.HaltOverflow() + } else { + c := bc.code + p := bc.pc + l0 := uint64(c[p+4])<<56 | uint64(c[p+5])<<48 | uint64(c[p+6])<<40 | uint64(c[p+7])<<32 | uint64(c[p+8])<<24 | uint64(c[p+9])<<16 | uint64(c[p+10])<<8 | uint64(c[p+11]) + l1 := uint64(c[p+0])<<24 | uint64(c[p+1])<<16 | uint64(c[p+2])<<8 | uint64(c[p+3]) + bc.pc = p + 12 + s.data[s.top] = uint256.Int{l0, l1, 0, 0} + s.top++ + } + case opcode.PUSH13: + if gas.remaining < spec.GasVerylow { interp.HaltOOG() return } - gas.remaining -= spec.GasBase + gas.remaining -= spec.GasVerylow s := interp.Stack if s.top >= StackLimit { interp.HaltOverflow() } else { - - s.data[s.top] = uint256.Int{uint64(bc.pc - 1), 0, 0, 0} + c := bc.code + p := bc.pc + l0 := uint64(c[p+5])<<56 | uint64(c[p+6])<<48 | uint64(c[p+7])<<40 | uint64(c[p+8])<<32 | uint64(c[p+9])<<24 | uint64(c[p+10])<<16 | uint64(c[p+11])<<8 | uint64(c[p+12]) + l1 := uint64(c[p+0])<<32 | uint64(c[p+1])<<24 | uint64(c[p+2])<<16 | uint64(c[p+3])<<8 | uint64(c[p+4]) + bc.pc = p + 13 + s.data[s.top] = uint256.Int{l0, l1, 0, 0} s.top++ - } - case opcode.MSIZE: - if gas.remaining < spec.GasBase { + case opcode.PUSH14: + if gas.remaining < spec.GasVerylow { interp.HaltOOG() return } - gas.remaining -= spec.GasBase + gas.remaining -= spec.GasVerylow s := interp.Stack if s.top >= StackLimit { interp.HaltOverflow() } else { - - s.data[s.top] = uint256.Int{uint64(interp.Memory.Len()), 0, 0, 0} + c := bc.code + p := bc.pc + l0 := uint64(c[p+6])<<56 | uint64(c[p+7])<<48 | uint64(c[p+8])<<40 | uint64(c[p+9])<<32 | uint64(c[p+10])<<24 | uint64(c[p+11])<<16 | uint64(c[p+12])<<8 | uint64(c[p+13]) + l1 := uint64(c[p+0])<<40 | uint64(c[p+1])<<32 | uint64(c[p+2])<<24 | uint64(c[p+3])<<16 | uint64(c[p+4])<<8 | uint64(c[p+5]) + bc.pc = p + 14 + s.data[s.top] = uint256.Int{l0, l1, 0, 0} s.top++ - - } - case opcode.GAS: - if gas.remaining < spec.GasBase { - interp.HaltOOG() - return } - gas.remaining -= spec.GasBase - opGas(interp) - case opcode.JUMPDEST: - if gas.remaining < spec.GasJumpdest { - interp.HaltOOG() - return - } - gas.remaining -= spec.GasJumpdest - case opcode.TLOAD: - if gas.remaining < spec.GasWarmStorageReadCost { + case opcode.PUSH15: + if gas.remaining < spec.GasVerylow { interp.HaltOOG() return } - gas.remaining -= spec.GasWarmStorageReadCost - if !interp.RuntimeFlag.ForkID.IsEnabledIn(spec.Cancun) { - interp.HaltNotActivated() + gas.remaining -= spec.GasVerylow + s := interp.Stack + if s.top >= StackLimit { + interp.HaltOverflow() } else { - opTload(interp, host) + c := bc.code + p := bc.pc + l0 := uint64(c[p+7])<<56 | uint64(c[p+8])<<48 | uint64(c[p+9])<<40 | uint64(c[p+10])<<32 | uint64(c[p+11])<<24 | uint64(c[p+12])<<16 | uint64(c[p+13])<<8 | uint64(c[p+14]) + l1 := uint64(c[p+0])<<48 | uint64(c[p+1])<<40 | uint64(c[p+2])<<32 | uint64(c[p+3])<<24 | uint64(c[p+4])<<16 | uint64(c[p+5])<<8 | uint64(c[p+6]) + bc.pc = p + 15 + s.data[s.top] = uint256.Int{l0, l1, 0, 0} + s.top++ } - case opcode.TSTORE: - if gas.remaining < spec.GasWarmStorageReadCost { + case opcode.PUSH16: + if gas.remaining < spec.GasVerylow { interp.HaltOOG() return } - gas.remaining -= spec.GasWarmStorageReadCost - if !interp.RuntimeFlag.ForkID.IsEnabledIn(spec.Cancun) { - interp.HaltNotActivated() + gas.remaining -= spec.GasVerylow + s := interp.Stack + if s.top >= StackLimit { + interp.HaltOverflow() } else { - opTstore(interp, host) + c := bc.code + p := bc.pc + l0 := uint64(c[p+8])<<56 | uint64(c[p+9])<<48 | uint64(c[p+10])<<40 | uint64(c[p+11])<<32 | uint64(c[p+12])<<24 | uint64(c[p+13])<<16 | uint64(c[p+14])<<8 | uint64(c[p+15]) + l1 := uint64(c[p+0])<<56 | uint64(c[p+1])<<48 | uint64(c[p+2])<<40 | uint64(c[p+3])<<32 | uint64(c[p+4])<<24 | uint64(c[p+5])<<16 | uint64(c[p+6])<<8 | uint64(c[p+7]) + bc.pc = p + 16 + s.data[s.top] = uint256.Int{l0, l1, 0, 0} + s.top++ } - case opcode.MCOPY: + case opcode.PUSH17: if gas.remaining < spec.GasVerylow { interp.HaltOOG() return } gas.remaining -= spec.GasVerylow - if !interp.RuntimeFlag.ForkID.IsEnabledIn(spec.Cancun) { - interp.HaltNotActivated() + s := interp.Stack + if s.top >= StackLimit { + interp.HaltOverflow() } else { - opMcopy(interp) + c := bc.code + p := bc.pc + l0 := uint64(c[p+9])<<56 | uint64(c[p+10])<<48 | uint64(c[p+11])<<40 | uint64(c[p+12])<<32 | uint64(c[p+13])<<24 | uint64(c[p+14])<<16 | uint64(c[p+15])<<8 | uint64(c[p+16]) + l1 := uint64(c[p+1])<<56 | uint64(c[p+2])<<48 | uint64(c[p+3])<<40 | uint64(c[p+4])<<32 | uint64(c[p+5])<<24 | uint64(c[p+6])<<16 | uint64(c[p+7])<<8 | uint64(c[p+8]) + l2 := uint64(c[p+0]) + bc.pc = p + 17 + s.data[s.top] = uint256.Int{l0, l1, l2, 0} + s.top++ } - case opcode.DUPN: + case opcode.PUSH18: if gas.remaining < spec.GasVerylow { interp.HaltOOG() return } gas.remaining -= spec.GasVerylow - if !interp.RuntimeFlag.ForkID.IsEnabledIn(spec.Amsterdam) { - interp.HaltNotActivated() + s := interp.Stack + if s.top >= StackLimit { + interp.HaltOverflow() } else { - opDupN(interp) + c := bc.code + p := bc.pc + l0 := uint64(c[p+10])<<56 | uint64(c[p+11])<<48 | uint64(c[p+12])<<40 | uint64(c[p+13])<<32 | uint64(c[p+14])<<24 | uint64(c[p+15])<<16 | uint64(c[p+16])<<8 | uint64(c[p+17]) + l1 := uint64(c[p+2])<<56 | uint64(c[p+3])<<48 | uint64(c[p+4])<<40 | uint64(c[p+5])<<32 | uint64(c[p+6])<<24 | uint64(c[p+7])<<16 | uint64(c[p+8])<<8 | uint64(c[p+9]) + l2 := uint64(c[p+0])<<8 | uint64(c[p+1]) + bc.pc = p + 18 + s.data[s.top] = uint256.Int{l0, l1, l2, 0} + s.top++ } - case opcode.SWAPN: + case opcode.PUSH19: if gas.remaining < spec.GasVerylow { interp.HaltOOG() return } gas.remaining -= spec.GasVerylow - if !interp.RuntimeFlag.ForkID.IsEnabledIn(spec.Amsterdam) { - interp.HaltNotActivated() + s := interp.Stack + if s.top >= StackLimit { + interp.HaltOverflow() } else { - opSwapN(interp) + c := bc.code + p := bc.pc + l0 := uint64(c[p+11])<<56 | uint64(c[p+12])<<48 | uint64(c[p+13])<<40 | uint64(c[p+14])<<32 | uint64(c[p+15])<<24 | uint64(c[p+16])<<16 | uint64(c[p+17])<<8 | uint64(c[p+18]) + l1 := uint64(c[p+3])<<56 | uint64(c[p+4])<<48 | uint64(c[p+5])<<40 | uint64(c[p+6])<<32 | uint64(c[p+7])<<24 | uint64(c[p+8])<<16 | uint64(c[p+9])<<8 | uint64(c[p+10]) + l2 := uint64(c[p+0])<<16 | uint64(c[p+1])<<8 | uint64(c[p+2]) + bc.pc = p + 19 + s.data[s.top] = uint256.Int{l0, l1, l2, 0} + s.top++ } - case opcode.EXCHANGE: + case opcode.PUSH21: if gas.remaining < spec.GasVerylow { interp.HaltOOG() return } gas.remaining -= spec.GasVerylow - if !interp.RuntimeFlag.ForkID.IsEnabledIn(spec.Amsterdam) { - interp.HaltNotActivated() + s := interp.Stack + if s.top >= StackLimit { + interp.HaltOverflow() } else { - opExchange(interp) - } - case opcode.CREATE: - opCreate(interp, host) - case opcode.CALL: - if gas.remaining < interp.ForkGas.Call { - interp.HaltOOG() - return - } - gas.remaining -= interp.ForkGas.Call - opCall(interp, host) - case opcode.CALLCODE: - if gas.remaining < interp.ForkGas.Call { - interp.HaltOOG() - return + c := bc.code + p := bc.pc + l0 := uint64(c[p+13])<<56 | uint64(c[p+14])<<48 | uint64(c[p+15])<<40 | uint64(c[p+16])<<32 | uint64(c[p+17])<<24 | uint64(c[p+18])<<16 | uint64(c[p+19])<<8 | uint64(c[p+20]) + l1 := uint64(c[p+5])<<56 | uint64(c[p+6])<<48 | uint64(c[p+7])<<40 | uint64(c[p+8])<<32 | uint64(c[p+9])<<24 | uint64(c[p+10])<<16 | uint64(c[p+11])<<8 | uint64(c[p+12]) + l2 := uint64(c[p+0])<<32 | uint64(c[p+1])<<24 | uint64(c[p+2])<<16 | uint64(c[p+3])<<8 | uint64(c[p+4]) + bc.pc = p + 21 + s.data[s.top] = uint256.Int{l0, l1, l2, 0} + s.top++ } - gas.remaining -= interp.ForkGas.Call - opCallcode(interp, host) - case opcode.RETURN: - opReturn(interp) - case opcode.DELEGATECALL: - if gas.remaining < interp.ForkGas.Call { + case opcode.PUSH22: + if gas.remaining < spec.GasVerylow { interp.HaltOOG() return } - gas.remaining -= interp.ForkGas.Call - if !interp.RuntimeFlag.ForkID.IsEnabledIn(spec.Homestead) { - interp.HaltNotActivated() - } else { - opDelegatecall(interp, host) - } - case opcode.CREATE2: - if !interp.RuntimeFlag.ForkID.IsEnabledIn(spec.Petersburg) { - interp.HaltNotActivated() + gas.remaining -= spec.GasVerylow + s := interp.Stack + if s.top >= StackLimit { + interp.HaltOverflow() } else { - opCreate2(interp, host) + c := bc.code + p := bc.pc + l0 := uint64(c[p+14])<<56 | uint64(c[p+15])<<48 | uint64(c[p+16])<<40 | uint64(c[p+17])<<32 | uint64(c[p+18])<<24 | uint64(c[p+19])<<16 | uint64(c[p+20])<<8 | uint64(c[p+21]) + l1 := uint64(c[p+6])<<56 | uint64(c[p+7])<<48 | uint64(c[p+8])<<40 | uint64(c[p+9])<<32 | uint64(c[p+10])<<24 | uint64(c[p+11])<<16 | uint64(c[p+12])<<8 | uint64(c[p+13]) + l2 := uint64(c[p+0])<<40 | uint64(c[p+1])<<32 | uint64(c[p+2])<<24 | uint64(c[p+3])<<16 | uint64(c[p+4])<<8 | uint64(c[p+5]) + bc.pc = p + 22 + s.data[s.top] = uint256.Int{l0, l1, l2, 0} + s.top++ } - case opcode.STATICCALL: - if gas.remaining < interp.ForkGas.Call { + case opcode.PUSH23: + if gas.remaining < spec.GasVerylow { interp.HaltOOG() return } - gas.remaining -= interp.ForkGas.Call - if !interp.RuntimeFlag.ForkID.IsEnabledIn(spec.Byzantium) { - interp.HaltNotActivated() - } else { - opStaticcall(interp, host) - } - case opcode.REVERT: - if !interp.RuntimeFlag.ForkID.IsEnabledIn(spec.Byzantium) { - interp.HaltNotActivated() + gas.remaining -= spec.GasVerylow + s := interp.Stack + if s.top >= StackLimit { + interp.HaltOverflow() } else { - opRevert(interp) - } - case opcode.INVALID: - - interp.Halt(InstructionResultInvalidFEOpcode) - - case opcode.SELFDESTRUCT: - if gas.remaining < interp.ForkGas.Selfdestruct { - interp.HaltOOG() - return + c := bc.code + p := bc.pc + l0 := uint64(c[p+15])<<56 | uint64(c[p+16])<<48 | uint64(c[p+17])<<40 | uint64(c[p+18])<<32 | uint64(c[p+19])<<24 | uint64(c[p+20])<<16 | uint64(c[p+21])<<8 | uint64(c[p+22]) + l1 := uint64(c[p+7])<<56 | uint64(c[p+8])<<48 | uint64(c[p+9])<<40 | uint64(c[p+10])<<32 | uint64(c[p+11])<<24 | uint64(c[p+12])<<16 | uint64(c[p+13])<<8 | uint64(c[p+14]) + l2 := uint64(c[p+0])<<48 | uint64(c[p+1])<<40 | uint64(c[p+2])<<32 | uint64(c[p+3])<<24 | uint64(c[p+4])<<16 | uint64(c[p+5])<<8 | uint64(c[p+6]) + bc.pc = p + 23 + s.data[s.top] = uint256.Int{l0, l1, l2, 0} + s.top++ } - gas.remaining -= interp.ForkGas.Selfdestruct - opSelfdestruct(interp, host) - case opcode.PUSH0: - if gas.remaining < spec.GasBase { + case opcode.PUSH24: + if gas.remaining < spec.GasVerylow { interp.HaltOOG() return } - gas.remaining -= spec.GasBase - if !interp.RuntimeFlag.ForkID.IsEnabledIn(spec.Shanghai) { - interp.HaltNotActivated() + gas.remaining -= spec.GasVerylow + s := interp.Stack + if s.top >= StackLimit { + interp.HaltOverflow() } else { - s := interp.Stack - if s.top >= StackLimit { - interp.HaltOverflow() - } else { - - s.data[s.top] = uint256.Int{} - s.top++ - - } + c := bc.code + p := bc.pc + l0 := uint64(c[p+16])<<56 | uint64(c[p+17])<<48 | uint64(c[p+18])<<40 | uint64(c[p+19])<<32 | uint64(c[p+20])<<24 | uint64(c[p+21])<<16 | uint64(c[p+22])<<8 | uint64(c[p+23]) + l1 := uint64(c[p+8])<<56 | uint64(c[p+9])<<48 | uint64(c[p+10])<<40 | uint64(c[p+11])<<32 | uint64(c[p+12])<<24 | uint64(c[p+13])<<16 | uint64(c[p+14])<<8 | uint64(c[p+15]) + l2 := uint64(c[p+0])<<56 | uint64(c[p+1])<<48 | uint64(c[p+2])<<40 | uint64(c[p+3])<<32 | uint64(c[p+4])<<24 | uint64(c[p+5])<<16 | uint64(c[p+6])<<8 | uint64(c[p+7]) + bc.pc = p + 24 + s.data[s.top] = uint256.Int{l0, l1, l2, 0} + s.top++ } - case opcode.PUSH1: + case opcode.PUSH25: if gas.remaining < spec.GasVerylow { interp.HaltOOG() return @@ -3476,13 +4462,17 @@ func (r *TracingRunner) Run(interp *Interpreter, host Host) { if s.top >= StackLimit { interp.HaltOverflow() } else { - - s.data[s.top] = uint256.Int{uint64(bc.code[bc.pc]), 0, 0, 0} - bc.pc++ + c := bc.code + p := bc.pc + l0 := uint64(c[p+17])<<56 | uint64(c[p+18])<<48 | uint64(c[p+19])<<40 | uint64(c[p+20])<<32 | uint64(c[p+21])<<24 | uint64(c[p+22])<<16 | uint64(c[p+23])<<8 | uint64(c[p+24]) + l1 := uint64(c[p+9])<<56 | uint64(c[p+10])<<48 | uint64(c[p+11])<<40 | uint64(c[p+12])<<32 | uint64(c[p+13])<<24 | uint64(c[p+14])<<16 | uint64(c[p+15])<<8 | uint64(c[p+16]) + l2 := uint64(c[p+1])<<56 | uint64(c[p+2])<<48 | uint64(c[p+3])<<40 | uint64(c[p+4])<<32 | uint64(c[p+5])<<24 | uint64(c[p+6])<<16 | uint64(c[p+7])<<8 | uint64(c[p+8]) + l3 := uint64(c[p+0]) + bc.pc = p + 25 + s.data[s.top] = uint256.Int{l0, l1, l2, l3} s.top++ - } - case opcode.PUSH2: + case opcode.PUSH26: if gas.remaining < spec.GasVerylow { interp.HaltOOG() return @@ -3492,14 +4482,17 @@ func (r *TracingRunner) Run(interp *Interpreter, host Host) { if s.top >= StackLimit { interp.HaltOverflow() } else { - - v := uint64(bc.code[bc.pc])<<8 | uint64(bc.code[bc.pc+1]) - bc.pc += 2 - s.data[s.top] = uint256.Int{v, 0, 0, 0} + c := bc.code + p := bc.pc + l0 := uint64(c[p+18])<<56 | uint64(c[p+19])<<48 | uint64(c[p+20])<<40 | uint64(c[p+21])<<32 | uint64(c[p+22])<<24 | uint64(c[p+23])<<16 | uint64(c[p+24])<<8 | uint64(c[p+25]) + l1 := uint64(c[p+10])<<56 | uint64(c[p+11])<<48 | uint64(c[p+12])<<40 | uint64(c[p+13])<<32 | uint64(c[p+14])<<24 | uint64(c[p+15])<<16 | uint64(c[p+16])<<8 | uint64(c[p+17]) + l2 := uint64(c[p+2])<<56 | uint64(c[p+3])<<48 | uint64(c[p+4])<<40 | uint64(c[p+5])<<32 | uint64(c[p+6])<<24 | uint64(c[p+7])<<16 | uint64(c[p+8])<<8 | uint64(c[p+9]) + l3 := uint64(c[p+0])<<8 | uint64(c[p+1]) + bc.pc = p + 26 + s.data[s.top] = uint256.Int{l0, l1, l2, l3} s.top++ - } - case opcode.PUSH3: + case opcode.PUSH27: if gas.remaining < spec.GasVerylow { interp.HaltOOG() return @@ -3509,16 +4502,17 @@ func (r *TracingRunner) Run(interp *Interpreter, host Host) { if s.top >= StackLimit { interp.HaltOverflow() } else { - c := bc.code p := bc.pc - v := uint64(c[p])<<16 | uint64(c[p+1])<<8 | uint64(c[p+2]) - bc.pc = p + 3 - s.data[s.top] = uint256.Int{v, 0, 0, 0} + l0 := uint64(c[p+19])<<56 | uint64(c[p+20])<<48 | uint64(c[p+21])<<40 | uint64(c[p+22])<<32 | uint64(c[p+23])<<24 | uint64(c[p+24])<<16 | uint64(c[p+25])<<8 | uint64(c[p+26]) + l1 := uint64(c[p+11])<<56 | uint64(c[p+12])<<48 | uint64(c[p+13])<<40 | uint64(c[p+14])<<32 | uint64(c[p+15])<<24 | uint64(c[p+16])<<16 | uint64(c[p+17])<<8 | uint64(c[p+18]) + l2 := uint64(c[p+3])<<56 | uint64(c[p+4])<<48 | uint64(c[p+5])<<40 | uint64(c[p+6])<<32 | uint64(c[p+7])<<24 | uint64(c[p+8])<<16 | uint64(c[p+9])<<8 | uint64(c[p+10]) + l3 := uint64(c[p+0])<<16 | uint64(c[p+1])<<8 | uint64(c[p+2]) + bc.pc = p + 27 + s.data[s.top] = uint256.Int{l0, l1, l2, l3} s.top++ - } - case opcode.PUSH4: + case opcode.PUSH28: if gas.remaining < spec.GasVerylow { interp.HaltOOG() return @@ -3528,16 +4522,17 @@ func (r *TracingRunner) Run(interp *Interpreter, host Host) { if s.top >= StackLimit { interp.HaltOverflow() } else { - c := bc.code p := bc.pc - v := uint64(c[p])<<24 | uint64(c[p+1])<<16 | uint64(c[p+2])<<8 | uint64(c[p+3]) - bc.pc = p + 4 - s.data[s.top] = uint256.Int{v, 0, 0, 0} + l0 := uint64(c[p+20])<<56 | uint64(c[p+21])<<48 | uint64(c[p+22])<<40 | uint64(c[p+23])<<32 | uint64(c[p+24])<<24 | uint64(c[p+25])<<16 | uint64(c[p+26])<<8 | uint64(c[p+27]) + l1 := uint64(c[p+12])<<56 | uint64(c[p+13])<<48 | uint64(c[p+14])<<40 | uint64(c[p+15])<<32 | uint64(c[p+16])<<24 | uint64(c[p+17])<<16 | uint64(c[p+18])<<8 | uint64(c[p+19]) + l2 := uint64(c[p+4])<<56 | uint64(c[p+5])<<48 | uint64(c[p+6])<<40 | uint64(c[p+7])<<32 | uint64(c[p+8])<<24 | uint64(c[p+9])<<16 | uint64(c[p+10])<<8 | uint64(c[p+11]) + l3 := uint64(c[p+0])<<24 | uint64(c[p+1])<<16 | uint64(c[p+2])<<8 | uint64(c[p+3]) + bc.pc = p + 28 + s.data[s.top] = uint256.Int{l0, l1, l2, l3} s.top++ - } - case opcode.PUSH20: + case opcode.PUSH29: if gas.remaining < spec.GasVerylow { interp.HaltOOG() return @@ -3547,21 +4542,17 @@ func (r *TracingRunner) Run(interp *Interpreter, host Host) { if s.top >= StackLimit { interp.HaltOverflow() } else { - c := bc.code p := bc.pc - // 20 bytes = limb2 (4 bytes) + limb1 (8 bytes) + limb0 (8 bytes) - l2 := uint64(c[p])<<24 | uint64(c[p+1])<<16 | uint64(c[p+2])<<8 | uint64(c[p+3]) - l1 := uint64(c[p+4])<<56 | uint64(c[p+5])<<48 | uint64(c[p+6])<<40 | uint64(c[p+7])<<32 | - uint64(c[p+8])<<24 | uint64(c[p+9])<<16 | uint64(c[p+10])<<8 | uint64(c[p+11]) - l0 := uint64(c[p+12])<<56 | uint64(c[p+13])<<48 | uint64(c[p+14])<<40 | uint64(c[p+15])<<32 | - uint64(c[p+16])<<24 | uint64(c[p+17])<<16 | uint64(c[p+18])<<8 | uint64(c[p+19]) - bc.pc = p + 20 - s.data[s.top] = uint256.Int{l0, l1, l2, 0} + l0 := uint64(c[p+21])<<56 | uint64(c[p+22])<<48 | uint64(c[p+23])<<40 | uint64(c[p+24])<<32 | uint64(c[p+25])<<24 | uint64(c[p+26])<<16 | uint64(c[p+27])<<8 | uint64(c[p+28]) + l1 := uint64(c[p+13])<<56 | uint64(c[p+14])<<48 | uint64(c[p+15])<<40 | uint64(c[p+16])<<32 | uint64(c[p+17])<<24 | uint64(c[p+18])<<16 | uint64(c[p+19])<<8 | uint64(c[p+20]) + l2 := uint64(c[p+5])<<56 | uint64(c[p+6])<<48 | uint64(c[p+7])<<40 | uint64(c[p+8])<<32 | uint64(c[p+9])<<24 | uint64(c[p+10])<<16 | uint64(c[p+11])<<8 | uint64(c[p+12]) + l3 := uint64(c[p+0])<<32 | uint64(c[p+1])<<24 | uint64(c[p+2])<<16 | uint64(c[p+3])<<8 | uint64(c[p+4]) + bc.pc = p + 29 + s.data[s.top] = uint256.Int{l0, l1, l2, l3} s.top++ - } - case opcode.PUSH32: + case opcode.PUSH30: if gas.remaining < spec.GasVerylow { interp.HaltOOG() return @@ -3571,23 +4562,17 @@ func (r *TracingRunner) Run(interp *Interpreter, host Host) { if s.top >= StackLimit { interp.HaltOverflow() } else { - c := bc.code p := bc.pc - l3 := uint64(c[p])<<56 | uint64(c[p+1])<<48 | uint64(c[p+2])<<40 | uint64(c[p+3])<<32 | - uint64(c[p+4])<<24 | uint64(c[p+5])<<16 | uint64(c[p+6])<<8 | uint64(c[p+7]) - l2 := uint64(c[p+8])<<56 | uint64(c[p+9])<<48 | uint64(c[p+10])<<40 | uint64(c[p+11])<<32 | - uint64(c[p+12])<<24 | uint64(c[p+13])<<16 | uint64(c[p+14])<<8 | uint64(c[p+15]) - l1 := uint64(c[p+16])<<56 | uint64(c[p+17])<<48 | uint64(c[p+18])<<40 | uint64(c[p+19])<<32 | - uint64(c[p+20])<<24 | uint64(c[p+21])<<16 | uint64(c[p+22])<<8 | uint64(c[p+23]) - l0 := uint64(c[p+24])<<56 | uint64(c[p+25])<<48 | uint64(c[p+26])<<40 | uint64(c[p+27])<<32 | - uint64(c[p+28])<<24 | uint64(c[p+29])<<16 | uint64(c[p+30])<<8 | uint64(c[p+31]) - bc.pc = p + 32 + l0 := uint64(c[p+22])<<56 | uint64(c[p+23])<<48 | uint64(c[p+24])<<40 | uint64(c[p+25])<<32 | uint64(c[p+26])<<24 | uint64(c[p+27])<<16 | uint64(c[p+28])<<8 | uint64(c[p+29]) + l1 := uint64(c[p+14])<<56 | uint64(c[p+15])<<48 | uint64(c[p+16])<<40 | uint64(c[p+17])<<32 | uint64(c[p+18])<<24 | uint64(c[p+19])<<16 | uint64(c[p+20])<<8 | uint64(c[p+21]) + l2 := uint64(c[p+6])<<56 | uint64(c[p+7])<<48 | uint64(c[p+8])<<40 | uint64(c[p+9])<<32 | uint64(c[p+10])<<24 | uint64(c[p+11])<<16 | uint64(c[p+12])<<8 | uint64(c[p+13]) + l3 := uint64(c[p+0])<<40 | uint64(c[p+1])<<32 | uint64(c[p+2])<<24 | uint64(c[p+3])<<16 | uint64(c[p+4])<<8 | uint64(c[p+5]) + bc.pc = p + 30 s.data[s.top] = uint256.Int{l0, l1, l2, l3} s.top++ - } - case opcode.PUSH5, opcode.PUSH6, opcode.PUSH7, opcode.PUSH8, opcode.PUSH9, opcode.PUSH10, opcode.PUSH11, opcode.PUSH12, opcode.PUSH13, opcode.PUSH14, opcode.PUSH15, opcode.PUSH16, opcode.PUSH17, opcode.PUSH18, opcode.PUSH19, opcode.PUSH21, opcode.PUSH22, opcode.PUSH23, opcode.PUSH24, opcode.PUSH25, opcode.PUSH26, opcode.PUSH27, opcode.PUSH28, opcode.PUSH29, opcode.PUSH30, opcode.PUSH31: + case opcode.PUSH31: if gas.remaining < spec.GasVerylow { interp.HaltOOG() return @@ -3597,9 +4582,14 @@ func (r *TracingRunner) Run(interp *Interpreter, host Host) { if s.top >= StackLimit { interp.HaltOverflow() } else { - n := int(op - opcode.PUSH0) - s.data[s.top] = *new(uint256.Int).SetBytes(bc.code[bc.pc : bc.pc+n]) - bc.pc += n + c := bc.code + p := bc.pc + l0 := uint64(c[p+23])<<56 | uint64(c[p+24])<<48 | uint64(c[p+25])<<40 | uint64(c[p+26])<<32 | uint64(c[p+27])<<24 | uint64(c[p+28])<<16 | uint64(c[p+29])<<8 | uint64(c[p+30]) + l1 := uint64(c[p+15])<<56 | uint64(c[p+16])<<48 | uint64(c[p+17])<<40 | uint64(c[p+18])<<32 | uint64(c[p+19])<<24 | uint64(c[p+20])<<16 | uint64(c[p+21])<<8 | uint64(c[p+22]) + l2 := uint64(c[p+7])<<56 | uint64(c[p+8])<<48 | uint64(c[p+9])<<40 | uint64(c[p+10])<<32 | uint64(c[p+11])<<24 | uint64(c[p+12])<<16 | uint64(c[p+13])<<8 | uint64(c[p+14]) + l3 := uint64(c[p+0])<<48 | uint64(c[p+1])<<40 | uint64(c[p+2])<<32 | uint64(c[p+3])<<24 | uint64(c[p+4])<<16 | uint64(c[p+5])<<8 | uint64(c[p+6]) + bc.pc = p + 31 + s.data[s.top] = uint256.Int{l0, l1, l2, l3} s.top++ } case opcode.DUP1: