-
Notifications
You must be signed in to change notification settings - Fork 0
/
stack.go
36 lines (31 loc) · 1.27 KB
/
stack.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
package specops
import (
"fmt"
"github.com/ethereum/go-ethereum/core/vm"
)
// A stackDelta carries the number of values popped and pushed by an opcode.
// Values are generated by the opcopy binary.
type stackDelta struct {
pop, push uint
}
// Inverted applies DUP<X> and SWAP<X> opcodes relative to the bottom-most value
// on the stack unless there are more than 16 values, in which case they are
// applied relative to the 16th.
//
// For a stack with n <= 16 values on it, `Inverted(DUP1)` and `Inverted(SWAP1)`
// will apply to the nth value instead of the first. Similarly, `Inverted(DUP2)`
// will apply to the (n-1)the value, etc. For a stack with >16 items, the same
// logic applies but with n = 16.
//
// Note that the semantics disallow `Inverted(SWAP16)` as it would be a noop. In
// fact, in all cases, inverted SWAPs are capped at `depth-1`. While they could
// be offset by one (like regular SWAPs) this is less intuitive than
// `Inverted(SWAP1)` being the bottom of a (sub-16-depth) stack.
//
// See stack.SetDepth() for caveats. It is best practice to use `Inverted` in
// conjunction with stack.{Set/Expect}Depth().
type Inverted vm.OpCode
// Bytecode always returns an error.
func (i Inverted) Bytecode() ([]byte, error) {
return nil, fmt.Errorf("call to %T.Bytecode()", i)
}